diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-21 14:23:26 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-05-21 14:23:26 -0400 |
| commit | 3b78ce4a34b761c7fe13520de822984019ff1a8f (patch) | |
| tree | 63b93664a184c2d561a70c7f8d16a388750739f7 | |
| parent | 6741c4bb389da103c0d79ad1961884628900bfe6 (diff) | |
| parent | af86ca4e3088fe5eacf2f7e58c01fa68ca067672 (diff) | |
Merge branch 'speck-v20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Merge speculative store buffer bypass fixes from Thomas Gleixner:
- rework of the SPEC_CTRL MSR management to accomodate the new fancy
SSBD (Speculative Store Bypass Disable) bit handling.
- the CPU bug and sysfs infrastructure for the exciting new Speculative
Store Bypass 'feature'.
- support for disabling SSB via LS_CFG MSR on AMD CPUs including
Hyperthread synchronization on ZEN.
- PRCTL support for dynamic runtime control of SSB
- SECCOMP integration to automatically disable SSB for sandboxed
processes with a filter flag for opt-out.
- KVM integration to allow guests fiddling with SSBD including the new
software MSR VIRT_SPEC_CTRL to handle the LS_CFG based oddities on
AMD.
- BPF protection against SSB
.. this is just the core and x86 side, other architecture support will
come separately.
* 'speck-v20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (49 commits)
bpf: Prevent memory disambiguation attack
x86/bugs: Rename SSBD_NO to SSB_NO
KVM: SVM: Implement VIRT_SPEC_CTRL support for SSBD
x86/speculation, KVM: Implement support for VIRT_SPEC_CTRL/LS_CFG
x86/bugs: Rework spec_ctrl base and mask logic
x86/bugs: Remove x86_spec_ctrl_set()
x86/bugs: Expose x86_spec_ctrl_base directly
x86/bugs: Unify x86_spec_ctrl_{set_guest,restore_host}
x86/speculation: Rework speculative_store_bypass_update()
x86/speculation: Add virtualized speculative store bypass disable support
x86/bugs, KVM: Extend speculation control for VIRT_SPEC_CTRL
x86/speculation: Handle HT correctly on AMD
x86/cpufeatures: Add FEATURE_ZEN
x86/cpufeatures: Disentangle SSBD enumeration
x86/cpufeatures: Disentangle MSR_SPEC_CTRL enumeration from IBRS
x86/speculation: Use synthetic bits for IBRS/IBPB/STIBP
KVM: SVM: Move spec control call after restore of GS
x86/cpu: Make alternative_msr_write work for 32-bit code
x86/bugs: Fix the parameters alignment and missing void
x86/bugs: Make cpu_show_common() static
...
34 files changed, 1166 insertions, 119 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index 025b7cf3768d..bd4975e132d3 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu | |||
| @@ -478,6 +478,7 @@ What: /sys/devices/system/cpu/vulnerabilities | |||
| 478 | /sys/devices/system/cpu/vulnerabilities/meltdown | 478 | /sys/devices/system/cpu/vulnerabilities/meltdown |
| 479 | /sys/devices/system/cpu/vulnerabilities/spectre_v1 | 479 | /sys/devices/system/cpu/vulnerabilities/spectre_v1 |
| 480 | /sys/devices/system/cpu/vulnerabilities/spectre_v2 | 480 | /sys/devices/system/cpu/vulnerabilities/spectre_v2 |
| 481 | /sys/devices/system/cpu/vulnerabilities/spec_store_bypass | ||
| 481 | Date: January 2018 | 482 | Date: January 2018 |
| 482 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> | 483 | Contact: Linux kernel mailing list <linux-kernel@vger.kernel.org> |
| 483 | Description: Information about CPU vulnerabilities | 484 | Description: Information about CPU vulnerabilities |
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 11fc28ecdb6d..f2040d46f095 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt | |||
| @@ -2680,6 +2680,9 @@ | |||
| 2680 | allow data leaks with this option, which is equivalent | 2680 | allow data leaks with this option, which is equivalent |
| 2681 | to spectre_v2=off. | 2681 | to spectre_v2=off. |
| 2682 | 2682 | ||
| 2683 | nospec_store_bypass_disable | ||
| 2684 | [HW] Disable all mitigations for the Speculative Store Bypass vulnerability | ||
| 2685 | |||
| 2683 | noxsave [BUGS=X86] Disables x86 extended register state save | 2686 | noxsave [BUGS=X86] Disables x86 extended register state save |
| 2684 | and restore using xsave. The kernel will fallback to | 2687 | and restore using xsave. The kernel will fallback to |
| 2685 | enabling legacy floating-point and sse state. | 2688 | enabling legacy floating-point and sse state. |
| @@ -4025,6 +4028,48 @@ | |||
| 4025 | Not specifying this option is equivalent to | 4028 | Not specifying this option is equivalent to |
| 4026 | spectre_v2=auto. | 4029 | spectre_v2=auto. |
| 4027 | 4030 | ||
| 4031 | spec_store_bypass_disable= | ||
| 4032 | [HW] Control Speculative Store Bypass (SSB) Disable mitigation | ||
| 4033 | (Speculative Store Bypass vulnerability) | ||
| 4034 | |||
| 4035 | Certain CPUs are vulnerable to an exploit against a | ||
| 4036 | a common industry wide performance optimization known | ||
| 4037 | as "Speculative Store Bypass" in which recent stores | ||
| 4038 | to the same memory location may not be observed by | ||
| 4039 | later loads during speculative execution. The idea | ||
| 4040 | is that such stores are unlikely and that they can | ||
| 4041 | be detected prior to instruction retirement at the | ||
| 4042 | end of a particular speculation execution window. | ||
| 4043 | |||
| 4044 | In vulnerable processors, the speculatively forwarded | ||
| 4045 | store can be used in a cache side channel attack, for | ||
| 4046 | example to read memory to which the attacker does not | ||
| 4047 | directly have access (e.g. inside sandboxed code). | ||
| 4048 | |||
| 4049 | This parameter controls whether the Speculative Store | ||
| 4050 | Bypass optimization is used. | ||
| 4051 | |||
| 4052 | on - Unconditionally disable Speculative Store Bypass | ||
| 4053 | off - Unconditionally enable Speculative Store Bypass | ||
| 4054 | auto - Kernel detects whether the CPU model contains an | ||
| 4055 | implementation of Speculative Store Bypass and | ||
| 4056 | picks the most appropriate mitigation. If the | ||
| 4057 | CPU is not vulnerable, "off" is selected. If the | ||
| 4058 | CPU is vulnerable the default mitigation is | ||
| 4059 | architecture and Kconfig dependent. See below. | ||
| 4060 | prctl - Control Speculative Store Bypass per thread | ||
| 4061 | via prctl. Speculative Store Bypass is enabled | ||
| 4062 | for a process by default. The state of the control | ||
| 4063 | is inherited on fork. | ||
| 4064 | seccomp - Same as "prctl" above, but all seccomp threads | ||
| 4065 | will disable SSB unless they explicitly opt out. | ||
| 4066 | |||
| 4067 | Not specifying this option is equivalent to | ||
| 4068 | spec_store_bypass_disable=auto. | ||
| 4069 | |||
| 4070 | Default mitigations: | ||
| 4071 | X86: If CONFIG_SECCOMP=y "seccomp", otherwise "prctl" | ||
| 4072 | |||
| 4028 | spia_io_base= [HW,MTD] | 4073 | spia_io_base= [HW,MTD] |
| 4029 | spia_fio_base= | 4074 | spia_fio_base= |
| 4030 | spia_pedr= | 4075 | spia_pedr= |
diff --git a/Documentation/userspace-api/index.rst b/Documentation/userspace-api/index.rst index 7b2eb1b7d4ca..a3233da7fa88 100644 --- a/Documentation/userspace-api/index.rst +++ b/Documentation/userspace-api/index.rst | |||
| @@ -19,6 +19,7 @@ place where this information is gathered. | |||
| 19 | no_new_privs | 19 | no_new_privs |
| 20 | seccomp_filter | 20 | seccomp_filter |
| 21 | unshare | 21 | unshare |
| 22 | spec_ctrl | ||
| 22 | 23 | ||
| 23 | .. only:: subproject and html | 24 | .. only:: subproject and html |
| 24 | 25 | ||
diff --git a/Documentation/userspace-api/spec_ctrl.rst b/Documentation/userspace-api/spec_ctrl.rst new file mode 100644 index 000000000000..32f3d55c54b7 --- /dev/null +++ b/Documentation/userspace-api/spec_ctrl.rst | |||
| @@ -0,0 +1,94 @@ | |||
| 1 | =================== | ||
| 2 | Speculation Control | ||
| 3 | =================== | ||
| 4 | |||
| 5 | Quite some CPUs have speculation-related misfeatures which are in | ||
| 6 | fact vulnerabilities causing data leaks in various forms even across | ||
| 7 | privilege domains. | ||
| 8 | |||
| 9 | The kernel provides mitigation for such vulnerabilities in various | ||
| 10 | forms. Some of these mitigations are compile-time configurable and some | ||
| 11 | can be supplied on the kernel command line. | ||
| 12 | |||
| 13 | There is also a class of mitigations which are very expensive, but they can | ||
| 14 | be restricted to a certain set of processes or tasks in controlled | ||
| 15 | environments. The mechanism to control these mitigations is via | ||
| 16 | :manpage:`prctl(2)`. | ||
| 17 | |||
| 18 | There are two prctl options which are related to this: | ||
| 19 | |||
| 20 | * PR_GET_SPECULATION_CTRL | ||
| 21 | |||
| 22 | * PR_SET_SPECULATION_CTRL | ||
| 23 | |||
| 24 | PR_GET_SPECULATION_CTRL | ||
| 25 | ----------------------- | ||
| 26 | |||
| 27 | PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature | ||
| 28 | which is selected with arg2 of prctl(2). The return value uses bits 0-3 with | ||
| 29 | the following meaning: | ||
| 30 | |||
| 31 | ==== ===================== =================================================== | ||
| 32 | Bit Define Description | ||
| 33 | ==== ===================== =================================================== | ||
| 34 | 0 PR_SPEC_PRCTL Mitigation can be controlled per task by | ||
| 35 | PR_SET_SPECULATION_CTRL. | ||
| 36 | 1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is | ||
| 37 | disabled. | ||
| 38 | 2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is | ||
| 39 | enabled. | ||
| 40 | 3 PR_SPEC_FORCE_DISABLE Same as PR_SPEC_DISABLE, but cannot be undone. A | ||
| 41 | subsequent prctl(..., PR_SPEC_ENABLE) will fail. | ||
| 42 | ==== ===================== =================================================== | ||
| 43 | |||
| 44 | If all bits are 0 the CPU is not affected by the speculation misfeature. | ||
| 45 | |||
| 46 | If PR_SPEC_PRCTL is set, then the per-task control of the mitigation is | ||
| 47 | available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation | ||
| 48 | misfeature will fail. | ||
| 49 | |||
| 50 | PR_SET_SPECULATION_CTRL | ||
| 51 | ----------------------- | ||
| 52 | |||
| 53 | PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which | ||
| 54 | is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand | ||
| 55 | in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE or | ||
| 56 | PR_SPEC_FORCE_DISABLE. | ||
| 57 | |||
| 58 | Common error codes | ||
| 59 | ------------------ | ||
| 60 | ======= ================================================================= | ||
| 61 | Value Meaning | ||
| 62 | ======= ================================================================= | ||
| 63 | EINVAL The prctl is not implemented by the architecture or unused | ||
| 64 | prctl(2) arguments are not 0. | ||
| 65 | |||
| 66 | ENODEV arg2 is selecting a not supported speculation misfeature. | ||
| 67 | ======= ================================================================= | ||
| 68 | |||
| 69 | PR_SET_SPECULATION_CTRL error codes | ||
| 70 | ----------------------------------- | ||
| 71 | ======= ================================================================= | ||
| 72 | Value Meaning | ||
| 73 | ======= ================================================================= | ||
| 74 | 0 Success | ||
| 75 | |||
| 76 | ERANGE arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor | ||
| 77 | PR_SPEC_DISABLE nor PR_SPEC_FORCE_DISABLE. | ||
| 78 | |||
| 79 | ENXIO Control of the selected speculation misfeature is not possible. | ||
| 80 | See PR_GET_SPECULATION_CTRL. | ||
| 81 | |||
| 82 | EPERM Speculation was disabled with PR_SPEC_FORCE_DISABLE and caller | ||
| 83 | tried to enable it again. | ||
| 84 | ======= ================================================================= | ||
| 85 | |||
| 86 | Speculation misfeature controls | ||
| 87 | ------------------------------- | ||
| 88 | - PR_SPEC_STORE_BYPASS: Speculative Store Bypass | ||
| 89 | |||
| 90 | Invocations: | ||
| 91 | * prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0); | ||
| 92 | * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0); | ||
| 93 | * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0); | ||
| 94 | * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0); | ||
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h index 578793e97431..fb00a2fca990 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h | |||
| @@ -198,7 +198,6 @@ | |||
| 198 | #define X86_FEATURE_CAT_L2 ( 7*32+ 5) /* Cache Allocation Technology L2 */ | 198 | #define X86_FEATURE_CAT_L2 ( 7*32+ 5) /* Cache Allocation Technology L2 */ |
| 199 | #define X86_FEATURE_CDP_L3 ( 7*32+ 6) /* Code and Data Prioritization L3 */ | 199 | #define X86_FEATURE_CDP_L3 ( 7*32+ 6) /* Code and Data Prioritization L3 */ |
| 200 | #define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */ | 200 | #define X86_FEATURE_INVPCID_SINGLE ( 7*32+ 7) /* Effectively INVPCID && CR4.PCIDE=1 */ |
| 201 | |||
| 202 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ | 201 | #define X86_FEATURE_HW_PSTATE ( 7*32+ 8) /* AMD HW-PState */ |
| 203 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ | 202 | #define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInterface */ |
| 204 | #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ | 203 | #define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption */ |
| @@ -207,13 +206,19 @@ | |||
| 207 | #define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ | 206 | #define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* "" AMD Retpoline mitigation for Spectre variant 2 */ |
| 208 | #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ | 207 | #define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Inventory Number */ |
| 209 | #define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */ | 208 | #define X86_FEATURE_CDP_L2 ( 7*32+15) /* Code and Data Prioritization L2 */ |
| 210 | 209 | #define X86_FEATURE_MSR_SPEC_CTRL ( 7*32+16) /* "" MSR SPEC_CTRL is implemented */ | |
| 210 | #define X86_FEATURE_SSBD ( 7*32+17) /* Speculative Store Bypass Disable */ | ||
| 211 | #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ | 211 | #define X86_FEATURE_MBA ( 7*32+18) /* Memory Bandwidth Allocation */ |
| 212 | #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ | 212 | #define X86_FEATURE_RSB_CTXSW ( 7*32+19) /* "" Fill RSB on context switches */ |
| 213 | #define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ | 213 | #define X86_FEATURE_SEV ( 7*32+20) /* AMD Secure Encrypted Virtualization */ |
| 214 | |||
| 215 | #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ | 214 | #define X86_FEATURE_USE_IBPB ( 7*32+21) /* "" Indirect Branch Prediction Barrier enabled */ |
| 216 | #define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ | 215 | #define X86_FEATURE_USE_IBRS_FW ( 7*32+22) /* "" Use IBRS during runtime firmware calls */ |
| 216 | #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* "" Disable Speculative Store Bypass. */ | ||
| 217 | #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* "" AMD SSBD implementation via LS_CFG MSR */ | ||
| 218 | #define X86_FEATURE_IBRS ( 7*32+25) /* Indirect Branch Restricted Speculation */ | ||
| 219 | #define X86_FEATURE_IBPB ( 7*32+26) /* Indirect Branch Prediction Barrier */ | ||
| 220 | #define X86_FEATURE_STIBP ( 7*32+27) /* Single Thread Indirect Branch Predictors */ | ||
| 221 | #define X86_FEATURE_ZEN ( 7*32+28) /* "" CPU is AMD family 0x17 (Zen) */ | ||
| 217 | 222 | ||
| 218 | /* Virtualization flags: Linux defined, word 8 */ | 223 | /* Virtualization flags: Linux defined, word 8 */ |
| 219 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ | 224 | #define X86_FEATURE_TPR_SHADOW ( 8*32+ 0) /* Intel TPR Shadow */ |
| @@ -274,9 +279,10 @@ | |||
| 274 | #define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */ | 279 | #define X86_FEATURE_CLZERO (13*32+ 0) /* CLZERO instruction */ |
| 275 | #define X86_FEATURE_IRPERF (13*32+ 1) /* Instructions Retired Count */ | 280 | #define X86_FEATURE_IRPERF (13*32+ 1) /* Instructions Retired Count */ |
| 276 | #define X86_FEATURE_XSAVEERPTR (13*32+ 2) /* Always save/restore FP error pointers */ | 281 | #define X86_FEATURE_XSAVEERPTR (13*32+ 2) /* Always save/restore FP error pointers */ |
| 277 | #define X86_FEATURE_IBPB (13*32+12) /* Indirect Branch Prediction Barrier */ | 282 | #define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */ |
| 278 | #define X86_FEATURE_IBRS (13*32+14) /* Indirect Branch Restricted Speculation */ | 283 | #define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */ |
| 279 | #define X86_FEATURE_STIBP (13*32+15) /* Single Thread Indirect Branch Predictors */ | 284 | #define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */ |
| 285 | #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ | ||
| 280 | 286 | ||
| 281 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ | 287 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ |
| 282 | #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ | 288 | #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */ |
| @@ -334,6 +340,7 @@ | |||
| 334 | #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ | 340 | #define X86_FEATURE_SPEC_CTRL (18*32+26) /* "" Speculation Control (IBRS + IBPB) */ |
| 335 | #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ | 341 | #define X86_FEATURE_INTEL_STIBP (18*32+27) /* "" Single Thread Indirect Branch Predictors */ |
| 336 | #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ | 342 | #define X86_FEATURE_ARCH_CAPABILITIES (18*32+29) /* IA32_ARCH_CAPABILITIES MSR (Intel) */ |
| 343 | #define X86_FEATURE_SPEC_CTRL_SSBD (18*32+31) /* "" Speculative Store Bypass Disable */ | ||
| 337 | 344 | ||
| 338 | /* | 345 | /* |
| 339 | * BUG word(s) | 346 | * BUG word(s) |
| @@ -363,5 +370,6 @@ | |||
| 363 | #define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ | 370 | #define X86_BUG_CPU_MELTDOWN X86_BUG(14) /* CPU is affected by meltdown attack and needs kernel page table isolation */ |
| 364 | #define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ | 371 | #define X86_BUG_SPECTRE_V1 X86_BUG(15) /* CPU is affected by Spectre variant 1 attack with conditional branches */ |
| 365 | #define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ | 372 | #define X86_BUG_SPECTRE_V2 X86_BUG(16) /* CPU is affected by Spectre variant 2 attack with indirect branches */ |
| 373 | #define X86_BUG_SPEC_STORE_BYPASS X86_BUG(17) /* CPU is affected by speculative store bypass attack */ | ||
| 366 | 374 | ||
| 367 | #endif /* _ASM_X86_CPUFEATURES_H */ | 375 | #endif /* _ASM_X86_CPUFEATURES_H */ |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index c25775fad4ed..f4b2588865e9 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
| @@ -924,7 +924,7 @@ struct kvm_x86_ops { | |||
| 924 | int (*hardware_setup)(void); /* __init */ | 924 | int (*hardware_setup)(void); /* __init */ |
| 925 | void (*hardware_unsetup)(void); /* __exit */ | 925 | void (*hardware_unsetup)(void); /* __exit */ |
| 926 | bool (*cpu_has_accelerated_tpr)(void); | 926 | bool (*cpu_has_accelerated_tpr)(void); |
| 927 | bool (*cpu_has_high_real_mode_segbase)(void); | 927 | bool (*has_emulated_msr)(int index); |
| 928 | void (*cpuid_update)(struct kvm_vcpu *vcpu); | 928 | void (*cpuid_update)(struct kvm_vcpu *vcpu); |
| 929 | 929 | ||
| 930 | struct kvm *(*vm_alloc)(void); | 930 | struct kvm *(*vm_alloc)(void); |
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h index 53d5b1b9255e..fda2114197b3 100644 --- a/arch/x86/include/asm/msr-index.h +++ b/arch/x86/include/asm/msr-index.h | |||
| @@ -42,6 +42,8 @@ | |||
| 42 | #define MSR_IA32_SPEC_CTRL 0x00000048 /* Speculation Control */ | 42 | #define MSR_IA32_SPEC_CTRL 0x00000048 /* Speculation Control */ |
| 43 | #define SPEC_CTRL_IBRS (1 << 0) /* Indirect Branch Restricted Speculation */ | 43 | #define SPEC_CTRL_IBRS (1 << 0) /* Indirect Branch Restricted Speculation */ |
| 44 | #define SPEC_CTRL_STIBP (1 << 1) /* Single Thread Indirect Branch Predictors */ | 44 | #define SPEC_CTRL_STIBP (1 << 1) /* Single Thread Indirect Branch Predictors */ |
| 45 | #define SPEC_CTRL_SSBD_SHIFT 2 /* Speculative Store Bypass Disable bit */ | ||
| 46 | #define SPEC_CTRL_SSBD (1 << SPEC_CTRL_SSBD_SHIFT) /* Speculative Store Bypass Disable */ | ||
| 45 | 47 | ||
| 46 | #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ | 48 | #define MSR_IA32_PRED_CMD 0x00000049 /* Prediction Command */ |
| 47 | #define PRED_CMD_IBPB (1 << 0) /* Indirect Branch Prediction Barrier */ | 49 | #define PRED_CMD_IBPB (1 << 0) /* Indirect Branch Prediction Barrier */ |
| @@ -68,6 +70,11 @@ | |||
| 68 | #define MSR_IA32_ARCH_CAPABILITIES 0x0000010a | 70 | #define MSR_IA32_ARCH_CAPABILITIES 0x0000010a |
| 69 | #define ARCH_CAP_RDCL_NO (1 << 0) /* Not susceptible to Meltdown */ | 71 | #define ARCH_CAP_RDCL_NO (1 << 0) /* Not susceptible to Meltdown */ |
| 70 | #define ARCH_CAP_IBRS_ALL (1 << 1) /* Enhanced IBRS support */ | 72 | #define ARCH_CAP_IBRS_ALL (1 << 1) /* Enhanced IBRS support */ |
| 73 | #define ARCH_CAP_SSB_NO (1 << 4) /* | ||
| 74 | * Not susceptible to Speculative Store Bypass | ||
| 75 | * attack, so no Speculative Store Bypass | ||
| 76 | * control required. | ||
| 77 | */ | ||
| 71 | 78 | ||
| 72 | #define MSR_IA32_BBL_CR_CTL 0x00000119 | 79 | #define MSR_IA32_BBL_CR_CTL 0x00000119 |
| 73 | #define MSR_IA32_BBL_CR_CTL3 0x0000011e | 80 | #define MSR_IA32_BBL_CR_CTL3 0x0000011e |
| @@ -340,6 +347,8 @@ | |||
| 340 | #define MSR_AMD64_SEV_ENABLED_BIT 0 | 347 | #define MSR_AMD64_SEV_ENABLED_BIT 0 |
| 341 | #define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) | 348 | #define MSR_AMD64_SEV_ENABLED BIT_ULL(MSR_AMD64_SEV_ENABLED_BIT) |
| 342 | 349 | ||
| 350 | #define MSR_AMD64_VIRT_SPEC_CTRL 0xc001011f | ||
| 351 | |||
| 343 | /* Fam 17h MSRs */ | 352 | /* Fam 17h MSRs */ |
| 344 | #define MSR_F17H_IRPERF 0xc00000e9 | 353 | #define MSR_F17H_IRPERF 0xc00000e9 |
| 345 | 354 | ||
diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/nospec-branch.h index f928ad9b143f..8b38df98548e 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h | |||
| @@ -217,6 +217,14 @@ enum spectre_v2_mitigation { | |||
| 217 | SPECTRE_V2_IBRS, | 217 | SPECTRE_V2_IBRS, |
| 218 | }; | 218 | }; |
| 219 | 219 | ||
| 220 | /* The Speculative Store Bypass disable variants */ | ||
| 221 | enum ssb_mitigation { | ||
| 222 | SPEC_STORE_BYPASS_NONE, | ||
| 223 | SPEC_STORE_BYPASS_DISABLE, | ||
| 224 | SPEC_STORE_BYPASS_PRCTL, | ||
| 225 | SPEC_STORE_BYPASS_SECCOMP, | ||
| 226 | }; | ||
| 227 | |||
| 220 | extern char __indirect_thunk_start[]; | 228 | extern char __indirect_thunk_start[]; |
| 221 | extern char __indirect_thunk_end[]; | 229 | extern char __indirect_thunk_end[]; |
| 222 | 230 | ||
| @@ -241,22 +249,27 @@ static inline void vmexit_fill_RSB(void) | |||
| 241 | #endif | 249 | #endif |
| 242 | } | 250 | } |
| 243 | 251 | ||
| 244 | #define alternative_msr_write(_msr, _val, _feature) \ | 252 | static __always_inline |
| 245 | asm volatile(ALTERNATIVE("", \ | 253 | void alternative_msr_write(unsigned int msr, u64 val, unsigned int feature) |
| 246 | "movl %[msr], %%ecx\n\t" \ | 254 | { |
| 247 | "movl %[val], %%eax\n\t" \ | 255 | asm volatile(ALTERNATIVE("", "wrmsr", %c[feature]) |
| 248 | "movl $0, %%edx\n\t" \ | 256 | : : "c" (msr), |
| 249 | "wrmsr", \ | 257 | "a" ((u32)val), |
| 250 | _feature) \ | 258 | "d" ((u32)(val >> 32)), |
| 251 | : : [msr] "i" (_msr), [val] "i" (_val) \ | 259 | [feature] "i" (feature) |
| 252 | : "eax", "ecx", "edx", "memory") | 260 | : "memory"); |
| 261 | } | ||
| 253 | 262 | ||
| 254 | static inline void indirect_branch_prediction_barrier(void) | 263 | static inline void indirect_branch_prediction_barrier(void) |
| 255 | { | 264 | { |
| 256 | alternative_msr_write(MSR_IA32_PRED_CMD, PRED_CMD_IBPB, | 265 | u64 val = PRED_CMD_IBPB; |
| 257 | X86_FEATURE_USE_IBPB); | 266 | |
| 267 | alternative_msr_write(MSR_IA32_PRED_CMD, val, X86_FEATURE_USE_IBPB); | ||
| 258 | } | 268 | } |
| 259 | 269 | ||
| 270 | /* The Intel SPEC CTRL MSR base value cache */ | ||
| 271 | extern u64 x86_spec_ctrl_base; | ||
| 272 | |||
| 260 | /* | 273 | /* |
| 261 | * With retpoline, we must use IBRS to restrict branch prediction | 274 | * With retpoline, we must use IBRS to restrict branch prediction |
| 262 | * before calling into firmware. | 275 | * before calling into firmware. |
| @@ -265,14 +278,18 @@ static inline void indirect_branch_prediction_barrier(void) | |||
| 265 | */ | 278 | */ |
| 266 | #define firmware_restrict_branch_speculation_start() \ | 279 | #define firmware_restrict_branch_speculation_start() \ |
| 267 | do { \ | 280 | do { \ |
| 281 | u64 val = x86_spec_ctrl_base | SPEC_CTRL_IBRS; \ | ||
| 282 | \ | ||
| 268 | preempt_disable(); \ | 283 | preempt_disable(); \ |
| 269 | alternative_msr_write(MSR_IA32_SPEC_CTRL, SPEC_CTRL_IBRS, \ | 284 | alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ |
| 270 | X86_FEATURE_USE_IBRS_FW); \ | 285 | X86_FEATURE_USE_IBRS_FW); \ |
| 271 | } while (0) | 286 | } while (0) |
| 272 | 287 | ||
| 273 | #define firmware_restrict_branch_speculation_end() \ | 288 | #define firmware_restrict_branch_speculation_end() \ |
| 274 | do { \ | 289 | do { \ |
| 275 | alternative_msr_write(MSR_IA32_SPEC_CTRL, 0, \ | 290 | u64 val = x86_spec_ctrl_base; \ |
| 291 | \ | ||
| 292 | alternative_msr_write(MSR_IA32_SPEC_CTRL, val, \ | ||
| 276 | X86_FEATURE_USE_IBRS_FW); \ | 293 | X86_FEATURE_USE_IBRS_FW); \ |
| 277 | preempt_enable(); \ | 294 | preempt_enable(); \ |
| 278 | } while (0) | 295 | } while (0) |
diff --git a/arch/x86/include/asm/spec-ctrl.h b/arch/x86/include/asm/spec-ctrl.h new file mode 100644 index 000000000000..ae7c2c5cd7f0 --- /dev/null +++ b/arch/x86/include/asm/spec-ctrl.h | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | #ifndef _ASM_X86_SPECCTRL_H_ | ||
| 3 | #define _ASM_X86_SPECCTRL_H_ | ||
| 4 | |||
| 5 | #include <linux/thread_info.h> | ||
| 6 | #include <asm/nospec-branch.h> | ||
| 7 | |||
| 8 | /* | ||
| 9 | * On VMENTER we must preserve whatever view of the SPEC_CTRL MSR | ||
| 10 | * the guest has, while on VMEXIT we restore the host view. This | ||
| 11 | * would be easier if SPEC_CTRL were architecturally maskable or | ||
| 12 | * shadowable for guests but this is not (currently) the case. | ||
| 13 | * Takes the guest view of SPEC_CTRL MSR as a parameter and also | ||
| 14 | * the guest's version of VIRT_SPEC_CTRL, if emulated. | ||
| 15 | */ | ||
| 16 | extern void x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool guest); | ||
| 17 | |||
| 18 | /** | ||
| 19 | * x86_spec_ctrl_set_guest - Set speculation control registers for the guest | ||
| 20 | * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL | ||
| 21 | * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL | ||
| 22 | * (may get translated to MSR_AMD64_LS_CFG bits) | ||
| 23 | * | ||
| 24 | * Avoids writing to the MSR if the content/bits are the same | ||
| 25 | */ | ||
| 26 | static inline | ||
| 27 | void x86_spec_ctrl_set_guest(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | ||
| 28 | { | ||
| 29 | x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, true); | ||
| 30 | } | ||
| 31 | |||
| 32 | /** | ||
| 33 | * x86_spec_ctrl_restore_host - Restore host speculation control registers | ||
| 34 | * @guest_spec_ctrl: The guest content of MSR_SPEC_CTRL | ||
| 35 | * @guest_virt_spec_ctrl: The guest controlled bits of MSR_VIRT_SPEC_CTRL | ||
| 36 | * (may get translated to MSR_AMD64_LS_CFG bits) | ||
| 37 | * | ||
| 38 | * Avoids writing to the MSR if the content/bits are the same | ||
| 39 | */ | ||
| 40 | static inline | ||
| 41 | void x86_spec_ctrl_restore_host(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl) | ||
| 42 | { | ||
| 43 | x86_virt_spec_ctrl(guest_spec_ctrl, guest_virt_spec_ctrl, false); | ||
| 44 | } | ||
| 45 | |||
| 46 | /* AMD specific Speculative Store Bypass MSR data */ | ||
| 47 | extern u64 x86_amd_ls_cfg_base; | ||
| 48 | extern u64 x86_amd_ls_cfg_ssbd_mask; | ||
| 49 | |||
| 50 | static inline u64 ssbd_tif_to_spec_ctrl(u64 tifn) | ||
| 51 | { | ||
| 52 | BUILD_BUG_ON(TIF_SSBD < SPEC_CTRL_SSBD_SHIFT); | ||
| 53 | return (tifn & _TIF_SSBD) >> (TIF_SSBD - SPEC_CTRL_SSBD_SHIFT); | ||
| 54 | } | ||
| 55 | |||
| 56 | static inline unsigned long ssbd_spec_ctrl_to_tif(u64 spec_ctrl) | ||
| 57 | { | ||
| 58 | BUILD_BUG_ON(TIF_SSBD < SPEC_CTRL_SSBD_SHIFT); | ||
| 59 | return (spec_ctrl & SPEC_CTRL_SSBD) << (TIF_SSBD - SPEC_CTRL_SSBD_SHIFT); | ||
| 60 | } | ||
| 61 | |||
| 62 | static inline u64 ssbd_tif_to_amd_ls_cfg(u64 tifn) | ||
| 63 | { | ||
| 64 | return (tifn & _TIF_SSBD) ? x86_amd_ls_cfg_ssbd_mask : 0ULL; | ||
| 65 | } | ||
| 66 | |||
| 67 | #ifdef CONFIG_SMP | ||
| 68 | extern void speculative_store_bypass_ht_init(void); | ||
| 69 | #else | ||
| 70 | static inline void speculative_store_bypass_ht_init(void) { } | ||
| 71 | #endif | ||
| 72 | |||
| 73 | extern void speculative_store_bypass_update(unsigned long tif); | ||
| 74 | |||
| 75 | static inline void speculative_store_bypass_update_current(void) | ||
| 76 | { | ||
| 77 | speculative_store_bypass_update(current_thread_info()->flags); | ||
| 78 | } | ||
| 79 | |||
| 80 | #endif | ||
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h index a5d9521bb2cb..2ff2a30a264f 100644 --- a/arch/x86/include/asm/thread_info.h +++ b/arch/x86/include/asm/thread_info.h | |||
| @@ -79,6 +79,7 @@ struct thread_info { | |||
| 79 | #define TIF_SIGPENDING 2 /* signal pending */ | 79 | #define TIF_SIGPENDING 2 /* signal pending */ |
| 80 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | 80 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ |
| 81 | #define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/ | 81 | #define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/ |
| 82 | #define TIF_SSBD 5 /* Reduced data speculation */ | ||
| 82 | #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ | 83 | #define TIF_SYSCALL_EMU 6 /* syscall emulation active */ |
| 83 | #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ | 84 | #define TIF_SYSCALL_AUDIT 7 /* syscall auditing active */ |
| 84 | #define TIF_SECCOMP 8 /* secure computing */ | 85 | #define TIF_SECCOMP 8 /* secure computing */ |
| @@ -105,6 +106,7 @@ struct thread_info { | |||
| 105 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) | 106 | #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) |
| 106 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) | 107 | #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) |
| 107 | #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) | 108 | #define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) |
| 109 | #define _TIF_SSBD (1 << TIF_SSBD) | ||
| 108 | #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) | 110 | #define _TIF_SYSCALL_EMU (1 << TIF_SYSCALL_EMU) |
| 109 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) | 111 | #define _TIF_SYSCALL_AUDIT (1 << TIF_SYSCALL_AUDIT) |
| 110 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) | 112 | #define _TIF_SECCOMP (1 << TIF_SECCOMP) |
| @@ -144,7 +146,7 @@ struct thread_info { | |||
| 144 | 146 | ||
| 145 | /* flags to check in __switch_to() */ | 147 | /* flags to check in __switch_to() */ |
| 146 | #define _TIF_WORK_CTXSW \ | 148 | #define _TIF_WORK_CTXSW \ |
| 147 | (_TIF_IO_BITMAP|_TIF_NOCPUID|_TIF_NOTSC|_TIF_BLOCKSTEP) | 149 | (_TIF_IO_BITMAP|_TIF_NOCPUID|_TIF_NOTSC|_TIF_BLOCKSTEP|_TIF_SSBD) |
| 148 | 150 | ||
| 149 | #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) | 151 | #define _TIF_WORK_CTXSW_PREV (_TIF_WORK_CTXSW|_TIF_USER_RETURN_NOTIFY) |
| 150 | #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) | 152 | #define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW) |
diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index 12bc0a1139da..1b18be3f35a8 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <asm/processor.h> | 10 | #include <asm/processor.h> |
| 11 | #include <asm/apic.h> | 11 | #include <asm/apic.h> |
| 12 | #include <asm/cpu.h> | 12 | #include <asm/cpu.h> |
| 13 | #include <asm/spec-ctrl.h> | ||
| 13 | #include <asm/smp.h> | 14 | #include <asm/smp.h> |
| 14 | #include <asm/pci-direct.h> | 15 | #include <asm/pci-direct.h> |
| 15 | #include <asm/delay.h> | 16 | #include <asm/delay.h> |
| @@ -554,6 +555,26 @@ static void bsp_init_amd(struct cpuinfo_x86 *c) | |||
| 554 | rdmsrl(MSR_FAM10H_NODE_ID, value); | 555 | rdmsrl(MSR_FAM10H_NODE_ID, value); |
| 555 | nodes_per_socket = ((value >> 3) & 7) + 1; | 556 | nodes_per_socket = ((value >> 3) & 7) + 1; |
| 556 | } | 557 | } |
| 558 | |||
| 559 | if (c->x86 >= 0x15 && c->x86 <= 0x17) { | ||
| 560 | unsigned int bit; | ||
| 561 | |||
| 562 | switch (c->x86) { | ||
| 563 | case 0x15: bit = 54; break; | ||
| 564 | case 0x16: bit = 33; break; | ||
| 565 | case 0x17: bit = 10; break; | ||
| 566 | default: return; | ||
| 567 | } | ||
| 568 | /* | ||
| 569 | * Try to cache the base value so further operations can | ||
| 570 | * avoid RMW. If that faults, do not enable SSBD. | ||
| 571 | */ | ||
| 572 | if (!rdmsrl_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) { | ||
| 573 | setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD); | ||
| 574 | setup_force_cpu_cap(X86_FEATURE_SSBD); | ||
| 575 | x86_amd_ls_cfg_ssbd_mask = 1ULL << bit; | ||
| 576 | } | ||
| 577 | } | ||
| 557 | } | 578 | } |
| 558 | 579 | ||
| 559 | static void early_detect_mem_encrypt(struct cpuinfo_x86 *c) | 580 | static void early_detect_mem_encrypt(struct cpuinfo_x86 *c) |
| @@ -791,6 +812,7 @@ static void init_amd_bd(struct cpuinfo_x86 *c) | |||
| 791 | 812 | ||
| 792 | static void init_amd_zn(struct cpuinfo_x86 *c) | 813 | static void init_amd_zn(struct cpuinfo_x86 *c) |
| 793 | { | 814 | { |
| 815 | set_cpu_cap(c, X86_FEATURE_ZEN); | ||
| 794 | /* | 816 | /* |
| 795 | * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects | 817 | * Fix erratum 1076: CPB feature bit not being set in CPUID. It affects |
| 796 | * all up to and including B1. | 818 | * all up to and including B1. |
diff --git a/arch/x86/kernel/cpu/bugs.c b/arch/x86/kernel/cpu/bugs.c index bfca937bdcc3..7416fc206b4a 100644 --- a/arch/x86/kernel/cpu/bugs.c +++ b/arch/x86/kernel/cpu/bugs.c | |||
| @@ -12,8 +12,10 @@ | |||
| 12 | #include <linux/utsname.h> | 12 | #include <linux/utsname.h> |
| 13 | #include <linux/cpu.h> | 13 | #include <linux/cpu.h> |
| 14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 15 | #include <linux/nospec.h> | ||
| 16 | #include <linux/prctl.h> | ||
| 15 | 17 | ||
| 16 | #include <asm/nospec-branch.h> | 18 | #include <asm/spec-ctrl.h> |
| 17 | #include <asm/cmdline.h> | 19 | #include <asm/cmdline.h> |
| 18 | #include <asm/bugs.h> | 20 | #include <asm/bugs.h> |
| 19 | #include <asm/processor.h> | 21 | #include <asm/processor.h> |
| @@ -27,6 +29,27 @@ | |||
| 27 | #include <asm/intel-family.h> | 29 | #include <asm/intel-family.h> |
| 28 | 30 | ||
| 29 | static void __init spectre_v2_select_mitigation(void); | 31 | static void __init spectre_v2_select_mitigation(void); |
| 32 | static void __init ssb_select_mitigation(void); | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Our boot-time value of the SPEC_CTRL MSR. We read it once so that any | ||
| 36 | * writes to SPEC_CTRL contain whatever reserved bits have been set. | ||
| 37 | */ | ||
| 38 | u64 __ro_after_init x86_spec_ctrl_base; | ||
| 39 | EXPORT_SYMBOL_GPL(x86_spec_ctrl_base); | ||
| 40 | |||
| 41 | /* | ||
| 42 | * The vendor and possibly platform specific bits which can be modified in | ||
| 43 | * x86_spec_ctrl_base. | ||
| 44 | */ | ||
| 45 | static u64 __ro_after_init x86_spec_ctrl_mask = SPEC_CTRL_IBRS; | ||
| 46 | |||
| 47 | /* | ||
| 48 | * AMD specific MSR info for Speculative Store Bypass control. | ||
| 49 | * x86_amd_ls_cfg_ssbd_mask is initialized in identify_boot_cpu(). | ||
| 50 | */ | ||
| 51 | u64 __ro_after_init x86_amd_ls_cfg_base; | ||
| 52 | u64 __ro_after_init x86_amd_ls_cfg_ssbd_mask; | ||
| 30 | 53 | ||
| 31 | void __init check_bugs(void) | 54 | void __init check_bugs(void) |
| 32 | { | 55 | { |
| @@ -37,9 +60,27 @@ void __init check_bugs(void) | |||
| 37 | print_cpu_info(&boot_cpu_data); | 60 | print_cpu_info(&boot_cpu_data); |
| 38 | } | 61 | } |
| 39 | 62 | ||
| 63 | /* | ||
| 64 | * Read the SPEC_CTRL MSR to account for reserved bits which may | ||
| 65 | * have unknown values. AMD64_LS_CFG MSR is cached in the early AMD | ||
| 66 | * init code as it is not enumerated and depends on the family. | ||
| 67 | */ | ||
| 68 | if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) | ||
| 69 | rdmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); | ||
| 70 | |||
| 71 | /* Allow STIBP in MSR_SPEC_CTRL if supported */ | ||
| 72 | if (boot_cpu_has(X86_FEATURE_STIBP)) | ||
| 73 | x86_spec_ctrl_mask |= SPEC_CTRL_STIBP; | ||
| 74 | |||
| 40 | /* Select the proper spectre mitigation before patching alternatives */ | 75 | /* Select the proper spectre mitigation before patching alternatives */ |
| 41 | spectre_v2_select_mitigation(); | 76 | spectre_v2_select_mitigation(); |
| 42 | 77 | ||
| 78 | /* | ||
| 79 | * Select proper mitigation for any exposure to the Speculative Store | ||
| 80 | * Bypass vulnerability. | ||
| 81 | */ | ||
| 82 | ssb_select_mitigation(); | ||
| 83 | |||
| 43 | #ifdef CONFIG_X86_32 | 84 | #ifdef CONFIG_X86_32 |
| 44 | /* | 85 | /* |
| 45 | * Check whether we are able to run this kernel safely on SMP. | 86 | * Check whether we are able to run this kernel safely on SMP. |
| @@ -93,7 +134,76 @@ static const char *spectre_v2_strings[] = { | |||
| 93 | #undef pr_fmt | 134 | #undef pr_fmt |
| 94 | #define pr_fmt(fmt) "Spectre V2 : " fmt | 135 | #define pr_fmt(fmt) "Spectre V2 : " fmt |
| 95 | 136 | ||
| 96 | static enum spectre_v2_mitigation spectre_v2_enabled = SPECTRE_V2_NONE; | 137 | static enum spectre_v2_mitigation spectre_v2_enabled __ro_after_init = |
| 138 | SPECTRE_V2_NONE; | ||
| 139 | |||
| 140 | void | ||
| 141 | x86_virt_spec_ctrl(u64 guest_spec_ctrl, u64 guest_virt_spec_ctrl, bool setguest) | ||
| 142 | { | ||
| 143 | u64 msrval, guestval, hostval = x86_spec_ctrl_base; | ||
| 144 | struct thread_info *ti = current_thread_info(); | ||
| 145 | |||
| 146 | /* Is MSR_SPEC_CTRL implemented ? */ | ||
| 147 | if (static_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) { | ||
| 148 | /* | ||
| 149 | * Restrict guest_spec_ctrl to supported values. Clear the | ||
| 150 | * modifiable bits in the host base value and or the | ||
| 151 | * modifiable bits from the guest value. | ||
| 152 | */ | ||
| 153 | guestval = hostval & ~x86_spec_ctrl_mask; | ||
| 154 | guestval |= guest_spec_ctrl & x86_spec_ctrl_mask; | ||
| 155 | |||
| 156 | /* SSBD controlled in MSR_SPEC_CTRL */ | ||
| 157 | if (static_cpu_has(X86_FEATURE_SPEC_CTRL_SSBD)) | ||
| 158 | hostval |= ssbd_tif_to_spec_ctrl(ti->flags); | ||
| 159 | |||
| 160 | if (hostval != guestval) { | ||
| 161 | msrval = setguest ? guestval : hostval; | ||
| 162 | wrmsrl(MSR_IA32_SPEC_CTRL, msrval); | ||
| 163 | } | ||
| 164 | } | ||
| 165 | |||
| 166 | /* | ||
| 167 | * If SSBD is not handled in MSR_SPEC_CTRL on AMD, update | ||
| 168 | * MSR_AMD64_L2_CFG or MSR_VIRT_SPEC_CTRL if supported. | ||
| 169 | */ | ||
| 170 | if (!static_cpu_has(X86_FEATURE_LS_CFG_SSBD) && | ||
| 171 | !static_cpu_has(X86_FEATURE_VIRT_SSBD)) | ||
| 172 | return; | ||
| 173 | |||
| 174 | /* | ||
| 175 | * If the host has SSBD mitigation enabled, force it in the host's | ||
| 176 | * virtual MSR value. If its not permanently enabled, evaluate | ||
| 177 | * current's TIF_SSBD thread flag. | ||
| 178 | */ | ||
| 179 | if (static_cpu_has(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE)) | ||
| 180 | hostval = SPEC_CTRL_SSBD; | ||
| 181 | else | ||
| 182 | hostval = ssbd_tif_to_spec_ctrl(ti->flags); | ||
| 183 | |||
| 184 | /* Sanitize the guest value */ | ||
| 185 | guestval = guest_virt_spec_ctrl & SPEC_CTRL_SSBD; | ||
| 186 | |||
| 187 | if (hostval != guestval) { | ||
| 188 | unsigned long tif; | ||
| 189 | |||
| 190 | tif = setguest ? ssbd_spec_ctrl_to_tif(guestval) : | ||
| 191 | ssbd_spec_ctrl_to_tif(hostval); | ||
| 192 | |||
| 193 | speculative_store_bypass_update(tif); | ||
| 194 | } | ||
| 195 | } | ||
| 196 | EXPORT_SYMBOL_GPL(x86_virt_spec_ctrl); | ||
| 197 | |||
| 198 | static void x86_amd_ssb_disable(void) | ||
| 199 | { | ||
| 200 | u64 msrval = x86_amd_ls_cfg_base | x86_amd_ls_cfg_ssbd_mask; | ||
| 201 | |||
| 202 | if (boot_cpu_has(X86_FEATURE_VIRT_SSBD)) | ||
| 203 | wrmsrl(MSR_AMD64_VIRT_SPEC_CTRL, SPEC_CTRL_SSBD); | ||
| 204 | else if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD)) | ||
| 205 | wrmsrl(MSR_AMD64_LS_CFG, msrval); | ||
| 206 | } | ||
| 97 | 207 | ||
| 98 | #ifdef RETPOLINE | 208 | #ifdef RETPOLINE |
| 99 | static bool spectre_v2_bad_module; | 209 | static bool spectre_v2_bad_module; |
| @@ -312,32 +422,289 @@ retpoline_auto: | |||
| 312 | } | 422 | } |
| 313 | 423 | ||
| 314 | #undef pr_fmt | 424 | #undef pr_fmt |
| 425 | #define pr_fmt(fmt) "Speculative Store Bypass: " fmt | ||
| 426 | |||
| 427 | static enum ssb_mitigation ssb_mode __ro_after_init = SPEC_STORE_BYPASS_NONE; | ||
| 428 | |||
| 429 | /* The kernel command line selection */ | ||
| 430 | enum ssb_mitigation_cmd { | ||
| 431 | SPEC_STORE_BYPASS_CMD_NONE, | ||
| 432 | SPEC_STORE_BYPASS_CMD_AUTO, | ||
| 433 | SPEC_STORE_BYPASS_CMD_ON, | ||
| 434 | SPEC_STORE_BYPASS_CMD_PRCTL, | ||
| 435 | SPEC_STORE_BYPASS_CMD_SECCOMP, | ||
| 436 | }; | ||
| 437 | |||
| 438 | static const char *ssb_strings[] = { | ||
| 439 | [SPEC_STORE_BYPASS_NONE] = "Vulnerable", | ||
| 440 | [SPEC_STORE_BYPASS_DISABLE] = "Mitigation: Speculative Store Bypass disabled", | ||
| 441 | [SPEC_STORE_BYPASS_PRCTL] = "Mitigation: Speculative Store Bypass disabled via prctl", | ||
| 442 | [SPEC_STORE_BYPASS_SECCOMP] = "Mitigation: Speculative Store Bypass disabled via prctl and seccomp", | ||
| 443 | }; | ||
| 444 | |||
| 445 | static const struct { | ||
| 446 | const char *option; | ||
| 447 | enum ssb_mitigation_cmd cmd; | ||
| 448 | } ssb_mitigation_options[] = { | ||
| 449 | { "auto", SPEC_STORE_BYPASS_CMD_AUTO }, /* Platform decides */ | ||
| 450 | { "on", SPEC_STORE_BYPASS_CMD_ON }, /* Disable Speculative Store Bypass */ | ||
| 451 | { "off", SPEC_STORE_BYPASS_CMD_NONE }, /* Don't touch Speculative Store Bypass */ | ||
| 452 | { "prctl", SPEC_STORE_BYPASS_CMD_PRCTL }, /* Disable Speculative Store Bypass via prctl */ | ||
| 453 | { "seccomp", SPEC_STORE_BYPASS_CMD_SECCOMP }, /* Disable Speculative Store Bypass via prctl and seccomp */ | ||
| 454 | }; | ||
| 455 | |||
| 456 | static enum ssb_mitigation_cmd __init ssb_parse_cmdline(void) | ||
| 457 | { | ||
| 458 | enum ssb_mitigation_cmd cmd = SPEC_STORE_BYPASS_CMD_AUTO; | ||
| 459 | char arg[20]; | ||
| 460 | int ret, i; | ||
| 461 | |||
| 462 | if (cmdline_find_option_bool(boot_command_line, "nospec_store_bypass_disable")) { | ||
| 463 | return SPEC_STORE_BYPASS_CMD_NONE; | ||
| 464 | } else { | ||
| 465 | ret = cmdline_find_option(boot_command_line, "spec_store_bypass_disable", | ||
| 466 | arg, sizeof(arg)); | ||
| 467 | if (ret < 0) | ||
| 468 | return SPEC_STORE_BYPASS_CMD_AUTO; | ||
| 469 | |||
| 470 | for (i = 0; i < ARRAY_SIZE(ssb_mitigation_options); i++) { | ||
| 471 | if (!match_option(arg, ret, ssb_mitigation_options[i].option)) | ||
| 472 | continue; | ||
| 473 | |||
| 474 | cmd = ssb_mitigation_options[i].cmd; | ||
| 475 | break; | ||
| 476 | } | ||
| 477 | |||
| 478 | if (i >= ARRAY_SIZE(ssb_mitigation_options)) { | ||
| 479 | pr_err("unknown option (%s). Switching to AUTO select\n", arg); | ||
| 480 | return SPEC_STORE_BYPASS_CMD_AUTO; | ||
| 481 | } | ||
| 482 | } | ||
| 483 | |||
| 484 | return cmd; | ||
| 485 | } | ||
| 486 | |||
| 487 | static enum ssb_mitigation __init __ssb_select_mitigation(void) | ||
| 488 | { | ||
| 489 | enum ssb_mitigation mode = SPEC_STORE_BYPASS_NONE; | ||
| 490 | enum ssb_mitigation_cmd cmd; | ||
| 491 | |||
| 492 | if (!boot_cpu_has(X86_FEATURE_SSBD)) | ||
| 493 | return mode; | ||
| 494 | |||
| 495 | cmd = ssb_parse_cmdline(); | ||
| 496 | if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS) && | ||
| 497 | (cmd == SPEC_STORE_BYPASS_CMD_NONE || | ||
| 498 | cmd == SPEC_STORE_BYPASS_CMD_AUTO)) | ||
| 499 | return mode; | ||
| 500 | |||
| 501 | switch (cmd) { | ||
| 502 | case SPEC_STORE_BYPASS_CMD_AUTO: | ||
| 503 | case SPEC_STORE_BYPASS_CMD_SECCOMP: | ||
| 504 | /* | ||
| 505 | * Choose prctl+seccomp as the default mode if seccomp is | ||
| 506 | * enabled. | ||
| 507 | */ | ||
| 508 | if (IS_ENABLED(CONFIG_SECCOMP)) | ||
| 509 | mode = SPEC_STORE_BYPASS_SECCOMP; | ||
| 510 | else | ||
| 511 | mode = SPEC_STORE_BYPASS_PRCTL; | ||
| 512 | break; | ||
| 513 | case SPEC_STORE_BYPASS_CMD_ON: | ||
| 514 | mode = SPEC_STORE_BYPASS_DISABLE; | ||
| 515 | break; | ||
| 516 | case SPEC_STORE_BYPASS_CMD_PRCTL: | ||
| 517 | mode = SPEC_STORE_BYPASS_PRCTL; | ||
| 518 | break; | ||
| 519 | case SPEC_STORE_BYPASS_CMD_NONE: | ||
| 520 | break; | ||
| 521 | } | ||
| 522 | |||
| 523 | /* | ||
| 524 | * We have three CPU feature flags that are in play here: | ||
| 525 | * - X86_BUG_SPEC_STORE_BYPASS - CPU is susceptible. | ||
| 526 | * - X86_FEATURE_SSBD - CPU is able to turn off speculative store bypass | ||
| 527 | * - X86_FEATURE_SPEC_STORE_BYPASS_DISABLE - engage the mitigation | ||
| 528 | */ | ||
| 529 | if (mode == SPEC_STORE_BYPASS_DISABLE) { | ||
| 530 | setup_force_cpu_cap(X86_FEATURE_SPEC_STORE_BYPASS_DISABLE); | ||
| 531 | /* | ||
| 532 | * Intel uses the SPEC CTRL MSR Bit(2) for this, while AMD uses | ||
| 533 | * a completely different MSR and bit dependent on family. | ||
| 534 | */ | ||
| 535 | switch (boot_cpu_data.x86_vendor) { | ||
| 536 | case X86_VENDOR_INTEL: | ||
| 537 | x86_spec_ctrl_base |= SPEC_CTRL_SSBD; | ||
| 538 | x86_spec_ctrl_mask |= SPEC_CTRL_SSBD; | ||
| 539 | wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); | ||
| 540 | break; | ||
| 541 | case X86_VENDOR_AMD: | ||
| 542 | x86_amd_ssb_disable(); | ||
| 543 | break; | ||
| 544 | } | ||
| 545 | } | ||
| 546 | |||
| 547 | return mode; | ||
| 548 | } | ||
| 549 | |||
| 550 | static void ssb_select_mitigation(void) | ||
| 551 | { | ||
| 552 | ssb_mode = __ssb_select_mitigation(); | ||
| 553 | |||
| 554 | if (boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS)) | ||
| 555 | pr_info("%s\n", ssb_strings[ssb_mode]); | ||
| 556 | } | ||
| 557 | |||
| 558 | #undef pr_fmt | ||
| 559 | #define pr_fmt(fmt) "Speculation prctl: " fmt | ||
| 560 | |||
| 561 | static int ssb_prctl_set(struct task_struct *task, unsigned long ctrl) | ||
| 562 | { | ||
| 563 | bool update; | ||
| 564 | |||
| 565 | if (ssb_mode != SPEC_STORE_BYPASS_PRCTL && | ||
| 566 | ssb_mode != SPEC_STORE_BYPASS_SECCOMP) | ||
| 567 | return -ENXIO; | ||
| 568 | |||
| 569 | switch (ctrl) { | ||
| 570 | case PR_SPEC_ENABLE: | ||
| 571 | /* If speculation is force disabled, enable is not allowed */ | ||
| 572 | if (task_spec_ssb_force_disable(task)) | ||
| 573 | return -EPERM; | ||
| 574 | task_clear_spec_ssb_disable(task); | ||
| 575 | update = test_and_clear_tsk_thread_flag(task, TIF_SSBD); | ||
| 576 | break; | ||
| 577 | case PR_SPEC_DISABLE: | ||
| 578 | task_set_spec_ssb_disable(task); | ||
| 579 | update = !test_and_set_tsk_thread_flag(task, TIF_SSBD); | ||
| 580 | break; | ||
| 581 | case PR_SPEC_FORCE_DISABLE: | ||
| 582 | task_set_spec_ssb_disable(task); | ||
| 583 | task_set_spec_ssb_force_disable(task); | ||
| 584 | update = !test_and_set_tsk_thread_flag(task, TIF_SSBD); | ||
| 585 | break; | ||
| 586 | default: | ||
| 587 | return -ERANGE; | ||
| 588 | } | ||
| 589 | |||
| 590 | /* | ||
| 591 | * If being set on non-current task, delay setting the CPU | ||
| 592 | * mitigation until it is next scheduled. | ||
| 593 | */ | ||
| 594 | if (task == current && update) | ||
| 595 | speculative_store_bypass_update_current(); | ||
| 596 | |||
| 597 | return 0; | ||
| 598 | } | ||
| 599 | |||
| 600 | int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, | ||
| 601 | unsigned long ctrl) | ||
| 602 | { | ||
| 603 | switch (which) { | ||
| 604 | case PR_SPEC_STORE_BYPASS: | ||
| 605 | return ssb_prctl_set(task, ctrl); | ||
| 606 | default: | ||
| 607 | return -ENODEV; | ||
| 608 | } | ||
| 609 | } | ||
| 610 | |||
| 611 | #ifdef CONFIG_SECCOMP | ||
| 612 | void arch_seccomp_spec_mitigate(struct task_struct *task) | ||
| 613 | { | ||
| 614 | if (ssb_mode == SPEC_STORE_BYPASS_SECCOMP) | ||
| 615 | ssb_prctl_set(task, PR_SPEC_FORCE_DISABLE); | ||
| 616 | } | ||
| 617 | #endif | ||
| 618 | |||
| 619 | static int ssb_prctl_get(struct task_struct *task) | ||
| 620 | { | ||
| 621 | switch (ssb_mode) { | ||
| 622 | case SPEC_STORE_BYPASS_DISABLE: | ||
| 623 | return PR_SPEC_DISABLE; | ||
| 624 | case SPEC_STORE_BYPASS_SECCOMP: | ||
| 625 | case SPEC_STORE_BYPASS_PRCTL: | ||
| 626 | if (task_spec_ssb_force_disable(task)) | ||
| 627 | return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; | ||
| 628 | if (task_spec_ssb_disable(task)) | ||
| 629 | return PR_SPEC_PRCTL | PR_SPEC_DISABLE; | ||
| 630 | return PR_SPEC_PRCTL | PR_SPEC_ENABLE; | ||
| 631 | default: | ||
| 632 | if (boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS)) | ||
| 633 | return PR_SPEC_ENABLE; | ||
| 634 | return PR_SPEC_NOT_AFFECTED; | ||
| 635 | } | ||
| 636 | } | ||
| 637 | |||
| 638 | int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which) | ||
| 639 | { | ||
| 640 | switch (which) { | ||
| 641 | case PR_SPEC_STORE_BYPASS: | ||
| 642 | return ssb_prctl_get(task); | ||
| 643 | default: | ||
| 644 | return -ENODEV; | ||
| 645 | } | ||
| 646 | } | ||
| 647 | |||
| 648 | void x86_spec_ctrl_setup_ap(void) | ||
| 649 | { | ||
| 650 | if (boot_cpu_has(X86_FEATURE_MSR_SPEC_CTRL)) | ||
| 651 | wrmsrl(MSR_IA32_SPEC_CTRL, x86_spec_ctrl_base); | ||
| 652 | |||
| 653 | if (ssb_mode == SPEC_STORE_BYPASS_DISABLE) | ||
| 654 | x86_amd_ssb_disable(); | ||
| 655 | } | ||
| 315 | 656 | ||
| 316 | #ifdef CONFIG_SYSFS | 657 | #ifdef CONFIG_SYSFS |
| 317 | ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) | 658 | |
| 659 | static ssize_t cpu_show_common(struct device *dev, struct device_attribute *attr, | ||
| 660 | char *buf, unsigned int bug) | ||
| 318 | { | 661 | { |
| 319 | if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN)) | 662 | if (!boot_cpu_has_bug(bug)) |
| 320 | return sprintf(buf, "Not affected\n"); | 663 | return sprintf(buf, "Not affected\n"); |
| 321 | if (boot_cpu_has(X86_FEATURE_PTI)) | 664 | |
| 322 | return sprintf(buf, "Mitigation: PTI\n"); | 665 | switch (bug) { |
| 666 | case X86_BUG_CPU_MELTDOWN: | ||
| 667 | if (boot_cpu_has(X86_FEATURE_PTI)) | ||
| 668 | return sprintf(buf, "Mitigation: PTI\n"); | ||
| 669 | |||
| 670 | break; | ||
| 671 | |||
| 672 | case X86_BUG_SPECTRE_V1: | ||
| 673 | return sprintf(buf, "Mitigation: __user pointer sanitization\n"); | ||
| 674 | |||
| 675 | case X86_BUG_SPECTRE_V2: | ||
| 676 | return sprintf(buf, "%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], | ||
| 677 | boot_cpu_has(X86_FEATURE_USE_IBPB) ? ", IBPB" : "", | ||
| 678 | boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", | ||
| 679 | spectre_v2_module_string()); | ||
| 680 | |||
| 681 | case X86_BUG_SPEC_STORE_BYPASS: | ||
| 682 | return sprintf(buf, "%s\n", ssb_strings[ssb_mode]); | ||
| 683 | |||
| 684 | default: | ||
| 685 | break; | ||
| 686 | } | ||
| 687 | |||
| 323 | return sprintf(buf, "Vulnerable\n"); | 688 | return sprintf(buf, "Vulnerable\n"); |
| 324 | } | 689 | } |
| 325 | 690 | ||
| 691 | ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf) | ||
| 692 | { | ||
| 693 | return cpu_show_common(dev, attr, buf, X86_BUG_CPU_MELTDOWN); | ||
| 694 | } | ||
| 695 | |||
| 326 | ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf) | 696 | ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf) |
| 327 | { | 697 | { |
| 328 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V1)) | 698 | return cpu_show_common(dev, attr, buf, X86_BUG_SPECTRE_V1); |
| 329 | return sprintf(buf, "Not affected\n"); | ||
| 330 | return sprintf(buf, "Mitigation: __user pointer sanitization\n"); | ||
| 331 | } | 699 | } |
| 332 | 700 | ||
| 333 | ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf) | 701 | ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, char *buf) |
| 334 | { | 702 | { |
| 335 | if (!boot_cpu_has_bug(X86_BUG_SPECTRE_V2)) | 703 | return cpu_show_common(dev, attr, buf, X86_BUG_SPECTRE_V2); |
| 336 | return sprintf(buf, "Not affected\n"); | 704 | } |
| 337 | 705 | ||
| 338 | return sprintf(buf, "%s%s%s%s\n", spectre_v2_strings[spectre_v2_enabled], | 706 | ssize_t cpu_show_spec_store_bypass(struct device *dev, struct device_attribute *attr, char *buf) |
| 339 | boot_cpu_has(X86_FEATURE_USE_IBPB) ? ", IBPB" : "", | 707 | { |
| 340 | boot_cpu_has(X86_FEATURE_USE_IBRS_FW) ? ", IBRS_FW" : "", | 708 | return cpu_show_common(dev, attr, buf, X86_BUG_SPEC_STORE_BYPASS); |
| 341 | spectre_v2_module_string()); | ||
| 342 | } | 709 | } |
| 343 | #endif | 710 | #endif |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index ce243f7d2d4e..78decc3e3067 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
| @@ -757,17 +757,32 @@ static void init_speculation_control(struct cpuinfo_x86 *c) | |||
| 757 | * and they also have a different bit for STIBP support. Also, | 757 | * and they also have a different bit for STIBP support. Also, |
| 758 | * a hypervisor might have set the individual AMD bits even on | 758 | * a hypervisor might have set the individual AMD bits even on |
| 759 | * Intel CPUs, for finer-grained selection of what's available. | 759 | * Intel CPUs, for finer-grained selection of what's available. |
| 760 | * | ||
| 761 | * We use the AMD bits in 0x8000_0008 EBX as the generic hardware | ||
| 762 | * features, which are visible in /proc/cpuinfo and used by the | ||
| 763 | * kernel. So set those accordingly from the Intel bits. | ||
| 764 | */ | 760 | */ |
| 765 | if (cpu_has(c, X86_FEATURE_SPEC_CTRL)) { | 761 | if (cpu_has(c, X86_FEATURE_SPEC_CTRL)) { |
| 766 | set_cpu_cap(c, X86_FEATURE_IBRS); | 762 | set_cpu_cap(c, X86_FEATURE_IBRS); |
| 767 | set_cpu_cap(c, X86_FEATURE_IBPB); | 763 | set_cpu_cap(c, X86_FEATURE_IBPB); |
| 764 | set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); | ||
| 768 | } | 765 | } |
| 766 | |||
| 769 | if (cpu_has(c, X86_FEATURE_INTEL_STIBP)) | 767 | if (cpu_has(c, X86_FEATURE_INTEL_STIBP)) |
| 770 | set_cpu_cap(c, X86_FEATURE_STIBP); | 768 | set_cpu_cap(c, X86_FEATURE_STIBP); |
| 769 | |||
| 770 | if (cpu_has(c, X86_FEATURE_SPEC_CTRL_SSBD) || | ||
| 771 | cpu_has(c, X86_FEATURE_VIRT_SSBD)) | ||
| 772 | set_cpu_cap(c, X86_FEATURE_SSBD); | ||
| 773 | |||
| 774 | if (cpu_has(c, X86_FEATURE_AMD_IBRS)) { | ||
| 775 | set_cpu_cap(c, X86_FEATURE_IBRS); | ||
| 776 | set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); | ||
| 777 | } | ||
| 778 | |||
| 779 | if (cpu_has(c, X86_FEATURE_AMD_IBPB)) | ||
| 780 | set_cpu_cap(c, X86_FEATURE_IBPB); | ||
| 781 | |||
| 782 | if (cpu_has(c, X86_FEATURE_AMD_STIBP)) { | ||
| 783 | set_cpu_cap(c, X86_FEATURE_STIBP); | ||
| 784 | set_cpu_cap(c, X86_FEATURE_MSR_SPEC_CTRL); | ||
| 785 | } | ||
| 771 | } | 786 | } |
| 772 | 787 | ||
| 773 | void get_cpu_cap(struct cpuinfo_x86 *c) | 788 | void get_cpu_cap(struct cpuinfo_x86 *c) |
| @@ -927,21 +942,55 @@ static const __initconst struct x86_cpu_id cpu_no_meltdown[] = { | |||
| 927 | {} | 942 | {} |
| 928 | }; | 943 | }; |
| 929 | 944 | ||
| 930 | static bool __init cpu_vulnerable_to_meltdown(struct cpuinfo_x86 *c) | 945 | static const __initconst struct x86_cpu_id cpu_no_spec_store_bypass[] = { |
| 946 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PINEVIEW }, | ||
| 947 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_LINCROFT }, | ||
| 948 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_PENWELL }, | ||
| 949 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CLOVERVIEW }, | ||
| 950 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_CEDARVIEW }, | ||
| 951 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT1 }, | ||
| 952 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_AIRMONT }, | ||
| 953 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_SILVERMONT2 }, | ||
| 954 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_MERRIFIELD }, | ||
| 955 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_CORE_YONAH }, | ||
| 956 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNL }, | ||
| 957 | { X86_VENDOR_INTEL, 6, INTEL_FAM6_XEON_PHI_KNM }, | ||
| 958 | { X86_VENDOR_CENTAUR, 5, }, | ||
| 959 | { X86_VENDOR_INTEL, 5, }, | ||
| 960 | { X86_VENDOR_NSC, 5, }, | ||
| 961 | { X86_VENDOR_AMD, 0x12, }, | ||
| 962 | { X86_VENDOR_AMD, 0x11, }, | ||
| 963 | { X86_VENDOR_AMD, 0x10, }, | ||
| 964 | { X86_VENDOR_AMD, 0xf, }, | ||
| 965 | { X86_VENDOR_ANY, 4, }, | ||
| 966 | {} | ||
| 967 | }; | ||
| 968 | |||
| 969 | static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) | ||
| 931 | { | 970 | { |
| 932 | u64 ia32_cap = 0; | 971 | u64 ia32_cap = 0; |
| 933 | 972 | ||
| 934 | if (x86_match_cpu(cpu_no_meltdown)) | ||
| 935 | return false; | ||
| 936 | |||
| 937 | if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) | 973 | if (cpu_has(c, X86_FEATURE_ARCH_CAPABILITIES)) |
| 938 | rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); | 974 | rdmsrl(MSR_IA32_ARCH_CAPABILITIES, ia32_cap); |
| 939 | 975 | ||
| 976 | if (!x86_match_cpu(cpu_no_spec_store_bypass) && | ||
| 977 | !(ia32_cap & ARCH_CAP_SSB_NO)) | ||
| 978 | setup_force_cpu_bug(X86_BUG_SPEC_STORE_BYPASS); | ||
| 979 | |||
| 980 | if (x86_match_cpu(cpu_no_speculation)) | ||
| 981 | return; | ||
| 982 | |||
| 983 | setup_force_cpu_bug(X86_BUG_SPECTRE_V1); | ||
| 984 | setup_force_cpu_bug(X86_BUG_SPECTRE_V2); | ||
| 985 | |||
| 986 | if (x86_match_cpu(cpu_no_meltdown)) | ||
| 987 | return; | ||
| 988 | |||
| 940 | /* Rogue Data Cache Load? No! */ | 989 | /* Rogue Data Cache Load? No! */ |
| 941 | if (ia32_cap & ARCH_CAP_RDCL_NO) | 990 | if (ia32_cap & ARCH_CAP_RDCL_NO) |
| 942 | return false; | 991 | return; |
| 943 | 992 | ||
| 944 | return true; | 993 | setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); |
| 945 | } | 994 | } |
| 946 | 995 | ||
| 947 | /* | 996 | /* |
| @@ -992,12 +1041,7 @@ static void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
| 992 | 1041 | ||
| 993 | setup_force_cpu_cap(X86_FEATURE_ALWAYS); | 1042 | setup_force_cpu_cap(X86_FEATURE_ALWAYS); |
| 994 | 1043 | ||
| 995 | if (!x86_match_cpu(cpu_no_speculation)) { | 1044 | cpu_set_bug_bits(c); |
| 996 | if (cpu_vulnerable_to_meltdown(c)) | ||
| 997 | setup_force_cpu_bug(X86_BUG_CPU_MELTDOWN); | ||
| 998 | setup_force_cpu_bug(X86_BUG_SPECTRE_V1); | ||
| 999 | setup_force_cpu_bug(X86_BUG_SPECTRE_V2); | ||
| 1000 | } | ||
| 1001 | 1045 | ||
| 1002 | fpu__init_system(c); | 1046 | fpu__init_system(c); |
| 1003 | 1047 | ||
| @@ -1359,6 +1403,7 @@ void identify_secondary_cpu(struct cpuinfo_x86 *c) | |||
| 1359 | #endif | 1403 | #endif |
| 1360 | mtrr_ap_init(); | 1404 | mtrr_ap_init(); |
| 1361 | validate_apic_and_package_id(c); | 1405 | validate_apic_and_package_id(c); |
| 1406 | x86_spec_ctrl_setup_ap(); | ||
| 1362 | } | 1407 | } |
| 1363 | 1408 | ||
| 1364 | static __init int setup_noclflush(char *arg) | 1409 | static __init int setup_noclflush(char *arg) |
diff --git a/arch/x86/kernel/cpu/cpu.h b/arch/x86/kernel/cpu/cpu.h index e806b11a99af..37672d299e35 100644 --- a/arch/x86/kernel/cpu/cpu.h +++ b/arch/x86/kernel/cpu/cpu.h | |||
| @@ -50,4 +50,6 @@ extern void cpu_detect_cache_sizes(struct cpuinfo_x86 *c); | |||
| 50 | 50 | ||
| 51 | unsigned int aperfmperf_get_khz(int cpu); | 51 | unsigned int aperfmperf_get_khz(int cpu); |
| 52 | 52 | ||
| 53 | extern void x86_spec_ctrl_setup_ap(void); | ||
| 54 | |||
| 53 | #endif /* ARCH_X86_CPU_H */ | 55 | #endif /* ARCH_X86_CPU_H */ |
diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index 60d1897041da..577e7f7ae273 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c | |||
| @@ -188,7 +188,10 @@ static void early_init_intel(struct cpuinfo_x86 *c) | |||
| 188 | setup_clear_cpu_cap(X86_FEATURE_IBPB); | 188 | setup_clear_cpu_cap(X86_FEATURE_IBPB); |
| 189 | setup_clear_cpu_cap(X86_FEATURE_STIBP); | 189 | setup_clear_cpu_cap(X86_FEATURE_STIBP); |
| 190 | setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL); | 190 | setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL); |
| 191 | setup_clear_cpu_cap(X86_FEATURE_MSR_SPEC_CTRL); | ||
| 191 | setup_clear_cpu_cap(X86_FEATURE_INTEL_STIBP); | 192 | setup_clear_cpu_cap(X86_FEATURE_INTEL_STIBP); |
| 193 | setup_clear_cpu_cap(X86_FEATURE_SSBD); | ||
| 194 | setup_clear_cpu_cap(X86_FEATURE_SPEC_CTRL_SSBD); | ||
| 192 | } | 195 | } |
| 193 | 196 | ||
| 194 | /* | 197 | /* |
diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c index 03408b942adb..30ca2d1a9231 100644 --- a/arch/x86/kernel/process.c +++ b/arch/x86/kernel/process.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <asm/switch_to.h> | 38 | #include <asm/switch_to.h> |
| 39 | #include <asm/desc.h> | 39 | #include <asm/desc.h> |
| 40 | #include <asm/prctl.h> | 40 | #include <asm/prctl.h> |
| 41 | #include <asm/spec-ctrl.h> | ||
| 41 | 42 | ||
| 42 | /* | 43 | /* |
| 43 | * per-CPU TSS segments. Threads are completely 'soft' on Linux, | 44 | * per-CPU TSS segments. Threads are completely 'soft' on Linux, |
| @@ -278,6 +279,148 @@ static inline void switch_to_bitmap(struct tss_struct *tss, | |||
| 278 | } | 279 | } |
| 279 | } | 280 | } |
| 280 | 281 | ||
| 282 | #ifdef CONFIG_SMP | ||
| 283 | |||
| 284 | struct ssb_state { | ||
| 285 | struct ssb_state *shared_state; | ||
| 286 | raw_spinlock_t lock; | ||
| 287 | unsigned int disable_state; | ||
| 288 | unsigned long local_state; | ||
| 289 | }; | ||
| 290 | |||
| 291 | #define LSTATE_SSB 0 | ||
| 292 | |||
| 293 | static DEFINE_PER_CPU(struct ssb_state, ssb_state); | ||
| 294 | |||
| 295 | void speculative_store_bypass_ht_init(void) | ||
| 296 | { | ||
| 297 | struct ssb_state *st = this_cpu_ptr(&ssb_state); | ||
| 298 | unsigned int this_cpu = smp_processor_id(); | ||
| 299 | unsigned int cpu; | ||
| 300 | |||
| 301 | st->local_state = 0; | ||
| 302 | |||
| 303 | /* | ||
| 304 | * Shared state setup happens once on the first bringup | ||
| 305 | * of the CPU. It's not destroyed on CPU hotunplug. | ||
| 306 | */ | ||
| 307 | if (st->shared_state) | ||
| 308 | return; | ||
| 309 | |||
| 310 | raw_spin_lock_init(&st->lock); | ||
| 311 | |||
| 312 | /* | ||
| 313 | * Go over HT siblings and check whether one of them has set up the | ||
| 314 | * shared state pointer already. | ||
| 315 | */ | ||
| 316 | for_each_cpu(cpu, topology_sibling_cpumask(this_cpu)) { | ||
| 317 | if (cpu == this_cpu) | ||
| 318 | continue; | ||
| 319 | |||
| 320 | if (!per_cpu(ssb_state, cpu).shared_state) | ||
| 321 | continue; | ||
| 322 | |||
| 323 | /* Link it to the state of the sibling: */ | ||
| 324 | st->shared_state = per_cpu(ssb_state, cpu).shared_state; | ||
| 325 | return; | ||
| 326 | } | ||
| 327 | |||
| 328 | /* | ||
| 329 | * First HT sibling to come up on the core. Link shared state of | ||
| 330 | * the first HT sibling to itself. The siblings on the same core | ||
| 331 | * which come up later will see the shared state pointer and link | ||
| 332 | * themself to the state of this CPU. | ||
| 333 | */ | ||
| 334 | st->shared_state = st; | ||
| 335 | } | ||
| 336 | |||
| 337 | /* | ||
| 338 | * Logic is: First HT sibling enables SSBD for both siblings in the core | ||
| 339 | * and last sibling to disable it, disables it for the whole core. This how | ||
| 340 | * MSR_SPEC_CTRL works in "hardware": | ||
| 341 | * | ||
| 342 | * CORE_SPEC_CTRL = THREAD0_SPEC_CTRL | THREAD1_SPEC_CTRL | ||
| 343 | */ | ||
| 344 | static __always_inline void amd_set_core_ssb_state(unsigned long tifn) | ||
| 345 | { | ||
| 346 | struct ssb_state *st = this_cpu_ptr(&ssb_state); | ||
| 347 | u64 msr = x86_amd_ls_cfg_base; | ||
| 348 | |||
| 349 | if (!static_cpu_has(X86_FEATURE_ZEN)) { | ||
| 350 | msr |= ssbd_tif_to_amd_ls_cfg(tifn); | ||
| 351 | wrmsrl(MSR_AMD64_LS_CFG, msr); | ||
| 352 | return; | ||
| 353 | } | ||
| 354 | |||
| 355 | if (tifn & _TIF_SSBD) { | ||
| 356 | /* | ||
| 357 | * Since this can race with prctl(), block reentry on the | ||
| 358 | * same CPU. | ||
| 359 | */ | ||
| 360 | if (__test_and_set_bit(LSTATE_SSB, &st->local_state)) | ||
| 361 | return; | ||
| 362 | |||
| 363 | msr |= x86_amd_ls_cfg_ssbd_mask; | ||
| 364 | |||
| 365 | raw_spin_lock(&st->shared_state->lock); | ||
| 366 | /* First sibling enables SSBD: */ | ||
| 367 | if (!st->shared_state->disable_state) | ||
| 368 | wrmsrl(MSR_AMD64_LS_CFG, msr); | ||
| 369 | st->shared_state->disable_state++; | ||
| 370 | raw_spin_unlock(&st->shared_state->lock); | ||
| 371 | } else { | ||
| 372 | if (!__test_and_clear_bit(LSTATE_SSB, &st->local_state)) | ||
| 373 | return; | ||
| 374 | |||
| 375 | raw_spin_lock(&st->shared_state->lock); | ||
| 376 | st->shared_state->disable_state--; | ||
| 377 | if (!st->shared_state->disable_state) | ||
| 378 | wrmsrl(MSR_AMD64_LS_CFG, msr); | ||
| 379 | raw_spin_unlock(&st->shared_state->lock); | ||
| 380 | } | ||
| 381 | } | ||
| 382 | #else | ||
| 383 | static __always_inline void amd_set_core_ssb_state(unsigned long tifn) | ||
| 384 | { | ||
| 385 | u64 msr = x86_amd_ls_cfg_base | ssbd_tif_to_amd_ls_cfg(tifn); | ||
| 386 | |||
| 387 | wrmsrl(MSR_AMD64_LS_CFG, msr); | ||
| 388 | } | ||
| 389 | #endif | ||
| 390 | |||
| 391 | static __always_inline void amd_set_ssb_virt_state(unsigned long tifn) | ||
| 392 | { | ||
| 393 | /* | ||
| 394 | * SSBD has the same definition in SPEC_CTRL and VIRT_SPEC_CTRL, | ||
| 395 | * so ssbd_tif_to_spec_ctrl() just works. | ||
| 396 | */ | ||
| 397 | wrmsrl(MSR_AMD64_VIRT_SPEC_CTRL, ssbd_tif_to_spec_ctrl(tifn)); | ||
| 398 | } | ||
| 399 | |||
| 400 | static __always_inline void intel_set_ssb_state(unsigned long tifn) | ||
| 401 | { | ||
| 402 | u64 msr = x86_spec_ctrl_base | ssbd_tif_to_spec_ctrl(tifn); | ||
| 403 | |||
| 404 | wrmsrl(MSR_IA32_SPEC_CTRL, msr); | ||
| 405 | } | ||
| 406 | |||
| 407 | static __always_inline void __speculative_store_bypass_update(unsigned long tifn) | ||
| 408 | { | ||
| 409 | if (static_cpu_has(X86_FEATURE_VIRT_SSBD)) | ||
| 410 | amd_set_ssb_virt_state(tifn); | ||
| 411 | else if (static_cpu_has(X86_FEATURE_LS_CFG_SSBD)) | ||
| 412 | amd_set_core_ssb_state(tifn); | ||
| 413 | else | ||
| 414 | intel_set_ssb_state(tifn); | ||
| 415 | } | ||
| 416 | |||
| 417 | void speculative_store_bypass_update(unsigned long tif) | ||
| 418 | { | ||
| 419 | preempt_disable(); | ||
| 420 | __speculative_store_bypass_update(tif); | ||
| 421 | preempt_enable(); | ||
| 422 | } | ||
| 423 | |||
| 281 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | 424 | void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, |
| 282 | struct tss_struct *tss) | 425 | struct tss_struct *tss) |
| 283 | { | 426 | { |
| @@ -309,6 +452,9 @@ void __switch_to_xtra(struct task_struct *prev_p, struct task_struct *next_p, | |||
| 309 | 452 | ||
| 310 | if ((tifp ^ tifn) & _TIF_NOCPUID) | 453 | if ((tifp ^ tifn) & _TIF_NOCPUID) |
| 311 | set_cpuid_faulting(!!(tifn & _TIF_NOCPUID)); | 454 | set_cpuid_faulting(!!(tifn & _TIF_NOCPUID)); |
| 455 | |||
| 456 | if ((tifp ^ tifn) & _TIF_SSBD) | ||
| 457 | __speculative_store_bypass_update(tifn); | ||
| 312 | } | 458 | } |
| 313 | 459 | ||
| 314 | /* | 460 | /* |
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index 0f1cbb042f49..9dd324ae4832 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c | |||
| @@ -79,6 +79,7 @@ | |||
| 79 | #include <asm/qspinlock.h> | 79 | #include <asm/qspinlock.h> |
| 80 | #include <asm/intel-family.h> | 80 | #include <asm/intel-family.h> |
| 81 | #include <asm/cpu_device_id.h> | 81 | #include <asm/cpu_device_id.h> |
| 82 | #include <asm/spec-ctrl.h> | ||
| 82 | 83 | ||
| 83 | /* Number of siblings per CPU package */ | 84 | /* Number of siblings per CPU package */ |
| 84 | int smp_num_siblings = 1; | 85 | int smp_num_siblings = 1; |
| @@ -244,6 +245,8 @@ static void notrace start_secondary(void *unused) | |||
| 244 | */ | 245 | */ |
| 245 | check_tsc_sync_target(); | 246 | check_tsc_sync_target(); |
| 246 | 247 | ||
| 248 | speculative_store_bypass_ht_init(); | ||
| 249 | |||
| 247 | /* | 250 | /* |
| 248 | * Lock vector_lock, set CPU online and bring the vector | 251 | * Lock vector_lock, set CPU online and bring the vector |
| 249 | * allocator online. Online must be set with vector_lock held | 252 | * allocator online. Online must be set with vector_lock held |
| @@ -1292,6 +1295,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) | |||
| 1292 | set_mtrr_aps_delayed_init(); | 1295 | set_mtrr_aps_delayed_init(); |
| 1293 | 1296 | ||
| 1294 | smp_quirk_init_udelay(); | 1297 | smp_quirk_init_udelay(); |
| 1298 | |||
| 1299 | speculative_store_bypass_ht_init(); | ||
| 1295 | } | 1300 | } |
| 1296 | 1301 | ||
| 1297 | void arch_enable_nonboot_cpus_begin(void) | 1302 | void arch_enable_nonboot_cpus_begin(void) |
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c index 82055b90a8b3..ced851169730 100644 --- a/arch/x86/kvm/cpuid.c +++ b/arch/x86/kvm/cpuid.c | |||
| @@ -379,7 +379,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 379 | 379 | ||
| 380 | /* cpuid 0x80000008.ebx */ | 380 | /* cpuid 0x80000008.ebx */ |
| 381 | const u32 kvm_cpuid_8000_0008_ebx_x86_features = | 381 | const u32 kvm_cpuid_8000_0008_ebx_x86_features = |
| 382 | F(IBPB) | F(IBRS); | 382 | F(AMD_IBPB) | F(AMD_IBRS) | F(VIRT_SSBD); |
| 383 | 383 | ||
| 384 | /* cpuid 0xC0000001.edx */ | 384 | /* cpuid 0xC0000001.edx */ |
| 385 | const u32 kvm_cpuid_C000_0001_edx_x86_features = | 385 | const u32 kvm_cpuid_C000_0001_edx_x86_features = |
| @@ -407,7 +407,7 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 407 | 407 | ||
| 408 | /* cpuid 7.0.edx*/ | 408 | /* cpuid 7.0.edx*/ |
| 409 | const u32 kvm_cpuid_7_0_edx_x86_features = | 409 | const u32 kvm_cpuid_7_0_edx_x86_features = |
| 410 | F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) | | 410 | F(AVX512_4VNNIW) | F(AVX512_4FMAPS) | F(SPEC_CTRL) | F(SSBD) | |
| 411 | F(ARCH_CAPABILITIES); | 411 | F(ARCH_CAPABILITIES); |
| 412 | 412 | ||
| 413 | /* all calls to cpuid_count() should be made on the same cpu */ | 413 | /* all calls to cpuid_count() should be made on the same cpu */ |
| @@ -647,13 +647,20 @@ static inline int __do_cpuid_ent(struct kvm_cpuid_entry2 *entry, u32 function, | |||
| 647 | g_phys_as = phys_as; | 647 | g_phys_as = phys_as; |
| 648 | entry->eax = g_phys_as | (virt_as << 8); | 648 | entry->eax = g_phys_as | (virt_as << 8); |
| 649 | entry->edx = 0; | 649 | entry->edx = 0; |
| 650 | /* IBRS and IBPB aren't necessarily present in hardware cpuid */ | 650 | /* |
| 651 | if (boot_cpu_has(X86_FEATURE_IBPB)) | 651 | * IBRS, IBPB and VIRT_SSBD aren't necessarily present in |
| 652 | entry->ebx |= F(IBPB); | 652 | * hardware cpuid |
| 653 | if (boot_cpu_has(X86_FEATURE_IBRS)) | 653 | */ |
| 654 | entry->ebx |= F(IBRS); | 654 | if (boot_cpu_has(X86_FEATURE_AMD_IBPB)) |
| 655 | entry->ebx |= F(AMD_IBPB); | ||
| 656 | if (boot_cpu_has(X86_FEATURE_AMD_IBRS)) | ||
| 657 | entry->ebx |= F(AMD_IBRS); | ||
| 658 | if (boot_cpu_has(X86_FEATURE_VIRT_SSBD)) | ||
| 659 | entry->ebx |= F(VIRT_SSBD); | ||
| 655 | entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features; | 660 | entry->ebx &= kvm_cpuid_8000_0008_ebx_x86_features; |
| 656 | cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX); | 661 | cpuid_mask(&entry->ebx, CPUID_8000_0008_EBX); |
| 662 | if (boot_cpu_has(X86_FEATURE_LS_CFG_SSBD)) | ||
| 663 | entry->ebx |= F(VIRT_SSBD); | ||
| 657 | break; | 664 | break; |
| 658 | } | 665 | } |
| 659 | case 0x80000019: | 666 | case 0x80000019: |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1fc05e428aba..26110c202b19 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
| @@ -49,7 +49,7 @@ | |||
| 49 | #include <asm/debugreg.h> | 49 | #include <asm/debugreg.h> |
| 50 | #include <asm/kvm_para.h> | 50 | #include <asm/kvm_para.h> |
| 51 | #include <asm/irq_remapping.h> | 51 | #include <asm/irq_remapping.h> |
| 52 | #include <asm/nospec-branch.h> | 52 | #include <asm/spec-ctrl.h> |
| 53 | 53 | ||
| 54 | #include <asm/virtext.h> | 54 | #include <asm/virtext.h> |
| 55 | #include "trace.h" | 55 | #include "trace.h" |
| @@ -213,6 +213,12 @@ struct vcpu_svm { | |||
| 213 | } host; | 213 | } host; |
| 214 | 214 | ||
| 215 | u64 spec_ctrl; | 215 | u64 spec_ctrl; |
| 216 | /* | ||
| 217 | * Contains guest-controlled bits of VIRT_SPEC_CTRL, which will be | ||
| 218 | * translated into the appropriate L2_CFG bits on the host to | ||
| 219 | * perform speculative control. | ||
| 220 | */ | ||
| 221 | u64 virt_spec_ctrl; | ||
| 216 | 222 | ||
| 217 | u32 *msrpm; | 223 | u32 *msrpm; |
| 218 | 224 | ||
| @@ -2060,6 +2066,7 @@ static void svm_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) | |||
| 2060 | 2066 | ||
| 2061 | vcpu->arch.microcode_version = 0x01000065; | 2067 | vcpu->arch.microcode_version = 0x01000065; |
| 2062 | svm->spec_ctrl = 0; | 2068 | svm->spec_ctrl = 0; |
| 2069 | svm->virt_spec_ctrl = 0; | ||
| 2063 | 2070 | ||
| 2064 | if (!init_event) { | 2071 | if (!init_event) { |
| 2065 | svm->vcpu.arch.apic_base = APIC_DEFAULT_PHYS_BASE | | 2072 | svm->vcpu.arch.apic_base = APIC_DEFAULT_PHYS_BASE | |
| @@ -4108,11 +4115,18 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
| 4108 | break; | 4115 | break; |
| 4109 | case MSR_IA32_SPEC_CTRL: | 4116 | case MSR_IA32_SPEC_CTRL: |
| 4110 | if (!msr_info->host_initiated && | 4117 | if (!msr_info->host_initiated && |
| 4111 | !guest_cpuid_has(vcpu, X86_FEATURE_IBRS)) | 4118 | !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS)) |
| 4112 | return 1; | 4119 | return 1; |
| 4113 | 4120 | ||
| 4114 | msr_info->data = svm->spec_ctrl; | 4121 | msr_info->data = svm->spec_ctrl; |
| 4115 | break; | 4122 | break; |
| 4123 | case MSR_AMD64_VIRT_SPEC_CTRL: | ||
| 4124 | if (!msr_info->host_initiated && | ||
| 4125 | !guest_cpuid_has(vcpu, X86_FEATURE_VIRT_SSBD)) | ||
| 4126 | return 1; | ||
| 4127 | |||
| 4128 | msr_info->data = svm->virt_spec_ctrl; | ||
| 4129 | break; | ||
| 4116 | case MSR_F15H_IC_CFG: { | 4130 | case MSR_F15H_IC_CFG: { |
| 4117 | 4131 | ||
| 4118 | int family, model; | 4132 | int family, model; |
| @@ -4203,7 +4217,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) | |||
| 4203 | break; | 4217 | break; |
| 4204 | case MSR_IA32_SPEC_CTRL: | 4218 | case MSR_IA32_SPEC_CTRL: |
| 4205 | if (!msr->host_initiated && | 4219 | if (!msr->host_initiated && |
| 4206 | !guest_cpuid_has(vcpu, X86_FEATURE_IBRS)) | 4220 | !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS)) |
| 4207 | return 1; | 4221 | return 1; |
| 4208 | 4222 | ||
| 4209 | /* The STIBP bit doesn't fault even if it's not advertised */ | 4223 | /* The STIBP bit doesn't fault even if it's not advertised */ |
| @@ -4230,7 +4244,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) | |||
| 4230 | break; | 4244 | break; |
| 4231 | case MSR_IA32_PRED_CMD: | 4245 | case MSR_IA32_PRED_CMD: |
| 4232 | if (!msr->host_initiated && | 4246 | if (!msr->host_initiated && |
| 4233 | !guest_cpuid_has(vcpu, X86_FEATURE_IBPB)) | 4247 | !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBPB)) |
| 4234 | return 1; | 4248 | return 1; |
| 4235 | 4249 | ||
| 4236 | if (data & ~PRED_CMD_IBPB) | 4250 | if (data & ~PRED_CMD_IBPB) |
| @@ -4244,6 +4258,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr) | |||
| 4244 | break; | 4258 | break; |
| 4245 | set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1); | 4259 | set_msr_interception(svm->msrpm, MSR_IA32_PRED_CMD, 0, 1); |
| 4246 | break; | 4260 | break; |
| 4261 | case MSR_AMD64_VIRT_SPEC_CTRL: | ||
| 4262 | if (!msr->host_initiated && | ||
| 4263 | !guest_cpuid_has(vcpu, X86_FEATURE_VIRT_SSBD)) | ||
| 4264 | return 1; | ||
| 4265 | |||
| 4266 | if (data & ~SPEC_CTRL_SSBD) | ||
| 4267 | return 1; | ||
| 4268 | |||
| 4269 | svm->virt_spec_ctrl = data; | ||
| 4270 | break; | ||
| 4247 | case MSR_STAR: | 4271 | case MSR_STAR: |
| 4248 | svm->vmcb->save.star = data; | 4272 | svm->vmcb->save.star = data; |
| 4249 | break; | 4273 | break; |
| @@ -5557,8 +5581,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
| 5557 | * is no need to worry about the conditional branch over the wrmsr | 5581 | * is no need to worry about the conditional branch over the wrmsr |
| 5558 | * being speculatively taken. | 5582 | * being speculatively taken. |
| 5559 | */ | 5583 | */ |
| 5560 | if (svm->spec_ctrl) | 5584 | x86_spec_ctrl_set_guest(svm->spec_ctrl, svm->virt_spec_ctrl); |
| 5561 | native_wrmsrl(MSR_IA32_SPEC_CTRL, svm->spec_ctrl); | ||
| 5562 | 5585 | ||
| 5563 | asm volatile ( | 5586 | asm volatile ( |
| 5564 | "push %%" _ASM_BP "; \n\t" | 5587 | "push %%" _ASM_BP "; \n\t" |
| @@ -5652,6 +5675,18 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
| 5652 | #endif | 5675 | #endif |
| 5653 | ); | 5676 | ); |
| 5654 | 5677 | ||
| 5678 | /* Eliminate branch target predictions from guest mode */ | ||
| 5679 | vmexit_fill_RSB(); | ||
| 5680 | |||
| 5681 | #ifdef CONFIG_X86_64 | ||
| 5682 | wrmsrl(MSR_GS_BASE, svm->host.gs_base); | ||
| 5683 | #else | ||
| 5684 | loadsegment(fs, svm->host.fs); | ||
| 5685 | #ifndef CONFIG_X86_32_LAZY_GS | ||
| 5686 | loadsegment(gs, svm->host.gs); | ||
| 5687 | #endif | ||
| 5688 | #endif | ||
| 5689 | |||
| 5655 | /* | 5690 | /* |
| 5656 | * We do not use IBRS in the kernel. If this vCPU has used the | 5691 | * We do not use IBRS in the kernel. If this vCPU has used the |
| 5657 | * SPEC_CTRL MSR it may have left it on; save the value and | 5692 | * SPEC_CTRL MSR it may have left it on; save the value and |
| @@ -5670,20 +5705,7 @@ static void svm_vcpu_run(struct kvm_vcpu *vcpu) | |||
| 5670 | if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) | 5705 | if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) |
| 5671 | svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); | 5706 | svm->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); |
| 5672 | 5707 | ||
| 5673 | if (svm->spec_ctrl) | 5708 | x86_spec_ctrl_restore_host(svm->spec_ctrl, svm->virt_spec_ctrl); |
| 5674 | native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); | ||
| 5675 | |||
| 5676 | /* Eliminate branch target predictions from guest mode */ | ||
| 5677 | vmexit_fill_RSB(); | ||
| 5678 | |||
| 5679 | #ifdef CONFIG_X86_64 | ||
| 5680 | wrmsrl(MSR_GS_BASE, svm->host.gs_base); | ||
| 5681 | #else | ||
| 5682 | loadsegment(fs, svm->host.fs); | ||
| 5683 | #ifndef CONFIG_X86_32_LAZY_GS | ||
| 5684 | loadsegment(gs, svm->host.gs); | ||
| 5685 | #endif | ||
| 5686 | #endif | ||
| 5687 | 5709 | ||
| 5688 | reload_tss(vcpu); | 5710 | reload_tss(vcpu); |
| 5689 | 5711 | ||
| @@ -5786,7 +5808,7 @@ static bool svm_cpu_has_accelerated_tpr(void) | |||
| 5786 | return false; | 5808 | return false; |
| 5787 | } | 5809 | } |
| 5788 | 5810 | ||
| 5789 | static bool svm_has_high_real_mode_segbase(void) | 5811 | static bool svm_has_emulated_msr(int index) |
| 5790 | { | 5812 | { |
| 5791 | return true; | 5813 | return true; |
| 5792 | } | 5814 | } |
| @@ -7012,7 +7034,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { | |||
| 7012 | .hardware_enable = svm_hardware_enable, | 7034 | .hardware_enable = svm_hardware_enable, |
| 7013 | .hardware_disable = svm_hardware_disable, | 7035 | .hardware_disable = svm_hardware_disable, |
| 7014 | .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr, | 7036 | .cpu_has_accelerated_tpr = svm_cpu_has_accelerated_tpr, |
| 7015 | .cpu_has_high_real_mode_segbase = svm_has_high_real_mode_segbase, | 7037 | .has_emulated_msr = svm_has_emulated_msr, |
| 7016 | 7038 | ||
| 7017 | .vcpu_create = svm_create_vcpu, | 7039 | .vcpu_create = svm_create_vcpu, |
| 7018 | .vcpu_free = svm_free_vcpu, | 7040 | .vcpu_free = svm_free_vcpu, |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 3f1696570b41..40aa29204baf 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
| @@ -51,7 +51,7 @@ | |||
| 51 | #include <asm/apic.h> | 51 | #include <asm/apic.h> |
| 52 | #include <asm/irq_remapping.h> | 52 | #include <asm/irq_remapping.h> |
| 53 | #include <asm/mmu_context.h> | 53 | #include <asm/mmu_context.h> |
| 54 | #include <asm/nospec-branch.h> | 54 | #include <asm/spec-ctrl.h> |
| 55 | #include <asm/mshyperv.h> | 55 | #include <asm/mshyperv.h> |
| 56 | 56 | ||
| 57 | #include "trace.h" | 57 | #include "trace.h" |
| @@ -3529,7 +3529,6 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
| 3529 | return kvm_get_msr_common(vcpu, msr_info); | 3529 | return kvm_get_msr_common(vcpu, msr_info); |
| 3530 | case MSR_IA32_SPEC_CTRL: | 3530 | case MSR_IA32_SPEC_CTRL: |
| 3531 | if (!msr_info->host_initiated && | 3531 | if (!msr_info->host_initiated && |
| 3532 | !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) && | ||
| 3533 | !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) | 3532 | !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) |
| 3534 | return 1; | 3533 | return 1; |
| 3535 | 3534 | ||
| @@ -3648,12 +3647,11 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
| 3648 | break; | 3647 | break; |
| 3649 | case MSR_IA32_SPEC_CTRL: | 3648 | case MSR_IA32_SPEC_CTRL: |
| 3650 | if (!msr_info->host_initiated && | 3649 | if (!msr_info->host_initiated && |
| 3651 | !guest_cpuid_has(vcpu, X86_FEATURE_IBRS) && | ||
| 3652 | !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) | 3650 | !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) |
| 3653 | return 1; | 3651 | return 1; |
| 3654 | 3652 | ||
| 3655 | /* The STIBP bit doesn't fault even if it's not advertised */ | 3653 | /* The STIBP bit doesn't fault even if it's not advertised */ |
| 3656 | if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP)) | 3654 | if (data & ~(SPEC_CTRL_IBRS | SPEC_CTRL_STIBP | SPEC_CTRL_SSBD)) |
| 3657 | return 1; | 3655 | return 1; |
| 3658 | 3656 | ||
| 3659 | vmx->spec_ctrl = data; | 3657 | vmx->spec_ctrl = data; |
| @@ -3679,7 +3677,6 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
| 3679 | break; | 3677 | break; |
| 3680 | case MSR_IA32_PRED_CMD: | 3678 | case MSR_IA32_PRED_CMD: |
| 3681 | if (!msr_info->host_initiated && | 3679 | if (!msr_info->host_initiated && |
| 3682 | !guest_cpuid_has(vcpu, X86_FEATURE_IBPB) && | ||
| 3683 | !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) | 3680 | !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL)) |
| 3684 | return 1; | 3681 | return 1; |
| 3685 | 3682 | ||
| @@ -9488,9 +9485,21 @@ static void vmx_handle_external_intr(struct kvm_vcpu *vcpu) | |||
| 9488 | } | 9485 | } |
| 9489 | STACK_FRAME_NON_STANDARD(vmx_handle_external_intr); | 9486 | STACK_FRAME_NON_STANDARD(vmx_handle_external_intr); |
| 9490 | 9487 | ||
| 9491 | static bool vmx_has_high_real_mode_segbase(void) | 9488 | static bool vmx_has_emulated_msr(int index) |
| 9492 | { | 9489 | { |
| 9493 | return enable_unrestricted_guest || emulate_invalid_guest_state; | 9490 | switch (index) { |
| 9491 | case MSR_IA32_SMBASE: | ||
| 9492 | /* | ||
| 9493 | * We cannot do SMM unless we can run the guest in big | ||
| 9494 | * real mode. | ||
| 9495 | */ | ||
| 9496 | return enable_unrestricted_guest || emulate_invalid_guest_state; | ||
| 9497 | case MSR_AMD64_VIRT_SPEC_CTRL: | ||
| 9498 | /* This is AMD only. */ | ||
| 9499 | return false; | ||
| 9500 | default: | ||
| 9501 | return true; | ||
| 9502 | } | ||
| 9494 | } | 9503 | } |
| 9495 | 9504 | ||
| 9496 | static bool vmx_mpx_supported(void) | 9505 | static bool vmx_mpx_supported(void) |
| @@ -9722,8 +9731,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
| 9722 | * is no need to worry about the conditional branch over the wrmsr | 9731 | * is no need to worry about the conditional branch over the wrmsr |
| 9723 | * being speculatively taken. | 9732 | * being speculatively taken. |
| 9724 | */ | 9733 | */ |
| 9725 | if (vmx->spec_ctrl) | 9734 | x86_spec_ctrl_set_guest(vmx->spec_ctrl, 0); |
| 9726 | native_wrmsrl(MSR_IA32_SPEC_CTRL, vmx->spec_ctrl); | ||
| 9727 | 9735 | ||
| 9728 | vmx->__launched = vmx->loaded_vmcs->launched; | 9736 | vmx->__launched = vmx->loaded_vmcs->launched; |
| 9729 | 9737 | ||
| @@ -9871,8 +9879,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
| 9871 | if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) | 9879 | if (unlikely(!msr_write_intercepted(vcpu, MSR_IA32_SPEC_CTRL))) |
| 9872 | vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); | 9880 | vmx->spec_ctrl = native_read_msr(MSR_IA32_SPEC_CTRL); |
| 9873 | 9881 | ||
| 9874 | if (vmx->spec_ctrl) | 9882 | x86_spec_ctrl_restore_host(vmx->spec_ctrl, 0); |
| 9875 | native_wrmsrl(MSR_IA32_SPEC_CTRL, 0); | ||
| 9876 | 9883 | ||
| 9877 | /* Eliminate branch target predictions from guest mode */ | 9884 | /* Eliminate branch target predictions from guest mode */ |
| 9878 | vmexit_fill_RSB(); | 9885 | vmexit_fill_RSB(); |
| @@ -12632,7 +12639,7 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = { | |||
| 12632 | .hardware_enable = hardware_enable, | 12639 | .hardware_enable = hardware_enable, |
| 12633 | .hardware_disable = hardware_disable, | 12640 | .hardware_disable = hardware_disable, |
| 12634 | .cpu_has_accelerated_tpr = report_flexpriority, | 12641 | .cpu_has_accelerated_tpr = report_flexpriority, |
| 12635 | .cpu_has_high_real_mode_segbase = vmx_has_high_real_mode_segbase, | 12642 | .has_emulated_msr = vmx_has_emulated_msr, |
| 12636 | 12643 | ||
| 12637 | .vm_init = vmx_vm_init, | 12644 | .vm_init = vmx_vm_init, |
| 12638 | .vm_alloc = vmx_vm_alloc, | 12645 | .vm_alloc = vmx_vm_alloc, |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 59371de5d722..22a183aac1c6 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
| @@ -1061,6 +1061,7 @@ static u32 emulated_msrs[] = { | |||
| 1061 | MSR_SMI_COUNT, | 1061 | MSR_SMI_COUNT, |
| 1062 | MSR_PLATFORM_INFO, | 1062 | MSR_PLATFORM_INFO, |
| 1063 | MSR_MISC_FEATURES_ENABLES, | 1063 | MSR_MISC_FEATURES_ENABLES, |
| 1064 | MSR_AMD64_VIRT_SPEC_CTRL, | ||
| 1064 | }; | 1065 | }; |
| 1065 | 1066 | ||
| 1066 | static unsigned num_emulated_msrs; | 1067 | static unsigned num_emulated_msrs; |
| @@ -2906,7 +2907,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) | |||
| 2906 | * fringe case that is not enabled except via specific settings | 2907 | * fringe case that is not enabled except via specific settings |
| 2907 | * of the module parameters. | 2908 | * of the module parameters. |
| 2908 | */ | 2909 | */ |
| 2909 | r = kvm_x86_ops->cpu_has_high_real_mode_segbase(); | 2910 | r = kvm_x86_ops->has_emulated_msr(MSR_IA32_SMBASE); |
| 2910 | break; | 2911 | break; |
| 2911 | case KVM_CAP_VAPIC: | 2912 | case KVM_CAP_VAPIC: |
| 2912 | r = !kvm_x86_ops->cpu_has_accelerated_tpr(); | 2913 | r = !kvm_x86_ops->cpu_has_accelerated_tpr(); |
| @@ -4606,14 +4607,8 @@ static void kvm_init_msr_list(void) | |||
| 4606 | num_msrs_to_save = j; | 4607 | num_msrs_to_save = j; |
| 4607 | 4608 | ||
| 4608 | for (i = j = 0; i < ARRAY_SIZE(emulated_msrs); i++) { | 4609 | for (i = j = 0; i < ARRAY_SIZE(emulated_msrs); i++) { |
| 4609 | switch (emulated_msrs[i]) { | 4610 | if (!kvm_x86_ops->has_emulated_msr(emulated_msrs[i])) |
| 4610 | case MSR_IA32_SMBASE: | 4611 | continue; |
| 4611 | if (!kvm_x86_ops->cpu_has_high_real_mode_segbase()) | ||
| 4612 | continue; | ||
| 4613 | break; | ||
| 4614 | default: | ||
| 4615 | break; | ||
| 4616 | } | ||
| 4617 | 4612 | ||
| 4618 | if (j < i) | 4613 | if (j < i) |
| 4619 | emulated_msrs[j] = emulated_msrs[i]; | 4614 | emulated_msrs[j] = emulated_msrs[i]; |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 2da998baa75c..30cc9c877ebb 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
| @@ -534,14 +534,22 @@ ssize_t __weak cpu_show_spectre_v2(struct device *dev, | |||
| 534 | return sprintf(buf, "Not affected\n"); | 534 | return sprintf(buf, "Not affected\n"); |
| 535 | } | 535 | } |
| 536 | 536 | ||
| 537 | ssize_t __weak cpu_show_spec_store_bypass(struct device *dev, | ||
| 538 | struct device_attribute *attr, char *buf) | ||
| 539 | { | ||
| 540 | return sprintf(buf, "Not affected\n"); | ||
| 541 | } | ||
| 542 | |||
| 537 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); | 543 | static DEVICE_ATTR(meltdown, 0444, cpu_show_meltdown, NULL); |
| 538 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); | 544 | static DEVICE_ATTR(spectre_v1, 0444, cpu_show_spectre_v1, NULL); |
| 539 | static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); | 545 | static DEVICE_ATTR(spectre_v2, 0444, cpu_show_spectre_v2, NULL); |
| 546 | static DEVICE_ATTR(spec_store_bypass, 0444, cpu_show_spec_store_bypass, NULL); | ||
| 540 | 547 | ||
| 541 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { | 548 | static struct attribute *cpu_root_vulnerabilities_attrs[] = { |
| 542 | &dev_attr_meltdown.attr, | 549 | &dev_attr_meltdown.attr, |
| 543 | &dev_attr_spectre_v1.attr, | 550 | &dev_attr_spectre_v1.attr, |
| 544 | &dev_attr_spectre_v2.attr, | 551 | &dev_attr_spectre_v2.attr, |
| 552 | &dev_attr_spec_store_bypass.attr, | ||
| 545 | NULL | 553 | NULL |
| 546 | }; | 554 | }; |
| 547 | 555 | ||
diff --git a/fs/proc/array.c b/fs/proc/array.c index ae2c807fd719..72391b3f6927 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
| @@ -85,6 +85,7 @@ | |||
| 85 | #include <linux/delayacct.h> | 85 | #include <linux/delayacct.h> |
| 86 | #include <linux/seq_file.h> | 86 | #include <linux/seq_file.h> |
| 87 | #include <linux/pid_namespace.h> | 87 | #include <linux/pid_namespace.h> |
| 88 | #include <linux/prctl.h> | ||
| 88 | #include <linux/ptrace.h> | 89 | #include <linux/ptrace.h> |
| 89 | #include <linux/tracehook.h> | 90 | #include <linux/tracehook.h> |
| 90 | #include <linux/string_helpers.h> | 91 | #include <linux/string_helpers.h> |
| @@ -335,6 +336,30 @@ static inline void task_seccomp(struct seq_file *m, struct task_struct *p) | |||
| 335 | #ifdef CONFIG_SECCOMP | 336 | #ifdef CONFIG_SECCOMP |
| 336 | seq_put_decimal_ull(m, "\nSeccomp:\t", p->seccomp.mode); | 337 | seq_put_decimal_ull(m, "\nSeccomp:\t", p->seccomp.mode); |
| 337 | #endif | 338 | #endif |
| 339 | seq_printf(m, "\nSpeculation_Store_Bypass:\t"); | ||
| 340 | switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) { | ||
| 341 | case -EINVAL: | ||
| 342 | seq_printf(m, "unknown"); | ||
| 343 | break; | ||
| 344 | case PR_SPEC_NOT_AFFECTED: | ||
| 345 | seq_printf(m, "not vulnerable"); | ||
| 346 | break; | ||
| 347 | case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE: | ||
| 348 | seq_printf(m, "thread force mitigated"); | ||
| 349 | break; | ||
| 350 | case PR_SPEC_PRCTL | PR_SPEC_DISABLE: | ||
| 351 | seq_printf(m, "thread mitigated"); | ||
| 352 | break; | ||
| 353 | case PR_SPEC_PRCTL | PR_SPEC_ENABLE: | ||
| 354 | seq_printf(m, "thread vulnerable"); | ||
| 355 | break; | ||
| 356 | case PR_SPEC_DISABLE: | ||
| 357 | seq_printf(m, "globally mitigated"); | ||
| 358 | break; | ||
| 359 | default: | ||
| 360 | seq_printf(m, "vulnerable"); | ||
| 361 | break; | ||
| 362 | } | ||
| 338 | seq_putc(m, '\n'); | 363 | seq_putc(m, '\n'); |
| 339 | } | 364 | } |
| 340 | 365 | ||
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h index 7e61c395fddf..65cfc2f59db9 100644 --- a/include/linux/bpf_verifier.h +++ b/include/linux/bpf_verifier.h | |||
| @@ -146,6 +146,7 @@ struct bpf_insn_aux_data { | |||
| 146 | s32 call_imm; /* saved imm field of call insn */ | 146 | s32 call_imm; /* saved imm field of call insn */ |
| 147 | }; | 147 | }; |
| 148 | int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ | 148 | int ctx_field_size; /* the ctx field size for load insn, maybe 0 */ |
| 149 | int sanitize_stack_off; /* stack slot to be cleared */ | ||
| 149 | bool seen; /* this insn was processed by the verifier */ | 150 | bool seen; /* this insn was processed by the verifier */ |
| 150 | }; | 151 | }; |
| 151 | 152 | ||
diff --git a/include/linux/cpu.h b/include/linux/cpu.h index 7b01bc11c692..a97a63eef59f 100644 --- a/include/linux/cpu.h +++ b/include/linux/cpu.h | |||
| @@ -53,6 +53,8 @@ extern ssize_t cpu_show_spectre_v1(struct device *dev, | |||
| 53 | struct device_attribute *attr, char *buf); | 53 | struct device_attribute *attr, char *buf); |
| 54 | extern ssize_t cpu_show_spectre_v2(struct device *dev, | 54 | extern ssize_t cpu_show_spectre_v2(struct device *dev, |
| 55 | struct device_attribute *attr, char *buf); | 55 | struct device_attribute *attr, char *buf); |
| 56 | extern ssize_t cpu_show_spec_store_bypass(struct device *dev, | ||
| 57 | struct device_attribute *attr, char *buf); | ||
| 56 | 58 | ||
| 57 | extern __printf(4, 5) | 59 | extern __printf(4, 5) |
| 58 | struct device *cpu_device_create(struct device *parent, void *drvdata, | 60 | struct device *cpu_device_create(struct device *parent, void *drvdata, |
diff --git a/include/linux/nospec.h b/include/linux/nospec.h index e791ebc65c9c..0c5ef54fd416 100644 --- a/include/linux/nospec.h +++ b/include/linux/nospec.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #define _LINUX_NOSPEC_H | 7 | #define _LINUX_NOSPEC_H |
| 8 | #include <asm/barrier.h> | 8 | #include <asm/barrier.h> |
| 9 | 9 | ||
| 10 | struct task_struct; | ||
| 11 | |||
| 10 | /** | 12 | /** |
| 11 | * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise | 13 | * array_index_mask_nospec() - generate a ~0 mask when index < size, 0 otherwise |
| 12 | * @index: array element index | 14 | * @index: array element index |
| @@ -55,4 +57,12 @@ static inline unsigned long array_index_mask_nospec(unsigned long index, | |||
| 55 | \ | 57 | \ |
| 56 | (typeof(_i)) (_i & _mask); \ | 58 | (typeof(_i)) (_i & _mask); \ |
| 57 | }) | 59 | }) |
| 60 | |||
| 61 | /* Speculation control prctl */ | ||
| 62 | int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which); | ||
| 63 | int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which, | ||
| 64 | unsigned long ctrl); | ||
| 65 | /* Speculation control for seccomp enforced mitigation */ | ||
| 66 | void arch_seccomp_spec_mitigate(struct task_struct *task); | ||
| 67 | |||
| 58 | #endif /* _LINUX_NOSPEC_H */ | 68 | #endif /* _LINUX_NOSPEC_H */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index c2413703f45d..ca3f3eae8980 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
| @@ -1433,7 +1433,8 @@ static inline bool is_percpu_thread(void) | |||
| 1433 | #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ | 1433 | #define PFA_NO_NEW_PRIVS 0 /* May not gain new privileges. */ |
| 1434 | #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ | 1434 | #define PFA_SPREAD_PAGE 1 /* Spread page cache over cpuset */ |
| 1435 | #define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */ | 1435 | #define PFA_SPREAD_SLAB 2 /* Spread some slab caches over cpuset */ |
| 1436 | 1436 | #define PFA_SPEC_SSB_DISABLE 3 /* Speculative Store Bypass disabled */ | |
| 1437 | #define PFA_SPEC_SSB_FORCE_DISABLE 4 /* Speculative Store Bypass force disabled*/ | ||
| 1437 | 1438 | ||
| 1438 | #define TASK_PFA_TEST(name, func) \ | 1439 | #define TASK_PFA_TEST(name, func) \ |
| 1439 | static inline bool task_##func(struct task_struct *p) \ | 1440 | static inline bool task_##func(struct task_struct *p) \ |
| @@ -1458,6 +1459,13 @@ TASK_PFA_TEST(SPREAD_SLAB, spread_slab) | |||
| 1458 | TASK_PFA_SET(SPREAD_SLAB, spread_slab) | 1459 | TASK_PFA_SET(SPREAD_SLAB, spread_slab) |
| 1459 | TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) | 1460 | TASK_PFA_CLEAR(SPREAD_SLAB, spread_slab) |
| 1460 | 1461 | ||
| 1462 | TASK_PFA_TEST(SPEC_SSB_DISABLE, spec_ssb_disable) | ||
| 1463 | TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable) | ||
| 1464 | TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable) | ||
| 1465 | |||
| 1466 | TASK_PFA_TEST(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable) | ||
| 1467 | TASK_PFA_SET(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable) | ||
| 1468 | |||
| 1461 | static inline void | 1469 | static inline void |
| 1462 | current_restore_flags(unsigned long orig_flags, unsigned long flags) | 1470 | current_restore_flags(unsigned long orig_flags, unsigned long flags) |
| 1463 | { | 1471 | { |
diff --git a/include/linux/seccomp.h b/include/linux/seccomp.h index c723a5c4e3ff..e5320f6c8654 100644 --- a/include/linux/seccomp.h +++ b/include/linux/seccomp.h | |||
| @@ -4,8 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #include <uapi/linux/seccomp.h> | 5 | #include <uapi/linux/seccomp.h> |
| 6 | 6 | ||
| 7 | #define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC | \ | 7 | #define SECCOMP_FILTER_FLAG_MASK (SECCOMP_FILTER_FLAG_TSYNC | \ |
| 8 | SECCOMP_FILTER_FLAG_LOG) | 8 | SECCOMP_FILTER_FLAG_LOG | \ |
| 9 | SECCOMP_FILTER_FLAG_SPEC_ALLOW) | ||
| 9 | 10 | ||
| 10 | #ifdef CONFIG_SECCOMP | 11 | #ifdef CONFIG_SECCOMP |
| 11 | 12 | ||
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h index af5f8c2df87a..db9f15f5db04 100644 --- a/include/uapi/linux/prctl.h +++ b/include/uapi/linux/prctl.h | |||
| @@ -207,4 +207,16 @@ struct prctl_mm_map { | |||
| 207 | # define PR_SVE_VL_LEN_MASK 0xffff | 207 | # define PR_SVE_VL_LEN_MASK 0xffff |
| 208 | # define PR_SVE_VL_INHERIT (1 << 17) /* inherit across exec */ | 208 | # define PR_SVE_VL_INHERIT (1 << 17) /* inherit across exec */ |
| 209 | 209 | ||
| 210 | /* Per task speculation control */ | ||
| 211 | #define PR_GET_SPECULATION_CTRL 52 | ||
| 212 | #define PR_SET_SPECULATION_CTRL 53 | ||
| 213 | /* Speculation control variants */ | ||
| 214 | # define PR_SPEC_STORE_BYPASS 0 | ||
| 215 | /* Return and control values for PR_SET/GET_SPECULATION_CTRL */ | ||
| 216 | # define PR_SPEC_NOT_AFFECTED 0 | ||
| 217 | # define PR_SPEC_PRCTL (1UL << 0) | ||
| 218 | # define PR_SPEC_ENABLE (1UL << 1) | ||
| 219 | # define PR_SPEC_DISABLE (1UL << 2) | ||
| 220 | # define PR_SPEC_FORCE_DISABLE (1UL << 3) | ||
| 221 | |||
| 210 | #endif /* _LINUX_PRCTL_H */ | 222 | #endif /* _LINUX_PRCTL_H */ |
diff --git a/include/uapi/linux/seccomp.h b/include/uapi/linux/seccomp.h index 2a0bd9dd104d..9efc0e73d50b 100644 --- a/include/uapi/linux/seccomp.h +++ b/include/uapi/linux/seccomp.h | |||
| @@ -17,8 +17,9 @@ | |||
| 17 | #define SECCOMP_GET_ACTION_AVAIL 2 | 17 | #define SECCOMP_GET_ACTION_AVAIL 2 |
| 18 | 18 | ||
| 19 | /* Valid flags for SECCOMP_SET_MODE_FILTER */ | 19 | /* Valid flags for SECCOMP_SET_MODE_FILTER */ |
| 20 | #define SECCOMP_FILTER_FLAG_TSYNC 1 | 20 | #define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) |
| 21 | #define SECCOMP_FILTER_FLAG_LOG 2 | 21 | #define SECCOMP_FILTER_FLAG_LOG (1UL << 1) |
| 22 | #define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) | ||
| 22 | 23 | ||
| 23 | /* | 24 | /* |
| 24 | * All BPF programs must return a 32-bit value. | 25 | * All BPF programs must return a 32-bit value. |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 5dd1dcb902bf..2ce967a63ede 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -978,7 +978,7 @@ static bool register_is_null(struct bpf_reg_state *reg) | |||
| 978 | */ | 978 | */ |
| 979 | static int check_stack_write(struct bpf_verifier_env *env, | 979 | static int check_stack_write(struct bpf_verifier_env *env, |
| 980 | struct bpf_func_state *state, /* func where register points to */ | 980 | struct bpf_func_state *state, /* func where register points to */ |
| 981 | int off, int size, int value_regno) | 981 | int off, int size, int value_regno, int insn_idx) |
| 982 | { | 982 | { |
| 983 | struct bpf_func_state *cur; /* state of the current function */ | 983 | struct bpf_func_state *cur; /* state of the current function */ |
| 984 | int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err; | 984 | int i, slot = -off - 1, spi = slot / BPF_REG_SIZE, err; |
| @@ -1017,8 +1017,33 @@ static int check_stack_write(struct bpf_verifier_env *env, | |||
| 1017 | state->stack[spi].spilled_ptr = cur->regs[value_regno]; | 1017 | state->stack[spi].spilled_ptr = cur->regs[value_regno]; |
| 1018 | state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN; | 1018 | state->stack[spi].spilled_ptr.live |= REG_LIVE_WRITTEN; |
| 1019 | 1019 | ||
| 1020 | for (i = 0; i < BPF_REG_SIZE; i++) | 1020 | for (i = 0; i < BPF_REG_SIZE; i++) { |
| 1021 | if (state->stack[spi].slot_type[i] == STACK_MISC && | ||
| 1022 | !env->allow_ptr_leaks) { | ||
| 1023 | int *poff = &env->insn_aux_data[insn_idx].sanitize_stack_off; | ||
| 1024 | int soff = (-spi - 1) * BPF_REG_SIZE; | ||
| 1025 | |||
| 1026 | /* detected reuse of integer stack slot with a pointer | ||
| 1027 | * which means either llvm is reusing stack slot or | ||
| 1028 | * an attacker is trying to exploit CVE-2018-3639 | ||
| 1029 | * (speculative store bypass) | ||
| 1030 | * Have to sanitize that slot with preemptive | ||
| 1031 | * store of zero. | ||
| 1032 | */ | ||
| 1033 | if (*poff && *poff != soff) { | ||
| 1034 | /* disallow programs where single insn stores | ||
| 1035 | * into two different stack slots, since verifier | ||
| 1036 | * cannot sanitize them | ||
| 1037 | */ | ||
| 1038 | verbose(env, | ||
| 1039 | "insn %d cannot access two stack slots fp%d and fp%d", | ||
| 1040 | insn_idx, *poff, soff); | ||
| 1041 | return -EINVAL; | ||
| 1042 | } | ||
| 1043 | *poff = soff; | ||
| 1044 | } | ||
| 1021 | state->stack[spi].slot_type[i] = STACK_SPILL; | 1045 | state->stack[spi].slot_type[i] = STACK_SPILL; |
| 1046 | } | ||
| 1022 | } else { | 1047 | } else { |
| 1023 | u8 type = STACK_MISC; | 1048 | u8 type = STACK_MISC; |
| 1024 | 1049 | ||
| @@ -1694,7 +1719,7 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn | |||
| 1694 | 1719 | ||
| 1695 | if (t == BPF_WRITE) | 1720 | if (t == BPF_WRITE) |
| 1696 | err = check_stack_write(env, state, off, size, | 1721 | err = check_stack_write(env, state, off, size, |
| 1697 | value_regno); | 1722 | value_regno, insn_idx); |
| 1698 | else | 1723 | else |
| 1699 | err = check_stack_read(env, state, off, size, | 1724 | err = check_stack_read(env, state, off, size, |
| 1700 | value_regno); | 1725 | value_regno); |
| @@ -5169,6 +5194,34 @@ static int convert_ctx_accesses(struct bpf_verifier_env *env) | |||
| 5169 | else | 5194 | else |
| 5170 | continue; | 5195 | continue; |
| 5171 | 5196 | ||
| 5197 | if (type == BPF_WRITE && | ||
| 5198 | env->insn_aux_data[i + delta].sanitize_stack_off) { | ||
| 5199 | struct bpf_insn patch[] = { | ||
| 5200 | /* Sanitize suspicious stack slot with zero. | ||
| 5201 | * There are no memory dependencies for this store, | ||
| 5202 | * since it's only using frame pointer and immediate | ||
| 5203 | * constant of zero | ||
| 5204 | */ | ||
| 5205 | BPF_ST_MEM(BPF_DW, BPF_REG_FP, | ||
| 5206 | env->insn_aux_data[i + delta].sanitize_stack_off, | ||
| 5207 | 0), | ||
| 5208 | /* the original STX instruction will immediately | ||
| 5209 | * overwrite the same stack slot with appropriate value | ||
| 5210 | */ | ||
| 5211 | *insn, | ||
| 5212 | }; | ||
| 5213 | |||
| 5214 | cnt = ARRAY_SIZE(patch); | ||
| 5215 | new_prog = bpf_patch_insn_data(env, i + delta, patch, cnt); | ||
| 5216 | if (!new_prog) | ||
| 5217 | return -ENOMEM; | ||
| 5218 | |||
| 5219 | delta += cnt - 1; | ||
| 5220 | env->prog = new_prog; | ||
| 5221 | insn = new_prog->insnsi + i + delta; | ||
| 5222 | continue; | ||
| 5223 | } | ||
| 5224 | |||
| 5172 | if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX) | 5225 | if (env->insn_aux_data[i + delta].ptr_type != PTR_TO_CTX) |
| 5173 | continue; | 5226 | continue; |
| 5174 | 5227 | ||
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index dc77548167ef..e691d9a6c58d 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | #include <linux/compat.h> | 19 | #include <linux/compat.h> |
| 20 | #include <linux/coredump.h> | 20 | #include <linux/coredump.h> |
| 21 | #include <linux/kmemleak.h> | 21 | #include <linux/kmemleak.h> |
| 22 | #include <linux/nospec.h> | ||
| 23 | #include <linux/prctl.h> | ||
| 22 | #include <linux/sched.h> | 24 | #include <linux/sched.h> |
| 23 | #include <linux/sched/task_stack.h> | 25 | #include <linux/sched/task_stack.h> |
| 24 | #include <linux/seccomp.h> | 26 | #include <linux/seccomp.h> |
| @@ -227,8 +229,11 @@ static inline bool seccomp_may_assign_mode(unsigned long seccomp_mode) | |||
| 227 | return true; | 229 | return true; |
| 228 | } | 230 | } |
| 229 | 231 | ||
| 232 | void __weak arch_seccomp_spec_mitigate(struct task_struct *task) { } | ||
| 233 | |||
| 230 | static inline void seccomp_assign_mode(struct task_struct *task, | 234 | static inline void seccomp_assign_mode(struct task_struct *task, |
| 231 | unsigned long seccomp_mode) | 235 | unsigned long seccomp_mode, |
| 236 | unsigned long flags) | ||
| 232 | { | 237 | { |
| 233 | assert_spin_locked(&task->sighand->siglock); | 238 | assert_spin_locked(&task->sighand->siglock); |
| 234 | 239 | ||
| @@ -238,6 +243,9 @@ static inline void seccomp_assign_mode(struct task_struct *task, | |||
| 238 | * filter) is set. | 243 | * filter) is set. |
| 239 | */ | 244 | */ |
| 240 | smp_mb__before_atomic(); | 245 | smp_mb__before_atomic(); |
| 246 | /* Assume default seccomp processes want spec flaw mitigation. */ | ||
| 247 | if ((flags & SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 0) | ||
| 248 | arch_seccomp_spec_mitigate(task); | ||
| 241 | set_tsk_thread_flag(task, TIF_SECCOMP); | 249 | set_tsk_thread_flag(task, TIF_SECCOMP); |
| 242 | } | 250 | } |
| 243 | 251 | ||
| @@ -305,7 +313,7 @@ static inline pid_t seccomp_can_sync_threads(void) | |||
| 305 | * without dropping the locks. | 313 | * without dropping the locks. |
| 306 | * | 314 | * |
| 307 | */ | 315 | */ |
| 308 | static inline void seccomp_sync_threads(void) | 316 | static inline void seccomp_sync_threads(unsigned long flags) |
| 309 | { | 317 | { |
| 310 | struct task_struct *thread, *caller; | 318 | struct task_struct *thread, *caller; |
| 311 | 319 | ||
| @@ -346,7 +354,8 @@ static inline void seccomp_sync_threads(void) | |||
| 346 | * allow one thread to transition the other. | 354 | * allow one thread to transition the other. |
| 347 | */ | 355 | */ |
| 348 | if (thread->seccomp.mode == SECCOMP_MODE_DISABLED) | 356 | if (thread->seccomp.mode == SECCOMP_MODE_DISABLED) |
| 349 | seccomp_assign_mode(thread, SECCOMP_MODE_FILTER); | 357 | seccomp_assign_mode(thread, SECCOMP_MODE_FILTER, |
| 358 | flags); | ||
| 350 | } | 359 | } |
| 351 | } | 360 | } |
| 352 | 361 | ||
| @@ -469,7 +478,7 @@ static long seccomp_attach_filter(unsigned int flags, | |||
| 469 | 478 | ||
| 470 | /* Now that the new filter is in place, synchronize to all threads. */ | 479 | /* Now that the new filter is in place, synchronize to all threads. */ |
| 471 | if (flags & SECCOMP_FILTER_FLAG_TSYNC) | 480 | if (flags & SECCOMP_FILTER_FLAG_TSYNC) |
| 472 | seccomp_sync_threads(); | 481 | seccomp_sync_threads(flags); |
| 473 | 482 | ||
| 474 | return 0; | 483 | return 0; |
| 475 | } | 484 | } |
| @@ -818,7 +827,7 @@ static long seccomp_set_mode_strict(void) | |||
| 818 | #ifdef TIF_NOTSC | 827 | #ifdef TIF_NOTSC |
| 819 | disable_TSC(); | 828 | disable_TSC(); |
| 820 | #endif | 829 | #endif |
| 821 | seccomp_assign_mode(current, seccomp_mode); | 830 | seccomp_assign_mode(current, seccomp_mode, 0); |
| 822 | ret = 0; | 831 | ret = 0; |
| 823 | 832 | ||
| 824 | out: | 833 | out: |
| @@ -876,7 +885,7 @@ static long seccomp_set_mode_filter(unsigned int flags, | |||
| 876 | /* Do not free the successfully attached filter. */ | 885 | /* Do not free the successfully attached filter. */ |
| 877 | prepared = NULL; | 886 | prepared = NULL; |
| 878 | 887 | ||
| 879 | seccomp_assign_mode(current, seccomp_mode); | 888 | seccomp_assign_mode(current, seccomp_mode, flags); |
| 880 | out: | 889 | out: |
| 881 | spin_unlock_irq(¤t->sighand->siglock); | 890 | spin_unlock_irq(¤t->sighand->siglock); |
| 882 | if (flags & SECCOMP_FILTER_FLAG_TSYNC) | 891 | if (flags & SECCOMP_FILTER_FLAG_TSYNC) |
diff --git a/kernel/sys.c b/kernel/sys.c index ad692183dfe9..b0eee418ee0d 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
| @@ -61,6 +61,8 @@ | |||
| 61 | #include <linux/uidgid.h> | 61 | #include <linux/uidgid.h> |
| 62 | #include <linux/cred.h> | 62 | #include <linux/cred.h> |
| 63 | 63 | ||
| 64 | #include <linux/nospec.h> | ||
| 65 | |||
| 64 | #include <linux/kmsg_dump.h> | 66 | #include <linux/kmsg_dump.h> |
| 65 | /* Move somewhere else to avoid recompiling? */ | 67 | /* Move somewhere else to avoid recompiling? */ |
| 66 | #include <generated/utsrelease.h> | 68 | #include <generated/utsrelease.h> |
| @@ -2242,6 +2244,17 @@ static int propagate_has_child_subreaper(struct task_struct *p, void *data) | |||
| 2242 | return 1; | 2244 | return 1; |
| 2243 | } | 2245 | } |
| 2244 | 2246 | ||
| 2247 | int __weak arch_prctl_spec_ctrl_get(struct task_struct *t, unsigned long which) | ||
| 2248 | { | ||
| 2249 | return -EINVAL; | ||
| 2250 | } | ||
| 2251 | |||
| 2252 | int __weak arch_prctl_spec_ctrl_set(struct task_struct *t, unsigned long which, | ||
| 2253 | unsigned long ctrl) | ||
| 2254 | { | ||
| 2255 | return -EINVAL; | ||
| 2256 | } | ||
| 2257 | |||
| 2245 | SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | 2258 | SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, |
| 2246 | unsigned long, arg4, unsigned long, arg5) | 2259 | unsigned long, arg4, unsigned long, arg5) |
| 2247 | { | 2260 | { |
| @@ -2450,6 +2463,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
| 2450 | case PR_SVE_GET_VL: | 2463 | case PR_SVE_GET_VL: |
| 2451 | error = SVE_GET_VL(); | 2464 | error = SVE_GET_VL(); |
| 2452 | break; | 2465 | break; |
| 2466 | case PR_GET_SPECULATION_CTRL: | ||
| 2467 | if (arg3 || arg4 || arg5) | ||
| 2468 | return -EINVAL; | ||
| 2469 | error = arch_prctl_spec_ctrl_get(me, arg2); | ||
| 2470 | break; | ||
| 2471 | case PR_SET_SPECULATION_CTRL: | ||
| 2472 | if (arg4 || arg5) | ||
| 2473 | return -EINVAL; | ||
| 2474 | error = arch_prctl_spec_ctrl_set(me, arg2, arg3); | ||
| 2475 | break; | ||
| 2453 | default: | 2476 | default: |
| 2454 | error = -EINVAL; | 2477 | error = -EINVAL; |
| 2455 | break; | 2478 | break; |
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 168c66d74fc5..e1473234968d 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c | |||
| @@ -134,11 +134,15 @@ struct seccomp_data { | |||
| 134 | #endif | 134 | #endif |
| 135 | 135 | ||
| 136 | #ifndef SECCOMP_FILTER_FLAG_TSYNC | 136 | #ifndef SECCOMP_FILTER_FLAG_TSYNC |
| 137 | #define SECCOMP_FILTER_FLAG_TSYNC 1 | 137 | #define SECCOMP_FILTER_FLAG_TSYNC (1UL << 0) |
| 138 | #endif | 138 | #endif |
| 139 | 139 | ||
| 140 | #ifndef SECCOMP_FILTER_FLAG_LOG | 140 | #ifndef SECCOMP_FILTER_FLAG_LOG |
| 141 | #define SECCOMP_FILTER_FLAG_LOG 2 | 141 | #define SECCOMP_FILTER_FLAG_LOG (1UL << 1) |
| 142 | #endif | ||
| 143 | |||
| 144 | #ifndef SECCOMP_FILTER_FLAG_SPEC_ALLOW | ||
| 145 | #define SECCOMP_FILTER_FLAG_SPEC_ALLOW (1UL << 2) | ||
| 142 | #endif | 146 | #endif |
| 143 | 147 | ||
| 144 | #ifndef PTRACE_SECCOMP_GET_METADATA | 148 | #ifndef PTRACE_SECCOMP_GET_METADATA |
| @@ -2072,14 +2076,26 @@ TEST(seccomp_syscall_mode_lock) | |||
| 2072 | TEST(detect_seccomp_filter_flags) | 2076 | TEST(detect_seccomp_filter_flags) |
| 2073 | { | 2077 | { |
| 2074 | unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC, | 2078 | unsigned int flags[] = { SECCOMP_FILTER_FLAG_TSYNC, |
| 2075 | SECCOMP_FILTER_FLAG_LOG }; | 2079 | SECCOMP_FILTER_FLAG_LOG, |
| 2080 | SECCOMP_FILTER_FLAG_SPEC_ALLOW }; | ||
| 2076 | unsigned int flag, all_flags; | 2081 | unsigned int flag, all_flags; |
| 2077 | int i; | 2082 | int i; |
| 2078 | long ret; | 2083 | long ret; |
| 2079 | 2084 | ||
| 2080 | /* Test detection of known-good filter flags */ | 2085 | /* Test detection of known-good filter flags */ |
| 2081 | for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) { | 2086 | for (i = 0, all_flags = 0; i < ARRAY_SIZE(flags); i++) { |
| 2087 | int bits = 0; | ||
| 2088 | |||
| 2082 | flag = flags[i]; | 2089 | flag = flags[i]; |
| 2090 | /* Make sure the flag is a single bit! */ | ||
| 2091 | while (flag) { | ||
| 2092 | if (flag & 0x1) | ||
| 2093 | bits ++; | ||
| 2094 | flag >>= 1; | ||
| 2095 | } | ||
| 2096 | ASSERT_EQ(1, bits); | ||
| 2097 | flag = flags[i]; | ||
| 2098 | |||
| 2083 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); | 2099 | ret = seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL); |
| 2084 | ASSERT_NE(ENOSYS, errno) { | 2100 | ASSERT_NE(ENOSYS, errno) { |
| 2085 | TH_LOG("Kernel does not support seccomp syscall!"); | 2101 | TH_LOG("Kernel does not support seccomp syscall!"); |
