From: Greg Kroah-Hartman Date: Tue, 6 Aug 2019 17:02:53 +0000 (+0200) Subject: 4.14-stable patches X-Git-Tag: v4.14.137~3 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a7dbfbb57df9f2fc6afccd8ac49280281c6d77fe;p=thirdparty%2Fkernel%2Fstable-queue.git 4.14-stable patches added patches: documentation-add-swapgs-description-to-the-spectre-v1-documentation.patch x86-cpufeatures-carve-out-cqm-features-retrieval.patch x86-cpufeatures-combine-word-11-and-12-into-a-new-scattered-features-word.patch x86-speculation-enable-spectre-v1-swapgs-mitigations.patch x86-speculation-prepare-entry-code-for-spectre-v1-swapgs-mitigations.patch x86-speculation-swapgs-exclude-atoms-from-speculation-through-swapgs.patch --- diff --git a/queue-4.14/documentation-add-swapgs-description-to-the-spectre-v1-documentation.patch b/queue-4.14/documentation-add-swapgs-description-to-the-spectre-v1-documentation.patch new file mode 100644 index 00000000000..02bbad9f15e --- /dev/null +++ b/queue-4.14/documentation-add-swapgs-description-to-the-spectre-v1-documentation.patch @@ -0,0 +1,166 @@ +From foo@baz Tue 06 Aug 2019 06:51:53 PM CEST +From: Josh Poimboeuf +Date: Sat, 3 Aug 2019 21:21:54 +0200 +Subject: Documentation: Add swapgs description to the Spectre v1 documentation + +From: Josh Poimboeuf + +commit 4c92057661a3412f547ede95715641d7ee16ddac upstream + +Add documentation to the Spectre document about the new swapgs variant of +Spectre v1. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Thomas Gleixner +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/admin-guide/hw-vuln/spectre.rst | 88 +++++++++++++++++++++++--- + 1 file changed, 80 insertions(+), 8 deletions(-) + +--- a/Documentation/admin-guide/hw-vuln/spectre.rst ++++ b/Documentation/admin-guide/hw-vuln/spectre.rst +@@ -41,10 +41,11 @@ Related CVEs + + The following CVE entries describe Spectre variants: + +- ============= ======================= ================= ++ ============= ======================= ========================== + CVE-2017-5753 Bounds check bypass Spectre variant 1 + CVE-2017-5715 Branch target injection Spectre variant 2 +- ============= ======================= ================= ++ CVE-2019-1125 Spectre v1 swapgs Spectre variant 1 (swapgs) ++ ============= ======================= ========================== + + Problem + ------- +@@ -78,6 +79,13 @@ There are some extensions of Spectre var + over the network, see :ref:`[12] `. However such attacks + are difficult, low bandwidth, fragile, and are considered low risk. + ++Note that, despite "Bounds Check Bypass" name, Spectre variant 1 is not ++only about user-controlled array bounds checks. It can affect any ++conditional checks. The kernel entry code interrupt, exception, and NMI ++handlers all have conditional swapgs checks. Those may be problematic ++in the context of Spectre v1, as kernel code can speculatively run with ++a user GS. ++ + Spectre variant 2 (Branch Target Injection) + ------------------------------------------- + +@@ -132,6 +140,9 @@ not cover all possible attack vectors. + 1. A user process attacking the kernel + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ++Spectre variant 1 ++~~~~~~~~~~~~~~~~~ ++ + The attacker passes a parameter to the kernel via a register or + via a known address in memory during a syscall. Such parameter may + be used later by the kernel as an index to an array or to derive +@@ -144,7 +155,40 @@ not cover all possible attack vectors. + potentially be influenced for Spectre attacks, new "nospec" accessor + macros are used to prevent speculative loading of data. + +- Spectre variant 2 attacker can :ref:`poison ` the branch ++Spectre variant 1 (swapgs) ++~~~~~~~~~~~~~~~~~~~~~~~~~~ ++ ++ An attacker can train the branch predictor to speculatively skip the ++ swapgs path for an interrupt or exception. If they initialize ++ the GS register to a user-space value, if the swapgs is speculatively ++ skipped, subsequent GS-related percpu accesses in the speculation ++ window will be done with the attacker-controlled GS value. This ++ could cause privileged memory to be accessed and leaked. ++ ++ For example: ++ ++ :: ++ ++ if (coming from user space) ++ swapgs ++ mov %gs:, %reg ++ mov (%reg), %reg1 ++ ++ When coming from user space, the CPU can speculatively skip the ++ swapgs, and then do a speculative percpu load using the user GS ++ value. So the user can speculatively force a read of any kernel ++ value. If a gadget exists which uses the percpu value as an address ++ in another load/store, then the contents of the kernel value may ++ become visible via an L1 side channel attack. ++ ++ A similar attack exists when coming from kernel space. The CPU can ++ speculatively do the swapgs, causing the user GS to get used for the ++ rest of the speculative window. ++ ++Spectre variant 2 ++~~~~~~~~~~~~~~~~~ ++ ++ A spectre variant 2 attacker can :ref:`poison ` the branch + target buffer (BTB) before issuing syscall to launch an attack. + After entering the kernel, the kernel could use the poisoned branch + target buffer on indirect jump and jump to gadget code in speculative +@@ -280,11 +324,18 @@ The sysfs file showing Spectre variant 1 + + The possible values in this file are: + +- ======================================= ================================= +- 'Mitigation: __user pointer sanitation' Protection in kernel on a case by +- case base with explicit pointer +- sanitation. +- ======================================= ================================= ++ .. list-table:: ++ ++ * - 'Not affected' ++ - The processor is not vulnerable. ++ * - 'Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers' ++ - The swapgs protections are disabled; otherwise it has ++ protection in the kernel on a case by case base with explicit ++ pointer sanitation and usercopy LFENCE barriers. ++ * - 'Mitigation: usercopy/swapgs barriers and __user pointer sanitization' ++ - Protection in the kernel on a case by case base with explicit ++ pointer sanitation, usercopy LFENCE barriers, and swapgs LFENCE ++ barriers. + + However, the protections are put in place on a case by case basis, + and there is no guarantee that all possible attack vectors for Spectre +@@ -366,12 +417,27 @@ Turning on mitigation for Spectre varian + 1. Kernel mitigation + ^^^^^^^^^^^^^^^^^^^^ + ++Spectre variant 1 ++~~~~~~~~~~~~~~~~~ ++ + For the Spectre variant 1, vulnerable kernel code (as determined + by code audit or scanning tools) is annotated on a case by case + basis to use nospec accessor macros for bounds clipping :ref:`[2] + ` to avoid any usable disclosure gadgets. However, it may + not cover all attack vectors for Spectre variant 1. + ++ Copy-from-user code has an LFENCE barrier to prevent the access_ok() ++ check from being mis-speculated. The barrier is done by the ++ barrier_nospec() macro. ++ ++ For the swapgs variant of Spectre variant 1, LFENCE barriers are ++ added to interrupt, exception and NMI entry where needed. These ++ barriers are done by the FENCE_SWAPGS_KERNEL_ENTRY and ++ FENCE_SWAPGS_USER_ENTRY macros. ++ ++Spectre variant 2 ++~~~~~~~~~~~~~~~~~ ++ + For Spectre variant 2 mitigation, the compiler turns indirect calls or + jumps in the kernel into equivalent return trampolines (retpolines) + :ref:`[3] ` :ref:`[9] ` to go to the target +@@ -473,6 +539,12 @@ Mitigation control on the kernel command + Spectre variant 2 mitigation can be disabled or force enabled at the + kernel command line. + ++ nospectre_v1 ++ ++ [X86,PPC] Disable mitigations for Spectre Variant 1 ++ (bounds check bypass). With this option data leaks are ++ possible in the system. ++ + nospectre_v2 + + [X86] Disable all mitigations for the Spectre variant 2 diff --git a/queue-4.14/series b/queue-4.14/series index 90a9aeff8e1..a5f07ff7e8b 100644 --- a/queue-4.14/series +++ b/queue-4.14/series @@ -51,3 +51,9 @@ eeprom-at24-make-spd-world-readable-again.patch objtool-support-gcc-9-cold-subfunction-naming-scheme.patch gcc-9-properly-declare-the-pv-hv-clock_page-storage.patch x86-vdso-prevent-segfaults-due-to-hoisted-vclock-reads.patch +x86-cpufeatures-carve-out-cqm-features-retrieval.patch +x86-cpufeatures-combine-word-11-and-12-into-a-new-scattered-features-word.patch +x86-speculation-prepare-entry-code-for-spectre-v1-swapgs-mitigations.patch +x86-speculation-enable-spectre-v1-swapgs-mitigations.patch +x86-speculation-swapgs-exclude-atoms-from-speculation-through-swapgs.patch +documentation-add-swapgs-description-to-the-spectre-v1-documentation.patch diff --git a/queue-4.14/x86-cpufeatures-carve-out-cqm-features-retrieval.patch b/queue-4.14/x86-cpufeatures-carve-out-cqm-features-retrieval.patch new file mode 100644 index 00000000000..135e943a0b0 --- /dev/null +++ b/queue-4.14/x86-cpufeatures-carve-out-cqm-features-retrieval.patch @@ -0,0 +1,107 @@ +From foo@baz Tue 06 Aug 2019 06:51:53 PM CEST +From: Borislav Petkov +Date: Wed, 19 Jun 2019 17:24:34 +0200 +Subject: x86/cpufeatures: Carve out CQM features retrieval + +From: Borislav Petkov + +commit 45fc56e629caa451467e7664fbd4c797c434a6c4 upstream + +... into a separate function for better readability. Split out from a +patch from Fenghua Yu to keep the mechanical, +sole code movement separate for easy review. + +No functional changes. + +Signed-off-by: Borislav Petkov +Signed-off-by: Thomas Gleixner +Cc: Fenghua Yu +Cc: x86@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/common.c | 60 +++++++++++++++++++++++-------------------- + 1 file changed, 33 insertions(+), 27 deletions(-) + +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -768,6 +768,38 @@ static void init_speculation_control(str + } + } + ++static void init_cqm(struct cpuinfo_x86 *c) ++{ ++ u32 eax, ebx, ecx, edx; ++ ++ /* Additional Intel-defined flags: level 0x0000000F */ ++ if (c->cpuid_level >= 0x0000000F) { ++ ++ /* QoS sub-leaf, EAX=0Fh, ECX=0 */ ++ cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx); ++ c->x86_capability[CPUID_F_0_EDX] = edx; ++ ++ if (cpu_has(c, X86_FEATURE_CQM_LLC)) { ++ /* will be overridden if occupancy monitoring exists */ ++ c->x86_cache_max_rmid = ebx; ++ ++ /* QoS sub-leaf, EAX=0Fh, ECX=1 */ ++ cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); ++ c->x86_capability[CPUID_F_1_EDX] = edx; ++ ++ if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) || ++ ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) || ++ (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) { ++ c->x86_cache_max_rmid = ecx; ++ c->x86_cache_occ_scale = ebx; ++ } ++ } else { ++ c->x86_cache_max_rmid = -1; ++ c->x86_cache_occ_scale = -1; ++ } ++ } ++} ++ + void get_cpu_cap(struct cpuinfo_x86 *c) + { + u32 eax, ebx, ecx, edx; +@@ -799,33 +831,6 @@ void get_cpu_cap(struct cpuinfo_x86 *c) + c->x86_capability[CPUID_D_1_EAX] = eax; + } + +- /* Additional Intel-defined flags: level 0x0000000F */ +- if (c->cpuid_level >= 0x0000000F) { +- +- /* QoS sub-leaf, EAX=0Fh, ECX=0 */ +- cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx); +- c->x86_capability[CPUID_F_0_EDX] = edx; +- +- if (cpu_has(c, X86_FEATURE_CQM_LLC)) { +- /* will be overridden if occupancy monitoring exists */ +- c->x86_cache_max_rmid = ebx; +- +- /* QoS sub-leaf, EAX=0Fh, ECX=1 */ +- cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); +- c->x86_capability[CPUID_F_1_EDX] = edx; +- +- if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) || +- ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) || +- (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) { +- c->x86_cache_max_rmid = ecx; +- c->x86_cache_occ_scale = ebx; +- } +- } else { +- c->x86_cache_max_rmid = -1; +- c->x86_cache_occ_scale = -1; +- } +- } +- + /* AMD-defined flags: level 0x80000001 */ + eax = cpuid_eax(0x80000000); + c->extended_cpuid_level = eax; +@@ -863,6 +868,7 @@ void get_cpu_cap(struct cpuinfo_x86 *c) + + init_scattered_cpuid_features(c); + init_speculation_control(c); ++ init_cqm(c); + + /* + * Clear/Set all flags overridden by options, after probe. diff --git a/queue-4.14/x86-cpufeatures-combine-word-11-and-12-into-a-new-scattered-features-word.patch b/queue-4.14/x86-cpufeatures-combine-word-11-and-12-into-a-new-scattered-features-word.patch new file mode 100644 index 00000000000..488a6f684ce --- /dev/null +++ b/queue-4.14/x86-cpufeatures-combine-word-11-and-12-into-a-new-scattered-features-word.patch @@ -0,0 +1,196 @@ +From foo@baz Tue 06 Aug 2019 06:51:53 PM CEST +From: Fenghua Yu +Date: Wed, 19 Jun 2019 18:51:09 +0200 +Subject: x86/cpufeatures: Combine word 11 and 12 into a new scattered features word + +From: Fenghua Yu + +commit acec0ce081de0c36459eea91647faf99296445a3 upstream + +It's a waste for the four X86_FEATURE_CQM_* feature bits to occupy two +whole feature bits words. To better utilize feature words, re-define +word 11 to host scattered features and move the four X86_FEATURE_CQM_* +features into Linux defined word 11. More scattered features can be +added in word 11 in the future. + +Rename leaf 11 in cpuid_leafs to CPUID_LNX_4 to reflect it's a +Linux-defined leaf. + +Rename leaf 12 as CPUID_DUMMY which will be replaced by a meaningful +name in the next patch when CPUID.7.1:EAX occupies world 12. + +Maximum number of RMID and cache occupancy scale are retrieved from +CPUID.0xf.1 after scattered CQM features are enumerated. Carve out the +code into a separate function. + +KVM doesn't support resctrl now. So it's safe to move the +X86_FEATURE_CQM_* features to scattered features word 11 for KVM. + +Signed-off-by: Fenghua Yu +Signed-off-by: Borislav Petkov +Signed-off-by: Thomas Gleixner +Cc: Aaron Lewis +Cc: Andy Lutomirski +Cc: Babu Moger +Cc: "Chang S. Bae" +Cc: "Sean J Christopherson" +Cc: Frederic Weisbecker +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: Jann Horn +Cc: Juergen Gross +Cc: Konrad Rzeszutek Wilk +Cc: kvm ML +Cc: Masahiro Yamada +Cc: Masami Hiramatsu +Cc: Nadav Amit +Cc: Paolo Bonzini +Cc: Pavel Tatashin +Cc: Peter Feiner +Cc: "Peter Zijlstra (Intel)" +Cc: "Radim Krčmář" +Cc: "Rafael J. Wysocki" +Cc: Ravi V Shankar +Cc: Sherry Hurwitz +Cc: Thomas Gleixner +Cc: Thomas Lendacky +Cc: x86 +Link: https://lkml.kernel.org/r/1560794416-217638-2-git-send-email-fenghua.yu@intel.com +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/cpufeature.h | 4 +-- + arch/x86/include/asm/cpufeatures.h | 17 ++++++++------ + arch/x86/kernel/cpu/common.c | 42 ++++++++++++++----------------------- + arch/x86/kernel/cpu/cpuid-deps.c | 3 ++ + arch/x86/kernel/cpu/scattered.c | 4 +++ + arch/x86/kvm/cpuid.h | 2 - + 6 files changed, 36 insertions(+), 36 deletions(-) + +--- a/arch/x86/include/asm/cpufeature.h ++++ b/arch/x86/include/asm/cpufeature.h +@@ -22,8 +22,8 @@ enum cpuid_leafs + CPUID_LNX_3, + CPUID_7_0_EBX, + CPUID_D_1_EAX, +- CPUID_F_0_EDX, +- CPUID_F_1_EDX, ++ CPUID_LNX_4, ++ CPUID_DUMMY, + CPUID_8000_0008_EBX, + CPUID_6_EAX, + CPUID_8000_000A_EDX, +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -271,13 +271,16 @@ + #define X86_FEATURE_XGETBV1 (10*32+ 2) /* XGETBV with ECX = 1 instruction */ + #define X86_FEATURE_XSAVES (10*32+ 3) /* XSAVES/XRSTORS instructions */ + +-/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:0 (EDX), word 11 */ +-#define X86_FEATURE_CQM_LLC (11*32+ 1) /* LLC QoS if 1 */ +- +-/* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (EDX), word 12 */ +-#define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring */ +-#define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */ +-#define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */ ++/* ++ * Extended auxiliary flags: Linux defined - for features scattered in various ++ * CPUID levels like 0xf, etc. ++ * ++ * Reuse free bits when adding new feature flags! ++ */ ++#define X86_FEATURE_CQM_LLC (11*32+ 0) /* LLC QoS if 1 */ ++#define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */ ++#define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */ ++#define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */ + + /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */ + #define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */ +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -770,33 +770,25 @@ static void init_speculation_control(str + + static void init_cqm(struct cpuinfo_x86 *c) + { +- u32 eax, ebx, ecx, edx; ++ if (!cpu_has(c, X86_FEATURE_CQM_LLC)) { ++ c->x86_cache_max_rmid = -1; ++ c->x86_cache_occ_scale = -1; ++ return; ++ } ++ ++ /* will be overridden if occupancy monitoring exists */ ++ c->x86_cache_max_rmid = cpuid_ebx(0xf); ++ ++ if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC) || ++ cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL) || ++ cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)) { ++ u32 eax, ebx, ecx, edx; + +- /* Additional Intel-defined flags: level 0x0000000F */ +- if (c->cpuid_level >= 0x0000000F) { ++ /* QoS sub-leaf, EAX=0Fh, ECX=1 */ ++ cpuid_count(0xf, 1, &eax, &ebx, &ecx, &edx); + +- /* QoS sub-leaf, EAX=0Fh, ECX=0 */ +- cpuid_count(0x0000000F, 0, &eax, &ebx, &ecx, &edx); +- c->x86_capability[CPUID_F_0_EDX] = edx; +- +- if (cpu_has(c, X86_FEATURE_CQM_LLC)) { +- /* will be overridden if occupancy monitoring exists */ +- c->x86_cache_max_rmid = ebx; +- +- /* QoS sub-leaf, EAX=0Fh, ECX=1 */ +- cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); +- c->x86_capability[CPUID_F_1_EDX] = edx; +- +- if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) || +- ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) || +- (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) { +- c->x86_cache_max_rmid = ecx; +- c->x86_cache_occ_scale = ebx; +- } +- } else { +- c->x86_cache_max_rmid = -1; +- c->x86_cache_occ_scale = -1; +- } ++ c->x86_cache_max_rmid = ecx; ++ c->x86_cache_occ_scale = ebx; + } + } + +--- a/arch/x86/kernel/cpu/cpuid-deps.c ++++ b/arch/x86/kernel/cpu/cpuid-deps.c +@@ -59,6 +59,9 @@ const static struct cpuid_dep cpuid_deps + { X86_FEATURE_AVX512_4VNNIW, X86_FEATURE_AVX512F }, + { X86_FEATURE_AVX512_4FMAPS, X86_FEATURE_AVX512F }, + { X86_FEATURE_AVX512_VPOPCNTDQ, X86_FEATURE_AVX512F }, ++ { X86_FEATURE_CQM_OCCUP_LLC, X86_FEATURE_CQM_LLC }, ++ { X86_FEATURE_CQM_MBM_TOTAL, X86_FEATURE_CQM_LLC }, ++ { X86_FEATURE_CQM_MBM_LOCAL, X86_FEATURE_CQM_LLC }, + {} + }; + +--- a/arch/x86/kernel/cpu/scattered.c ++++ b/arch/x86/kernel/cpu/scattered.c +@@ -21,6 +21,10 @@ struct cpuid_bit { + static const struct cpuid_bit cpuid_bits[] = { + { X86_FEATURE_APERFMPERF, CPUID_ECX, 0, 0x00000006, 0 }, + { X86_FEATURE_EPB, CPUID_ECX, 3, 0x00000006, 0 }, ++ { X86_FEATURE_CQM_LLC, CPUID_EDX, 1, 0x0000000f, 0 }, ++ { X86_FEATURE_CQM_OCCUP_LLC, CPUID_EDX, 0, 0x0000000f, 1 }, ++ { X86_FEATURE_CQM_MBM_TOTAL, CPUID_EDX, 1, 0x0000000f, 1 }, ++ { X86_FEATURE_CQM_MBM_LOCAL, CPUID_EDX, 2, 0x0000000f, 1 }, + { X86_FEATURE_CAT_L3, CPUID_EBX, 1, 0x00000010, 0 }, + { X86_FEATURE_CAT_L2, CPUID_EBX, 2, 0x00000010, 0 }, + { X86_FEATURE_CDP_L3, CPUID_ECX, 2, 0x00000010, 1 }, +--- a/arch/x86/kvm/cpuid.h ++++ b/arch/x86/kvm/cpuid.h +@@ -47,8 +47,6 @@ static const struct cpuid_reg reverse_cp + [CPUID_8000_0001_ECX] = {0x80000001, 0, CPUID_ECX}, + [CPUID_7_0_EBX] = { 7, 0, CPUID_EBX}, + [CPUID_D_1_EAX] = { 0xd, 1, CPUID_EAX}, +- [CPUID_F_0_EDX] = { 0xf, 0, CPUID_EDX}, +- [CPUID_F_1_EDX] = { 0xf, 1, CPUID_EDX}, + [CPUID_8000_0008_EBX] = {0x80000008, 0, CPUID_EBX}, + [CPUID_6_EAX] = { 6, 0, CPUID_EAX}, + [CPUID_8000_000A_EDX] = {0x8000000a, 0, CPUID_EDX}, diff --git a/queue-4.14/x86-speculation-enable-spectre-v1-swapgs-mitigations.patch b/queue-4.14/x86-speculation-enable-spectre-v1-swapgs-mitigations.patch new file mode 100644 index 00000000000..dceb73413c1 --- /dev/null +++ b/queue-4.14/x86-speculation-enable-spectre-v1-swapgs-mitigations.patch @@ -0,0 +1,262 @@ +From foo@baz Tue 06 Aug 2019 06:51:53 PM CEST +From: Josh Poimboeuf +Date: Mon, 8 Jul 2019 11:52:26 -0500 +Subject: x86/speculation: Enable Spectre v1 swapgs mitigations + +From: Josh Poimboeuf + +commit a2059825986a1c8143fd6698774fa9d83733bb11 upstream + +The previous commit added macro calls in the entry code which mitigate the +Spectre v1 swapgs issue if the X86_FEATURE_FENCE_SWAPGS_* features are +enabled. Enable those features where applicable. + +The mitigations may be disabled with "nospectre_v1" or "mitigations=off". + +There are different features which can affect the risk of attack: + +- When FSGSBASE is enabled, unprivileged users are able to place any + value in GS, using the wrgsbase instruction. This means they can + write a GS value which points to any value in kernel space, which can + be useful with the following gadget in an interrupt/exception/NMI + handler: + + if (coming from user space) + swapgs + mov %gs:, %reg1 + // dependent load or store based on the value of %reg + // for example: mov %(reg1), %reg2 + + If an interrupt is coming from user space, and the entry code + speculatively skips the swapgs (due to user branch mistraining), it + may speculatively execute the GS-based load and a subsequent dependent + load or store, exposing the kernel data to an L1 side channel leak. + + Note that, on Intel, a similar attack exists in the above gadget when + coming from kernel space, if the swapgs gets speculatively executed to + switch back to the user GS. On AMD, this variant isn't possible + because swapgs is serializing with respect to future GS-based + accesses. + + NOTE: The FSGSBASE patch set hasn't been merged yet, so the above case + doesn't exist quite yet. + +- When FSGSBASE is disabled, the issue is mitigated somewhat because + unprivileged users must use prctl(ARCH_SET_GS) to set GS, which + restricts GS values to user space addresses only. That means the + gadget would need an additional step, since the target kernel address + needs to be read from user space first. Something like: + + if (coming from user space) + swapgs + mov %gs:, %reg1 + mov (%reg1), %reg2 + // dependent load or store based on the value of %reg2 + // for example: mov %(reg2), %reg3 + + It's difficult to audit for this gadget in all the handlers, so while + there are no known instances of it, it's entirely possible that it + exists somewhere (or could be introduced in the future). Without + tooling to analyze all such code paths, consider it vulnerable. + + Effects of SMAP on the !FSGSBASE case: + + - If SMAP is enabled, and the CPU reports RDCL_NO (i.e., not + susceptible to Meltdown), the kernel is prevented from speculatively + reading user space memory, even L1 cached values. This effectively + disables the !FSGSBASE attack vector. + + - If SMAP is enabled, but the CPU *is* susceptible to Meltdown, SMAP + still prevents the kernel from speculatively reading user space + memory. But it does *not* prevent the kernel from reading the + user value from L1, if it has already been cached. This is probably + only a small hurdle for an attacker to overcome. + +Thanks to Dave Hansen for contributing the speculative_smap() function. + +Thanks to Andrew Cooper for providing the inside scoop on whether swapgs +is serializing on AMD. + +[ tglx: Fixed the USER fence decision and polished the comment as suggested + by Dave Hansen ] + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Thomas Gleixner +Reviewed-by: Dave Hansen +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/admin-guide/kernel-parameters.txt | 7 - + arch/x86/kernel/cpu/bugs.c | 115 ++++++++++++++++++++++-- + 2 files changed, 110 insertions(+), 12 deletions(-) + +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -2401,6 +2401,7 @@ + Equivalent to: nopti [X86,PPC] + nospectre_v1 [PPC] + nobp=0 [S390] ++ nospectre_v1 [X86] + nospectre_v2 [X86,PPC,S390] + spectre_v2_user=off [X86] + spec_store_bypass_disable=off [X86,PPC] +@@ -2740,9 +2741,9 @@ + nosmt=force: Force disable SMT, cannot be undone + via the sysfs control file. + +- nospectre_v1 [PPC] Disable mitigations for Spectre Variant 1 (bounds +- check bypass). With this option data leaks are possible +- in the system. ++ nospectre_v1 [X66, PPC] Disable mitigations for Spectre Variant 1 ++ (bounds check bypass). With this option data leaks ++ are possible in the system. + + nospectre_v2 [X86,PPC_FSL_BOOK3E] Disable all mitigations for the Spectre variant 2 + (indirect branch prediction) vulnerability. System may +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -32,6 +32,7 @@ + #include + #include + ++static void __init spectre_v1_select_mitigation(void); + static void __init spectre_v2_select_mitigation(void); + static void __init ssb_select_mitigation(void); + static void __init l1tf_select_mitigation(void); +@@ -96,17 +97,11 @@ void __init check_bugs(void) + if (boot_cpu_has(X86_FEATURE_STIBP)) + x86_spec_ctrl_mask |= SPEC_CTRL_STIBP; + +- /* Select the proper spectre mitigation before patching alternatives */ ++ /* Select the proper CPU mitigations before patching alternatives: */ ++ spectre_v1_select_mitigation(); + spectre_v2_select_mitigation(); +- +- /* +- * Select proper mitigation for any exposure to the Speculative Store +- * Bypass vulnerability. +- */ + ssb_select_mitigation(); +- + l1tf_select_mitigation(); +- + mds_select_mitigation(); + + arch_smt_update(); +@@ -272,6 +267,108 @@ static int __init mds_cmdline(char *str) + early_param("mds", mds_cmdline); + + #undef pr_fmt ++#define pr_fmt(fmt) "Spectre V1 : " fmt ++ ++enum spectre_v1_mitigation { ++ SPECTRE_V1_MITIGATION_NONE, ++ SPECTRE_V1_MITIGATION_AUTO, ++}; ++ ++static enum spectre_v1_mitigation spectre_v1_mitigation __ro_after_init = ++ SPECTRE_V1_MITIGATION_AUTO; ++ ++static const char * const spectre_v1_strings[] = { ++ [SPECTRE_V1_MITIGATION_NONE] = "Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers", ++ [SPECTRE_V1_MITIGATION_AUTO] = "Mitigation: usercopy/swapgs barriers and __user pointer sanitization", ++}; ++ ++static bool is_swapgs_serializing(void) ++{ ++ /* ++ * Technically, swapgs isn't serializing on AMD (despite it previously ++ * being documented as such in the APM). But according to AMD, %gs is ++ * updated non-speculatively, and the issuing of %gs-relative memory ++ * operands will be blocked until the %gs update completes, which is ++ * good enough for our purposes. ++ */ ++ return boot_cpu_data.x86_vendor == X86_VENDOR_AMD; ++} ++ ++/* ++ * Does SMAP provide full mitigation against speculative kernel access to ++ * userspace? ++ */ ++static bool smap_works_speculatively(void) ++{ ++ if (!boot_cpu_has(X86_FEATURE_SMAP)) ++ return false; ++ ++ /* ++ * On CPUs which are vulnerable to Meltdown, SMAP does not ++ * prevent speculative access to user data in the L1 cache. ++ * Consider SMAP to be non-functional as a mitigation on these ++ * CPUs. ++ */ ++ if (boot_cpu_has(X86_BUG_CPU_MELTDOWN)) ++ return false; ++ ++ return true; ++} ++ ++static void __init spectre_v1_select_mitigation(void) ++{ ++ if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1) || cpu_mitigations_off()) { ++ spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE; ++ return; ++ } ++ ++ if (spectre_v1_mitigation == SPECTRE_V1_MITIGATION_AUTO) { ++ /* ++ * With Spectre v1, a user can speculatively control either ++ * path of a conditional swapgs with a user-controlled GS ++ * value. The mitigation is to add lfences to both code paths. ++ * ++ * If FSGSBASE is enabled, the user can put a kernel address in ++ * GS, in which case SMAP provides no protection. ++ * ++ * [ NOTE: Don't check for X86_FEATURE_FSGSBASE until the ++ * FSGSBASE enablement patches have been merged. ] ++ * ++ * If FSGSBASE is disabled, the user can only put a user space ++ * address in GS. That makes an attack harder, but still ++ * possible if there's no SMAP protection. ++ */ ++ if (!smap_works_speculatively()) { ++ /* ++ * Mitigation can be provided from SWAPGS itself or ++ * PTI as the CR3 write in the Meltdown mitigation ++ * is serializing. ++ * ++ * If neither is there, mitigate with an LFENCE. ++ */ ++ if (!is_swapgs_serializing() && !boot_cpu_has(X86_FEATURE_PTI)) ++ setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_USER); ++ ++ /* ++ * Enable lfences in the kernel entry (non-swapgs) ++ * paths, to prevent user entry from speculatively ++ * skipping swapgs. ++ */ ++ setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_KERNEL); ++ } ++ } ++ ++ pr_info("%s\n", spectre_v1_strings[spectre_v1_mitigation]); ++} ++ ++static int __init nospectre_v1_cmdline(char *str) ++{ ++ spectre_v1_mitigation = SPECTRE_V1_MITIGATION_NONE; ++ return 0; ++} ++early_param("nospectre_v1", nospectre_v1_cmdline); ++ ++#undef pr_fmt + #define pr_fmt(fmt) "Spectre V2 : " fmt + + static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = +@@ -1255,7 +1352,7 @@ static ssize_t cpu_show_common(struct de + break; + + case X86_BUG_SPECTRE_V1: +- return sprintf(buf, "Mitigation: __user pointer sanitization\n"); ++ return sprintf(buf, "%s\n", spectre_v1_strings[spectre_v1_mitigation]); + + case X86_BUG_SPECTRE_V2: + return sprintf(buf, "%s%s%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], diff --git a/queue-4.14/x86-speculation-prepare-entry-code-for-spectre-v1-swapgs-mitigations.patch b/queue-4.14/x86-speculation-prepare-entry-code-for-spectre-v1-swapgs-mitigations.patch new file mode 100644 index 00000000000..32c9bf1b57b --- /dev/null +++ b/queue-4.14/x86-speculation-prepare-entry-code-for-spectre-v1-swapgs-mitigations.patch @@ -0,0 +1,184 @@ +From foo@baz Tue 06 Aug 2019 06:51:53 PM CEST +From: Josh Poimboeuf +Date: Mon, 8 Jul 2019 11:52:25 -0500 +Subject: x86/speculation: Prepare entry code for Spectre v1 swapgs mitigations + +From: Josh Poimboeuf + +commit 18ec54fdd6d18d92025af097cd042a75cf0ea24c upstream + +Spectre v1 isn't only about array bounds checks. It can affect any +conditional checks. The kernel entry code interrupt, exception, and NMI +handlers all have conditional swapgs checks. Those may be problematic in +the context of Spectre v1, as kernel code can speculatively run with a user +GS. + +For example: + + if (coming from user space) + swapgs + mov %gs:, %reg + mov (%reg), %reg1 + +When coming from user space, the CPU can speculatively skip the swapgs, and +then do a speculative percpu load using the user GS value. So the user can +speculatively force a read of any kernel value. If a gadget exists which +uses the percpu value as an address in another load/store, then the +contents of the kernel value may become visible via an L1 side channel +attack. + +A similar attack exists when coming from kernel space. The CPU can +speculatively do the swapgs, causing the user GS to get used for the rest +of the speculative window. + +The mitigation is similar to a traditional Spectre v1 mitigation, except: + + a) index masking isn't possible; because the index (percpu offset) + isn't user-controlled; and + + b) an lfence is needed in both the "from user" swapgs path and the + "from kernel" non-swapgs path (because of the two attacks described + above). + +The user entry swapgs paths already have SWITCH_TO_KERNEL_CR3, which has a +CR3 write when PTI is enabled. Since CR3 writes are serializing, the +lfences can be skipped in those cases. + +On the other hand, the kernel entry swapgs paths don't depend on PTI. + +To avoid unnecessary lfences for the user entry case, create two separate +features for alternative patching: + + X86_FEATURE_FENCE_SWAPGS_USER + X86_FEATURE_FENCE_SWAPGS_KERNEL + +Use these features in entry code to patch in lfences where needed. + +The features aren't enabled yet, so there's no functional change. + +Signed-off-by: Josh Poimboeuf +Signed-off-by: Thomas Gleixner +Reviewed-by: Dave Hansen +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/entry/calling.h | 17 +++++++++++++++++ + arch/x86/entry/entry_64.S | 19 +++++++++++++++++-- + arch/x86/include/asm/cpufeatures.h | 2 ++ + 3 files changed, 36 insertions(+), 2 deletions(-) + +--- a/arch/x86/entry/calling.h ++++ b/arch/x86/entry/calling.h +@@ -332,6 +332,23 @@ For 32-bit we have the following convent + + #endif + ++/* ++ * Mitigate Spectre v1 for conditional swapgs code paths. ++ * ++ * FENCE_SWAPGS_USER_ENTRY is used in the user entry swapgs code path, to ++ * prevent a speculative swapgs when coming from kernel space. ++ * ++ * FENCE_SWAPGS_KERNEL_ENTRY is used in the kernel entry non-swapgs code path, ++ * to prevent the swapgs from getting speculatively skipped when coming from ++ * user space. ++ */ ++.macro FENCE_SWAPGS_USER_ENTRY ++ ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_USER ++.endm ++.macro FENCE_SWAPGS_KERNEL_ENTRY ++ ALTERNATIVE "", "lfence", X86_FEATURE_FENCE_SWAPGS_KERNEL ++.endm ++ + #endif /* CONFIG_X86_64 */ + + /* +--- a/arch/x86/entry/entry_64.S ++++ b/arch/x86/entry/entry_64.S +@@ -531,9 +531,12 @@ END(irq_entries_start) + testb $3, CS-ORIG_RAX(%rsp) + jz 1f + SWAPGS ++ FENCE_SWAPGS_USER_ENTRY + call switch_to_thread_stack ++ jmp 2f + 1: +- ++ FENCE_SWAPGS_KERNEL_ENTRY ++2: + PUSH_AND_CLEAR_REGS + ENCODE_FRAME_POINTER + +@@ -1146,6 +1149,12 @@ ENTRY(paranoid_entry) + + 1: + SAVE_AND_SWITCH_TO_KERNEL_CR3 scratch_reg=%rax save_reg=%r14 ++ /* ++ * The above SAVE_AND_SWITCH_TO_KERNEL_CR3 macro doesn't do an ++ * unconditional CR3 write, even in the PTI case. So do an lfence ++ * to prevent GS speculation, regardless of whether PTI is enabled. ++ */ ++ FENCE_SWAPGS_KERNEL_ENTRY + + ret + END(paranoid_entry) +@@ -1195,6 +1204,7 @@ ENTRY(error_entry) + * from user mode due to an IRET fault. + */ + SWAPGS ++ FENCE_SWAPGS_USER_ENTRY + /* We have user CR3. Change to kernel CR3. */ + SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + +@@ -1216,6 +1226,8 @@ ENTRY(error_entry) + CALL_enter_from_user_mode + ret + ++.Lerror_entry_done_lfence: ++ FENCE_SWAPGS_KERNEL_ENTRY + .Lerror_entry_done: + TRACE_IRQS_OFF + ret +@@ -1234,7 +1246,7 @@ ENTRY(error_entry) + cmpq %rax, RIP+8(%rsp) + je .Lbstep_iret + cmpq $.Lgs_change, RIP+8(%rsp) +- jne .Lerror_entry_done ++ jne .Lerror_entry_done_lfence + + /* + * hack: .Lgs_change can fail with user gsbase. If this happens, fix up +@@ -1242,6 +1254,7 @@ ENTRY(error_entry) + * .Lgs_change's error handler with kernel gsbase. + */ + SWAPGS ++ FENCE_SWAPGS_USER_ENTRY + SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + jmp .Lerror_entry_done + +@@ -1256,6 +1269,7 @@ ENTRY(error_entry) + * gsbase and CR3. Switch to kernel gsbase and CR3: + */ + SWAPGS ++ FENCE_SWAPGS_USER_ENTRY + SWITCH_TO_KERNEL_CR3 scratch_reg=%rax + + /* +@@ -1347,6 +1361,7 @@ ENTRY(nmi) + + swapgs + cld ++ FENCE_SWAPGS_USER_ENTRY + SWITCH_TO_KERNEL_CR3 scratch_reg=%rdx + movq %rsp, %rdx + movq PER_CPU_VAR(cpu_current_top_of_stack), %rsp +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -281,6 +281,8 @@ + #define X86_FEATURE_CQM_OCCUP_LLC (11*32+ 1) /* LLC occupancy monitoring */ + #define X86_FEATURE_CQM_MBM_TOTAL (11*32+ 2) /* LLC Total MBM monitoring */ + #define X86_FEATURE_CQM_MBM_LOCAL (11*32+ 3) /* LLC Local MBM monitoring */ ++#define X86_FEATURE_FENCE_SWAPGS_USER (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */ ++#define X86_FEATURE_FENCE_SWAPGS_KERNEL (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */ + + /* AMD-defined CPU features, CPUID level 0x80000008 (EBX), word 13 */ + #define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */ diff --git a/queue-4.14/x86-speculation-swapgs-exclude-atoms-from-speculation-through-swapgs.patch b/queue-4.14/x86-speculation-swapgs-exclude-atoms-from-speculation-through-swapgs.patch new file mode 100644 index 00000000000..7ccf2b80c29 --- /dev/null +++ b/queue-4.14/x86-speculation-swapgs-exclude-atoms-from-speculation-through-swapgs.patch @@ -0,0 +1,151 @@ +From foo@baz Tue 06 Aug 2019 06:51:53 PM CEST +From: Thomas Gleixner +Date: Wed, 17 Jul 2019 21:18:59 +0200 +Subject: x86/speculation/swapgs: Exclude ATOMs from speculation through SWAPGS + +From: Thomas Gleixner + +commit f36cf386e3fec258a341d446915862eded3e13d8 upstream + +Intel provided the following information: + + On all current Atom processors, instructions that use a segment register + value (e.g. a load or store) will not speculatively execute before the + last writer of that segment retires. Thus they will not use a + speculatively written segment value. + +That means on ATOMs there is no speculation through SWAPGS, so the SWAPGS +entry paths can be excluded from the extra LFENCE if PTI is disabled. + +Create a separate bug flag for the through SWAPGS speculation and mark all +out-of-order ATOMs and AMD/HYGON CPUs as not affected. The in-order ATOMs +are excluded from the whole mitigation mess anyway. + +Reported-by: Andrew Cooper +Signed-off-by: Thomas Gleixner +Reviewed-by: Tyler Hicks +Reviewed-by: Josh Poimboeuf +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/kernel/cpu/bugs.c | 18 +++------------ + arch/x86/kernel/cpu/common.c | 42 +++++++++++++++++++++++-------------- + 3 files changed, 32 insertions(+), 29 deletions(-) + +--- a/arch/x86/include/asm/cpufeatures.h ++++ b/arch/x86/include/asm/cpufeatures.h +@@ -387,5 +387,6 @@ + #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 */ + #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 */ + + #endif /* _ASM_X86_CPUFEATURES_H */ +--- a/arch/x86/kernel/cpu/bugs.c ++++ b/arch/x86/kernel/cpu/bugs.c +@@ -282,18 +282,6 @@ static const char * const spectre_v1_str + [SPECTRE_V1_MITIGATION_AUTO] = "Mitigation: usercopy/swapgs barriers and __user pointer sanitization", + }; + +-static bool is_swapgs_serializing(void) +-{ +- /* +- * Technically, swapgs isn't serializing on AMD (despite it previously +- * being documented as such in the APM). But according to AMD, %gs is +- * updated non-speculatively, and the issuing of %gs-relative memory +- * operands will be blocked until the %gs update completes, which is +- * good enough for our purposes. +- */ +- return boot_cpu_data.x86_vendor == X86_VENDOR_AMD; +-} +- + /* + * Does SMAP provide full mitigation against speculative kernel access to + * userspace? +@@ -344,9 +332,11 @@ static void __init spectre_v1_select_mit + * PTI as the CR3 write in the Meltdown mitigation + * is serializing. + * +- * If neither is there, mitigate with an LFENCE. ++ * If neither is there, mitigate with an LFENCE to ++ * stop speculation through swapgs. + */ +- if (!is_swapgs_serializing() && !boot_cpu_has(X86_FEATURE_PTI)) ++ if (boot_cpu_has_bug(X86_BUG_SWAPGS) && ++ !boot_cpu_has(X86_FEATURE_PTI)) + setup_force_cpu_cap(X86_FEATURE_FENCE_SWAPGS_USER); + + /* +--- a/arch/x86/kernel/cpu/common.c ++++ b/arch/x86/kernel/cpu/common.c +@@ -903,6 +903,7 @@ static void identify_cpu_without_cpuid(s + #define NO_L1TF BIT(3) + #define NO_MDS BIT(4) + #define MSBDS_ONLY BIT(5) ++#define NO_SWAPGS BIT(6) + + #define VULNWL(_vendor, _family, _model, _whitelist) \ + { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } +@@ -926,29 +927,37 @@ static const __initconst struct x86_cpu_ + VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION), + VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION), + +- VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY), +- VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF | MSBDS_ONLY), +- VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF | MSBDS_ONLY), +- VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF | MSBDS_ONLY), +- VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF | MSBDS_ONLY), +- VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF | MSBDS_ONLY), ++ VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF | MSBDS_ONLY | NO_SWAPGS), ++ VULNWL_INTEL(ATOM_SILVERMONT_X, 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(CORE_YONAH, NO_SSB), + +- VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY), ++ VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF | MSBDS_ONLY | NO_SWAPGS), + +- 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), ++ VULNWL_INTEL(ATOM_GOLDMONT, NO_MDS | NO_L1TF | NO_SWAPGS), ++ VULNWL_INTEL(ATOM_GOLDMONT_X, NO_MDS | NO_L1TF | NO_SWAPGS), ++ VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_MDS | NO_L1TF | NO_SWAPGS), ++ ++ /* ++ * Technically, swapgs isn't serializing on AMD (despite it previously ++ * being documented as such in the APM). But according to AMD, %gs is ++ * updated non-speculatively, and the issuing of %gs-relative memory ++ * operands will be blocked until the %gs update completes, which is ++ * good enough for our purposes. ++ */ + + /* 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), ++ 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), + + /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ +- VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS), ++ VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF | NO_MDS | NO_SWAPGS), + {} + }; + +@@ -985,6 +994,9 @@ static void __init cpu_set_bug_bits(stru + setup_force_cpu_bug(X86_BUG_MSBDS_ONLY); + } + ++ if (!cpu_matches(NO_SWAPGS)) ++ setup_force_cpu_bug(X86_BUG_SWAPGS); ++ + if (cpu_matches(NO_MELTDOWN)) + return; +