x86: clear AC bit in RFLAGS to protect Xen itself by SMAP
authorFeng Wu <feng.wu@intel.com>
Mon, 12 May 2014 15:01:47 +0000 (17:01 +0200)
committerJan Beulich <jbeulich@suse.com>
Mon, 12 May 2014 15:01:47 +0000 (17:01 +0200)
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 <feng.wu@intel.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
xen/arch/x86/acpi/suspend.c
xen/arch/x86/boot/x86_64.S
xen/arch/x86/traps.c
xen/arch/x86/x86_64/compat/entry.S
xen/arch/x86/x86_64/entry.S
xen/arch/x86/x86_64/traps.c
xen/include/asm-x86/asm_defns.h
xen/include/asm-x86/processor.h

index a373e9a11f257fcf52e06644e89238def3db4e7b..1d8344cb35d1910e6c591fd546e51db406e6a46c 100644 (file)
@@ -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);
index 22645d6cf64ea0e126d992b652d36b88b571e40b..67dfef9198078a1d78d925a7a3aba3e02caacb1c 100644 (file)
@@ -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
index 5d27581064c8f8dd5727b674ddcd2ec1298a6da8..ac68a8540b312832b7209c605dda717a74460dcd 100644 (file)
@@ -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
index 32b3bcc17e37a151184fde8bfd79e8022963eded..ac594c950911911398447efc9ee5e7ce5c549a9c 100644 (file)
@@ -13,6 +13,7 @@
 #include <irq_vectors.h>
 
 ENTRY(compat_hypercall)
+        ASM_CLAC
         pushq $0
         SAVE_VOLATILE type=TRAP_syscall compat=1
 
index 1c81852d7b026d52cc01691d874d20f5d7655b4a..42f66bf8d5008270b7de129ad4837948a39bbe06 100644 (file)
@@ -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
index 90072c1a65fd42026bbaf41725fb2524ccc1d460..3a484788391b34e5bd8e762a6b2e1d6e81082f07 100644 (file)
@@ -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)
index b75905adc78cd80e5481820dc2d772d7457c3f20..df4873b46f93f047fc5d79df968dbbd10f791c87 100644 (file)
@@ -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)
index 604f5b316d3de86ecc0787da433aea17195ec01b..35b2433f22a23e1eca3e145273e0db327fe9d408 100644 (file)
 #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;