aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir@xensource.com>2007-04-06 15:07:34 +0100
committerKeir Fraser <keir@xensource.com>2007-04-06 15:07:34 +0100
commite620b631ab97fddf8ae51545903fec76a9a15379 (patch)
tree0d9eb8275f83ed1465abfeadd5d384450f09c9ba
parentfff07ef6152ccaf5767f02f4e65146b28a0620df (diff)
downloadxen-e620b631ab97fddf8ae51545903fec76a9a15379.tar.gz
xen-e620b631ab97fddf8ae51545903fec76a9a15379.tar.bz2
xen-e620b631ab97fddf8ae51545903fec76a9a15379.zip
xen x86/64: Fix int80 direct trap. It must check for events and also
disable interrupts before exiting to guest context. Also sprinkle about some assertions about interrupt-enable status. Signed-off-by: Keir Fraser <keir@xensource.com>
-rw-r--r--xen/arch/x86/x86_32/entry.S1
-rw-r--r--xen/arch/x86/x86_64/compat/entry.S4
-rw-r--r--xen/arch/x86/x86_64/entry.S6
-rw-r--r--xen/arch/x86/x86_64/traps.c12
-rw-r--r--xen/include/asm-x86/desc.h2
-rw-r--r--xen/include/asm-x86/x86_32/asm_defns.h10
-rw-r--r--xen/include/asm-x86/x86_64/asm_defns.h10
7 files changed, 37 insertions, 8 deletions
diff --git a/xen/arch/x86/x86_32/entry.S b/xen/arch/x86/x86_32/entry.S
index 5f434af0ad..93177eda9a 100644
--- a/xen/arch/x86/x86_32/entry.S
+++ b/xen/arch/x86/x86_32/entry.S
@@ -283,6 +283,7 @@ bad_hypercall:
/* %edx == trap_bounce, %ebx == struct vcpu */
/* %eax,%ecx are clobbered. %gs:%esi contain new UREGS_ss/UREGS_esp. */
create_bounce_frame:
+ ASSERT_INTERRUPTS_ENABLED
movl UREGS_eflags+4(%esp),%ecx
movb UREGS_cs+4(%esp),%cl
testl $(2|X86_EFLAGS_VM),%ecx
diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S
index ec254f7382..3d1864e632 100644
--- a/xen/arch/x86/x86_64/compat/entry.S
+++ b/xen/arch/x86/x86_64/compat/entry.S
@@ -137,6 +137,7 @@ compat_bad_hypercall:
/* %rbx: struct vcpu, interrupts disabled */
compat_restore_all_guest:
+ ASSERT_INTERRUPTS_DISABLED
RESTORE_ALL
addq $8,%rsp
.Lft0: iretq
@@ -188,13 +189,14 @@ ENTRY(compat_post_handle_exception)
ENTRY(compat_int80_direct_trap)
call compat_create_bounce_frame
- jmp compat_restore_all_guest
+ jmp compat_test_all_events
/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK: */
/* {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]} */
/* %rdx: trap_bounce, %rbx: struct vcpu */
/* On return only %rbx is guaranteed non-clobbered. */
compat_create_bounce_frame:
+ ASSERT_INTERRUPTS_ENABLED
mov %fs,%edi
testb $2,UREGS_cs+8(%rsp)
jz 1f
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index c921579e3c..d5701588d7 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -38,6 +38,7 @@ switch_to_kernel:
/* %rbx: struct vcpu, interrupts disabled */
restore_all_guest:
+ ASSERT_INTERRUPTS_DISABLED
RESTORE_ALL
testw $TRAP_syscall,4(%rsp)
jz iret_exit_to_guest
@@ -230,7 +231,7 @@ ENTRY(int80_direct_trap)
/* Check that the callback is non-null. */
leaq VCPU_int80_bounce(%rbx),%rdx
- cmp $0, TRAPBOUNCE_flags(%rdx)
+ cmp $0,TRAPBOUNCE_flags(%rdx)
jz int80_slow_path
movq VCPU_domain(%rbx),%rax
@@ -238,7 +239,7 @@ ENTRY(int80_direct_trap)
jnz compat_int80_direct_trap
call create_bounce_frame
- jmp restore_all_guest
+ jmp test_all_events
int80_slow_path:
/*
@@ -256,6 +257,7 @@ int80_slow_path:
/* %rdx: trap_bounce, %rbx: struct vcpu */
/* On return only %rbx is guaranteed non-clobbered. */
create_bounce_frame:
+ ASSERT_INTERRUPTS_ENABLED
testb $TF_kernel_mode,VCPU_thread_flags(%rbx)
jnz 1f
/* Push new frame at registered guest-OS stack base. */
diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c
index af1429ac56..662cfa9517 100644
--- a/xen/arch/x86/x86_64/traps.c
+++ b/xen/arch/x86/x86_64/traps.c
@@ -170,7 +170,8 @@ asmlinkage void do_double_fault(struct cpu_user_regs *regs)
regs->r9, regs->r10, regs->r11);
printk("r12: %016lx r13: %016lx r14: %016lx\n",
regs->r12, regs->r13, regs->r14);
- printk("r15: %016lx\n", regs->r15);
+ printk("r15: %016lx cs: %016lx ss: %016lx\n",
+ regs->r15, (long)regs->cs, (long)regs->ss);
show_stack_overflow(cpu, regs->rsp);
panic("DOUBLE FAULT -- system shutdown\n");
@@ -260,11 +261,14 @@ void __init percpu_traps_init(void)
idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */
idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */
-#ifdef CONFIG_COMPAT
- /* The hypercall entry vector is only accessible from ring 1. */
+ /*
+ * The 32-on-64 hypercall entry vector is only accessible from ring 1.
+ * Also note that this is a trap gate, not an interrupt gate.
+ */
_set_gate(idt_table+HYPERCALL_VECTOR, 15, 1, &compat_hypercall);
+
+ /* Fast trap for int80 (faster than taking the #GP-fixup path). */
_set_gate(idt_table+0x80, 15, 3, &int80_direct_trap);
-#endif
}
stack_bottom = (char *)get_stack_bottom();
diff --git a/xen/include/asm-x86/desc.h b/xen/include/asm-x86/desc.h
index 154f76736b..e3b41643bc 100644
--- a/xen/include/asm-x86/desc.h
+++ b/xen/include/asm-x86/desc.h
@@ -106,7 +106,7 @@
((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */ \
((sel) == (!IS_COMPAT(d) ? \
FLAT_KERNEL_CS : /* Xen default seg? */ \
- FLAT_COMPAT_KERNEL_CS)) || /* Xen default compat seg? */ \
+ FLAT_COMPAT_KERNEL_CS)) || \
((sel) & 4)) /* LDT seg? */
#endif /* __ASSEMBLY__ */
diff --git a/xen/include/asm-x86/x86_32/asm_defns.h b/xen/include/asm-x86/x86_32/asm_defns.h
index a972dd10dc..b37f3c5a9b 100644
--- a/xen/include/asm-x86/x86_32/asm_defns.h
+++ b/xen/include/asm-x86/x86_32/asm_defns.h
@@ -8,10 +8,20 @@
#define SETUP_EXCEPTION_FRAME_POINTER \
movl %esp,%ebp; \
notl %ebp
+#define ASSERT_INTERRUPT_STATUS(x) \
+ pushf; \
+ testb $X86_EFLAGS_IF>>8,1(%esp); \
+ j##x 1f; \
+ ud2a; \
+1: addl $4,%esp;
#else
#define SETUP_EXCEPTION_FRAME_POINTER
+#define ASSERT_INTERRUPT_STATUS(x)
#endif
+#define ASSERT_INTERRUPTS_ENABLED ASSERT_INTERRUPT_STATUS(nz)
+#define ASSERT_INTERRUPTS_DISABLED ASSERT_INTERRUPT_STATUS(z)
+
#define __SAVE_ALL_PRE \
cld; \
pushl %eax; \
diff --git a/xen/include/asm-x86/x86_64/asm_defns.h b/xen/include/asm-x86/x86_64/asm_defns.h
index f84cb516ac..231f3aa02e 100644
--- a/xen/include/asm-x86/x86_64/asm_defns.h
+++ b/xen/include/asm-x86/x86_64/asm_defns.h
@@ -8,10 +8,20 @@
#define SETUP_EXCEPTION_FRAME_POINTER \
movq %rsp,%rbp; \
notq %rbp
+#define ASSERT_INTERRUPT_STATUS(x) \
+ pushf; \
+ testb $X86_EFLAGS_IF>>8,1(%rsp); \
+ j##x 1f; \
+ ud2a; \
+1: addq $8,%rsp;
#else
#define SETUP_EXCEPTION_FRAME_POINTER
+#define ASSERT_INTERRUPT_STATUS(x)
#endif
+#define ASSERT_INTERRUPTS_ENABLED ASSERT_INTERRUPT_STATUS(nz)
+#define ASSERT_INTERRUPTS_DISABLED ASSERT_INTERRUPT_STATUS(z)
+
#define SAVE_ALL \
cld; \
pushq %rdi; \