[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86: introduce and use setup_force_cpu_cap()
commit 0829a6bdbdc6b79990bd0668e847275b6a2717e5 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Wed Sep 6 12:32:00 2017 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Wed Sep 6 12:32:00 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 <security@xxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- 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 2638414..ed59440 100644 --- a/xen/arch/x86/apic.c +++ b/xen/arch/x86/apic.c @@ -853,7 +853,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 2fdc2f9..78f5667 100644 --- a/xen/arch/x86/cpu/common.c +++ b/xen/arch/x86/cpu/common.c @@ -54,6 +54,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) { @@ -63,6 +64,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); @@ -72,9 +77,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... */ @@ -375,8 +399,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 2e20327..6a41334 100644 --- a/xen/arch/x86/cpu/intel.c +++ b/xen/arch/x86/cpu/intel.c @@ -27,7 +27,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 bc466e8..3cbe305 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -1485,14 +1485,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 4bef698..8b39fb4 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -169,6 +169,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#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |