[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] x86: re-enable NX if disabled



commit 7cc65a9e8178124464760fe6a6bf2ab3726db877
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Dec 10 13:17:21 2015 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Dec 10 13:17:21 2015 +0100

    x86: re-enable NX if disabled
    
    I noticed Linux 4.4 doing this universally now, and I think it's a good
    idea to override such anti-security BIOS settings (we certainly have no
    compatibility problem due to NX being enabled).
    
    Secondary changes:
    - no need to check supported extended CPUID level for leaves 80000000
      and 80000001 (required on x86-64)
    - no need to update c->cpuid_level in early_init_intel() (done anyway
      in generic_identify())
    - alignment of trampoline data items
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/boot/trampoline.S  |   22 ++++++++++++++++++++++
 xen/arch/x86/cpu/common.c       |   18 +++++++++---------
 xen/arch/x86/cpu/intel.c        |   25 ++++++++++++++++---------
 xen/include/asm-x86/msr-index.h |    1 +
 xen/include/asm-x86/processor.h |    1 +
 5 files changed, 49 insertions(+), 18 deletions(-)

diff --git a/xen/arch/x86/boot/trampoline.S b/xen/arch/x86/boot/trampoline.S
index c8f32cd..b013614 100644
--- a/xen/arch/x86/boot/trampoline.S
+++ b/xen/arch/x86/boot/trampoline.S
@@ -32,9 +32,13 @@ GLOBAL(trampoline_realmode_entry)
         lmsw    %ax                       # CR0.PE = 1 (enter protected mode)
         ljmpl   $BOOT_CS32,$bootsym_rel(trampoline_protmode_entry,6)
 
+        .balign 8
+        .word   0
 idt_48: .word   0, 0, 0 # base = limit = 0
+        .word   0
 gdt_48: .word   6*8-1
         .long   bootsym_rel(trampoline_gdt,4)
+
 trampoline_gdt:
         /* 0x0000: unused */
         .quad   0x0000000000000000
@@ -56,6 +60,9 @@ trampoline_gdt:
         .long   trampoline_gdt + BOOT_PSEUDORM_DS + 2 - .
         .popsection
 
+GLOBAL(trampoline_misc_enable_off)
+        .quad   0
+
 GLOBAL(cpuid_ext_features)
         .long   0
 
@@ -84,6 +91,21 @@ trampoline_protmode_entry:
         add     bootsym_rel(trampoline_xen_phys_start,4,%eax)
         mov     %eax,%cr3
 
+        /* Adjust IA32_MISC_ENABLE if needed (for NX enabling below). */
+        mov     bootsym_rel(trampoline_misc_enable_off,4,%esi)
+        mov     bootsym_rel(trampoline_misc_enable_off+4,4,%edi)
+        mov     %esi,%eax
+        or      %edi,%eax
+        jz      1f
+        mov     $MSR_IA32_MISC_ENABLE,%ecx
+        rdmsr
+        not     %esi
+        not     %edi
+        and     %esi,%eax
+        and     %edi,%edx
+        wrmsr
+1:
+
         /* Set up EFER (Extended Feature Enable Register). */
         mov     bootsym_rel(cpuid_ext_features,4,%edi)
         movl    $MSR_EFER,%ecx
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index 310ec85..07566d9 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -256,15 +256,15 @@ static void __cpuinit generic_identify(struct cpuinfo_x86 
*c)
 
        /* AMD-defined flags: level 0x80000001 */
        c->extended_cpuid_level = cpuid_eax(0x80000000);
-       if ( (c->extended_cpuid_level & 0xffff0000) == 0x80000000 ) {
-               if ( c->extended_cpuid_level >= 0x80000001 )
-                       cpuid(0x80000001, &tmp, &tmp,
-                             
&c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)],
-                             
&c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]);
-
-               if ( c->extended_cpuid_level >= 0x80000004 )
-                       get_model_name(c); /* Default name */
-       }
+       cpuid(0x80000001, &tmp, &tmp,
+             &c->x86_capability[cpufeat_word(X86_FEATURE_LAHF_LM)],
+             &c->x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]);
+       if (c == &boot_cpu_data)
+               bootsym(cpuid_ext_features) =
+                       c->x86_capability[cpufeat_word(X86_FEATURE_NX)];
+
+       if (c->extended_cpuid_level >= 0x80000004)
+               get_model_name(c); /* Default name */
 
        /* Intel-defined flags: level 0x00000007 */
        if ( c->cpuid_level >= 0x00000007 )
diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index 67dabc0..d4f574b 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -162,19 +162,26 @@ static void early_init_intel(struct cpuinfo_x86 *c)
        if (c->x86 == 15 && c->x86_cache_alignment == 64)
                c->x86_cache_alignment = 128;
 
-       /* Unmask CPUID levels if masked: */
+       /* Unmask CPUID levels and NX if masked: */
        if (c->x86 > 6 || (c->x86 == 6 && c->x86_model >= 0xd)) {
-               u64 misc_enable;
+               u64 misc_enable, disable;
 
                rdmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
 
-               if (misc_enable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID) {
-                       misc_enable &= ~MSR_IA32_MISC_ENABLE_LIMIT_CPUID;
-                       wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable);
-                       c->cpuid_level = cpuid_eax(0);
-                       if (opt_cpu_info || c == &boot_cpu_data)
-                               printk(KERN_INFO "revised cpuid level: %d\n",
-                                      c->cpuid_level);
+               disable = misc_enable & (MSR_IA32_MISC_ENABLE_LIMIT_CPUID |
+                                        MSR_IA32_MISC_ENABLE_XD_DISABLE);
+               if (disable) {
+                       wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable & ~disable);
+                       bootsym(trampoline_misc_enable_off) |= disable;
+               }
+
+               if (disable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID)
+                       printk(KERN_INFO "revised cpuid level: %d\n",
+                              cpuid_eax(0));
+               if (disable & MSR_IA32_MISC_ENABLE_XD_DISABLE) {
+                       write_efer(read_efer() | EFER_NX);
+                       printk(KERN_INFO
+                              "re-enabled NX (Execute Disable) protection\n");
                }
        }
 
diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h
index b8ad93c..2b97861 100644
--- a/xen/include/asm-x86/msr-index.h
+++ b/xen/include/asm-x86/msr-index.h
@@ -322,6 +322,7 @@
 #define MSR_IA32_MISC_ENABLE_MONITOR_ENABLE (1<<18)
 #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID  (1<<22)
 #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1<<23)
+#define MSR_IA32_MISC_ENABLE_XD_DISABLE        (1ULL << 34)
 
 #define MSR_IA32_TSC_DEADLINE          0x000006E0
 #define MSR_IA32_ENERGY_PERF_BIAS      0x000001b0
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 3f8411f..26ba141 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -216,6 +216,7 @@ extern void set_cpuid_faulting(bool_t enable);
 extern u64 host_pat;
 extern bool_t opt_cpu_info;
 extern u32 cpuid_ext_features;
+extern u64 trampoline_misc_enable_off;
 
 /* Maximum width of physical addresses supported by the hardware */
 extern unsigned int paddr_bits;
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.