.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * x86 FPU boot time init code: |
---|
3 | 4 | */ |
---|
4 | 5 | #include <asm/fpu/internal.h> |
---|
5 | 6 | #include <asm/tlbflush.h> |
---|
6 | 7 | #include <asm/setup.h> |
---|
7 | | -#include <asm/cmdline.h> |
---|
8 | 8 | |
---|
9 | 9 | #include <linux/sched.h> |
---|
10 | 10 | #include <linux/sched/task.h> |
---|
.. | .. |
---|
49 | 49 | fpu__init_cpu_xstate(); |
---|
50 | 50 | } |
---|
51 | 51 | |
---|
52 | | -static bool fpu__probe_without_cpuid(void) |
---|
| 52 | +static bool __init fpu__probe_without_cpuid(void) |
---|
53 | 53 | { |
---|
54 | 54 | unsigned long cr0; |
---|
55 | 55 | u16 fsw, fcw; |
---|
.. | .. |
---|
67 | 67 | return fsw == 0 && (fcw & 0x103f) == 0x003f; |
---|
68 | 68 | } |
---|
69 | 69 | |
---|
70 | | -static void fpu__init_system_early_generic(struct cpuinfo_x86 *c) |
---|
| 70 | +static void __init fpu__init_system_early_generic(void) |
---|
71 | 71 | { |
---|
72 | 72 | if (!boot_cpu_has(X86_FEATURE_CPUID) && |
---|
73 | 73 | !test_bit(X86_FEATURE_FPU, (unsigned long *)cpu_caps_cleared)) { |
---|
.. | .. |
---|
138 | 138 | unsigned int fpu_kernel_xstate_size; |
---|
139 | 139 | EXPORT_SYMBOL_GPL(fpu_kernel_xstate_size); |
---|
140 | 140 | |
---|
141 | | -/* Get alignment of the TYPE. */ |
---|
142 | | -#define TYPE_ALIGN(TYPE) offsetof(struct { char x; TYPE test; }, test) |
---|
143 | | - |
---|
144 | 141 | /* |
---|
145 | 142 | * Enforce that 'MEMBER' is the last field of 'TYPE'. |
---|
146 | 143 | * |
---|
.. | .. |
---|
148 | 145 | * because that's how C aligns structs. |
---|
149 | 146 | */ |
---|
150 | 147 | #define CHECK_MEMBER_AT_END_OF(TYPE, MEMBER) \ |
---|
151 | | - BUILD_BUG_ON(sizeof(TYPE) != ALIGN(offsetofend(TYPE, MEMBER), \ |
---|
152 | | - TYPE_ALIGN(TYPE))) |
---|
| 148 | + BUILD_BUG_ON(sizeof(TYPE) != \ |
---|
| 149 | + ALIGN(offsetofend(TYPE, MEMBER), _Alignof(TYPE))) |
---|
153 | 150 | |
---|
154 | 151 | /* |
---|
155 | 152 | * We append the 'struct fpu' to the task_struct: |
---|
.. | .. |
---|
203 | 200 | */ |
---|
204 | 201 | |
---|
205 | 202 | if (!boot_cpu_has(X86_FEATURE_FPU)) { |
---|
206 | | - /* |
---|
207 | | - * Disable xsave as we do not support it if i387 |
---|
208 | | - * emulation is enabled. |
---|
209 | | - */ |
---|
210 | | - setup_clear_cpu_cap(X86_FEATURE_XSAVE); |
---|
211 | | - setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); |
---|
212 | 203 | fpu_kernel_xstate_size = sizeof(struct swregs_state); |
---|
213 | 204 | } else { |
---|
214 | 205 | if (boot_cpu_has(X86_FEATURE_FXSR)) |
---|
.. | .. |
---|
229 | 220 | */ |
---|
230 | 221 | u64 __init fpu__get_supported_xfeatures_mask(void) |
---|
231 | 222 | { |
---|
232 | | - return XCNTXT_MASK; |
---|
| 223 | + return XFEATURE_MASK_USER_SUPPORTED | |
---|
| 224 | + XFEATURE_MASK_SUPERVISOR_SUPPORTED; |
---|
233 | 225 | } |
---|
234 | 226 | |
---|
235 | 227 | /* Legacy code to initialize eager fpu mode. */ |
---|
.. | .. |
---|
239 | 231 | |
---|
240 | 232 | WARN_ON_FPU(!on_boot_cpu); |
---|
241 | 233 | on_boot_cpu = 0; |
---|
242 | | - |
---|
243 | | - WARN_ON_FPU(current->thread.fpu.initialized); |
---|
244 | | -} |
---|
245 | | - |
---|
246 | | -/* |
---|
247 | | - * We parse fpu parameters early because fpu__init_system() is executed |
---|
248 | | - * before parse_early_param(). |
---|
249 | | - */ |
---|
250 | | -static void __init fpu__init_parse_early_param(void) |
---|
251 | | -{ |
---|
252 | | - char arg[128]; |
---|
253 | | - char *argptr = arg; |
---|
254 | | - int arglen, res, bit; |
---|
255 | | - |
---|
256 | | - if (cmdline_find_option_bool(boot_command_line, "no387")) |
---|
257 | | - setup_clear_cpu_cap(X86_FEATURE_FPU); |
---|
258 | | - |
---|
259 | | - if (cmdline_find_option_bool(boot_command_line, "nofxsr")) { |
---|
260 | | - setup_clear_cpu_cap(X86_FEATURE_FXSR); |
---|
261 | | - setup_clear_cpu_cap(X86_FEATURE_FXSR_OPT); |
---|
262 | | - setup_clear_cpu_cap(X86_FEATURE_XMM); |
---|
263 | | - } |
---|
264 | | - |
---|
265 | | - if (cmdline_find_option_bool(boot_command_line, "noxsave")) |
---|
266 | | - fpu__xstate_clear_all_cpu_caps(); |
---|
267 | | - |
---|
268 | | - if (cmdline_find_option_bool(boot_command_line, "noxsaveopt")) |
---|
269 | | - setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); |
---|
270 | | - |
---|
271 | | - if (cmdline_find_option_bool(boot_command_line, "noxsaves")) |
---|
272 | | - setup_clear_cpu_cap(X86_FEATURE_XSAVES); |
---|
273 | | - |
---|
274 | | - arglen = cmdline_find_option(boot_command_line, "clearcpuid", arg, sizeof(arg)); |
---|
275 | | - if (arglen <= 0) |
---|
276 | | - return; |
---|
277 | | - |
---|
278 | | - pr_info("Clearing CPUID bits:"); |
---|
279 | | - do { |
---|
280 | | - res = get_option(&argptr, &bit); |
---|
281 | | - if (res == 0 || res == 3) |
---|
282 | | - break; |
---|
283 | | - |
---|
284 | | - /* If the argument was too long, the last bit may be cut off */ |
---|
285 | | - if (res == 1 && arglen >= sizeof(arg)) |
---|
286 | | - break; |
---|
287 | | - |
---|
288 | | - if (bit >= 0 && bit < NCAPINTS * 32) { |
---|
289 | | - pr_cont(" " X86_CAP_FMT, x86_cap_flag(bit)); |
---|
290 | | - setup_clear_cpu_cap(bit); |
---|
291 | | - } |
---|
292 | | - } while (res == 2); |
---|
293 | | - pr_cont("\n"); |
---|
294 | 234 | } |
---|
295 | 235 | |
---|
296 | 236 | /* |
---|
297 | 237 | * Called on the boot CPU once per system bootup, to set up the initial |
---|
298 | 238 | * FPU state that is later cloned into all processes: |
---|
299 | 239 | */ |
---|
300 | | -void __init fpu__init_system(struct cpuinfo_x86 *c) |
---|
| 240 | +void __init fpu__init_system(void) |
---|
301 | 241 | { |
---|
302 | | - fpu__init_parse_early_param(); |
---|
303 | | - fpu__init_system_early_generic(c); |
---|
| 242 | + fpu__init_system_early_generic(); |
---|
304 | 243 | |
---|
305 | 244 | /* |
---|
306 | 245 | * The FPU has to be operational for some of the |
---|