From: Feng Wu Date: Mon, 12 May 2014 15:01:47 +0000 (+0200) Subject: x86: clear AC bit in RFLAGS to protect Xen itself by SMAP X-Git-Tag: archive/raspbian/4.8.0-1+rpi1~1^2~5025 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=4ee0ad72d33a4c7ae9ccc26ce1b04dad399fabe8;p=xen.git x86: clear AC bit in RFLAGS to protect Xen itself by SMAP Clear AC bit in RFLAGS at the beginning of exception, interrupt, hypercall, so Xen itself can be protected by SMAP mechanism. This patch also sets AC bit at the beginning of double_fault and fatal_trap() to reduce the likelihood of taking a further fault while trying to dump state. Signed-off-by: Feng Wu Reviewed-by: Jan Beulich Reviewed-by: Andrew Cooper --- diff --git a/xen/arch/x86/acpi/suspend.c b/xen/arch/x86/acpi/suspend.c index a373e9a11f..1d8344cb35 100644 --- a/xen/arch/x86/acpi/suspend.c +++ b/xen/arch/x86/acpi/suspend.c @@ -56,10 +56,7 @@ void restore_rest_processor_state(void) wrmsrl(MSR_LSTAR, saved_lstar); wrmsrl(MSR_CSTAR, saved_cstar); wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS); - wrmsr(MSR_SYSCALL_MASK, - X86_EFLAGS_VM|X86_EFLAGS_RF|X86_EFLAGS_NT| - X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_TF, - 0U); + wrmsr(MSR_SYSCALL_MASK, XEN_SYSCALL_MASK, 0U); wrfsbase(saved_fs_base); wrgsbase(saved_gs_base); diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 22645d6cf6..67dfef9198 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -60,7 +60,7 @@ start_bsp: /* This is the default interrupt handler. */ ignore_int: - SAVE_ALL + SAVE_ALL CLAC movq %cr2,%rsi leaq int_msg(%rip),%rdi xorl %eax,%eax diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 5d27581064..ac68a8540b 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -401,6 +401,9 @@ void fatal_trap(int trapnr, struct cpu_user_regs *regs) { static DEFINE_PER_CPU(char, depth); + /* Set AC to reduce chance of further SMAP faults */ + stac(); + /* * In some cases, we can end up in a vicious cycle of fatal_trap()s * within fatal_trap()s. We give the problem a couple of iterations to diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 32b3bcc17e..ac594c9509 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -13,6 +13,7 @@ #include ENTRY(compat_hypercall) + ASM_CLAC pushq $0 SAVE_VOLATILE type=TRAP_syscall compat=1 diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 1c81852d7b..42f66bf8d5 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -273,6 +273,7 @@ ENTRY(sysenter_entry) pushq $0 pushfq GLOBAL(sysenter_eflags_saved) + ASM_CLAC pushq $3 /* ring 3 null cs */ pushq $0 /* null rip */ pushq $0 @@ -309,6 +310,7 @@ UNLIKELY_END(sysenter_gpf) jmp .Lbounce_exception ENTRY(int80_direct_trap) + ASM_CLAC pushq $0 SAVE_VOLATILE 0x80 @@ -466,7 +468,7 @@ ENTRY(dom_crash_sync_extable) jmp asm_domain_crash_synchronous /* Does not return */ ENTRY(common_interrupt) - SAVE_ALL + SAVE_ALL CLAC movq %rsp,%rdi callq do_IRQ jmp ret_from_intr @@ -485,7 +487,7 @@ ENTRY(page_fault) movl $TRAP_page_fault,4(%rsp) /* No special register assumptions. */ GLOBAL(handle_exception) - SAVE_ALL + SAVE_ALL CLAC handle_exception_saved: testb $X86_EFLAGS_IF>>8,UREGS_eflags+1(%rsp) jz exception_with_ints_disabled @@ -614,7 +616,8 @@ ENTRY(spurious_interrupt_bug) ENTRY(double_fault) movl $TRAP_double_fault,4(%rsp) - SAVE_ALL + /* Set AC to reduce chance of further SMAP faults */ + SAVE_ALL STAC movq %rsp,%rdi call do_double_fault ud2 @@ -631,7 +634,7 @@ ENTRY(nmi) pushq $0 movl $TRAP_nmi,4(%rsp) handle_ist_exception: - SAVE_ALL + SAVE_ALL CLAC testb $3,UREGS_cs(%rsp) jz 1f /* Interrupted guest context. Copy the context to stack bottom. */ @@ -667,7 +670,8 @@ handle_ist_exception: ENTRY(nmi_crash) pushq $0 movl $TRAP_nmi,4(%rsp) - SAVE_ALL + /* Set AC to reduce chance of further SMAP faults */ + SAVE_ALL STAC movq %rsp,%rdi callq do_nmi_crash /* Does not return */ ud2 diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 90072c1a65..3a48478839 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -436,10 +436,7 @@ void __devinit subarch_percpu_traps_init(void) /* Common SYSCALL parameters. */ wrmsr(MSR_STAR, 0, (FLAT_RING3_CS32<<16) | __HYPERVISOR_CS); - wrmsr(MSR_SYSCALL_MASK, - X86_EFLAGS_VM|X86_EFLAGS_RF|X86_EFLAGS_NT| - X86_EFLAGS_DF|X86_EFLAGS_IF|X86_EFLAGS_TF, - 0U); + wrmsr(MSR_SYSCALL_MASK, XEN_SYSCALL_MASK, 0U); } void init_int80_direct_trap(struct vcpu *v) diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h index b75905adc7..df4873b46f 100644 --- a/xen/include/asm-x86/asm_defns.h +++ b/xen/include/asm-x86/asm_defns.h @@ -190,7 +190,18 @@ static inline void stac(void) #endif #ifdef __ASSEMBLY__ -.macro SAVE_ALL +.macro SAVE_ALL op +.ifeqs "\op", "CLAC" + ASM_CLAC +.else +.ifeqs "\op", "STAC" + ASM_STAC +.else +.ifnb \op + .err +.endif +.endif +.endif addq $-(UREGS_error_code-UREGS_r15), %rsp cld movq %rdi,UREGS_rdi(%rsp) diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 604f5b316d..35b2433f22 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -141,6 +141,10 @@ #define PFEC_page_paged (1U<<5) #define PFEC_page_shared (1U<<6) +#define XEN_SYSCALL_MASK (X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF| \ + X86_EFLAGS_NT|X86_EFLAGS_DF|X86_EFLAGS_IF| \ + X86_EFLAGS_TF) + #ifndef __ASSEMBLY__ struct domain;