~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/mm/pkey-arm64.h

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 /*
  3  * Copyright (C) 2023 Arm Ltd.
  4  */
  5 
  6 #ifndef _PKEYS_ARM64_H
  7 #define _PKEYS_ARM64_H
  8 
  9 #include "vm_util.h"
 10 /* for signal frame parsing */
 11 #include "../arm64/signal/testcases/testcases.h"
 12 
 13 #ifndef SYS_mprotect_key
 14 # define SYS_mprotect_key       288
 15 #endif
 16 #ifndef SYS_pkey_alloc
 17 # define SYS_pkey_alloc         289
 18 # define SYS_pkey_free          290
 19 #endif
 20 #define MCONTEXT_IP(mc)         mc.pc
 21 #define MCONTEXT_TRAPNO(mc)     -1
 22 
 23 #define PKEY_MASK               0xf
 24 
 25 #define POE_NONE                0x0
 26 #define POE_X                   0x2
 27 #define POE_RX                  0x3
 28 #define POE_RWX                 0x7
 29 
 30 #define NR_PKEYS                8
 31 #define NR_RESERVED_PKEYS       1 /* pkey-0 */
 32 
 33 #define PKEY_ALLOW_ALL          0x77777777
 34 
 35 #define PKEY_BITS_PER_PKEY      4
 36 #define PAGE_SIZE               sysconf(_SC_PAGESIZE)
 37 #undef HPAGE_SIZE
 38 #define HPAGE_SIZE              default_huge_page_size()
 39 
 40 /* 4-byte instructions * 16384 = 64K page */
 41 #define __page_o_noops() asm(".rept 16384 ; nop; .endr")
 42 
 43 static inline u64 __read_pkey_reg(void)
 44 {
 45         u64 pkey_reg = 0;
 46 
 47         // POR_EL0
 48         asm volatile("mrs %0, S3_3_c10_c2_4" : "=r" (pkey_reg));
 49 
 50         return pkey_reg;
 51 }
 52 
 53 static inline void __write_pkey_reg(u64 pkey_reg)
 54 {
 55         u64 por = pkey_reg;
 56 
 57         dprintf4("%s() changing %016llx to %016llx\n",
 58                          __func__, __read_pkey_reg(), pkey_reg);
 59 
 60         // POR_EL0
 61         asm volatile("msr S3_3_c10_c2_4, %0\nisb" :: "r" (por) :);
 62 
 63         dprintf4("%s() pkey register after changing %016llx to %016llx\n",
 64                         __func__, __read_pkey_reg(), pkey_reg);
 65 }
 66 
 67 static inline int cpu_has_pkeys(void)
 68 {
 69         /* No simple way to determine this */
 70         return 1;
 71 }
 72 
 73 static inline u32 pkey_bit_position(int pkey)
 74 {
 75         return pkey * PKEY_BITS_PER_PKEY;
 76 }
 77 
 78 static inline int get_arch_reserved_keys(void)
 79 {
 80         return NR_RESERVED_PKEYS;
 81 }
 82 
 83 void expect_fault_on_read_execonly_key(void *p1, int pkey)
 84 {
 85 }
 86 
 87 void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
 88 {
 89         return PTR_ERR_ENOTSUP;
 90 }
 91 
 92 #define set_pkey_bits   set_pkey_bits
 93 static inline u64 set_pkey_bits(u64 reg, int pkey, u64 flags)
 94 {
 95         u32 shift = pkey_bit_position(pkey);
 96         u64 new_val = POE_RWX;
 97 
 98         /* mask out bits from pkey in old value */
 99         reg &= ~((u64)PKEY_MASK << shift);
100 
101         if (flags & PKEY_DISABLE_ACCESS)
102                 new_val = POE_X;
103         else if (flags & PKEY_DISABLE_WRITE)
104                 new_val = POE_RX;
105 
106         /* OR in new bits for pkey */
107         reg |= new_val << shift;
108 
109         return reg;
110 }
111 
112 #define get_pkey_bits   get_pkey_bits
113 static inline u64 get_pkey_bits(u64 reg, int pkey)
114 {
115         u32 shift = pkey_bit_position(pkey);
116         /*
117          * shift down the relevant bits to the lowest four, then
118          * mask off all the other higher bits
119          */
120         u32 perm = (reg >> shift) & PKEY_MASK;
121 
122         if (perm == POE_X)
123                 return PKEY_DISABLE_ACCESS;
124         if (perm == POE_RX)
125                 return PKEY_DISABLE_WRITE;
126         return 0;
127 }
128 
129 static void aarch64_write_signal_pkey(ucontext_t *uctxt, u64 pkey)
130 {
131         struct _aarch64_ctx *ctx = GET_UC_RESV_HEAD(uctxt);
132         struct poe_context *poe_ctx =
133                 (struct poe_context *) get_header(ctx, POE_MAGIC,
134                                                 sizeof(uctxt->uc_mcontext), NULL);
135         if (poe_ctx)
136                 poe_ctx->por_el0 = pkey;
137 }
138 
139 #endif /* _PKEYS_ARM64_H */
140 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php