mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 05:04:09 +08:00
e8c24d3a23
This patch adds two new system calls: int pkey_alloc(unsigned long flags, unsigned long init_access_rights) int pkey_free(int pkey); These implement an "allocator" for the protection keys themselves, which can be thought of as analogous to the allocator that the kernel has for file descriptors. The kernel tracks which numbers are in use, and only allows operations on keys that are valid. A key which was not obtained by pkey_alloc() may not, for instance, be passed to pkey_mprotect(). These system calls are also very important given the kernel's use of pkeys to implement execute-only support. These help ensure that userspace can never assume that it has control of a key unless it first asks the kernel. The kernel does not promise to preserve PKRU (right register) contents except for allocated pkeys. The 'init_access_rights' argument to pkey_alloc() specifies the rights that will be established for the returned pkey. For instance: pkey = pkey_alloc(flags, PKEY_DENY_WRITE); will allocate 'pkey', but also sets the bits in PKRU[1] such that writing to 'pkey' is already denied. The kernel does not prevent pkey_free() from successfully freeing in-use pkeys (those still assigned to a memory range by pkey_mprotect()). It would be expensive to implement the checks for this, so we instead say, "Just don't do it" since sane software will never do it anyway. Any piece of userspace calling pkey_alloc() needs to be prepared for it to fail. Why? pkey_alloc() returns the same error code (ENOSPC) when there are no pkeys and when pkeys are unsupported. They can be unsupported for a whole host of reasons, so apps must be prepared for this. Also, libraries or LD_PRELOADs might steal keys before an application gets access to them. This allocation mechanism could be implemented in userspace. Even if we did it in userspace, we would still need additional user/kernel interfaces to tell userspace which keys are being used by the kernel internally (such as for execute-only mappings). Having the kernel provide this facility completely removes the need for these additional interfaces, or having an implementation of this in userspace at all. Note that we have to make changes to all of the architectures that do not use mman-common.h because we use the new PKEY_DENY_ACCESS/WRITE macros in arch-independent code. 1. PKRU is the Protection Key Rights User register. It is a usermode-accessible register that controls whether writes and/or access to each individual pkey is allowed or denied. Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Acked-by: Mel Gorman <mgorman@techsingularity.net> Cc: linux-arch@vger.kernel.org Cc: Dave Hansen <dave@sr71.net> Cc: arnd@arndb.de Cc: linux-api@vger.kernel.org Cc: linux-mm@kvack.org Cc: luto@kernel.org Cc: akpm@linux-foundation.org Cc: torvalds@linux-foundation.org Link: http://lkml.kernel.org/r/20160729163015.444FE75F@viggo.jf.intel.com Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
87 lines
3.5 KiB
C
87 lines
3.5 KiB
C
#ifndef __ALPHA_MMAN_H__
|
|
#define __ALPHA_MMAN_H__
|
|
|
|
#define PROT_READ 0x1 /* page can be read */
|
|
#define PROT_WRITE 0x2 /* page can be written */
|
|
#define PROT_EXEC 0x4 /* page can be executed */
|
|
#define PROT_SEM 0x8 /* page may be used for atomic ops */
|
|
#define PROT_NONE 0x0 /* page can not be accessed */
|
|
#define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */
|
|
#define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */
|
|
|
|
#define MAP_SHARED 0x01 /* Share changes */
|
|
#define MAP_PRIVATE 0x02 /* Changes are private */
|
|
#define MAP_TYPE 0x0f /* Mask for type of mapping (OSF/1 is _wrong_) */
|
|
#define MAP_FIXED 0x100 /* Interpret addr exactly */
|
|
#define MAP_ANONYMOUS 0x10 /* don't use a file */
|
|
|
|
/* not used by linux, but here to make sure we don't clash with OSF/1 defines */
|
|
#define _MAP_HASSEMAPHORE 0x0200
|
|
#define _MAP_INHERIT 0x0400
|
|
#define _MAP_UNALIGNED 0x0800
|
|
|
|
/* These are linux-specific */
|
|
#define MAP_GROWSDOWN 0x01000 /* stack-like segment */
|
|
#define MAP_DENYWRITE 0x02000 /* ETXTBSY */
|
|
#define MAP_EXECUTABLE 0x04000 /* mark it as an executable */
|
|
#define MAP_LOCKED 0x08000 /* lock the mapping */
|
|
#define MAP_NORESERVE 0x10000 /* don't check for reservations */
|
|
#define MAP_POPULATE 0x20000 /* populate (prefault) pagetables */
|
|
#define MAP_NONBLOCK 0x40000 /* do not block on IO */
|
|
#define MAP_STACK 0x80000 /* give out an address that is best suited for process/thread stacks */
|
|
#define MAP_HUGETLB 0x100000 /* create a huge page mapping */
|
|
|
|
#define MS_ASYNC 1 /* sync memory asynchronously */
|
|
#define MS_SYNC 2 /* synchronous memory sync */
|
|
#define MS_INVALIDATE 4 /* invalidate the caches */
|
|
|
|
#define MCL_CURRENT 8192 /* lock all currently mapped pages */
|
|
#define MCL_FUTURE 16384 /* lock all additions to address space */
|
|
#define MCL_ONFAULT 32768 /* lock all pages that are faulted in */
|
|
|
|
#define MLOCK_ONFAULT 0x01 /* Lock pages in range after they are faulted in, do not prefault */
|
|
|
|
#define MADV_NORMAL 0 /* no further special treatment */
|
|
#define MADV_RANDOM 1 /* expect random page references */
|
|
#define MADV_SEQUENTIAL 2 /* expect sequential page references */
|
|
#define MADV_WILLNEED 3 /* will need these pages */
|
|
#define MADV_SPACEAVAIL 5 /* ensure resources are available */
|
|
#define MADV_DONTNEED 6 /* don't need these pages */
|
|
|
|
/* common/generic parameters */
|
|
#define MADV_FREE 8 /* free pages only if memory pressure */
|
|
#define MADV_REMOVE 9 /* remove these pages & resources */
|
|
#define MADV_DONTFORK 10 /* don't inherit across fork */
|
|
#define MADV_DOFORK 11 /* do inherit across fork */
|
|
|
|
#define MADV_MERGEABLE 12 /* KSM may merge identical pages */
|
|
#define MADV_UNMERGEABLE 13 /* KSM may not merge identical pages */
|
|
|
|
#define MADV_HUGEPAGE 14 /* Worth backing with hugepages */
|
|
#define MADV_NOHUGEPAGE 15 /* Not worth backing with hugepages */
|
|
|
|
#define MADV_DONTDUMP 16 /* Explicity exclude from the core dump,
|
|
overrides the coredump filter bits */
|
|
#define MADV_DODUMP 17 /* Clear the MADV_NODUMP flag */
|
|
|
|
/* compatibility flags */
|
|
#define MAP_FILE 0
|
|
|
|
/*
|
|
* When MAP_HUGETLB is set bits [26:31] encode the log2 of the huge page size.
|
|
* This gives us 6 bits, which is enough until someone invents 128 bit address
|
|
* spaces.
|
|
*
|
|
* Assume these are all power of twos.
|
|
* When 0 use the default page size.
|
|
*/
|
|
#define MAP_HUGE_SHIFT 26
|
|
#define MAP_HUGE_MASK 0x3f
|
|
|
|
#define PKEY_DISABLE_ACCESS 0x1
|
|
#define PKEY_DISABLE_WRITE 0x2
|
|
#define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\
|
|
PKEY_DISABLE_WRITE)
|
|
|
|
#endif /* __ALPHA_MMAN_H__ */
|