From: Andrew Cooper Date: Wed, 14 Feb 2018 15:42:25 +0000 (+0000) Subject: 32bit: Save and restore %ds and %es when handling exceptions X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=48258ebd21c2208d74ccb3be3790a20e04168725;p=people%2Fandrewcoop%2Fxen-test-framework.git 32bit: Save and restore %ds and %es when handling exceptions For tests which play with segments (especially those which reduce %ds.limit), failing to restore usable segments can result in cascade failures (most obviously when trying to poke characters into the console ring). Remove the vm86 special case in handle_exception() and load __KERN_DS into %ds and %es unconditionally. Forgo the unconditional loading of %fs and %gs as they are unreferenced in exception context. Signed-off-by: Andrew Cooper --- diff --git a/arch/x86/entry_32.S b/arch/x86/entry_32.S index d1bdbab..9869b78 100644 --- a/arch/x86/entry_32.S +++ b/arch/x86/entry_32.S @@ -75,25 +75,24 @@ exception_entry VE X86_EXC_VE .align 16 handle_exception: - SAVE_ALL + push %es + push %ds -#if defined(CONFIG_HVM) - testl $X86_EFLAGS_VM, 11*4(%esp) - jz 1f + SAVE_ALL - mov $__KERN_DS, %eax /* Restore data segments if leaving vm86 mode. */ + mov $__KERN_DS, %eax /* Restore data segments. */ mov %eax, %ds mov %eax, %es - mov %eax, %fs - mov %eax, %gs -1: -#endif push %esp /* struct cpu_regs * */ call do_exception add $4, %esp RESTORE_ALL + + pop %ds + pop %es + add $8, %esp /* Pop error_code/entry_vector. */ env_IRET diff --git a/arch/x86/include/arch/regs.h b/arch/x86/include/arch/regs.h index 618b562..963d2a0 100644 --- a/arch/x86/include/arch/regs.h +++ b/arch/x86/include/arch/regs.h @@ -19,6 +19,9 @@ struct cpu_regs { DECL_REG(si); DECL_REG(di); + uint16_t ds, :16; + uint16_t es, :16; + uint32_t entry_vector; uint32_t error_code; diff --git a/tests/nmi-taskswitch-priv/main.c b/tests/nmi-taskswitch-priv/main.c index cbb6f09..61565cb 100644 --- a/tests/nmi-taskswitch-priv/main.c +++ b/tests/nmi-taskswitch-priv/main.c @@ -64,6 +64,9 @@ asm("exit_NMI_task:" "push $0;" "push $" STR(X86_EXC_NMI) ";" + "push %es;" + "push %ds;" + "push %edi;" "push %esi;" "push %edx;" @@ -84,6 +87,9 @@ asm("exit_NMI_task:" "pop %esi;" "pop %edi;" + "pop %ds;" + "pop %es;" + "add $2*4, %esp;" /* entry_vector/error_code. */ "jmp exit_NMI_task;");