Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.13-rc5 140 lines 3.0 kB view raw
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#define PKEY_REG_ALLOW_NONE 0x0 35 36#define PKEY_BITS_PER_PKEY 4 37#define PAGE_SIZE sysconf(_SC_PAGESIZE) 38#undef HPAGE_SIZE 39#define HPAGE_SIZE default_huge_page_size() 40 41/* 4-byte instructions * 16384 = 64K page */ 42#define __page_o_noops() asm(".rept 16384 ; nop; .endr") 43 44static inline u64 __read_pkey_reg(void) 45{ 46 u64 pkey_reg = 0; 47 48 // POR_EL0 49 asm volatile("mrs %0, S3_3_c10_c2_4" : "=r" (pkey_reg)); 50 51 return pkey_reg; 52} 53 54static inline void __write_pkey_reg(u64 pkey_reg) 55{ 56 u64 por = pkey_reg; 57 58 dprintf4("%s() changing %016llx to %016llx\n", 59 __func__, __read_pkey_reg(), pkey_reg); 60 61 // POR_EL0 62 asm volatile("msr S3_3_c10_c2_4, %0\nisb" :: "r" (por) :); 63 64 dprintf4("%s() pkey register after changing %016llx to %016llx\n", 65 __func__, __read_pkey_reg(), pkey_reg); 66} 67 68static inline int cpu_has_pkeys(void) 69{ 70 /* No simple way to determine this */ 71 return 1; 72} 73 74static inline u32 pkey_bit_position(int pkey) 75{ 76 return pkey * PKEY_BITS_PER_PKEY; 77} 78 79static inline int get_arch_reserved_keys(void) 80{ 81 return NR_RESERVED_PKEYS; 82} 83 84void expect_fault_on_read_execonly_key(void *p1, int pkey) 85{ 86} 87 88void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey) 89{ 90 return PTR_ERR_ENOTSUP; 91} 92 93#define set_pkey_bits set_pkey_bits 94static inline u64 set_pkey_bits(u64 reg, int pkey, u64 flags) 95{ 96 u32 shift = pkey_bit_position(pkey); 97 u64 new_val = POE_RWX; 98 99 /* mask out bits from pkey in old value */ 100 reg &= ~((u64)PKEY_MASK << shift); 101 102 if (flags & PKEY_DISABLE_ACCESS) 103 new_val = POE_X; 104 else if (flags & PKEY_DISABLE_WRITE) 105 new_val = POE_RX; 106 107 /* OR in new bits for pkey */ 108 reg |= new_val << shift; 109 110 return reg; 111} 112 113#define get_pkey_bits get_pkey_bits 114static inline u64 get_pkey_bits(u64 reg, int pkey) 115{ 116 u32 shift = pkey_bit_position(pkey); 117 /* 118 * shift down the relevant bits to the lowest four, then 119 * mask off all the other higher bits 120 */ 121 u32 perm = (reg >> shift) & PKEY_MASK; 122 123 if (perm == POE_X) 124 return PKEY_DISABLE_ACCESS; 125 if (perm == POE_RX) 126 return PKEY_DISABLE_WRITE; 127 return 0; 128} 129 130static inline void aarch64_write_signal_pkey(ucontext_t *uctxt, u64 pkey) 131{ 132 struct _aarch64_ctx *ctx = GET_UC_RESV_HEAD(uctxt); 133 struct poe_context *poe_ctx = 134 (struct poe_context *) get_header(ctx, POE_MAGIC, 135 sizeof(uctxt->uc_mcontext), NULL); 136 if (poe_ctx) 137 poe_ctx->por_el0 = pkey; 138} 139 140#endif /* _PKEYS_ARM64_H */