Description: x86: clear EFLAGS.NT in SYSENTER entry path
 ... as it causes problems if we happen to exit back via IRET: In the
 course of trying to handle the fault, the hypervisor creates a stack
 frame by hand, and uses PUSHFQ to set the respective EFLAGS field, but
 expects to be able to IRET through that stack frame to the second
 portion of the fixup code (which causes a #GP due to the stored EFLAGS
 having NT set).
 .
 And even if this worked (e.g if we cleared NT in that path), it would
 then (through the fail safe callback) cause a #GP in the guest with the
 SYSENTER handler's first instruction as the source, which in turn would
 allow guest user mode code to crash the guest kernel.
 .
 Inject a #GP on the fake (NULL) address of the SYSENTER instruction
 instead, just like in the case where the guest kernel didn't register
 a corresponding entry point.
 .
 On 32-bit we also need to make sure we clear SYSENTER_CS for all CPUs
 (neither #RESET nor #INIT guarantee this).
From: Jan Beulich <jbeulich@suse.com>
Origin: upstream, commit:b5d22afa109d
Id: CVE-2013-1917 XSA-44
---
--- a/xen/arch/x86/acpi/suspend.c	Thu Apr 18 15:29:45 2013 +0200
+++ b/xen/arch/x86/acpi/suspend.c	Thu Apr 18 16:23:07 2013 +0200
@@ -81,8 +81,12 @@
     }
 
 #else /* !defined(CONFIG_X86_64) */
-    if ( supervisor_mode_kernel && cpu_has_sep )
-        wrmsr(MSR_IA32_SYSENTER_ESP, &this_cpu(init_tss).esp1, 0);
+    if ( cpu_has_sep )
+    {
+        wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
+        if ( supervisor_mode_kernel )
+            wrmsr(MSR_IA32_SYSENTER_ESP, &this_cpu(init_tss).esp1, 0);
+    }
 #endif
 
     /* Maybe load the debug registers. */
--- a/xen/arch/x86/cpu/common.c	Thu Apr 18 15:29:45 2013 +0200
+++ b/xen/arch/x86/cpu/common.c	Thu Apr 18 16:23:07 2013 +0200
@@ -715,8 +715,11 @@
 #if defined(CONFIG_X86_32)
 	t->ss0  = __HYPERVISOR_DS;
 	t->esp0 = get_stack_bottom();
-	if ( supervisor_mode_kernel && cpu_has_sep )
+	if ( cpu_has_sep ) {
+	    wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
+	    if ( supervisor_mode_kernel )
 		wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0);
+	}
 #elif defined(CONFIG_X86_64)
 	/* Bottom-of-stack must be 16-byte aligned! */
 	BUG_ON((get_stack_bottom() & 15) != 0);
diff -r 8f3d4607baee -r b5d22afa109d xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S	Thu Apr 18 15:29:45 2013 +0200
+++ b/xen/arch/x86/x86_64/entry.S	Thu Apr 18 16:23:07 2013 +0200
@@ -288,7 +288,14 @@
         movl  $3,UREGS_cs(%rsp)  /* ring 3 null cs */
         movq  VCPU_sysenter_addr(%rbx),%rax
         setne %cl
+        testl $X86_EFLAGS_NT,UREGS_eflags(%rsp)
         leaq  VCPU_trap_bounce(%rbx),%rdx
+UNLIKELY_START(nz, sysenter_nt_set)
+        pushfq
+        andl  $~X86_EFLAGS_NT,(%rsp)
+        popfq
+        xorl  %eax,%eax
+UNLIKELY_END(sysenter_nt_set)
         testq %rax,%rax
         leal  (,%rcx,TBF_INTERRUPT),%ecx
 UNLIKELY_START(z, sysenter_gpf)

