| From foo@baz Tue Jun 14 07:05:29 PM CEST 2022 |
| From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> |
| Date: Thu, 19 May 2022 20:27:08 -0700 |
| Subject: x86/speculation/mmio: Enumerate Processor MMIO Stale Data bug |
| |
| From: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> |
| |
| commit 51802186158c74a0304f51ab963e7c2b3a2b046f upstream |
| |
| Processor MMIO Stale Data is a class of vulnerabilities that may |
| expose data after an MMIO operation. For more details please refer to |
| Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst |
| |
| Add the Processor MMIO Stale Data bug enumeration. A microcode update |
| adds new bits to the MSR IA32_ARCH_CAPABILITIES, define them. |
| |
| Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> |
| Signed-off-by: Borislav Petkov <bp@suse.de> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/include/asm/cpufeatures.h | 1 |
| arch/x86/include/asm/msr-index.h | 19 +++++++++++++ |
| arch/x86/kernel/cpu/common.c | 43 +++++++++++++++++++++++++++++-- |
| tools/arch/x86/include/asm/cpufeatures.h | 1 |
| tools/arch/x86/include/asm/msr-index.h | 19 +++++++++++++ |
| 5 files changed, 81 insertions(+), 2 deletions(-) |
| |
| --- a/arch/x86/include/asm/cpufeatures.h |
| +++ b/arch/x86/include/asm/cpufeatures.h |
| @@ -443,5 +443,6 @@ |
| #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ |
| #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ |
| #define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ |
| +#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */ |
| |
| #endif /* _ASM_X86_CPUFEATURES_H */ |
| --- a/arch/x86/include/asm/msr-index.h |
| +++ b/arch/x86/include/asm/msr-index.h |
| @@ -114,6 +114,25 @@ |
| * Not susceptible to |
| * TSX Async Abort (TAA) vulnerabilities. |
| */ |
| +#define ARCH_CAP_SBDR_SSDP_NO BIT(13) /* |
| + * Not susceptible to SBDR and SSDP |
| + * variants of Processor MMIO stale data |
| + * vulnerabilities. |
| + */ |
| +#define ARCH_CAP_FBSDP_NO BIT(14) /* |
| + * Not susceptible to FBSDP variant of |
| + * Processor MMIO stale data |
| + * vulnerabilities. |
| + */ |
| +#define ARCH_CAP_PSDP_NO BIT(15) /* |
| + * Not susceptible to PSDP variant of |
| + * Processor MMIO stale data |
| + * vulnerabilities. |
| + */ |
| +#define ARCH_CAP_FB_CLEAR BIT(17) /* |
| + * VERW clears CPU fill buffer |
| + * even on MDS_NO CPUs. |
| + */ |
| |
| #define MSR_IA32_FLUSH_CMD 0x0000010b |
| #define L1D_FLUSH BIT(0) /* |
| --- a/arch/x86/kernel/cpu/common.c |
| +++ b/arch/x86/kernel/cpu/common.c |
| @@ -1237,18 +1237,39 @@ static const __initconst struct x86_cpu_ |
| X86_FEATURE_ANY, issues) |
| |
| #define SRBDS BIT(0) |
| +/* CPU is affected by X86_BUG_MMIO_STALE_DATA */ |
| +#define MMIO BIT(1) |
| |
| static const struct x86_cpu_id cpu_vuln_blacklist[] __initconst = { |
| VULNBL_INTEL_STEPPINGS(IVYBRIDGE, X86_STEPPING_ANY, SRBDS), |
| VULNBL_INTEL_STEPPINGS(HASWELL, X86_STEPPING_ANY, SRBDS), |
| VULNBL_INTEL_STEPPINGS(HASWELL_L, X86_STEPPING_ANY, SRBDS), |
| VULNBL_INTEL_STEPPINGS(HASWELL_G, X86_STEPPING_ANY, SRBDS), |
| + VULNBL_INTEL_STEPPINGS(HASWELL_X, BIT(2) | BIT(4), MMIO), |
| + VULNBL_INTEL_STEPPINGS(BROADWELL_D, X86_STEPPINGS(0x3, 0x5), MMIO), |
| VULNBL_INTEL_STEPPINGS(BROADWELL_G, X86_STEPPING_ANY, SRBDS), |
| + VULNBL_INTEL_STEPPINGS(BROADWELL_X, X86_STEPPING_ANY, MMIO), |
| VULNBL_INTEL_STEPPINGS(BROADWELL, X86_STEPPING_ANY, SRBDS), |
| + VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO), |
| VULNBL_INTEL_STEPPINGS(SKYLAKE_L, X86_STEPPING_ANY, SRBDS), |
| + VULNBL_INTEL_STEPPINGS(SKYLAKE_X, BIT(3) | BIT(4) | BIT(6) | |
| + BIT(7) | BIT(0xB), MMIO), |
| + VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPINGS(0x3, 0x3), SRBDS | MMIO), |
| VULNBL_INTEL_STEPPINGS(SKYLAKE, X86_STEPPING_ANY, SRBDS), |
| - VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x0, 0xC), SRBDS), |
| - VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x0, 0xD), SRBDS), |
| + VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x9, 0xC), SRBDS | MMIO), |
| + VULNBL_INTEL_STEPPINGS(KABYLAKE_L, X86_STEPPINGS(0x0, 0x8), SRBDS), |
| + VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x9, 0xD), SRBDS | MMIO), |
| + VULNBL_INTEL_STEPPINGS(KABYLAKE, X86_STEPPINGS(0x0, 0x8), SRBDS), |
| + VULNBL_INTEL_STEPPINGS(ICELAKE_L, X86_STEPPINGS(0x5, 0x5), MMIO), |
| + VULNBL_INTEL_STEPPINGS(ICELAKE_D, X86_STEPPINGS(0x1, 0x1), MMIO), |
| + VULNBL_INTEL_STEPPINGS(ICELAKE_X, X86_STEPPINGS(0x4, 0x6), MMIO), |
| + VULNBL_INTEL_STEPPINGS(COMETLAKE, BIT(2) | BIT(3) | BIT(5), MMIO), |
| + VULNBL_INTEL_STEPPINGS(COMETLAKE_L, X86_STEPPINGS(0x0, 0x1), MMIO), |
| + VULNBL_INTEL_STEPPINGS(LAKEFIELD, X86_STEPPINGS(0x1, 0x1), MMIO), |
| + VULNBL_INTEL_STEPPINGS(ROCKETLAKE, X86_STEPPINGS(0x1, 0x1), MMIO), |
| + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT, X86_STEPPINGS(0x1, 0x1), MMIO), |
| + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_D, X86_STEPPING_ANY, MMIO), |
| + VULNBL_INTEL_STEPPINGS(ATOM_TREMONT_L, X86_STEPPINGS(0x0, 0x0), MMIO), |
| {} |
| }; |
| |
| @@ -1269,6 +1290,13 @@ u64 x86_read_arch_cap_msr(void) |
| return ia32_cap; |
| } |
| |
| +static bool arch_cap_mmio_immune(u64 ia32_cap) |
| +{ |
| + return (ia32_cap & ARCH_CAP_FBSDP_NO && |
| + ia32_cap & ARCH_CAP_PSDP_NO && |
| + ia32_cap & ARCH_CAP_SBDR_SSDP_NO); |
| +} |
| + |
| static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) |
| { |
| u64 ia32_cap = x86_read_arch_cap_msr(); |
| @@ -1328,6 +1356,17 @@ static void __init cpu_set_bug_bits(stru |
| cpu_matches(cpu_vuln_blacklist, SRBDS)) |
| setup_force_cpu_bug(X86_BUG_SRBDS); |
| |
| + /* |
| + * Processor MMIO Stale Data bug enumeration |
| + * |
| + * Affected CPU list is generally enough to enumerate the vulnerability, |
| + * but for virtualization case check for ARCH_CAP MSR bits also, VMM may |
| + * not want the guest to enumerate the bug. |
| + */ |
| + if (cpu_matches(cpu_vuln_blacklist, MMIO) && |
| + !arch_cap_mmio_immune(ia32_cap)) |
| + setup_force_cpu_bug(X86_BUG_MMIO_STALE_DATA); |
| + |
| if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| return; |
| |
| --- a/tools/arch/x86/include/asm/cpufeatures.h |
| +++ b/tools/arch/x86/include/asm/cpufeatures.h |
| @@ -443,5 +443,6 @@ |
| #define X86_BUG_TAA X86_BUG(22) /* CPU is affected by TSX Async Abort(TAA) */ |
| #define X86_BUG_ITLB_MULTIHIT X86_BUG(23) /* CPU may incur MCE during certain page attribute changes */ |
| #define X86_BUG_SRBDS X86_BUG(24) /* CPU may leak RNG bits if not mitigated */ |
| +#define X86_BUG_MMIO_STALE_DATA X86_BUG(25) /* CPU is affected by Processor MMIO Stale Data vulnerabilities */ |
| |
| #endif /* _ASM_X86_CPUFEATURES_H */ |
| --- a/tools/arch/x86/include/asm/msr-index.h |
| +++ b/tools/arch/x86/include/asm/msr-index.h |
| @@ -114,6 +114,25 @@ |
| * Not susceptible to |
| * TSX Async Abort (TAA) vulnerabilities. |
| */ |
| +#define ARCH_CAP_SBDR_SSDP_NO BIT(13) /* |
| + * Not susceptible to SBDR and SSDP |
| + * variants of Processor MMIO stale data |
| + * vulnerabilities. |
| + */ |
| +#define ARCH_CAP_FBSDP_NO BIT(14) /* |
| + * Not susceptible to FBSDP variant of |
| + * Processor MMIO stale data |
| + * vulnerabilities. |
| + */ |
| +#define ARCH_CAP_PSDP_NO BIT(15) /* |
| + * Not susceptible to PSDP variant of |
| + * Processor MMIO stale data |
| + * vulnerabilities. |
| + */ |
| +#define ARCH_CAP_FB_CLEAR BIT(17) /* |
| + * VERW clears CPU fill buffer |
| + * even on MDS_NO CPUs. |
| + */ |
| |
| #define MSR_IA32_FLUSH_CMD 0x0000010b |
| #define L1D_FLUSH BIT(0) /* |