forked from mirrors/linux
		
	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>
			
			
This commit is contained in:
		
							parent
							
								
									28a2775217
								
							
						
					
					
						commit
						b617cfc858
					
				
					 5 changed files with 125 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -19,6 +19,7 @@ place where this information is gathered.
 | 
			
		|||
   no_new_privs
 | 
			
		||||
   seccomp_filter
 | 
			
		||||
   unshare
 | 
			
		||||
   spec_ctrl
 | 
			
		||||
 | 
			
		||||
.. only::  subproject and html
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										86
									
								
								Documentation/userspace-api/spec_ctrl.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								Documentation/userspace-api/spec_ctrl.rst
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
===================
 | 
			
		||||
Speculation Control
 | 
			
		||||
===================
 | 
			
		||||
 | 
			
		||||
Quite some CPUs have speculation related misfeatures which are in fact
 | 
			
		||||
vulnerabilites causing data leaks in various forms even accross privilege
 | 
			
		||||
domains.
 | 
			
		||||
 | 
			
		||||
The kernel provides mitigation for such vulnerabilities in various
 | 
			
		||||
forms. Some of these mitigations are compile time configurable and some on
 | 
			
		||||
the kernel command line.
 | 
			
		||||
 | 
			
		||||
There is also a class of mitigations which are very expensive, but they can
 | 
			
		||||
be restricted to a certain set of processes or tasks in controlled
 | 
			
		||||
environments. The mechanism to control these mitigations is via
 | 
			
		||||
:manpage:`prctl(2)`.
 | 
			
		||||
 | 
			
		||||
There are two prctl options which are related to this:
 | 
			
		||||
 | 
			
		||||
 * PR_GET_SPECULATION_CTRL
 | 
			
		||||
 | 
			
		||||
 * PR_SET_SPECULATION_CTRL
 | 
			
		||||
 | 
			
		||||
PR_GET_SPECULATION_CTRL
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
PR_GET_SPECULATION_CTRL returns the state of the speculation misfeature
 | 
			
		||||
which is selected with arg2 of prctl(2). The return value uses bits 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
 | 
			
		||||
-----------------------
 | 
			
		||||
PR_SET_SPECULATION_CTRL allows to control the speculation misfeature, which
 | 
			
		||||
is selected by arg2 of :manpage:`prctl(2)` per task. arg3 is used to hand
 | 
			
		||||
in the control value, i.e. either PR_SPEC_ENABLE or PR_SPEC_DISABLE.
 | 
			
		||||
 | 
			
		||||
Common error codes
 | 
			
		||||
------------------
 | 
			
		||||
======= =================================================================
 | 
			
		||||
Value   Meaning
 | 
			
		||||
======= =================================================================
 | 
			
		||||
EINVAL  The prctl is not implemented by the architecture or unused
 | 
			
		||||
        prctl(2) arguments are not 0
 | 
			
		||||
 | 
			
		||||
ENODEV  arg2 is selecting a not supported speculation misfeature
 | 
			
		||||
======= =================================================================
 | 
			
		||||
 | 
			
		||||
PR_SET_SPECULATION_CTRL error codes
 | 
			
		||||
-----------------------------------
 | 
			
		||||
======= =================================================================
 | 
			
		||||
Value   Meaning
 | 
			
		||||
======= =================================================================
 | 
			
		||||
0       Success
 | 
			
		||||
 | 
			
		||||
ERANGE  arg3 is incorrect, i.e. it's neither PR_SPEC_ENABLE nor
 | 
			
		||||
        PR_SPEC_DISABLE
 | 
			
		||||
 | 
			
		||||
ENXIO   Control of the selected speculation misfeature is not possible.
 | 
			
		||||
        See PR_GET_SPECULATION_CTRL.
 | 
			
		||||
======= =================================================================
 | 
			
		||||
 | 
			
		||||
Speculation misfeature controls
 | 
			
		||||
-------------------------------
 | 
			
		||||
- PR_SPEC_STORE_BYPASS: Speculative Store Bypass
 | 
			
		||||
 | 
			
		||||
  Invocations:
 | 
			
		||||
   * prctl(PR_GET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, 0, 0, 0);
 | 
			
		||||
   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_ENABLE, 0, 0);
 | 
			
		||||
   * prctl(PR_SET_SPECULATION_CTRL, PR_SPEC_STORE_BYPASS, PR_SPEC_DISABLE, 0, 0);
 | 
			
		||||
| 
						 | 
				
			
			@ -55,4 +55,9 @@ static inline unsigned long array_index_mask_nospec(unsigned long index,
 | 
			
		|||
									\
 | 
			
		||||
	(typeof(_i)) (_i & _mask);					\
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
/* Speculation control prctl */
 | 
			
		||||
int arch_prctl_spec_ctrl_get(unsigned long which);
 | 
			
		||||
int arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl);
 | 
			
		||||
 | 
			
		||||
#endif /* _LINUX_NOSPEC_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -207,4 +207,15 @@ struct prctl_mm_map {
 | 
			
		|||
# define PR_SVE_VL_LEN_MASK		0xffff
 | 
			
		||||
# define PR_SVE_VL_INHERIT		(1 << 17) /* inherit across exec */
 | 
			
		||||
 | 
			
		||||
/* Per task speculation control */
 | 
			
		||||
#define PR_GET_SPECULATION_CTRL		52
 | 
			
		||||
#define PR_SET_SPECULATION_CTRL		53
 | 
			
		||||
/* Speculation control variants */
 | 
			
		||||
# define PR_SPEC_STORE_BYPASS		0
 | 
			
		||||
/* Return and control values for PR_SET/GET_SPECULATION_CTRL */
 | 
			
		||||
# define PR_SPEC_NOT_AFFECTED		0
 | 
			
		||||
# define PR_SPEC_PRCTL			(1UL << 0)
 | 
			
		||||
# define PR_SPEC_ENABLE			(1UL << 1)
 | 
			
		||||
# define PR_SPEC_DISABLE		(1UL << 2)
 | 
			
		||||
 | 
			
		||||
#endif /* _LINUX_PRCTL_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										22
									
								
								kernel/sys.c
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								kernel/sys.c
									
									
									
									
									
								
							| 
						 | 
				
			
			@ -61,6 +61,8 @@
 | 
			
		|||
#include <linux/uidgid.h>
 | 
			
		||||
#include <linux/cred.h>
 | 
			
		||||
 | 
			
		||||
#include <linux/nospec.h>
 | 
			
		||||
 | 
			
		||||
#include <linux/kmsg_dump.h>
 | 
			
		||||
/* Move somewhere else to avoid recompiling? */
 | 
			
		||||
#include <generated/utsrelease.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -2242,6 +2244,16 @@ static int propagate_has_child_subreaper(struct task_struct *p, void *data)
 | 
			
		|||
	return 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __weak arch_prctl_spec_ctrl_get(unsigned long which)
 | 
			
		||||
{
 | 
			
		||||
	return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __weak arch_prctl_spec_ctrl_set(unsigned long which, unsigned long ctrl)
 | 
			
		||||
{
 | 
			
		||||
	return -EINVAL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 | 
			
		||||
		unsigned long, arg4, unsigned long, arg5)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -2450,6 +2462,16 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
 | 
			
		|||
	case PR_SVE_GET_VL:
 | 
			
		||||
		error = SVE_GET_VL();
 | 
			
		||||
		break;
 | 
			
		||||
	case PR_GET_SPECULATION_CTRL:
 | 
			
		||||
		if (arg3 || arg4 || arg5)
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		error = arch_prctl_spec_ctrl_get(arg2);
 | 
			
		||||
		break;
 | 
			
		||||
	case PR_SET_SPECULATION_CTRL:
 | 
			
		||||
		if (arg4 || arg5)
 | 
			
		||||
			return -EINVAL;
 | 
			
		||||
		error = arch_prctl_spec_ctrl_set(arg2, arg3);
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		error = -EINVAL;
 | 
			
		||||
		break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue