]>
Commit | Line | Data |
---|---|---|
b07c49f8 GKH |
1 | From ea14078054cff48062700c792f30ee7e493c566c Mon Sep 17 00:00:00 2001 |
2 | From: Thomas Gleixner <tglx@linutronix.de> | |
3 | Date: Wed, 27 Feb 2019 10:10:23 +0100 | |
4 | Subject: [PATCH 02/27] x86/speculation: Consolidate CPU whitelists | |
5 | ||
6 | commit 36ad35131adacc29b328b9c8b6277a8bf0d6fd5d upstream | |
7 | ||
8 | The CPU vulnerability whitelists have some overlap and there are more | |
9 | whitelists coming along. | |
10 | ||
11 | Use the driver_data field in the x86_cpu_id struct to denote the | |
12 | whitelisted vulnerabilities and combine all whitelists into one. | |
13 | ||
14 | Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> | |
15 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> | |
16 | Reviewed-by: Frederic Weisbecker <frederic@kernel.org> | |
17 | Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
18 | Reviewed-by: Borislav Petkov <bp@suse.de> | |
19 | Reviewed-by: Jon Masters <jcm@redhat.com> | |
20 | Tested-by: Jon Masters <jcm@redhat.com> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
22 | --- | |
23 | arch/x86/kernel/cpu/common.c | 110 +++++++++++++++++++---------------- | |
24 | 1 file changed, 60 insertions(+), 50 deletions(-) | |
25 | ||
26 | diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c | |
27 | index cb28e98a0659..26ec15034f86 100644 | |
28 | --- a/arch/x86/kernel/cpu/common.c | |
29 | +++ b/arch/x86/kernel/cpu/common.c | |
30 | @@ -948,61 +948,72 @@ static void identify_cpu_without_cpuid(struct cpuinfo_x86 *c) | |
31 | #endif | |
32 | } | |
33 | ||
34 | -static const __initconst struct x86_cpu_id cpu_no_speculation[] = { | |
35 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SALTWELL, X86_FEATURE_ANY }, | |
36 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SALTWELL_TABLET, X86_FEATURE_ANY }, | |
37 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_BONNELL_MID, X86_FEATURE_ANY }, | |
38 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SALTWELL_MID, X86_FEATURE_ANY }, | |
39 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_BONNELL, X86_FEATURE_ANY }, | |
40 | - { X86_VENDOR_CENTAUR, 5 }, | |
41 | - { X86_VENDOR_INTEL, 5 }, | |
42 | - { X86_VENDOR_NSC, 5 }, | |
43 | - { X86_VENDOR_ANY, 4 }, | |
44 | +#define NO_SPECULATION BIT(0) | |
45 | +#define NO_MELTDOWN BIT(1) | |
46 | +#define NO_SSB BIT(2) | |
47 | +#define NO_L1TF BIT(3) | |
48 | + | |
49 | +#define VULNWL(_vendor, _family, _model, _whitelist) \ | |
50 | + { X86_VENDOR_##_vendor, _family, _model, X86_FEATURE_ANY, _whitelist } | |
51 | + | |
52 | +#define VULNWL_INTEL(model, whitelist) \ | |
53 | + VULNWL(INTEL, 6, INTEL_FAM6_##model, whitelist) | |
54 | + | |
55 | +#define VULNWL_AMD(family, whitelist) \ | |
56 | + VULNWL(AMD, family, X86_MODEL_ANY, whitelist) | |
57 | + | |
58 | +#define VULNWL_HYGON(family, whitelist) \ | |
59 | + VULNWL(HYGON, family, X86_MODEL_ANY, whitelist) | |
60 | + | |
61 | +static const __initconst struct x86_cpu_id cpu_vuln_whitelist[] = { | |
62 | + VULNWL(ANY, 4, X86_MODEL_ANY, NO_SPECULATION), | |
63 | + VULNWL(CENTAUR, 5, X86_MODEL_ANY, NO_SPECULATION), | |
64 | + VULNWL(INTEL, 5, X86_MODEL_ANY, NO_SPECULATION), | |
65 | + VULNWL(NSC, 5, X86_MODEL_ANY, NO_SPECULATION), | |
66 | + | |
67 | + VULNWL_INTEL(ATOM_SALTWELL, NO_SPECULATION), | |
68 | + VULNWL_INTEL(ATOM_SALTWELL_TABLET, NO_SPECULATION), | |
69 | + VULNWL_INTEL(ATOM_SALTWELL_MID, NO_SPECULATION), | |
70 | + VULNWL_INTEL(ATOM_BONNELL, NO_SPECULATION), | |
71 | + VULNWL_INTEL(ATOM_BONNELL_MID, NO_SPECULATION), | |
72 | + | |
73 | + VULNWL_INTEL(ATOM_SILVERMONT, NO_SSB | NO_L1TF), | |
74 | + VULNWL_INTEL(ATOM_SILVERMONT_X, NO_SSB | NO_L1TF), | |
75 | + VULNWL_INTEL(ATOM_SILVERMONT_MID, NO_SSB | NO_L1TF), | |
76 | + VULNWL_INTEL(ATOM_AIRMONT, NO_SSB | NO_L1TF), | |
77 | + VULNWL_INTEL(XEON_PHI_KNL, NO_SSB | NO_L1TF), | |
78 | + VULNWL_INTEL(XEON_PHI_KNM, NO_SSB | NO_L1TF), | |
79 | + | |
80 | + VULNWL_INTEL(CORE_YONAH, NO_SSB), | |
81 | + | |
82 | + VULNWL_INTEL(ATOM_AIRMONT_MID, NO_L1TF), | |
83 | + VULNWL_INTEL(ATOM_GOLDMONT, NO_L1TF), | |
84 | + VULNWL_INTEL(ATOM_GOLDMONT_X, NO_L1TF), | |
85 | + VULNWL_INTEL(ATOM_GOLDMONT_PLUS, NO_L1TF), | |
86 | + | |
87 | + VULNWL_AMD(0x0f, NO_MELTDOWN | NO_SSB | NO_L1TF), | |
88 | + VULNWL_AMD(0x10, NO_MELTDOWN | NO_SSB | NO_L1TF), | |
89 | + VULNWL_AMD(0x11, NO_MELTDOWN | NO_SSB | NO_L1TF), | |
90 | + VULNWL_AMD(0x12, NO_MELTDOWN | NO_SSB | NO_L1TF), | |
91 | + | |
92 | + /* FAMILY_ANY must be last, otherwise 0x0f - 0x12 matches won't work */ | |
93 | + VULNWL_AMD(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF), | |
94 | + VULNWL_HYGON(X86_FAMILY_ANY, NO_MELTDOWN | NO_L1TF), | |
95 | {} | |
96 | }; | |
97 | ||
98 | -static const __initconst struct x86_cpu_id cpu_no_meltdown[] = { | |
99 | - { X86_VENDOR_AMD }, | |
100 | - { X86_VENDOR_HYGON }, | |
101 | - {} | |
102 | -}; | |
103 | - | |
104 | -/* Only list CPUs which speculate but are non susceptible to SSB */ | |
105 | -static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = { | |
106 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, | |
107 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, | |
108 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_X }, | |
109 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_MID }, | |
110 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_CORE_YONAH }, | |
111 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL }, | |
112 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM }, | |
113 | - { X86_VENDOR_AMD, 0x12, }, | |
114 | - { X86_VENDOR_AMD, 0x11, }, | |
115 | - { X86_VENDOR_AMD, 0x10, }, | |
116 | - { X86_VENDOR_AMD, 0xf, }, | |
117 | - {} | |
118 | -}; | |
119 | +static bool __init cpu_matches(unsigned long which) | |
120 | +{ | |
121 | + const struct x86_cpu_id *m = x86_match_cpu(cpu_vuln_whitelist); | |
122 | ||
123 | -static const __initconst struct x86_cpu_id cpu_no_l1tf[] = { | |
124 | - /* in addition to cpu_no_speculation */ | |
125 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT }, | |
126 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_X }, | |
127 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, | |
128 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT_MID }, | |
129 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT_MID }, | |
130 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT }, | |
131 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT_X }, | |
132 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_GOLDMONT_PLUS }, | |
133 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL }, | |
134 | - { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM }, | |
135 | - {} | |
136 | -}; | |
137 | + return m && !!(m->driver_data & which); | |
138 | +} | |
139 | ||
140 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | |
141 | { | |
142 | u64 ia32_cap = 0; | |
143 | ||
144 | - if (x86_match_cpu(cpu_no_speculation)) | |
145 | + if (cpu_matches(NO_SPECULATION)) | |
146 | return; | |
147 | ||
148 | setup_force_cpu_bug(X86_BUG_SPECTRE_V1); | |
149 | @@ -1011,15 +1022,14 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | |
150 | if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) | |
151 | rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); | |
152 | ||
153 | - if (!x86_match_cpu(cpu_no_spec_store_bypass) && | |
154 | - !(ia32_cap & ARCH_CAP_SSB_NO) && | |
155 | + if (!cpu_matches(NO_SSB) && !(ia32_cap & ARCH_CAP_SSB_NO) && | |
156 | !cpu_has(c, X86_FEATURE_AMD_SSB_NO)) | |
157 | setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); | |
158 | ||
159 | if (ia32_cap & ARCH_CAP_IBRS_ALL) | |
160 | setup_force_cpu_cap(X86_FEATURE_IBRS_ENHANCED); | |
161 | ||
162 | - if (x86_match_cpu(cpu_no_meltdown)) | |
163 | + if (cpu_matches(NO_MELTDOWN)) | |
164 | return; | |
165 | ||
166 | /* Rogue Data Cache Load? No! */ | |
167 | @@ -1028,7 +1038,7 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | |
168 | ||
169 | setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); | |
170 | ||
171 | - if (x86_match_cpu(cpu_no_l1tf)) | |
172 | + if (cpu_matches(NO_L1TF)) | |
173 | return; | |
174 | ||
175 | setup_force_cpu_bug(X86_BUG_L1TF); | |
176 | -- | |
177 | 2.21.0 | |
178 |