From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail.linutronix.de (193.142.43.55:993) by crypto-ml.lab.linutronix.de with IMAP4-SSL for ; 24 Oct 2019 08:58:05 -0000 Received: from us-smtp-delivery-1.mimecast.com ([205.139.110.120] helo=us-smtp-1.mimecast.com) by Galois.linutronix.de with esmtps (TLS1.2:DHE_RSA_AES_256_CBC_SHA256:256) (Exim 4.80) (envelope-from ) id 1iNYwW-00017A-3I for speck@linutronix.de; Thu, 24 Oct 2019 10:58:04 +0200 Received: by mail-wr1-f70.google.com with SMTP id x9so6132918wrq.5 for ; Thu, 24 Oct 2019 01:57:58 -0700 (PDT) Received: from ?IPv6:2001:b07:6468:f312:6887:47f9:72a7:24e6? ([2001:b07:6468:f312:6887:47f9:72a7:24e6]) by smtp.gmail.com with ESMTPSA id f7sm16936619wre.68.2019.10.24.01.57.55 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 24 Oct 2019 01:57:55 -0700 (PDT) Subject: [MODERATED] Re: [PATCH v7 1/5] NX 1 References: <1571902455-22638-1-git-send-email-pbonzini@redhat.com> <1571902455-22638-2-git-send-email-pbonzini@redhat.com> From: Paolo Bonzini Message-ID: <9625dc0f-e16e-a3b7-8ed3-504efbadc549@redhat.com> Date: Thu, 24 Oct 2019 10:57:57 +0200 MIME-Version: 1.0 In-Reply-To: <1571902455-22638-2-git-send-email-pbonzini@redhat.com> Content-Type: multipart/mixed; boundary="GvAKwbWKOVDg3gzJ7GwkCD49H4McKwPbJ"; protected-headers="v1" To: speck@linutronix.de List-ID: This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156) --GvAKwbWKOVDg3gzJ7GwkCD49H4McKwPbJ Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: quoted-printable Uhm, this time I'm sure that I included the From/Subject lines, both in=20 this series and the QEMU patch. $ gpg --decrypt 0001-target-i386-add-PSCHANGE_MC_NO-bit-for-MSR_ARCH_CAPA= =2Epatch=20 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_CAPABIL= ITIES 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: >=20 > 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]. >=20 > This issue affects both bare-metal x86 page tables and EPT. >=20 > 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. >=20 > 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. >=20 > [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/d= esktop-6th-gen-core-family-spec-update.html > https://www.google.com/search?q=3Dsite:intel.com+SKL002 >=20 > 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. >=20 > 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(-) >=20 > diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Docum= entation/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 Microarchitect= ural 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 */ > =20 > #endif /* _ASM_X86_CPUFEATURES_H */ > diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/ms= r-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. > + */ > =20 > #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 > =20 > +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); > =20 > + 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 d= evice_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_attri= bute *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 c= puinfo_x86 *c) > #endif > } > =20 > -#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) > =20 > #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 c= puinfo_x86 *c) > VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION), > =20 > /* 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_SWA= PGS), > - VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_S= WAPGS), > - 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_SWA= PGS | NO_ITLB_MULTIHIT), > + VULNWL_INTEL(ATOM_SILVERMONT_D, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_S= WAPGS | 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), > =20 > VULNWL_INTEL(CORE_YONAH, NO_SSB), > =20 > - 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= ), > =20 > - 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_M= ULTIHIT), > + 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_IT= LB_MULTIHIT), > =20 > /* > * Technically, swapgs isn't serializing on AMD (despite it previousl= y > @@ -1074,14 +1075,14 @@ static void identify_cpu_without_cpuid(struct c= puinfo_x86 *c) > */ > =20 > /* 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), > =20 > /* 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_SWAP= GS), > + 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_SWAP= GS | NO_ITLB_MULTIHIT), > {} > }; > =20 > @@ -1096,15 +1097,19 @@ static void __init cpu_set_bug_bits(struct cpui= nfo_x86 *c) > { > u64 ia32_cap =3D 0; > =20 > + 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 mitig= ated */ > + 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; > =20 > setup_force_cpu_bug(X86_BUG_SPECTRE_V1); > setup_force_cpu_bug(X86_BUG_SPECTRE_V2); > =20 > - 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"); > } > =20 > +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);= > =20 > static struct attribute *cpu_root_vulnerabilities_attrs[] =3D { > &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 > }; > =20 > 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); > =20 > extern __printf(4, 5) > struct device *cpu_device_create(struct device *parent, void *drvdata,= >=20 --GvAKwbWKOVDg3gzJ7GwkCD49H4McKwPbJ--