aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-04-29 09:20:11 -0400
committerThomas Gleixner <tglx@linutronix.de>2018-05-03 07:55:50 -0400
commitb617cfc858161140d69cc0b5cc211996b557a1c7 (patch)
tree64803e15cb79a0d535504ea9b873b7846f614c58 /kernel
parent28a2775217b17208811fa43a9e96bd1fdf417b86 (diff)
prctl: Add speculation control prctls
Add two new prctls to control aspects of speculation related vulnerabilites and their mitigations to provide finer grained control over performance impacting mitigations. PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature which is selected with arg2 of prctl(2). The return value uses bit 0-2 with the following meaning: Bit Define Description 0 PR_SPEC_PRCTL Mitigation can be controlled per task by PR_SET_SPECULATION_CTRL 1 PR_SPEC_ENABLE The speculation feature is enabled, mitigation is disabled 2 PR_SPEC_DISABLE The speculation feature is disabled, mitigation is enabled If all bits are 0 the CPU is not affected by the speculation misfeature. If PR_SPEC_PRCTL is set, then the per task control of the mitigation is available. If not set, prctl(PR_SET_SPECULATION_CTRL) for the speculation misfeature will fail. PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which is selected by arg2 of prctl(2) per task. arg3 is used to hand in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE. The common return values are: EINVAL prctl is not implemented by the architecture or the unused prctl() arguments are not 0 ENODEV arg2 is selecting a not supported speculation misfeature PR_SET_SPECULATION_CTRL has these additional return values: ERANGE arg3 is incorrect, i.e. it's not either PR_SPEC_ENABLE or PR_SPEC_DISABLE ENXIO prctl control of the selected speculation misfeature is disabled The first supported controlable speculation misfeature is PR_SPEC_STORE_BYPASS. Add the define so this can be shared between architectures. Based on an initial patch from Tim Chen and mostly rewritten. Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sys.c22
1 files changed, 22 insertions, 0 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index ad692183dfe9..b76dee23bdc9 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,16 @@ static int propagate_has_child_subreaper(struct task_struct *p, void *data)
2242 return 1; 2244 return 1;
2243} 2245}
2244 2246
2247int __weak arch_prctl_spec_ctrl_get(unsigned long which)
2248{
2249 return -EINVAL;
2250}
2251
2252int __weak arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
2253{
2254 return -EINVAL;
2255}
2256
2245SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, 2257SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
2246 unsigned long, arg4, unsigned long, arg5) 2258 unsigned long, arg4, unsigned long, arg5)
2247{ 2259{
@@ -2450,6 +2462,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
2450 case PR_SVE_GET_VL: 2462 case PR_SVE_GET_VL:
2451 error = SVE_GET_VL(); 2463 error = SVE_GET_VL();
2452 break; 2464 break;
2465 case PR_GET_SPECULATION_CTRL:
2466 if (arg3 || arg4 || arg5)
2467 return -EINVAL;
2468 error = arch_prctl_spec_ctrl_get(arg2);
2469 break;
2470 case PR_SET_SPECULATION_CTRL:
2471 if (arg4 || arg5)
2472 return -EINVAL;
2473 error = arch_prctl_spec_ctrl_set(arg2, arg3);
2474 break;
2453 default: 2475 default:
2454 error = -EINVAL; 2476 error = -EINVAL;
2455 break; 2477 break;