Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86/pti update from Thomas Gleixner:
"Just a single change from the anti-performance departement:

- Add a new PR_SPEC_DISABLE_NOEXEC option which allows to apply the
speculation protections on a process without inheriting the state
on exec.

This remedies a situation where a Java-launcher has speculation
protections enabled because that's the default for JVMs which
causes the launched regular harmless processes to inherit the
protection state which results in unintended performance
degradation"

* 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/speculation: Add PR_SPEC_DISABLE_NOEXEC

+46 -12
+15 -12
Documentation/userspace-api/spec_ctrl.rst
··· 28 28 which is selected with arg2 of prctl(2). The return value uses bits 0-3 with 29 29 the following meaning: 30 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 - ==== ===================== =================================================== 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 + 4 PR_SPEC_DISABLE_NOEXEC Same as PR_SPEC_DISABLE, but the state will be 43 + cleared on :manpage:`execve(2)`. 44 + ==== ====================== ================================================== 43 45 44 46 If all bits are 0 the CPU is not affected by the speculation misfeature. 45 47 ··· 94 92 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0); 95 93 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0); 96 94 * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_FORCE_DISABLE, 0, 0); 95 + * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE_NOEXEC, 0, 0); 97 96 98 97 - PR_SPEC_INDIR_BRANCH: Indirect Branch Speculation in User Processes 99 98 (Mitigate Spectre V2 style attacks against user processes)
+12
arch/x86/kernel/cpu/bugs.c
··· 798 798 if (task_spec_ssb_force_disable(task)) 799 799 return -EPERM; 800 800 task_clear_spec_ssb_disable(task); 801 + task_clear_spec_ssb_noexec(task); 801 802 task_update_spec_tif(task); 802 803 break; 803 804 case PR_SPEC_DISABLE: 804 805 task_set_spec_ssb_disable(task); 806 + task_clear_spec_ssb_noexec(task); 805 807 task_update_spec_tif(task); 806 808 break; 807 809 case PR_SPEC_FORCE_DISABLE: 808 810 task_set_spec_ssb_disable(task); 809 811 task_set_spec_ssb_force_disable(task); 812 + task_clear_spec_ssb_noexec(task); 813 + task_update_spec_tif(task); 814 + break; 815 + case PR_SPEC_DISABLE_NOEXEC: 816 + if (task_spec_ssb_force_disable(task)) 817 + return -EPERM; 818 + task_set_spec_ssb_disable(task); 819 + task_set_spec_ssb_noexec(task); 810 820 task_update_spec_tif(task); 811 821 break; 812 822 default: ··· 895 885 case SPEC_STORE_BYPASS_PRCTL: 896 886 if (task_spec_ssb_force_disable(task)) 897 887 return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE; 888 + if (task_spec_ssb_noexec(task)) 889 + return PR_SPEC_PRCTL | PR_SPEC_DISABLE_NOEXEC; 898 890 if (task_spec_ssb_disable(task)) 899 891 return PR_SPEC_PRCTL | PR_SPEC_DISABLE; 900 892 return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
+12
arch/x86/kernel/process.c
··· 255 255 /* If cpuid was previously disabled for this task, re-enable it. */ 256 256 if (test_thread_flag(TIF_NOCPUID)) 257 257 enable_cpuid(); 258 + 259 + /* 260 + * Don't inherit TIF_SSBD across exec boundary when 261 + * PR_SPEC_DISABLE_NOEXEC is used. 262 + */ 263 + if (test_thread_flag(TIF_SSBD) && 264 + task_spec_ssb_noexec(current)) { 265 + clear_thread_flag(TIF_SSBD); 266 + task_clear_spec_ssb_disable(current); 267 + task_clear_spec_ssb_noexec(current); 268 + speculation_ctrl_update(task_thread_info(current)->flags); 269 + } 258 270 } 259 271 260 272 static inline void switch_to_bitmap(struct thread_struct *prev,
+5
include/linux/sched.h
··· 1453 1453 #define PFA_SPEC_SSB_FORCE_DISABLE 4 /* Speculative Store Bypass force disabled*/ 1454 1454 #define PFA_SPEC_IB_DISABLE 5 /* Indirect branch speculation restricted */ 1455 1455 #define PFA_SPEC_IB_FORCE_DISABLE 6 /* Indirect branch speculation permanently restricted */ 1456 + #define PFA_SPEC_SSB_NOEXEC 7 /* Speculative Store Bypass clear on execve() */ 1456 1457 1457 1458 #define TASK_PFA_TEST(name, func) \ 1458 1459 static inline bool task_##func(struct task_struct *p) \ ··· 1481 1480 TASK_PFA_TEST(SPEC_SSB_DISABLE, spec_ssb_disable) 1482 1481 TASK_PFA_SET(SPEC_SSB_DISABLE, spec_ssb_disable) 1483 1482 TASK_PFA_CLEAR(SPEC_SSB_DISABLE, spec_ssb_disable) 1483 + 1484 + TASK_PFA_TEST(SPEC_SSB_NOEXEC, spec_ssb_noexec) 1485 + TASK_PFA_SET(SPEC_SSB_NOEXEC, spec_ssb_noexec) 1486 + TASK_PFA_CLEAR(SPEC_SSB_NOEXEC, spec_ssb_noexec) 1484 1487 1485 1488 TASK_PFA_TEST(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable) 1486 1489 TASK_PFA_SET(SPEC_SSB_FORCE_DISABLE, spec_ssb_force_disable)
+1
include/uapi/linux/prctl.h
··· 219 219 # define PR_SPEC_ENABLE (1UL << 1) 220 220 # define PR_SPEC_DISABLE (1UL << 2) 221 221 # define PR_SPEC_FORCE_DISABLE (1UL << 3) 222 + # define PR_SPEC_DISABLE_NOEXEC (1UL << 4) 222 223 223 224 /* Reset arm64 pointer authentication keys */ 224 225 #define PR_PAC_RESET_KEYS 54
+1
tools/include/uapi/linux/prctl.h
··· 219 219 # define PR_SPEC_ENABLE (1UL << 1) 220 220 # define PR_SPEC_DISABLE (1UL << 2) 221 221 # define PR_SPEC_FORCE_DISABLE (1UL << 3) 222 + # define PR_SPEC_DISABLE_NOEXEC (1UL << 4) 222 223 223 224 /* Reset arm64 pointer authentication keys */ 224 225 #define PR_PAC_RESET_KEYS 54