Uhm, this time I'm sure that I included the From/Subject lines, both in this series and the QEMU patch. $ gpg --decrypt 0001-target-i386-add-PSCHANGE_MC_NO-bit-for-MSR_ARCH_CAPA.patch gpg: encrypted with 4096-bit RSA key, ID 0x5669D7C4E1794FF3, created 2018-04-11 "speck@linutronix.de " gpg: encrypted with 2048-bit RSA key, ID 0x873AB00F2B8E02C3, created 2014-10-18 "Paolo Bonzini " From: Paolo Bonzini Subject: [PATCH] target/i386: add PSCHANGE_MC_NO bit for MSR_ARCH_CAPABILITIES This is required to disable ITLB multihit mitigations in nested hypervisors. Signed-off-by: Paolo Bonzini --- target/i386/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) etc... Paolo On 24/10/19 09:34, speck for Paolo Bonzini wrote: > > Some processors may incur a machine check error possibly > resulting in an unrecoverable cpu hang when an instruction fetch > encounters a TLB multi-hit in the instruction TLB. This can occur > when the page size is changed along with either the physical > address or cache type [1]. > > This issue affects both bare-metal x86 page tables and EPT. > > This can be mitigated by either eliminating the use of large > pages or by using careful TLB invalidations when changing the > page size in the page tables. > > Just like Spectre, Meltdown, L1TF and MDS, a new bit has been > allocated in MSR_IA32_ARCH_CAPABILITIES (PSCHANGE_MC_NO) and will > be set on CPUs which are mitigated against this issue. > > [1] For example please refer to erratum SKL002 in "6th Generation > Intel Processor Family Specification Update" > https://www.intel.com/content/www/us/en/products/docs/processors/core/desktop-6th-gen-core-family-spec-update.html > https://www.google.com/search?q=site:intel.com+SKL002 > > There are a lot of other affected processors outside of Skylake and > that the erratum(referred above) does not fully disclose the issue > and the impact, both on Skylake and across all the affected CPUs. > > Signed-off-by: Vineela Tummalapalli > Co-developed-by: Pawan Gupta > Signed-off-by: Pawan Gupta > Signed-off-by: Paolo Bonzini > --- > Documentation/ABI/testing/sysfs-devices-system-cpu | 1 + > arch/x86/include/asm/cpufeatures.h | 1 + > arch/x86/include/asm/msr-index.h | 7 +++ > arch/x86/kernel/cpu/bugs.c | 13 ++++ > arch/x86/kernel/cpu/common.c | 71 ++++++++++++---------- > drivers/base/cpu.c | 8 +++ > include/linux/cpu.h | 2 + > 7 files changed, 70 insertions(+), 33 deletions(-) > > diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu > index 06d0931119cc..55bf5e1538ad 100644 > --- a/Documentation/ABI/testing/sysfs-devices-system-cpu > +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu > @@ -486,6 +486,7 @@ What: /sys/devices/system/cpu/vulnerabilities > /sys/devices/system/cpu/vulnerabilities/spec_store_bypass > /sys/devices/system/cpu/vulnerabilities/l1tf > /sys/devices/system/cpu/vulnerabilities/mds > + /sys/devices/system/cpu/vulnerabilities/itlb_multihit > Date: January 2018 > Contact: Linux kernel mailing list > Description: Information about CPU vulnerabilities > diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h > index 0652d3eed9bd..66aaad7611b2 100644 > --- a/arch/x86/include/asm/cpufeatures.h > +++ b/arch/x86/include/asm/cpufeatures.h > @@ -399,5 +399,6 @@ > #define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */ > #define X86_BUG_MSBDS_ONLY X86_BUG(20) /* CPU is only affected by the MSDBS variant of BUG_MDS */ > #define X86_BUG_SWAPGS X86_BUG(21) /* CPU is affected by speculation through SWAPGS */ > +#define X86_BUG_ITLB_MULTIHIT X86_BUG(22) /* CPU may incur MCE during certain page attribute changes */ > > #endif /* _ASM_X86_CPUFEATURES_H */ > diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h > index 20ce682a2540..c678899b21db 100644 > --- a/arch/x86/include/asm/msr-index.h > +++ b/arch/x86/include/asm/msr-index.h > @@ -93,6 +93,13 @@ > * Microarchitectural Data > * Sampling (MDS) vulnerabilities. > */ > +#define ARCH_CAP_PSCHANGE_MC_NO BIT(6) /* > + * The processor is not susceptible to a > + * machine check error due to modifying the > + * code page size along with either the > + * physical address or cache type > + * without TLB invalidation. > + */ > > #define MSR_IA32_FLUSH_CMD 0x0000010b > #define L1D_FLUSH BIT(0) /* > diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c > index 91c2561b905f..ecd0126648ea 100644 > --- a/arch/x86/kernel/cpu/bugs.c > +++ b/arch/x86/kernel/cpu/bugs.c > @@ -1311,6 +1311,11 @@ static ssize_t l1tf_show_state(char *buf) > } > #endif > > +static ssize_t itlb_multihit_show_state(char *buf) > +{ > + return sprintf(buf, "Processor vulnerable\n"); > +} > + > static ssize_t mds_show_state(char *buf) > { > if (boot_cpu_has(X86_FEATURE_HYPERVISOR)) { > @@ -1398,6 +1403,9 @@ static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr > case X86_BUG_MDS: > return mds_show_state(buf); > > + case X86_BUG_ITLB_MULTIHIT: > + return itlb_multihit_show_state(buf); > + > default: > break; > } > @@ -1434,4 +1442,9 @@ ssize_t cpu_show_mds(struct device *dev, struct device_attribute *attr, char *bu > { > return cpu_show_common(dev, attr, buf, X86_BUG_MDS); > } > + > +ssize_t cpu_show_itlb_multihit(struct device *dev, struct device_attribute *attr, char *buf) > +{ > + return cpu_show_common(dev, attr, buf, X86_BUG_ITLB_MULTIHIT); > +} > #endif > diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c > index 9ae7d1bcd4f4..fc00b2349a9f 100644 > --- a/arch/x86/kernel/cpu/common.c > +++ b/arch/x86/kernel/cpu/common.c > @@ -1016,13 +1016,14 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) > #endif > } > > -#define NO_SPECULATION BIT(0) > -#define NO_MELTDOWN BIT(1) > -#define NO_SSB BIT(2) > -#define NO_L1TF BIT(3) > -#define NO_MDS BIT(4) > -#define MSBDS_ONLY BIT(5) > -#define NO_SWAPGS BIT(6) > +#define NO_SPECULATION BIT(0) > +#define NO_MELTDOWN BIT(1) > +#define NO_SSB BIT(2) > +#define NO_L1TF BIT(3) > +#define NO_MDS BIT(4) > +#define MSBDS_ONLY BIT(5) > +#define NO_SWAPGS BIT(6) > +#define NO_ITLB_MULTIHIT BIT(7) > > #define VULNWL(_vendor, _family, _model, _whitelist) \ > { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } > @@ -1043,27 +1044,27 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) > VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION), > > /* Intel Family 6 */ > - VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION), > - VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION), > - VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION), > - VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION), > - VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION), > - > - VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), > - VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), > - VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), > - VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), > - VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), > - VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), > + VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION | NO_ITLB_MULTIHIT), > + > + VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), > > VULNWL_INTEL(CORE_YONAH, NO_SSB), > > - VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS), > - VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS), > + VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_AIRMONT_NP, NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), > > - VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS), > - VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS), > - VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS), > + VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_GOLDMONT_D, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS | NO_ITLB_MULTIHIT), > > /* > * Technically, swapgs isn't serializing on AMD (despite it previously > @@ -1074,14 +1075,14 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) > */ > > /* AMD Family 0xf - 0x12 */ > - VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), > - VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), > - VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), > - VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS), > + VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), > > /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ > - VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS), > - VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS), > + VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), > + VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS | NO_ITLB_MULTIHIT), > {} > }; > > @@ -1096,15 +1097,19 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) > { > u64 ia32_cap = 0; > > + if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) > + rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); > + > + /* Set ITLB_MULTIHIT bug if cpu is not in the whitelist and not mitigated */ > + if (!cpu_matches(NO_ITLB_MULTIHIT) && !(ia32_cap & ARCH_CAP_PSCHANGE_MC_NO)) > + setup_force_cpu_bug(X86_BUG_ITLB_MULTIHIT); > + > if (cpu_matches(NO_SPECULATION)) > return; > > setup_force_cpu_bug(X86_BUG_SPECTRE_V1); > setup_force_cpu_bug(X86_BUG_SPECTRE_V2); > > - if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) > - rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); > - > if (!cpu_matches(NO_SSB) && !(ia32_cap & ARCH_CAP_SSB_NO) && > !cpu_has(c, X86_FEATURE_AMD_SSB_NO)) > setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); > diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c > index cc37511de866..f1a6e020ed8d 100644 > --- a/drivers/base/cpu.c > +++ b/drivers/base/cpu.c > @@ -554,12 +554,19 @@ ssize_t __weak cpu_show_mds(struct device *dev, > return sprintf(buf, "Not affected\n"); > } > > +ssize_t __weak cpu_show_itlb_multihit(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + return sprintf(buf, "Not affected\n"); > +} > + > static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); > static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); > static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); > static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL); > static DEVICE_ATTR(l1tf, 0444, cpu_show_l1tf, NULL); > static DEVICE_ATTR(mds, 0444, cpu_show_mds, NULL); > +static DEVICE_ATTR(itlb_multihit, 0444, cpu_show_itlb_multihit, NULL); > > static struct attribute *cpu_root_vulnerabilities_attrs[] = { > &dev_attr_meltdown.attr, > @@ -568,6 +575,7 @@ ssize_t __weak cpu_show_mds(struct device *dev, > &dev_attr_spec_store_bypass.attr, > &dev_attr_l1tf.attr, > &dev_attr_mds.attr, > + &dev_attr_itlb_multihit.attr, > NULL > }; > > diff --git a/include/linux/cpu.h b/include/linux/cpu.h > index d0633ebdaa9c..038866a28f2c 100644 > --- a/include/linux/cpu.h > +++ b/include/linux/cpu.h > @@ -59,6 +59,8 @@ extern ssize_t cpu_show_l1tf(struct device *dev, > struct device_attribute *attr, char *buf); > extern ssize_t cpu_show_mds(struct device *dev, > struct device_attribute *attr, char *buf); > +extern ssize_t cpu_show_itlb_multihit(struct device *dev, > + struct device_attribute *attr, char *buf); > > extern __printf(4, 5) > struct device *cpu_device_create(struct device *parent, void *drvdata, >