x86/mm: Use WRITE_ONCE() when setting PTEs
[linux/fpc-iii.git] / arch / arm64 / kernel / ssbd.c
blob0560738c1d5ccad415d1f50d2ffec56ba7e9ff08
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3 * Copyright (C) 2018 ARM Ltd, All Rights Reserved.
4 */
6 #include <linux/errno.h>
7 #include <linux/prctl.h>
8 #include <linux/sched.h>
9 #include <linux/thread_info.h>
11 #include <asm/cpufeature.h>
14 * prctl interface for SSBD
16 static int ssbd_prctl_set(struct task_struct *task, unsigned long ctrl)
18 int state = arm64_get_ssbd_state();
20 /* Unsupported */
21 if (state == ARM64_SSBD_UNKNOWN)
22 return -EINVAL;
24 /* Treat the unaffected/mitigated state separately */
25 if (state == ARM64_SSBD_MITIGATED) {
26 switch (ctrl) {
27 case PR_SPEC_ENABLE:
28 return -EPERM;
29 case PR_SPEC_DISABLE:
30 case PR_SPEC_FORCE_DISABLE:
31 return 0;
36 * Things are a bit backward here: the arm64 internal API
37 * *enables the mitigation* when the userspace API *disables
38 * speculation*. So much fun.
40 switch (ctrl) {
41 case PR_SPEC_ENABLE:
42 /* If speculation is force disabled, enable is not allowed */
43 if (state == ARM64_SSBD_FORCE_ENABLE ||
44 task_spec_ssb_force_disable(task))
45 return -EPERM;
46 task_clear_spec_ssb_disable(task);
47 clear_tsk_thread_flag(task, TIF_SSBD);
48 break;
49 case PR_SPEC_DISABLE:
50 if (state == ARM64_SSBD_FORCE_DISABLE)
51 return -EPERM;
52 task_set_spec_ssb_disable(task);
53 set_tsk_thread_flag(task, TIF_SSBD);
54 break;
55 case PR_SPEC_FORCE_DISABLE:
56 if (state == ARM64_SSBD_FORCE_DISABLE)
57 return -EPERM;
58 task_set_spec_ssb_disable(task);
59 task_set_spec_ssb_force_disable(task);
60 set_tsk_thread_flag(task, TIF_SSBD);
61 break;
62 default:
63 return -ERANGE;
66 return 0;
69 int arch_prctl_spec_ctrl_set(struct task_struct *task, unsigned long which,
70 unsigned long ctrl)
72 switch (which) {
73 case PR_SPEC_STORE_BYPASS:
74 return ssbd_prctl_set(task, ctrl);
75 default:
76 return -ENODEV;
80 static int ssbd_prctl_get(struct task_struct *task)
82 switch (arm64_get_ssbd_state()) {
83 case ARM64_SSBD_UNKNOWN:
84 return -EINVAL;
85 case ARM64_SSBD_FORCE_ENABLE:
86 return PR_SPEC_DISABLE;
87 case ARM64_SSBD_KERNEL:
88 if (task_spec_ssb_force_disable(task))
89 return PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE;
90 if (task_spec_ssb_disable(task))
91 return PR_SPEC_PRCTL | PR_SPEC_DISABLE;
92 return PR_SPEC_PRCTL | PR_SPEC_ENABLE;
93 case ARM64_SSBD_FORCE_DISABLE:
94 return PR_SPEC_ENABLE;
95 default:
96 return PR_SPEC_NOT_AFFECTED;
100 int arch_prctl_spec_ctrl_get(struct task_struct *task, unsigned long which)
102 switch (which) {
103 case PR_SPEC_STORE_BYPASS:
104 return ssbd_prctl_get(task);
105 default:
106 return -ENODEV;