diff --git a/src/arch/i386/prefix/libprefix.S b/src/arch/i386/prefix/libprefix.S index 197a86bc..3aee415f 100644 --- a/src/arch/i386/prefix/libprefix.S +++ b/src/arch/i386/prefix/libprefix.S @@ -522,8 +522,11 @@ alloc_basemem: subw $_data16_memsz_pgh, %ax pushw %ax - /* Calculate .text16 segment address */ + /* Calculate .text16 segment address. Round down to ensure + * low bits are zero, to speed up mode transitions under KVM. + */ subw $_text16_memsz_pgh, %ax + andb $~0x03, %al pushw %ax /* Update FBMS */ diff --git a/src/arch/i386/transitions/librm.S b/src/arch/i386/transitions/librm.S index 0d8110ac..eaf520b3 100644 --- a/src/arch/i386/transitions/librm.S +++ b/src/arch/i386/transitions/librm.S @@ -200,10 +200,22 @@ real_to_prot: addr32 leal (%eax,%edx), %esi subl rm_virt_offset, %esi + /* Load protected-mode global descriptor table */ + data32 lgdt gdtr + + /* Zero segment registers. This wastes around 12 cycles on + * real hardware, but saves a substantial number of emulated + * instructions under KVM. + */ + xorw %ax, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + /* Switch to protected mode */ cli - data32 lgdt gdtr - data32 lidt idtr movl %cr0, %eax orb $CR0_PE, %al movl %eax, %cr0 @@ -220,6 +232,9 @@ r2p_pmode: movw %ax, %ss movl pm_esp, %esp + /* Load protected-mode interrupt descriptor table */ + lidt idtr + /* Record real-mode %ss:sp (after removal of data) */ movw %bp, rm_ss addl %ecx, %edx diff --git a/src/arch/i386/transitions/librm_mgmt.c b/src/arch/i386/transitions/librm_mgmt.c index dee14357..f90d49b0 100644 --- a/src/arch/i386/transitions/librm_mgmt.c +++ b/src/arch/i386/transitions/librm_mgmt.c @@ -26,10 +26,9 @@ static struct interrupt_vector intr_vec[ IRQ_MAX + 1 ]; struct interrupt_descriptor idt[NUM_INT] __attribute__ (( aligned ( 16 ) )); /** The interrupt descriptor table register */ -struct idtr __data16 ( idtr ) = { +struct idtr idtr = { .limit = ( sizeof ( idt ) - 1 ), }; -#define idtr __use_data16 ( idtr ) /** * Allocate space on the real-mode stack and copy data there from a