]> xenbits.xensource.com Git - people/sstabellini/xen-unstable.git/.git/commitdiff
x86/boot: Remove cached CPUID data from the trampoline
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 9 Sep 2019 10:43:33 +0000 (11:43 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 21 Nov 2019 15:49:52 +0000 (15:49 +0000)
We have a cached cpuid_ext_features in the trampoline which is kept in sync by
various pieces of boot logic.  This is complicated, and all it is actually
used for is to derive whether NX is safe to use.

Replace it with a canned value to load into EFER.

trampoline_setup() and efi_arch_cpu() now tweak trampoline_efer at the point
that they are stashing the main copy of CPUID data.  Similarly,
early_init_intel() needs to tweak if it has re-enabled the use of NX.

This simplifies the AP boot and S3 resume paths by using trampoline_efer
directly, rather than locally turning FEATURE_NX into EFER_NX.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Juergen Gross <jgross@suse.com>
xen/arch/x86/boot/head.S
xen/arch/x86/boot/trampoline.S
xen/arch/x86/boot/wakeup.S
xen/arch/x86/cpu/common.c
xen/arch/x86/cpu/intel.c
xen/arch/x86/efi/efi-boot.h
xen/include/asm-x86/processor.h

index a1564b520bb1526ad9aa4fcfb4f5aade8498644c..77309e3c8289ec2d4fffda160af87648e09d4ece 100644 (file)
@@ -640,8 +640,13 @@ trampoline_setup:
         jbe     1f
         mov     $0x80000001,%eax
         cpuid
-1:      mov     %edx,sym_fs(cpuid_ext_features)
-        mov     %edx,sym_fs(boot_cpu_data)+CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM)
+1:      mov     %edx, sym_fs(boot_cpu_data) + CPUINFO_FEATURE_OFFSET(X86_FEATURE_LM)
+
+        /* Check for NX. Adjust EFER setting if available. */
+        bt      $cpufeat_bit(X86_FEATURE_NX), %edx
+        jnc     1f
+        orb     $EFER_NX >> 8, 1 + sym_esi(trampoline_efer)
+1:
 
         /* Check for availability of long mode. */
         bt      $cpufeat_bit(X86_FEATURE_LM),%edx
index 870ec79a2da6236b2aa54b39efde05f6e4a2cc17..26584493bbd2e3f8b8c46c336f5702dabd460809 100644 (file)
@@ -88,8 +88,9 @@ trampoline_gdt:
 GLOBAL(trampoline_misc_enable_off)
         .quad   0
 
-GLOBAL(cpuid_ext_features)
-        .long   0
+/* EFER OR-mask for boot paths.  This gets adjusted with NX when available. */
+GLOBAL(trampoline_efer)
+        .long   EFER_LME | EFER_SCE
 
 GLOBAL(trampoline_xen_phys_start)
         .long   0
@@ -132,14 +133,10 @@ trampoline_protmode_entry:
 1:
 
         /* Set up EFER (Extended Feature Enable Register). */
-        mov     bootsym_rel(cpuid_ext_features,4,%edi)
         movl    $MSR_EFER,%ecx
         rdmsr
-        or      $EFER_LME|EFER_SCE,%eax   /* Long Mode + SYSCALL/SYSRET */
-        bt      $cpufeat_bit(X86_FEATURE_NX),%edi /* No Execute? */
-        jnc     1f
-        btsl    $_EFER_NX,%eax  /* No Execute     */
-1:      wrmsr
+        or      bootsym_rel(trampoline_efer, 4, %eax)
+        wrmsr
 
         mov     $(X86_CR0_PG | X86_CR0_AM | X86_CR0_WP | X86_CR0_NE |\
                   X86_CR0_ET | X86_CR0_MP | X86_CR0_PE), %eax
index 25ec2fa32bdef1880037256ff9015ba3c01adfdb..fc47721f4346f5aaf73d40fe7953c64fcc689f03 100644 (file)
@@ -131,20 +131,11 @@ wakeup_32:
         wrmsr
 1:
 
-        /* Will cpuid feature change after resume? */
         /* Set up EFER (Extended Feature Enable Register). */
-        mov     bootsym_rel(cpuid_ext_features,4,%edi)
-        test    $0x20100800,%edi /* SYSCALL/SYSRET, No Execute, Long Mode? */
-        jz      .Lskip_eferw
         movl    $MSR_EFER,%ecx
         rdmsr
-        btsl    $_EFER_LME,%eax /* Long Mode      */
-        btsl    $_EFER_SCE,%eax /* SYSCALL/SYSRET */
-        btl     $20,%edi        /* No Execute?    */
-        jnc     1f
-        btsl    $_EFER_NX,%eax  /* No Execute     */
-1:      wrmsr
-.Lskip_eferw:
+        or      bootsym_rel(trampoline_efer, 4, %eax)
+        wrmsr
 
         wbinvd
 
index 6c6bd6330129b0454d5df605978db335f30c74e0..e5ad17d8d9f4d67ae79ec83f02f747b700a0eb26 100644 (file)
@@ -391,9 +391,6 @@ static void generic_identify(struct cpuinfo_x86 *c)
                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 */
index 5356a6ae10d230026de8ed29e080f936bccf826f..4d7324e4d07f8d48732283692b1f0fcb6488aec7 100644 (file)
@@ -270,6 +270,7 @@ static void early_init_intel(struct cpuinfo_x86 *c)
        if (disable) {
                wrmsrl(MSR_IA32_MISC_ENABLE, misc_enable & ~disable);
                bootsym(trampoline_misc_enable_off) |= disable;
+               bootsym(trampoline_efer) |= EFER_NX;
        }
 
        if (disable & MSR_IA32_MISC_ENABLE_LIMIT_CPUID)
index 940ce12706559f7bc75a5f62897c245f1c47203d..cde193a771b058e9c4470149528cbd8d50b50532 100644 (file)
@@ -238,7 +238,7 @@ static void __init noreturn efi_arch_post_exit_boot(void)
     asm volatile("pushq $0\n\tpopfq");
     rdmsrl(MSR_EFER, efer);
     efer |= EFER_SCE;
-    if ( cpuid_ext_features & cpufeat_mask(X86_FEATURE_NX) )
+    if ( cpu_has_nx )
         efer |= EFER_NX;
     wrmsrl(MSR_EFER, efer);
     write_cr0(X86_CR0_PE | X86_CR0_MP | X86_CR0_ET | X86_CR0_NE | X86_CR0_WP |
@@ -640,9 +640,11 @@ static void __init efi_arch_cpu(void)
 
     if ( (eax >> 16) == 0x8000 && eax > 0x80000000 )
     {
-        cpuid_ext_features = cpuid_edx(0x80000001);
         boot_cpu_data.x86_capability[cpufeat_word(X86_FEATURE_SYSCALL)]
-            = cpuid_ext_features;
+            = cpuid_edx(0x80000001);
+
+        if ( cpu_has_nx )
+            trampoline_efer |= EFER_NX;
     }
 }
 
index 557f9b6ddaf244193a4c7594d90ea26f6fb8249e..19328f481ab338a24093afaf83e3c66b9b4d408c 100644 (file)
@@ -151,7 +151,7 @@ extern void ctxt_switch_levelling(const struct vcpu *next);
 extern void (*ctxt_switch_masking)(const struct vcpu *next);
 
 extern bool_t opt_cpu_info;
-extern u32 cpuid_ext_features;
+extern u32 trampoline_efer;
 extern u64 trampoline_misc_enable_off;
 
 /* Maximum width of physical addresses supported by the hardware. */