0001
0002
0003 #ifndef _PKEYS_X86_H
0004 #define _PKEYS_X86_H
0005
0006 #ifdef __i386__
0007
0008 #ifndef SYS_mprotect_key
0009 # define SYS_mprotect_key 380
0010 #endif
0011
0012 #ifndef SYS_pkey_alloc
0013 # define SYS_pkey_alloc 381
0014 # define SYS_pkey_free 382
0015 #endif
0016
0017 #define REG_IP_IDX REG_EIP
0018 #define si_pkey_offset 0x14
0019
0020 #else
0021
0022 #ifndef SYS_mprotect_key
0023 # define SYS_mprotect_key 329
0024 #endif
0025
0026 #ifndef SYS_pkey_alloc
0027 # define SYS_pkey_alloc 330
0028 # define SYS_pkey_free 331
0029 #endif
0030
0031 #define REG_IP_IDX REG_RIP
0032 #define si_pkey_offset 0x20
0033
0034 #endif
0035
0036 #ifndef PKEY_DISABLE_ACCESS
0037 # define PKEY_DISABLE_ACCESS 0x1
0038 #endif
0039
0040 #ifndef PKEY_DISABLE_WRITE
0041 # define PKEY_DISABLE_WRITE 0x2
0042 #endif
0043
0044 #define NR_PKEYS 16
0045 #define NR_RESERVED_PKEYS 2
0046 #define PKEY_BITS_PER_PKEY 2
0047 #define HPAGE_SIZE (1UL<<21)
0048 #define PAGE_SIZE 4096
0049 #define MB (1<<20)
0050
0051 static inline void __page_o_noops(void)
0052 {
0053
0054 asm(".rept 512 ; nopl 0x7eeeeeee(%eax) ; .endr");
0055 }
0056
0057 static inline u64 __read_pkey_reg(void)
0058 {
0059 unsigned int eax, edx;
0060 unsigned int ecx = 0;
0061 unsigned pkey_reg;
0062
0063 asm volatile(".byte 0x0f,0x01,0xee\n\t"
0064 : "=a" (eax), "=d" (edx)
0065 : "c" (ecx));
0066 pkey_reg = eax;
0067 return pkey_reg;
0068 }
0069
0070 static inline void __write_pkey_reg(u64 pkey_reg)
0071 {
0072 unsigned int eax = pkey_reg;
0073 unsigned int ecx = 0;
0074 unsigned int edx = 0;
0075
0076 dprintf4("%s() changing %016llx to %016llx\n", __func__,
0077 __read_pkey_reg(), pkey_reg);
0078 asm volatile(".byte 0x0f,0x01,0xef\n\t"
0079 : : "a" (eax), "c" (ecx), "d" (edx));
0080 assert(pkey_reg == __read_pkey_reg());
0081 }
0082
0083
0084 #define X86_FEATURE_PKU (1<<3)
0085 #define X86_FEATURE_OSPKE (1<<4)
0086
0087 static inline int cpu_has_pkeys(void)
0088 {
0089 unsigned int eax;
0090 unsigned int ebx;
0091 unsigned int ecx;
0092 unsigned int edx;
0093
0094 __cpuid_count(0x7, 0x0, eax, ebx, ecx, edx);
0095
0096 if (!(ecx & X86_FEATURE_PKU)) {
0097 dprintf2("cpu does not have PKU\n");
0098 return 0;
0099 }
0100 if (!(ecx & X86_FEATURE_OSPKE)) {
0101 dprintf2("cpu does not have OSPKE\n");
0102 return 0;
0103 }
0104 return 1;
0105 }
0106
0107 static inline u32 pkey_bit_position(int pkey)
0108 {
0109 return pkey * PKEY_BITS_PER_PKEY;
0110 }
0111
0112 #define XSTATE_PKEY_BIT (9)
0113 #define XSTATE_PKEY 0x200
0114 #define XSTATE_BV_OFFSET 512
0115
0116 int pkey_reg_xstate_offset(void)
0117 {
0118 unsigned int eax;
0119 unsigned int ebx;
0120 unsigned int ecx;
0121 unsigned int edx;
0122 int xstate_offset;
0123 int xstate_size;
0124 unsigned long XSTATE_CPUID = 0xd;
0125 int leaf;
0126
0127
0128 leaf = XSTATE_PKEY_BIT;
0129 {
0130 __cpuid_count(XSTATE_CPUID, leaf, eax, ebx, ecx, edx);
0131
0132 if (leaf == XSTATE_PKEY_BIT) {
0133 xstate_offset = ebx;
0134 xstate_size = eax;
0135 }
0136 }
0137
0138 if (xstate_size == 0) {
0139 printf("could not find size/offset of PKEY in xsave state\n");
0140 return 0;
0141 }
0142
0143 return xstate_offset;
0144 }
0145
0146 static inline int get_arch_reserved_keys(void)
0147 {
0148 return NR_RESERVED_PKEYS;
0149 }
0150
0151 void expect_fault_on_read_execonly_key(void *p1, int pkey)
0152 {
0153 int ptr_contents;
0154
0155 ptr_contents = read_ptr(p1);
0156 dprintf2("ptr (%p) contents@%d: %x\n", p1, __LINE__, ptr_contents);
0157 expected_pkey_fault(pkey);
0158 }
0159
0160 void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey)
0161 {
0162 return PTR_ERR_ENOTSUP;
0163 }
0164
0165 #endif