| From c5ff349a49e0a64f0b1cc53ecc11ed7643c4bf3e Mon Sep 17 00:00:00 2001 |
| From: Andi Kleen <ak@linux.intel.com> |
| Date: Fri, 18 Jan 2019 16:50:16 -0800 |
| Subject: [PATCH 06/30] x86/speculation/mds: Add basic bug infrastructure for |
| MDS |
| |
| commit ed5194c2732c8084af9fd159c146ea92bf137128 upstream |
| |
| Microarchitectural Data Sampling (MDS), is a class of side channel attacks |
| on internal buffers in Intel CPUs. The variants are: |
| |
| - Microarchitectural Store Buffer Data Sampling (MSBDS) (CVE-2018-12126) |
| - Microarchitectural Fill Buffer Data Sampling (MFBDS) (CVE-2018-12130) |
| - Microarchitectural Load Port Data Sampling (MLPDS) (CVE-2018-12127) |
| |
| MSBDS leaks Store Buffer Entries which can be speculatively forwarded to a |
| dependent load (store-to-load forwarding) as an optimization. The forward |
| can also happen to a faulting or assisting load operation for a different |
| memory address, which can be exploited under certain conditions. Store |
| buffers are partitioned between Hyper-Threads so cross thread forwarding is |
| not possible. But if a thread enters or exits a sleep state the store |
| buffer is repartitioned which can expose data from one thread to the other. |
| |
| MFBDS leaks Fill Buffer Entries. Fill buffers are used internally to manage |
| L1 miss situations and to hold data which is returned or sent in response |
| to a memory or I/O operation. Fill buffers can forward data to a load |
| operation and also write data to the cache. When the fill buffer is |
| deallocated it can retain the stale data of the preceding operations which |
| can then be forwarded to a faulting or assisting load operation, which can |
| be exploited under certain conditions. Fill buffers are shared between |
| Hyper-Threads so cross thread leakage is possible. |
| |
| MLDPS leaks Load Port Data. Load ports are used to perform load operations |
| from memory or I/O. The received data is then forwarded to the register |
| file or a subsequent operation. In some implementations the Load Port can |
| contain stale data from a previous operation which can be forwarded to |
| faulting or assisting loads under certain conditions, which again can be |
| exploited eventually. Load ports are shared between Hyper-Threads so cross |
| thread leakage is possible. |
| |
| All variants have the same mitigation for single CPU thread case (SMT off), |
| so the kernel can treat them as one MDS issue. |
| |
| Add the basic infrastructure to detect if the current CPU is affected by |
| MDS. |
| |
| [ tglx: Rewrote changelog ] |
| |
| Signed-off-by: Andi Kleen <ak@linux.intel.com> |
| Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| Reviewed-by: Borislav Petkov <bp@suse.de> |
| Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| Reviewed-by: Frederic Weisbecker <frederic@kernel.org> |
| Reviewed-by: Jon Masters <jcm@redhat.com> |
| Tested-by: Jon Masters <jcm@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| arch/x86/include/asm/cpufeatures.h | 2 ++ |
| arch/x86/include/asm/msr-index.h | 5 +++++ |
| arch/x86/kernel/cpu/common.c | 23 +++++++++++++++-------- |
| 3 files changed, 22 insertions(+), 8 deletions(-) |
| |
| diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h |
| index 7b31ee5223fc..1dc7b8129b55 100644 |
| --- a/arch/x86/include/asm/cpufeatures.h |
| +++ b/arch/x86/include/asm/cpufeatures.h |
| @@ -341,6 +341,7 @@ |
| #define X86_FEATURE_AVX512_4VNNIW (18*32+ 2) /* AVX-512 Neural Network Instructions */ |
| #define X86_FEATURE_AVX512_4FMAPS (18*32+ 3) /* AVX-512 Multiply Accumulation Single precision */ |
| #define X86_FEATURE_TSX_FORCE_ABORT (18*32+13) /* "" TSX_FORCE_ABORT */ |
| +#define X86_FEATURE_MD_CLEAR (18*32+10) /* VERW clears CPU buffers */ |
| #define X86_FEATURE_PCONFIG (18*32+18) /* Intel PCONFIG */ |
| #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ |
| #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ |
| @@ -378,5 +379,6 @@ |
| #define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ |
| #define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ |
| #define X86_BUG_L1TF X86_BUG(18) /* CPU is affected by L1 Terminal Fault */ |
| +#define X86_BUG_MDS X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */ |
| |
| #endif /* _ASM_X86_CPUFEATURES_H */ |
| diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h |
| index 308b7c94df00..f85f43db9225 100644 |
| --- a/arch/x86/include/asm/msr-index.h |
| +++ b/arch/x86/include/asm/msr-index.h |
| @@ -79,6 +79,11 @@ |
| * attack, so no Speculative Store Bypass |
| * control required. |
| */ |
| +#define ARCH_CAP_MDS_NO BIT(5) /* |
| + * Not susceptible to |
| + * Microarchitectural Data |
| + * Sampling (MDS) vulnerabilities. |
| + */ |
| |
| #define MSR_IA32_FLUSH_CMD 0x0000010b |
| #define L1D_FLUSH BIT(0) /* |
| diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c |
| index fd16b4cc991f..0ea1e4bc3e20 100644 |
| --- a/arch/x86/kernel/cpu/common.c |
| +++ b/arch/x86/kernel/cpu/common.c |
| @@ -952,6 +952,7 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) |
| #define NO_MELTDOWN BIT(1) |
| #define NO_SSB BIT(2) |
| #define NO_L1TF BIT(3) |
| +#define NO_MDS BIT(4) |
| |
| #define VULNWL(_vendor, _family, _model, _whitelist) \ |
| { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } |
| @@ -968,6 +969,7 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { |
| VULNWL(INTEL, 5, X86_MODEL_ANY, NO_SPECULATION), |
| 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), |
| @@ -984,17 +986,19 @@ static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { |
| VULNWL_INTEL(CORE_YONAH, NO_SSB), |
| |
| VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF), |
| - VULNWL_INTEL(ATOM_GOLDMONT, NO_L1TF), |
| - VULNWL_INTEL(ATOM_GOLDMONT_X, NO_L1TF), |
| - VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_L1TF), |
| |
| - VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF), |
| - VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF), |
| - VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF), |
| - VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF), |
| + VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF), |
| + VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF), |
| + VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF), |
| + |
| + /* AMD Family 0xf - 0x12 */ |
| + VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), |
| + VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), |
| + VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), |
| + VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF | NO_MDS), |
| |
| /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ |
| - VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF), |
| + VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS), |
| {} |
| }; |
| |
| @@ -1025,6 +1029,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) |
| if (ia32_cap & ARCH_CAP_IBRS_ALL) |
| setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED); |
| |
| + if (!cpu_matches(NO_MDS) && !(ia32_cap & ARCH_CAP_MDS_NO)) |
| + setup_force_cpu_bug(X86_BUG_MDS); |
| + |
| if (cpu_matches(NO_MELTDOWN)) |
| return; |
| |
| -- |
| 2.21.0 |
| |