diff options
author | Keir Fraser <keir@xensource.com> | 2007-04-06 15:07:34 +0100 |
---|---|---|
committer | Keir Fraser <keir@xensource.com> | 2007-04-06 15:07:34 +0100 |
commit | e620b631ab97fddf8ae51545903fec76a9a15379 (patch) | |
tree | 0d9eb8275f83ed1465abfeadd5d384450f09c9ba | |
parent | fff07ef6152ccaf5767f02f4e65146b28a0620df (diff) | |
download | xen-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.S | 1 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/compat/entry.S | 4 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/entry.S | 6 | ||||
-rw-r--r-- | xen/arch/x86/x86_64/traps.c | 12 | ||||
-rw-r--r-- | xen/include/asm-x86/desc.h | 2 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_32/asm_defns.h | 10 | ||||
-rw-r--r-- | xen/include/asm-x86/x86_64/asm_defns.h | 10 |
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; \ |