Mitigation for SpectreV4, based on SSBD. The following sysctl branches are added: machdep.spectre_v4.mitigated = {0/1} user-settable machdep.spectre_v4.affected = {0/1} set by the kernel The mitigation is not enabled by default yet. It is not tested either, because no microcode update has been published yet. On current CPUs a microcode/bios update must be applied for SSBD to be available. The user can then set mitigated=1. Even with an update applied the kernel will set affected=1. On future CPUs, where the problem will presumably be fixed by default, the CPU will report SSB_NO, and the kernel will set affected=0. In this case we also have mitigated=0, but the mitigation is not needed. For now the feature is system-wide. Perhaps we will want a more fine-grained, per-process approach in the future.diff -r1.120 -r1.121 src/sys/arch/x86/include/specialreg.h
(maxv)
--- src/sys/arch/x86/include/specialreg.h 2018/03/30 19:49:49 1.120
+++ src/sys/arch/x86/include/specialreg.h 2018/05/22 07:11:53 1.121
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: specialreg.h,v 1.120 2018/03/30 19:49:49 maxv Exp $ */ | 1 | /* $NetBSD: specialreg.h,v 1.121 2018/05/22 07:11:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 1991 The Regents of the University of California. | 4 | * Copyright (c) 1991 The Regents of the University of California. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without | |
8 | * modification, are permitted provided that the following conditions | 8 | * modification, are permitted provided that the following conditions | |
9 | * are met: | 9 | * are met: | |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * 1. Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | 11 | * notice, this list of conditions and the following disclaimer. | |
12 | * 2. Redistributions in binary form must reproduce the above copyright | 12 | * 2. Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | 13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | 14 | * documentation and/or other materials provided with the distribution. | |
@@ -395,31 +395,31 @@ | @@ -395,31 +395,31 @@ | |||
395 | "\1" "PREFETCHWT1" "\2" "AVX512_VBMI" "\3" "UMIP" "\4" "PKU" \ | 395 | "\1" "PREFETCHWT1" "\2" "AVX512_VBMI" "\3" "UMIP" "\4" "PKU" \ | |
396 | "\5" "OSPKE" "\7" "AVX512_VBMI2" \ | 396 | "\5" "OSPKE" "\7" "AVX512_VBMI2" \ | |
397 | "\11" "GFNI" "\12" "VAES" "\13" "VPCLMULQDQ" "\14" "AVX512_VNNI"\ | 397 | "\11" "GFNI" "\12" "VAES" "\13" "VPCLMULQDQ" "\14" "AVX512_VNNI"\ | |
398 | "\15" "AVX512_BITALG" "\17" "AVX512_VPOPCNTDQ" \ | 398 | "\15" "AVX512_BITALG" "\17" "AVX512_VPOPCNTDQ" \ | |
399 | "\27" "RDPID" \ | 399 | "\27" "RDPID" \ | |
400 | "\37" "SGXLC" | 400 | "\37" "SGXLC" | |
401 | 401 | |||
402 | /* %edx */ | 402 | /* %edx */ | |
403 | #define CPUID_SEF_AVX512_4VNNIW __BIT(2) | 403 | #define CPUID_SEF_AVX512_4VNNIW __BIT(2) | |
404 | #define CPUID_SEF_AVX512_4FMAPS __BIT(3) | 404 | #define CPUID_SEF_AVX512_4FMAPS __BIT(3) | |
405 | #define CPUID_SEF_IBRS __BIT(26) /* IBRS / IBPB Speculation Control */ | 405 | #define CPUID_SEF_IBRS __BIT(26) /* IBRS / IBPB Speculation Control */ | |
406 | #define CPUID_SEF_STIBP __BIT(27) /* STIBP Speculation Control */ | 406 | #define CPUID_SEF_STIBP __BIT(27) /* STIBP Speculation Control */ | |
407 | #define CPUID_SEF_ARCH_CAP __BIT(29) /* IA32_ARCH_CAPABILITIES */ | 407 | #define CPUID_SEF_ARCH_CAP __BIT(29) /* IA32_ARCH_CAPABILITIES */ | |
408 | #define CPUID_SEF_SSBD __BIT(31) /* Speculative Store Bypass Disable */ | |||
408 | 409 | |||
409 | #define CPUID_SEF_FLAGS2 "\20" \ | 410 | #define CPUID_SEF_FLAGS2 \ | |
410 | "\3" "AVX512_4VNNIW" "\4" "AVX512_4FMAPS" \ | 411 | "\20" "\3" "AVX512_4VNNIW" "\4" "AVX512_4FMAPS" \ | |
411 | "\33" "IBRS" "\34" "STIBP" \ | 412 | "\33" "IBRS" "\34" "STIBP" "\36" "ARCH_CAP" "\38" "SSBD" | |
412 | "\36" "ARCH_CAP" | |||
413 | 413 | |||
414 | /* | 414 | /* | |
415 | * CPUID Processor extended state Enumeration Fn0000000d | 415 | * CPUID Processor extended state Enumeration Fn0000000d | |
416 | * | 416 | * | |
417 | * %ecx == 0: supported features info: | 417 | * %ecx == 0: supported features info: | |
418 | * %eax: Valid bits of lower 32bits of XCR0 | 418 | * %eax: Valid bits of lower 32bits of XCR0 | |
419 | * %ebx: Maximum save area size for features enabled in XCR0 | 419 | * %ebx: Maximum save area size for features enabled in XCR0 | |
420 | * %ecx: Maximum save area size for all cpu features | 420 | * %ecx: Maximum save area size for all cpu features | |
421 | * %edx: Valid bits of upper 32bits of XCR0 | 421 | * %edx: Valid bits of upper 32bits of XCR0 | |
422 | * | 422 | * | |
423 | * %ecx == 1: | 423 | * %ecx == 1: | |
424 | * %eax: Bit 0 => xsaveopt instruction available (sandy bridge onwards) | 424 | * %eax: Bit 0 => xsaveopt instruction available (sandy bridge onwards) | |
425 | * %ebx: Save area size for features enabled by XCR0 | IA32_XSS | 425 | * %ebx: Save area size for features enabled by XCR0 | IA32_XSS | |
@@ -633,43 +633,45 @@ | @@ -633,43 +633,45 @@ | |||
633 | #define APICBASE_EN 0x00000800 /* software enable */ | 633 | #define APICBASE_EN 0x00000800 /* software enable */ | |
634 | /* | 634 | /* | |
635 | * APICBASE_PHYSADDR is actually variable-sized on some CPUs. But we're | 635 | * APICBASE_PHYSADDR is actually variable-sized on some CPUs. But we're | |
636 | * only interested in the initial value, which is guaranteed to fit the | 636 | * only interested in the initial value, which is guaranteed to fit the | |
637 | * first 32 bits. So this macro is fine. | 637 | * first 32 bits. So this macro is fine. | |
638 | */ | 638 | */ | |
639 | #define APICBASE_PHYSADDR 0xfffff000 /* physical address */ | 639 | #define APICBASE_PHYSADDR 0xfffff000 /* physical address */ | |
640 | #define MSR_EBL_CR_POWERON 0x02a | 640 | #define MSR_EBL_CR_POWERON 0x02a | |
641 | #define MSR_EBC_FREQUENCY_ID 0x02c /* PIV only */ | 641 | #define MSR_EBC_FREQUENCY_ID 0x02c /* PIV only */ | |
642 | #define MSR_TEST_CTL 0x033 | 642 | #define MSR_TEST_CTL 0x033 | |
643 | #define MSR_IA32_SPEC_CTRL 0x048 | 643 | #define MSR_IA32_SPEC_CTRL 0x048 | |
644 | #define IA32_SPEC_CTRL_IBRS 0x01 | 644 | #define IA32_SPEC_CTRL_IBRS 0x01 | |
645 | #define IA32_SPEC_CTRL_STIBP 0x02 | 645 | #define IA32_SPEC_CTRL_STIBP 0x02 | |
646 | #define IA32_SPEC_CTRL_SSBD 0x04 | |||
646 | #define MSR_IA32_PRED_CMD 0x049 | 647 | #define MSR_IA32_PRED_CMD 0x049 | |
647 | #define IA32_PRED_CMD_IBPB 0x01 | 648 | #define IA32_PRED_CMD_IBPB 0x01 | |
648 | #define MSR_BIOS_UPDT_TRIG 0x079 | 649 | #define MSR_BIOS_UPDT_TRIG 0x079 | |
649 | #define MSR_BBL_CR_D0 0x088 /* PII+ only */ | 650 | #define MSR_BBL_CR_D0 0x088 /* PII+ only */ | |
650 | #define MSR_BBL_CR_D1 0x089 /* PII+ only */ | 651 | #define MSR_BBL_CR_D1 0x089 /* PII+ only */ | |
651 | #define MSR_BBL_CR_D2 0x08a /* PII+ only */ | 652 | #define MSR_BBL_CR_D2 0x08a /* PII+ only */ | |
652 | #define MSR_BIOS_SIGN 0x08b | 653 | #define MSR_BIOS_SIGN 0x08b | |
653 | #define MSR_PERFCTR0 0x0c1 | 654 | #define MSR_PERFCTR0 0x0c1 | |
654 | #define MSR_PERFCTR1 0x0c2 | 655 | #define MSR_PERFCTR1 0x0c2 | |
655 | #define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */ | 656 | #define MSR_FSB_FREQ 0x0cd /* Core Duo/Solo only */ | |
656 | #define MSR_MPERF 0x0e7 | 657 | #define MSR_MPERF 0x0e7 | |
657 | #define MSR_APERF 0x0e8 | 658 | #define MSR_APERF 0x0e8 | |
658 | #define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */ | 659 | #define MSR_IA32_EXT_CONFIG 0x0ee /* Undocumented. Core Solo/Duo only */ | |
659 | #define MSR_MTRRcap 0x0fe | 660 | #define MSR_MTRRcap 0x0fe | |
660 | #define MSR_IA32_ARCH_CAPABILITIES 0x10a | 661 | #define MSR_IA32_ARCH_CAPABILITIES 0x10a | |
661 | #define IA32_ARCH_RDCL_NO 0x01 | 662 | #define IA32_ARCH_RDCL_NO 0x01 | |
662 | #define IA32_ARCH_IBRS_ALL 0x02 | 663 | #define IA32_ARCH_IBRS_ALL 0x02 | |
664 | #define IA32_ARCH_SSB_NO 0x10 | |||
663 | #define MSR_BBL_CR_ADDR 0x116 /* PII+ only */ | 665 | #define MSR_BBL_CR_ADDR 0x116 /* PII+ only */ | |
664 | #define MSR_BBL_CR_DECC 0x118 /* PII+ only */ | 666 | #define MSR_BBL_CR_DECC 0x118 /* PII+ only */ | |
665 | #define MSR_BBL_CR_CTL 0x119 /* PII+ only */ | 667 | #define MSR_BBL_CR_CTL 0x119 /* PII+ only */ | |
666 | #define MSR_BBL_CR_TRIG 0x11a /* PII+ only */ | 668 | #define MSR_BBL_CR_TRIG 0x11a /* PII+ only */ | |
667 | #define MSR_BBL_CR_BUSY 0x11b /* PII+ only */ | 669 | #define MSR_BBL_CR_BUSY 0x11b /* PII+ only */ | |
668 | #define MSR_BBL_CR_CTR3 0x11e /* PII+ only */ | 670 | #define MSR_BBL_CR_CTR3 0x11e /* PII+ only */ | |
669 | #define MSR_SYSENTER_CS 0x174 /* PII+ only */ | 671 | #define MSR_SYSENTER_CS 0x174 /* PII+ only */ | |
670 | #define MSR_SYSENTER_ESP 0x175 /* PII+ only */ | 672 | #define MSR_SYSENTER_ESP 0x175 /* PII+ only */ | |
671 | #define MSR_SYSENTER_EIP 0x176 /* PII+ only */ | 673 | #define MSR_SYSENTER_EIP 0x176 /* PII+ only */ | |
672 | #define MSR_MCG_CAP 0x179 | 674 | #define MSR_MCG_CAP 0x179 | |
673 | #define MSR_MCG_STATUS 0x17a | 675 | #define MSR_MCG_STATUS 0x17a | |
674 | #define MSR_MCG_CTL 0x17b | 676 | #define MSR_MCG_CTL 0x17b | |
675 | #define MSR_EVNTSEL0 0x186 | 677 | #define MSR_EVNTSEL0 0x186 |
--- src/sys/arch/x86/x86/spectre.c 2018/05/22 06:31:05 1.11
+++ src/sys/arch/x86/x86/spectre.c 2018/05/22 07:11:53 1.12
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: spectre.c,v 1.11 2018/05/22 06:31:05 maxv Exp $ */ | 1 | /* $NetBSD: spectre.c,v 1.12 2018/05/22 07:11:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /* | 3 | /* | |
4 | * Copyright (c) 2018 NetBSD Foundation, Inc. | 4 | * Copyright (c) 2018 NetBSD Foundation, Inc. | |
5 | * All rights reserved. | 5 | * All rights reserved. | |
6 | * | 6 | * | |
7 | * This code is derived from software contributed to The NetBSD Foundation | 7 | * This code is derived from software contributed to The NetBSD Foundation | |
8 | * by Maxime Villard. | 8 | * by Maxime Villard. | |
9 | * | 9 | * | |
10 | * Redistribution and use in source and binary forms, with or without | 10 | * Redistribution and use in source and binary forms, with or without | |
11 | * modification, are permitted provided that the following conditions | 11 | * modification, are permitted provided that the following conditions | |
12 | * are met: | 12 | * are met: | |
13 | * 1. Redistributions of source code must retain the above copyright | 13 | * 1. Redistributions of source code must retain the above copyright | |
14 | * notice, this list of conditions and the following disclaimer. | 14 | * notice, this list of conditions and the following disclaimer. | |
@@ -24,27 +24,27 @@ | @@ -24,27 +24,27 @@ | |||
24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 24 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 25 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 27 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 28 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
29 | * POSSIBILITY OF SUCH DAMAGE. | 29 | * POSSIBILITY OF SUCH DAMAGE. | |
30 | */ | 30 | */ | |
31 | 31 | |||
32 | /* | 32 | /* | |
33 | * Mitigations for the Spectre V2 CPU flaw. | 33 | * Mitigations for the Spectre V2 CPU flaw. | |
34 | */ | 34 | */ | |
35 | 35 | |||
36 | #include <sys/cdefs.h> | 36 | #include <sys/cdefs.h> | |
37 | __KERNEL_RCSID(0, "$NetBSD: spectre.c,v 1.11 2018/05/22 06:31:05 maxv Exp $"); | 37 | __KERNEL_RCSID(0, "$NetBSD: spectre.c,v 1.12 2018/05/22 07:11:53 maxv Exp $"); | |
38 | 38 | |||
39 | #include <sys/param.h> | 39 | #include <sys/param.h> | |
40 | #include <sys/systm.h> | 40 | #include <sys/systm.h> | |
41 | #include <sys/cpu.h> | 41 | #include <sys/cpu.h> | |
42 | #include <sys/sysctl.h> | 42 | #include <sys/sysctl.h> | |
43 | #include <sys/xcall.h> | 43 | #include <sys/xcall.h> | |
44 | 44 | |||
45 | #include <machine/cpufunc.h> | 45 | #include <machine/cpufunc.h> | |
46 | #include <machine/cpuvar.h> | 46 | #include <machine/cpuvar.h> | |
47 | #include <machine/specialreg.h> | 47 | #include <machine/specialreg.h> | |
48 | #include <machine/frameasm.h> | 48 | #include <machine/frameasm.h> | |
49 | 49 | |||
50 | #include <x86/cputypes.h> | 50 | #include <x86/cputypes.h> | |
@@ -337,26 +337,160 @@ sysctl_machdep_spectreV2_mitigated(SYSCT | @@ -337,26 +337,160 @@ sysctl_machdep_spectreV2_mitigated(SYSCT | |||
337 | error = mitigation_v2_change(false); | 337 | error = mitigation_v2_change(false); | |
338 | } else { | 338 | } else { | |
339 | if (spec_v2_mitigation_enabled) | 339 | if (spec_v2_mitigation_enabled) | |
340 | error = 0; | 340 | error = 0; | |
341 | else | 341 | else | |
342 | error = mitigation_v2_change(true); | 342 | error = mitigation_v2_change(true); | |
343 | } | 343 | } | |
344 | 344 | |||
345 | return error; | 345 | return error; | |
346 | } | 346 | } | |
347 | 347 | |||
348 | /* -------------------------------------------------------------------------- */ | 348 | /* -------------------------------------------------------------------------- */ | |
349 | 349 | |||
350 | bool spec_v4_mitigation_enabled __read_mostly = false; | |||
351 | bool spec_v4_affected __read_mostly = true; | |||
352 | ||||
353 | int sysctl_machdep_spectreV4_mitigated(SYSCTLFN_ARGS); | |||
354 | ||||
355 | static bool ssbd_needed(void) | |||
356 | { | |||
357 | uint64_t msr; | |||
358 | ||||
359 | if (cpu_info_primary.ci_feat_val[7] & CPUID_SEF_ARCH_CAP) { | |||
360 | msr = rdmsr(MSR_IA32_ARCH_CAPABILITIES); | |||
361 | if (msr & IA32_ARCH_SSB_NO) { | |||
362 | /* | |||
363 | * The processor indicates it is not vulnerable to the | |||
364 | * Speculative Store Bypass (SpectreV4) flaw. | |||
365 | */ | |||
366 | return false; | |||
367 | } | |||
368 | } | |||
369 | ||||
370 | return true; | |||
371 | } | |||
372 | ||||
373 | static bool ssbd_supported(void) | |||
374 | { | |||
375 | u_int descs[4]; | |||
376 | ||||
377 | if (cpu_vendor == CPUVENDOR_INTEL) { | |||
378 | if (cpuid_level >= 7) { | |||
379 | x86_cpuid(7, descs); | |||
380 | if (descs[3] & CPUID_SEF_SSBD) { | |||
381 | /* descs[3] = %edx */ | |||
382 | return true; | |||
383 | } | |||
384 | } | |||
385 | } | |||
386 | return false; | |||
387 | } | |||
388 | ||||
389 | static void | |||
390 | mitigation_v4_apply_cpu(bool enabled) | |||
391 | { | |||
392 | uint64_t msr; | |||
393 | ||||
394 | msr = rdmsr(MSR_IA32_SPEC_CTRL); | |||
395 | ||||
396 | if (enabled) { | |||
397 | msr |= IA32_SPEC_CTRL_SSBD; | |||
398 | } else { | |||
399 | msr &= ~IA32_SPEC_CTRL_SSBD; | |||
400 | } | |||
401 | ||||
402 | wrmsr(MSR_IA32_SPEC_CTRL, msr); | |||
403 | } | |||
404 | ||||
405 | static void | |||
406 | mitigation_v4_change_cpu(void *arg1, void *arg2) | |||
407 | { | |||
408 | bool enabled = (bool)arg1; | |||
409 | ||||
410 | mitigation_v4_apply_cpu(enabled); | |||
411 | } | |||
412 | ||||
413 | static int mitigation_v4_change(bool enabled) | |||
414 | { | |||
415 | struct cpu_info *ci = NULL; | |||
416 | CPU_INFO_ITERATOR cii; | |||
417 | uint64_t xc; | |||
418 | ||||
419 | if (!ssbd_supported()) { | |||
420 | printf("[!] No mitigation available\n"); | |||
421 | return EOPNOTSUPP; | |||
422 | } | |||
423 | ||||
424 | mutex_enter(&cpu_lock); | |||
425 | ||||
426 | /* | |||
427 | * We expect all the CPUs to be online. | |||
428 | */ | |||
429 | for (CPU_INFO_FOREACH(cii, ci)) { | |||
430 | struct schedstate_percpu *spc = &ci->ci_schedstate; | |||
431 | if (spc->spc_flags & SPCF_OFFLINE) { | |||
432 | printf("[!] cpu%d offline, SpectreV4 not changed\n", | |||
433 | cpu_index(ci)); | |||
434 | mutex_exit(&cpu_lock); | |||
435 | return EOPNOTSUPP; | |||
436 | } | |||
437 | } | |||
438 | ||||
439 | printf("[+] %s SpectreV4 Mitigation...", | |||
440 | enabled ? "Enabling" : "Disabling"); | |||
441 | xc = xc_broadcast(0, mitigation_v4_change_cpu, | |||
442 | (void *)enabled, NULL); | |||
443 | xc_wait(xc); | |||
444 | printf(" done!\n"); | |||
445 | spec_v4_mitigation_enabled = enabled; | |||
446 | mutex_exit(&cpu_lock); | |||
447 | ||||
448 | return 0; | |||
449 | } | |||
450 | ||||
451 | int | |||
452 | sysctl_machdep_spectreV4_mitigated(SYSCTLFN_ARGS) | |||
453 | { | |||
454 | struct sysctlnode node; | |||
455 | int error; | |||
456 | bool val; | |||
457 | ||||
458 | val = *(bool *)rnode->sysctl_data; | |||
459 | ||||
460 | node = *rnode; | |||
461 | node.sysctl_data = &val; | |||
462 | ||||
463 | error = sysctl_lookup(SYSCTLFN_CALL(&node)); | |||
464 | if (error != 0 || newp == NULL) | |||
465 | return error; | |||
466 | ||||
467 | if (val == 0) { | |||
468 | if (!spec_v4_mitigation_enabled) | |||
469 | error = 0; | |||
470 | else | |||
471 | error = mitigation_v4_change(false); | |||
472 | } else { | |||
473 | if (spec_v4_mitigation_enabled) | |||
474 | error = 0; | |||
475 | else | |||
476 | error = mitigation_v4_change(true); | |||
477 | } | |||
478 | ||||
479 | return error; | |||
480 | } | |||
481 | ||||
482 | /* -------------------------------------------------------------------------- */ | |||
483 | ||||
350 | void speculation_barrier(struct lwp *, struct lwp *); | 484 | void speculation_barrier(struct lwp *, struct lwp *); | |
351 | 485 | |||
352 | void | 486 | void | |
353 | speculation_barrier(struct lwp *oldlwp, struct lwp *newlwp) | 487 | speculation_barrier(struct lwp *oldlwp, struct lwp *newlwp) | |
354 | { | 488 | { | |
355 | /* | 489 | /* | |
356 | * Speculation barriers are applicable only to Spectre V2. | 490 | * Speculation barriers are applicable only to Spectre V2. | |
357 | */ | 491 | */ | |
358 | if (!spec_v2_mitigation_enabled) | 492 | if (!spec_v2_mitigation_enabled) | |
359 | return; | 493 | return; | |
360 | 494 | |||
361 | /* | 495 | /* | |
362 | * From kernel thread to kernel thread, no need for a barrier. | 496 | * From kernel thread to kernel thread, no need for a barrier. | |
@@ -383,14 +517,25 @@ cpu_speculation_init(struct cpu_info *ci | @@ -383,14 +517,25 @@ cpu_speculation_init(struct cpu_info *ci | |||
383 | * | 517 | * | |
384 | * cpu0 is the one that detects the method and sets the global | 518 | * cpu0 is the one that detects the method and sets the global | |
385 | * variable. | 519 | * variable. | |
386 | */ | 520 | */ | |
387 | if (ci == &cpu_info_primary) { | 521 | if (ci == &cpu_info_primary) { | |
388 | spec_v2_detect_method(); | 522 | spec_v2_detect_method(); | |
389 | spec_v2_mitigation_enabled = | 523 | spec_v2_mitigation_enabled = | |
390 | (mitigation_v2_method != MITIGATION_NONE); | 524 | (mitigation_v2_method != MITIGATION_NONE); | |
391 | spec_v2_set_name(); | 525 | spec_v2_set_name(); | |
392 | } | 526 | } | |
393 | if (mitigation_v2_method != MITIGATION_NONE) { | 527 | if (mitigation_v2_method != MITIGATION_NONE) { | |
394 | mitigation_v2_apply_cpu(ci, true); | 528 | mitigation_v2_apply_cpu(ci, true); | |
395 | } | 529 | } | |
530 | ||||
531 | /* | |||
532 | * Spectre V4. | |||
533 | */ | |||
534 | if (ssbd_needed()) { | |||
535 | if (ci == &cpu_info_primary) { | |||
536 | spec_v4_affected = true; | |||
537 | } | |||
538 | /* mitigation_v4_apply_cpu(true); */ | |||
539 | /* spec_v4_mitigation_enabled = true; */ | |||
540 | } | |||
396 | } | 541 | } |
--- src/sys/arch/x86/x86/x86_machdep.c 2018/05/22 06:31:05 1.112
+++ src/sys/arch/x86/x86/x86_machdep.c 2018/05/22 07:11:53 1.113
@@ -1,14 +1,14 @@ | @@ -1,14 +1,14 @@ | |||
1 | /* $NetBSD: x86_machdep.c,v 1.112 2018/05/22 06:31:05 maxv Exp $ */ | 1 | /* $NetBSD: x86_machdep.c,v 1.113 2018/05/22 07:11:53 maxv Exp $ */ | |
2 | 2 | |||
3 | /*- | 3 | /*- | |
4 | * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi, | 4 | * Copyright (c) 2002, 2006, 2007 YAMAMOTO Takashi, | |
5 | * Copyright (c) 2005, 2008, 2009 The NetBSD Foundation, Inc. | 5 | * Copyright (c) 2005, 2008, 2009 The NetBSD Foundation, Inc. | |
6 | * All rights reserved. | 6 | * All rights reserved. | |
7 | * | 7 | * | |
8 | * This code is derived from software contributed to The NetBSD Foundation | 8 | * This code is derived from software contributed to The NetBSD Foundation | |
9 | * by Julio M. Merino Vidal. | 9 | * by Julio M. Merino Vidal. | |
10 | * | 10 | * | |
11 | * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without | |
12 | * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions | |
13 | * are met: | 13 | * are met: | |
14 | * 1. Redistributions of source code must retain the above copyright | 14 | * 1. Redistributions of source code must retain the above copyright | |
@@ -21,27 +21,27 @@ | @@ -21,27 +21,27 @@ | |||
21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | 21 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS | |
24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 24 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 25 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 26 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | 27 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
30 | * POSSIBILITY OF SUCH DAMAGE. | 30 | * POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | 31 | */ | |
32 | 32 | |||
33 | #include <sys/cdefs.h> | 33 | #include <sys/cdefs.h> | |
34 | __KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.112 2018/05/22 06:31:05 maxv Exp $"); | 34 | __KERNEL_RCSID(0, "$NetBSD: x86_machdep.c,v 1.113 2018/05/22 07:11:53 maxv Exp $"); | |
35 | 35 | |||
36 | #include "opt_modular.h" | 36 | #include "opt_modular.h" | |
37 | #include "opt_physmem.h" | 37 | #include "opt_physmem.h" | |
38 | #include "opt_splash.h" | 38 | #include "opt_splash.h" | |
39 | #include "opt_kaslr.h" | 39 | #include "opt_kaslr.h" | |
40 | #include "opt_svs.h" | 40 | #include "opt_svs.h" | |
41 | 41 | |||
42 | #include <sys/types.h> | 42 | #include <sys/types.h> | |
43 | #include <sys/param.h> | 43 | #include <sys/param.h> | |
44 | #include <sys/systm.h> | 44 | #include <sys/systm.h> | |
45 | #include <sys/kcore.h> | 45 | #include <sys/kcore.h> | |
46 | #include <sys/errno.h> | 46 | #include <sys/errno.h> | |
47 | #include <sys/kauth.h> | 47 | #include <sys/kauth.h> | |
@@ -1263,28 +1263,31 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc | @@ -1263,28 +1263,31 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc | |||
1263 | CTLTYPE_NODE, "svs", NULL, | 1263 | CTLTYPE_NODE, "svs", NULL, | |
1264 | NULL, 0, NULL, 0, | 1264 | NULL, 0, NULL, 0, | |
1265 | CTL_MACHDEP, CTL_CREATE); | 1265 | CTL_MACHDEP, CTL_CREATE); | |
1266 | sysctl_createv(clog, 0, &svs_rnode, &svs_rnode, | 1266 | sysctl_createv(clog, 0, &svs_rnode, &svs_rnode, | |
1267 | CTLFLAG_READWRITE, | 1267 | CTLFLAG_READWRITE, | |
1268 | CTLTYPE_BOOL, "enabled", | 1268 | CTLTYPE_BOOL, "enabled", | |
1269 | SYSCTL_DESCR("Whether the kernel uses SVS"), | 1269 | SYSCTL_DESCR("Whether the kernel uses SVS"), | |
1270 | sysctl_machdep_svs_enabled, 0, &svs_enabled, 0, | 1270 | sysctl_machdep_svs_enabled, 0, &svs_enabled, 0, | |
1271 | CTL_CREATE, CTL_EOL); | 1271 | CTL_CREATE, CTL_EOL); | |
1272 | #endif | 1272 | #endif | |
1273 | 1273 | |||
1274 | #ifndef XEN | 1274 | #ifndef XEN | |
1275 | int sysctl_machdep_spectreV2_mitigated(SYSCTLFN_ARGS); | 1275 | int sysctl_machdep_spectreV2_mitigated(SYSCTLFN_ARGS); | |
1276 | int sysctl_machdep_spectreV4_mitigated(SYSCTLFN_ARGS); | |||
1276 | extern bool spec_v2_mitigation_enabled; | 1277 | extern bool spec_v2_mitigation_enabled; | |
1278 | extern bool spec_v4_mitigation_enabled; | |||
1277 | extern char spec_v2_mitigation_name[]; | 1279 | extern char spec_v2_mitigation_name[]; | |
1280 | extern bool spec_v4_affected; | |||
1278 | const struct sysctlnode *spec_rnode; | 1281 | const struct sysctlnode *spec_rnode; | |
1279 | 1282 | |||
1280 | /* SpectreV1 */ | 1283 | /* SpectreV1 */ | |
1281 | spec_rnode = NULL; | 1284 | spec_rnode = NULL; | |
1282 | sysctl_createv(clog, 0, NULL, &spec_rnode, | 1285 | sysctl_createv(clog, 0, NULL, &spec_rnode, | |
1283 | CTLFLAG_PERMANENT, | 1286 | CTLFLAG_PERMANENT, | |
1284 | CTLTYPE_NODE, "spectre_v1", NULL, | 1287 | CTLTYPE_NODE, "spectre_v1", NULL, | |
1285 | NULL, 0, NULL, 0, | 1288 | NULL, 0, NULL, 0, | |
1286 | CTL_MACHDEP, CTL_CREATE); | 1289 | CTL_MACHDEP, CTL_CREATE); | |
1287 | sysctl_createv(clog, 0, &spec_rnode, &spec_rnode, | 1290 | sysctl_createv(clog, 0, &spec_rnode, &spec_rnode, | |
1288 | CTLFLAG_PERMANENT | CTLFLAG_IMMEDIATE, | 1291 | CTLFLAG_PERMANENT | CTLFLAG_IMMEDIATE, | |
1289 | CTLTYPE_BOOL, "mitigated", | 1292 | CTLTYPE_BOOL, "mitigated", | |
1290 | SYSCTL_DESCR("Whether Spectre Variant 1 is mitigated"), | 1293 | SYSCTL_DESCR("Whether Spectre Variant 1 is mitigated"), | |
@@ -1302,26 +1305,48 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc | @@ -1302,26 +1305,48 @@ SYSCTL_SETUP(sysctl_machdep_setup, "sysc | |||
1302 | CTLFLAG_READWRITE, | 1305 | CTLFLAG_READWRITE, | |
1303 | CTLTYPE_BOOL, "mitigated", | 1306 | CTLTYPE_BOOL, "mitigated", | |
1304 | SYSCTL_DESCR("Whether Spectre Variant 2 is mitigated"), | 1307 | SYSCTL_DESCR("Whether Spectre Variant 2 is mitigated"), | |
1305 | sysctl_machdep_spectreV2_mitigated, 0, | 1308 | sysctl_machdep_spectreV2_mitigated, 0, | |
1306 | &spec_v2_mitigation_enabled, 0, | 1309 | &spec_v2_mitigation_enabled, 0, | |
1307 | CTL_CREATE, CTL_EOL); | 1310 | CTL_CREATE, CTL_EOL); | |
1308 | sysctl_createv(clog, 0, &spec_rnode, NULL, | 1311 | sysctl_createv(clog, 0, &spec_rnode, NULL, | |
1309 | CTLFLAG_PERMANENT, | 1312 | CTLFLAG_PERMANENT, | |
1310 | CTLTYPE_STRING, "method", | 1313 | CTLTYPE_STRING, "method", | |
1311 | SYSCTL_DESCR("Mitigation method in use"), | 1314 | SYSCTL_DESCR("Mitigation method in use"), | |
1312 | NULL, 0, | 1315 | NULL, 0, | |
1313 | spec_v2_mitigation_name, 0, | 1316 | spec_v2_mitigation_name, 0, | |
1314 | CTL_CREATE, CTL_EOL); | 1317 | CTL_CREATE, CTL_EOL); | |
1318 | ||||
1319 | /* SpectreV4 */ | |||
1320 | spec_rnode = NULL; | |||
1321 | sysctl_createv(clog, 0, NULL, &spec_rnode, | |||
1322 | CTLFLAG_PERMANENT, | |||
1323 | CTLTYPE_NODE, "spectre_v4", NULL, | |||
1324 | NULL, 0, NULL, 0, | |||
1325 | CTL_MACHDEP, CTL_CREATE); | |||
1326 | sysctl_createv(clog, 0, &spec_rnode, NULL, | |||
1327 | CTLFLAG_READWRITE, | |||
1328 | CTLTYPE_BOOL, "mitigated", | |||
1329 | SYSCTL_DESCR("Whether Spectre Variant 4 is mitigated"), | |||
1330 | sysctl_machdep_spectreV4_mitigated, 0, | |||
1331 | &spec_v4_mitigation_enabled, 0, | |||
1332 | CTL_CREATE, CTL_EOL); | |||
1333 | sysctl_createv(clog, 0, &spec_rnode, NULL, | |||
1334 | CTLFLAG_PERMANENT, | |||
1335 | CTLTYPE_BOOL, "affected", | |||
1336 | SYSCTL_DESCR("Whether the CPU is affected by SpectreV4"), | |||
1337 | NULL, 0, | |||
1338 | &spec_v4_affected, 0, | |||
1339 | CTL_CREATE, CTL_EOL); | |||
1315 | #endif | 1340 | #endif | |
1316 | 1341 | |||
1317 | /* None of these can ever change once the system has booted */ | 1342 | /* None of these can ever change once the system has booted */ | |
1318 | const_sysctl(clog, "fpu_present", CTLTYPE_INT, i386_fpu_present, | 1343 | const_sysctl(clog, "fpu_present", CTLTYPE_INT, i386_fpu_present, | |
1319 | CPU_FPU_PRESENT); | 1344 | CPU_FPU_PRESENT); | |
1320 | const_sysctl(clog, "osfxsr", CTLTYPE_INT, i386_use_fxsave, | 1345 | const_sysctl(clog, "osfxsr", CTLTYPE_INT, i386_use_fxsave, | |
1321 | CPU_OSFXSR); | 1346 | CPU_OSFXSR); | |
1322 | const_sysctl(clog, "sse", CTLTYPE_INT, i386_has_sse, | 1347 | const_sysctl(clog, "sse", CTLTYPE_INT, i386_has_sse, | |
1323 | CPU_SSE); | 1348 | CPU_SSE); | |
1324 | const_sysctl(clog, "sse2", CTLTYPE_INT, i386_has_sse2, | 1349 | const_sysctl(clog, "sse2", CTLTYPE_INT, i386_has_sse2, | |
1325 | CPU_SSE2); | 1350 | CPU_SSE2); | |
1326 | 1351 | |||
1327 | const_sysctl(clog, "fpu_save", CTLTYPE_INT, x86_fpu_save, | 1352 | const_sysctl(clog, "fpu_save", CTLTYPE_INT, x86_fpu_save, |