File Index
Files and directories
Sign in
FILE

pkey-arm64.h

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/mm/pkey-arm64.h C
  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_REG_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
 84static inline void expect_fault_on_read_execonly_key(void *p1, int pkey)
 85{
 86}
 87
 88static inline void *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 */
~/ Read-only file preview.