Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1/* SPDX-License-Identifier: GPL-2.0 */
  2
  3#ifndef _PKEYS_X86_H
  4#define _PKEYS_X86_H
  5
  6#ifdef __i386__
  7
  8#ifndef SYS_mprotect_key
  9# define SYS_mprotect_key	380
 10#endif
 11
 12#ifndef SYS_pkey_alloc
 13# define SYS_pkey_alloc		381
 14# define SYS_pkey_free		382
 15#endif
 16
 17#define REG_IP_IDX		REG_EIP
 18#define si_pkey_offset		0x14
 19
 20#else
 21
 22#ifndef SYS_mprotect_key
 23# define SYS_mprotect_key	329
 24#endif
 25
 26#ifndef SYS_pkey_alloc
 27# define SYS_pkey_alloc		330
 28# define SYS_pkey_free		331
 29#endif
 30
 31#define REG_IP_IDX		REG_RIP
 32#define si_pkey_offset		0x20
 33
 34#endif
 35
 36#ifndef PKEY_DISABLE_ACCESS
 37# define PKEY_DISABLE_ACCESS	0x1
 38#endif
 39
 40#ifndef PKEY_DISABLE_WRITE
 41# define PKEY_DISABLE_WRITE	0x2
 42#endif
 43
 44#define NR_PKEYS		16
 45#define NR_RESERVED_PKEYS	2 /* pkey-0 and exec-only-pkey */
 46#define PKEY_BITS_PER_PKEY	2
 47#define HPAGE_SIZE		(1UL<<21)
 48#define PAGE_SIZE		4096
 49#define MB			(1<<20)
 50
 51static inline void __page_o_noops(void)
 52{
 53	/* 8-bytes of instruction * 512 bytes = 1 page */
 54	asm(".rept 512 ; nopl 0x7eeeeeee(%eax) ; .endr");
 55}
 56
 57static inline u64 __read_pkey_reg(void)
 58{
 59	unsigned int eax, edx;
 60	unsigned int ecx = 0;
 61	unsigned pkey_reg;
 62
 63	asm volatile(".byte 0x0f,0x01,0xee\n\t"
 64		     : "=a" (eax), "=d" (edx)
 65		     : "c" (ecx));
 66	pkey_reg = eax;
 67	return pkey_reg;
 68}
 69
 70static inline void __write_pkey_reg(u64 pkey_reg)
 71{
 72	unsigned int eax = pkey_reg;
 73	unsigned int ecx = 0;
 74	unsigned int edx = 0;
 75
 76	dprintf4("%s() changing %016llx to %016llx\n", __func__,
 77			__read_pkey_reg(), pkey_reg);
 78	asm volatile(".byte 0x0f,0x01,0xef\n\t"
 79		     : : "a" (eax), "c" (ecx), "d" (edx));
 80	assert(pkey_reg == __read_pkey_reg());
 81}
 82
 83/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx) */
 84#define X86_FEATURE_PKU        (1<<3) /* Protection Keys for Userspace */
 85#define X86_FEATURE_OSPKE      (1<<4) /* OS Protection Keys Enable */
 86
 87static inline int cpu_has_pkeys(void)
 88{
 89	unsigned int eax;
 90	unsigned int ebx;
 91	unsigned int ecx;
 92	unsigned int edx;
 93
 94	__cpuid_count(0x7, 0x0, eax, ebx, ecx, edx);
 95
 96	if (!(ecx & X86_FEATURE_PKU)) {
 97		dprintf2("cpu does not have PKU\n");
 98		return 0;
 99	}
100	if (!(ecx & X86_FEATURE_OSPKE)) {
101		dprintf2("cpu does not have OSPKE\n");
102		return 0;
103	}
104	return 1;
105}
106
107static inline int cpu_max_xsave_size(void)
108{
109	unsigned long XSTATE_CPUID = 0xd;
110	unsigned int eax;
111	unsigned int ebx;
112	unsigned int ecx;
113	unsigned int edx;
114
115	__cpuid_count(XSTATE_CPUID, 0, eax, ebx, ecx, edx);
116	return ecx;
117}
118
119static inline u32 pkey_bit_position(int pkey)
120{
121	return pkey * PKEY_BITS_PER_PKEY;
122}
123
124#define XSTATE_PKEY_BIT	(9)
125#define XSTATE_PKEY	0x200
126#define XSTATE_BV_OFFSET	512
127
128int pkey_reg_xstate_offset(void)
129{
130	unsigned int eax;
131	unsigned int ebx;
132	unsigned int ecx;
133	unsigned int edx;
134	int xstate_offset;
135	int xstate_size;
136	unsigned long XSTATE_CPUID = 0xd;
137	int leaf;
138
139	/* assume that XSTATE_PKEY is set in XCR0 */
140	leaf = XSTATE_PKEY_BIT;
141	{
142		__cpuid_count(XSTATE_CPUID, leaf, eax, ebx, ecx, edx);
143
144		if (leaf == XSTATE_PKEY_BIT) {
145			xstate_offset = ebx;
146			xstate_size = eax;
147		}
148	}
149
150	if (xstate_size == 0) {
151		printf("could not find size/offset of PKEY in xsave state\n");
152		return 0;
153	}
154
155	return xstate_offset;
156}
157
158static inline int get_arch_reserved_keys(void)
159{
160	return NR_RESERVED_PKEYS;
161}
162
163void expect_fault_on_read_execonly_key(void *p1, int pkey)
164{
165	int ptr_contents;
166
167	ptr_contents = read_ptr(p1);
168	dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents);
169	expected_pkey_fault(pkey);
170}
171
172void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
173{
174	return PTR_ERR_ENOTSUP;
175}
176
177#endif /* _PKEYS_X86_H */