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 <andrew.cooper3@citrix.com>
.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
DECL_REG(si);
DECL_REG(di);
+ uint16_t ds, :16;
+ uint16_t es, :16;
+
uint32_t entry_vector;
uint32_t error_code;
"push $0;"
"push $" STR(X86_EXC_NMI) ";"
+ "push %es;"
+ "push %ds;"
+
"push %edi;"
"push %esi;"
"push %edx;"
"pop %esi;"
"pop %edi;"
+ "pop %ds;"
+ "pop %es;"
+
"add $2*4, %esp;" /* entry_vector/error_code. */
"jmp exit_NMI_task;");