Преглед изворни кода

[librm] Speed up real-to-protected mode transition under KVM

Ensure that all segment registers have zero in the low two bits before
transitioning to protected mode.  This allows the CPU state to
immediately be deemed to be "valid", and eliminates the need for any
further emulated instructions.

Load the protected-mode interrupt descriptor table after switching to
protected mode, since this avoids triggering an EXCEPTION_NMI and
corresponding VM exit.

This reduces the time taken by real_to_prot under KVM by around 50%.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown пре 10 година
родитељ
комит
c64747db50

+ 4
- 1
src/arch/i386/prefix/libprefix.S Прегледај датотеку

@@ -522,8 +522,11 @@ alloc_basemem:
522 522
 	subw	$_data16_memsz_pgh, %ax
523 523
 	pushw	%ax
524 524
 
525
-	/* Calculate .text16 segment address */
525
+	/* Calculate .text16 segment address.  Round down to ensure
526
+	 * low bits are zero, to speed up mode transitions under KVM.
527
+	 */
526 528
 	subw	$_text16_memsz_pgh, %ax
529
+	andb	$~0x03, %al
527 530
 	pushw	%ax
528 531
 
529 532
 	/* Update FBMS */

+ 17
- 2
src/arch/i386/transitions/librm.S Прегледај датотеку

@@ -200,10 +200,22 @@ real_to_prot:
200 200
 	addr32 leal (%eax,%edx), %esi
201 201
 	subl	rm_virt_offset, %esi
202 202
 
203
+	/* Load protected-mode global descriptor table */
204
+	data32 lgdt gdtr
205
+
206
+	/* Zero segment registers.  This wastes around 12 cycles on
207
+	 * real hardware, but saves a substantial number of emulated
208
+	 * instructions under KVM.
209
+	 */
210
+	xorw	%ax, %ax
211
+	movw	%ax, %ds
212
+	movw	%ax, %es
213
+	movw	%ax, %fs
214
+	movw	%ax, %gs
215
+	movw	%ax, %ss
216
+
203 217
 	/* Switch to protected mode */
204 218
 	cli
205
-	data32 lgdt gdtr
206
-	data32 lidt idtr
207 219
 	movl	%cr0, %eax
208 220
 	orb	$CR0_PE, %al
209 221
 	movl	%eax, %cr0
@@ -220,6 +232,9 @@ r2p_pmode:
220 232
 	movw	%ax, %ss
221 233
 	movl	pm_esp, %esp
222 234
 
235
+	/* Load protected-mode interrupt descriptor table */
236
+	lidt	idtr
237
+
223 238
 	/* Record real-mode %ss:sp (after removal of data) */
224 239
 	movw	%bp, rm_ss
225 240
 	addl	%ecx, %edx

+ 1
- 2
src/arch/i386/transitions/librm_mgmt.c Прегледај датотеку

@@ -26,10 +26,9 @@ static struct interrupt_vector intr_vec[ IRQ_MAX + 1 ];
26 26
 struct interrupt_descriptor idt[NUM_INT] __attribute__ (( aligned ( 16 ) ));
27 27
 
28 28
 /** The interrupt descriptor table register */
29
-struct idtr __data16 ( idtr ) = {
29
+struct idtr idtr = {
30 30
 	.limit = ( sizeof ( idt ) - 1 ),
31 31
 };
32
-#define idtr __use_data16 ( idtr )
33 32
 
34 33
 /**
35 34
  * Allocate space on the real-mode stack and copy data there from a

Loading…
Откажи
Сачувај