[xen stable-4.8] x86: introduce and use setup_force_cpu_cap()

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen stable-4.8] x86: introduce and use setup_force_cpu_cap()

patchbot
commit ee3fc2417755e1893f4486eb1893dff7fe5fcd19
Author:     Jan Beulich <[hidden email]>
AuthorDate: Fri Oct 6 15:05:38 2017 +0200
Commit:     Jan Beulich <[hidden email]>
CommitDate: Fri Oct 6 15:05:38 2017 +0200

    x86: introduce and use setup_force_cpu_cap()
   
    For XEN_SMEP and XEN_SMAP to not be cleared while bringing up APs we'd
    need to clone the respective hack used for CPUID_FAULTING. Introduce an
    inverse of setup_clear_cpu_cap() instead, but let clearing of features
    overrule forced setting of them.
   
    XEN_SMAP being wrong post-boot is a problem specifically for live
    patching, as a live patch may need alternative instruction patching
    keyed off of that feature flag.
   
    Reported-by: Sarah Newman <[hidden email]>
    Signed-off-by: Jan Beulich <[hidden email]>
    Reviewed-by: Andrew Cooper <[hidden email]>
    master commit: 0829a6bdbdc6b79990bd0668e847275b6a2717e5
    master date: 2017-09-06 12:32:00 +0200
---
 xen/arch/x86/apic.c             |  2 +-
 xen/arch/x86/cpu/common.c       | 28 +++++++++++++++++++++++++++-
 xen/arch/x86/cpu/intel.c        |  5 +----
 xen/arch/x86/setup.c            |  4 ++--
 xen/include/asm-x86/processor.h |  1 +
 5 files changed, 32 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/apic.c b/xen/arch/x86/apic.c
index 3fb9a82..e6fa217 100644
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -857,7 +857,7 @@ static int __init detect_init_APIC (void)
         return -1;
     }
 
-    __set_bit(X86_FEATURE_APIC, boot_cpu_data.x86_capability);
+    setup_force_cpu_cap(X86_FEATURE_APIC);
     mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
 
     /* The BIOS may have set up the APIC at some other address */
diff --git a/xen/arch/x86/cpu/common.c b/xen/arch/x86/cpu/common.c
index b5da94a..3c8bed8 100644
--- a/xen/arch/x86/cpu/common.c
+++ b/xen/arch/x86/cpu/common.c
@@ -55,6 +55,7 @@ unsigned int vaddr_bits __read_mostly = VADDR_BITS;
 u64 host_pat = 0x050100070406;
 
 static unsigned int cleared_caps[NCAPINTS];
+static unsigned int forced_caps[NCAPINTS];
 
 void __init setup_clear_cpu_cap(unsigned int cap)
 {
@@ -64,6 +65,10 @@ void __init setup_clear_cpu_cap(unsigned int cap)
  if (__test_and_set_bit(cap, cleared_caps))
  return;
 
+ if (test_bit(cap, forced_caps))
+ printk("%pS clearing previously forced feature %#x\n",
+       __builtin_return_address(0), cap);
+
  __clear_bit(cap, boot_cpu_data.x86_capability);
  dfs = lookup_deep_deps(cap);
 
@@ -73,9 +78,28 @@ void __init setup_clear_cpu_cap(unsigned int cap)
  for (i = 0; i < FSCAPINTS; ++i) {
  cleared_caps[i] |= dfs[i];
  boot_cpu_data.x86_capability[i] &= ~dfs[i];
+ if (!(forced_caps[i] & dfs[i]))
+ continue;
+ printk("%pS implicitly clearing previously forced feature(s) %u:%#x\n",
+       __builtin_return_address(0),
+       i, forced_caps[i] & dfs[i]);
  }
 }
 
+void __init setup_force_cpu_cap(unsigned int cap)
+{
+ if (__test_and_set_bit(cap, forced_caps))
+ return;
+
+ if (test_bit(cap, cleared_caps)) {
+ printk("%pS tries to force previously cleared feature %#x\n",
+       __builtin_return_address(0), cap);
+ return;
+ }
+
+ __set_bit(cap, boot_cpu_data.x86_capability);
+}
+
 static void default_init(struct cpuinfo_x86 * c)
 {
  /* Not much we can do here... */
@@ -383,8 +407,10 @@ void identify_cpu(struct cpuinfo_x86 *c)
  for (i = 0; i < FSCAPINTS; ++i)
  c->x86_capability[i] &= known_features[i];
 
- for (i = 0 ; i < NCAPINTS ; ++i)
+ for (i = 0 ; i < NCAPINTS ; ++i) {
+ c->x86_capability[i] |= forced_caps[i];
  c->x86_capability[i] &= ~cleared_caps[i];
+ }
 
  /* If the model name is still unset, do table lookup. */
  if ( !c->x86_model_id[0] ) {
diff --git a/xen/arch/x86/cpu/intel.c b/xen/arch/x86/cpu/intel.c
index 2e11662..390eb66 100644
--- a/xen/arch/x86/cpu/intel.c
+++ b/xen/arch/x86/cpu/intel.c
@@ -28,7 +28,7 @@ static bool __init probe_intel_cpuid_faulting(void)
 
  expected_levelling_cap |= LCAP_faulting;
  levelling_caps |=  LCAP_faulting;
- __set_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability);
+ setup_force_cpu_cap(X86_FEATURE_CPUID_FAULTING);
  return 1;
 }
 
@@ -320,9 +320,6 @@ static void early_init_intel(struct cpuinfo_x86 *c)
  if (c == &boot_cpu_data)
  intel_init_levelling();
 
- if (test_bit(X86_FEATURE_CPUID_FAULTING, boot_cpu_data.x86_capability))
- __set_bit(X86_FEATURE_CPUID_FAULTING, c->x86_capability);
-
  intel_ctxt_switch_levelling(NULL);
 }
 
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index 1bfe4ce..468e51e 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1463,14 +1463,14 @@ void __init noreturn __start_xen(unsigned long mbi_p)
     if ( !opt_smep )
         setup_clear_cpu_cap(X86_FEATURE_SMEP);
     if ( cpu_has_smep && opt_smep != SMEP_HVM_ONLY )
-        __set_bit(X86_FEATURE_XEN_SMEP, boot_cpu_data.x86_capability);
+        setup_force_cpu_cap(X86_FEATURE_XEN_SMEP);
     if ( boot_cpu_has(X86_FEATURE_XEN_SMEP) )
         set_in_cr4(X86_CR4_SMEP);
 
     if ( !opt_smap )
         setup_clear_cpu_cap(X86_FEATURE_SMAP);
     if ( cpu_has_smap && opt_smap != SMAP_HVM_ONLY )
-        __set_bit(X86_FEATURE_XEN_SMAP, boot_cpu_data.x86_capability);
+        setup_force_cpu_cap(X86_FEATURE_XEN_SMAP);
     if ( boot_cpu_has(X86_FEATURE_XEN_SMAP) )
         set_in_cr4(X86_CR4_SMAP);
 
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index 6378afd..fb0cd55 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -235,6 +235,7 @@ extern const struct x86_cpu_id *x86_match_cpu(const struct x86_cpu_id table[]);
 
 extern void identify_cpu(struct cpuinfo_x86 *);
 extern void setup_clear_cpu_cap(unsigned int);
+extern void setup_force_cpu_cap(unsigned int);
 extern void print_cpu_info(unsigned int cpu);
 extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
 
--
generated by git-patchbot for /home/xen/git/xen.git#stable-4.8

_______________________________________________
Xen-changelog mailing list
[hidden email]
https://lists.xenproject.org/xen-changelog