Tue May 22 07:11:54 2018 UTC ()
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.


(maxv)
diff -r1.120 -r1.121 src/sys/arch/x86/include/specialreg.h
diff -r1.11 -r1.12 src/sys/arch/x86/x86/spectre.c
diff -r1.112 -r1.113 src/sys/arch/x86/x86/x86_machdep.c

cvs diff -r1.120 -r1.121 src/sys/arch/x86/include/specialreg.h (expand / switch to unified diff)

--- 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

cvs diff -r1.11 -r1.12 src/sys/arch/x86/x86/spectre.c (expand / switch to unified diff)

--- 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
 350bool spec_v4_mitigation_enabled __read_mostly = false;
 351bool spec_v4_affected __read_mostly = true;
 352
 353int sysctl_machdep_spectreV4_mitigated(SYSCTLFN_ARGS);
 354
 355static 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
 373static 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
 389static void
 390mitigation_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
 405static void
 406mitigation_v4_change_cpu(void *arg1, void *arg2)
 407{
 408 bool enabled = (bool)arg1;
 409
 410 mitigation_v4_apply_cpu(enabled);
 411}
 412
 413static 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
 451int
 452sysctl_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
350void speculation_barrier(struct lwp *, struct lwp *); 484void speculation_barrier(struct lwp *, struct lwp *);
351 485
352void 486void
353speculation_barrier(struct lwp *oldlwp, struct lwp *newlwp) 487speculation_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}

cvs diff -r1.112 -r1.113 src/sys/arch/x86/x86/x86_machdep.c (expand / switch to unified diff)

--- 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,