This source file includes following definitions.
- ssbd_ssbs_enable
- ssbd_ssbs_disable
- ssbd_prctl_set
- arch_prctl_spec_ctrl_set
- ssbd_prctl_get
- arch_prctl_spec_ctrl_get
1
2
3
4
5
6 #include <linux/compat.h>
7 #include <linux/errno.h>
8 #include <linux/prctl.h>
9 #include <linux/sched.h>
10 #include <linux/sched/task_stack.h>
11 #include <linux/thread_info.h>
12
13 #include <asm/cpufeature.h>
14
15 static void ssbd_ssbs_enable(struct task_struct *task)
16 {
17 u64 val = is_compat_thread(task_thread_info(task)) ?
18 PSR_AA32_SSBS_BIT : PSR_SSBS_BIT;
19
20 task_pt_regs(task)->pstate |= val;
21 }
22
23 static void ssbd_ssbs_disable(struct task_struct *task)
24 {
25 u64 val = is_compat_thread(task_thread_info(task)) ?
26 PSR_AA32_SSBS_BIT : PSR_SSBS_BIT;
27
28 task_pt_regs(task)->pstate &= ~val;
29 }
30
31
32
33
34 static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
35 {
36 int state = arm64_get_ssbd_state();
37
38
39 if (state == ARM64_SSBD_UNKNOWN)
40 return -EINVAL;
41
42
43 if (state == ARM64_SSBD_MITIGATED) {
44 switch (ctrl) {
45 case PR_SPEC_ENABLE:
46 return -EPERM;
47 case PR_SPEC_DISABLE:
48 case PR_SPEC_FORCE_DISABLE:
49 return 0;
50 }
51 }
52
53
54
55
56
57
58 switch (ctrl) {
59 case PR_SPEC_ENABLE:
60
61 if (state == ARM64_SSBD_FORCE_ENABLE ||
62 task_spec_ssb_force_disable(task))
63 return -EPERM;
64 task_clear_spec_ssb_disable(task);
65 clear_tsk_thread_flag(task, TIF_SSBD);
66 ssbd_ssbs_enable(task);
67 break;
68 case PR_SPEC_DISABLE:
69 if (state == ARM64_SSBD_FORCE_DISABLE)
70 return -EPERM;
71 task_set_spec_ssb_disable(task);
72 set_tsk_thread_flag(task, TIF_SSBD);
73 ssbd_ssbs_disable(task);
74 break;
75 case PR_SPEC_FORCE_DISABLE:
76 if (state == ARM64_SSBD_FORCE_DISABLE)
77 return -EPERM;
78 task_set_spec_ssb_disable(task);
79 task_set_spec_ssb_force_disable(task);
80 set_tsk_thread_flag(task, TIF_SSBD);
81 ssbd_ssbs_disable(task);
82 break;
83 default:
84 return -ERANGE;
85 }
86
87 return 0;
88 }
89
90 int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
91 unsigned long ctrl)
92 {
93 switch (which) {
94 case PR_SPEC_STORE_BYPASS:
95 return ssbd_prctl_set(task, ctrl);
96 default:
97 return -ENODEV;
98 }
99 }
100
101 static int ssbd_prctl_get(struct task_struct *task)
102 {
103 switch (arm64_get_ssbd_state()) {
104 case ARM64_SSBD_UNKNOWN:
105 return -EINVAL;
106 case ARM64_SSBD_FORCE_ENABLE:
107 return PR_SPEC_DISABLE;
108 case ARM64_SSBD_KERNEL:
109 if (task_spec_ssb_force_disable(task))
110 return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
111 if (task_spec_ssb_disable(task))
112 return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
113 return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
114 case ARM64_SSBD_FORCE_DISABLE:
115 return PR_SPEC_ENABLE;
116 default:
117 return PR_SPEC_NOT_AFFECTED;
118 }
119 }
120
121 int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
122 {
123 switch (which) {
124 case PR_SPEC_STORE_BYPASS:
125 return ssbd_prctl_get(task);
126 default:
127 return -ENODEV;
128 }
129 }