0001
0002 #ifndef _X86_ENCLS_H
0003 #define _X86_ENCLS_H
0004
0005 #include <linux/bitops.h>
0006 #include <linux/err.h>
0007 #include <linux/io.h>
0008 #include <linux/rwsem.h>
0009 #include <linux/types.h>
0010 #include <asm/asm.h>
0011 #include <asm/traps.h>
0012 #include "sgx.h"
0013
0014
0015 #define ENCLS_TRAPNR(r) ((r) & ~SGX_ENCLS_FAULT_FLAG)
0016
0017
0018 #define ENCLS_WARN(r, name) { \
0019 do { \
0020 int _r = (r); \
0021 WARN_ONCE(_r, "%s returned %d (0x%x)\n", (name), _r, _r); \
0022 } while (0); \
0023 }
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 static inline bool encls_faulted(int ret)
0034 {
0035 return ret & SGX_ENCLS_FAULT_FLAG;
0036 }
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 static inline bool encls_failed(int ret)
0047 {
0048 if (encls_faulted(ret))
0049 return ENCLS_TRAPNR(ret) != X86_TRAP_PF;
0050
0051 return !!ret;
0052 }
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067 #define __encls_ret_N(rax, inputs...) \
0068 ({ \
0069 int ret; \
0070 asm volatile( \
0071 "1: .byte 0x0f, 0x01, 0xcf;\n\t" \
0072 "2:\n" \
0073 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_SGX) \
0074 : "=a"(ret) \
0075 : "a"(rax), inputs \
0076 : "memory", "cc"); \
0077 ret; \
0078 })
0079
0080 #define __encls_ret_1(rax, rcx) \
0081 ({ \
0082 __encls_ret_N(rax, "c"(rcx)); \
0083 })
0084
0085 #define __encls_ret_2(rax, rbx, rcx) \
0086 ({ \
0087 __encls_ret_N(rax, "b"(rbx), "c"(rcx)); \
0088 })
0089
0090 #define __encls_ret_3(rax, rbx, rcx, rdx) \
0091 ({ \
0092 __encls_ret_N(rax, "b"(rbx), "c"(rcx), "d"(rdx)); \
0093 })
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110 #define __encls_N(rax, rbx_out, inputs...) \
0111 ({ \
0112 int ret; \
0113 asm volatile( \
0114 "1: .byte 0x0f, 0x01, 0xcf;\n\t" \
0115 " xor %%eax,%%eax;\n" \
0116 "2:\n" \
0117 _ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_SGX) \
0118 : "=a"(ret), "=b"(rbx_out) \
0119 : "a"(rax), inputs \
0120 : "memory"); \
0121 ret; \
0122 })
0123
0124 #define __encls_2(rax, rbx, rcx) \
0125 ({ \
0126 unsigned long ign_rbx_out; \
0127 __encls_N(rax, ign_rbx_out, "b"(rbx), "c"(rcx)); \
0128 })
0129
0130 #define __encls_1_1(rax, data, rcx) \
0131 ({ \
0132 unsigned long rbx_out; \
0133 int ret = __encls_N(rax, rbx_out, "c"(rcx)); \
0134 if (!ret) \
0135 data = rbx_out; \
0136 ret; \
0137 })
0138
0139
0140 static inline int __ecreate(struct sgx_pageinfo *pginfo, void *secs)
0141 {
0142 return __encls_2(ECREATE, pginfo, secs);
0143 }
0144
0145
0146 static inline int __eextend(void *secs, void *addr)
0147 {
0148 return __encls_2(EEXTEND, secs, addr);
0149 }
0150
0151
0152
0153
0154
0155 static inline int __eadd(struct sgx_pageinfo *pginfo, void *addr)
0156 {
0157 return __encls_2(EADD, pginfo, addr);
0158 }
0159
0160
0161 static inline int __einit(void *sigstruct, void *token, void *secs)
0162 {
0163 return __encls_ret_3(EINIT, sigstruct, secs, token);
0164 }
0165
0166
0167 static inline int __eremove(void *addr)
0168 {
0169 return __encls_ret_1(EREMOVE, addr);
0170 }
0171
0172
0173 static inline int __edbgwr(void *addr, unsigned long *data)
0174 {
0175 return __encls_2(EDGBWR, *data, addr);
0176 }
0177
0178
0179 static inline int __edbgrd(void *addr, unsigned long *data)
0180 {
0181 return __encls_1_1(EDGBRD, *data, addr);
0182 }
0183
0184
0185 static inline int __etrack(void *addr)
0186 {
0187 return __encls_ret_1(ETRACK, addr);
0188 }
0189
0190
0191 static inline int __eldu(struct sgx_pageinfo *pginfo, void *addr,
0192 void *va)
0193 {
0194 return __encls_ret_3(ELDU, pginfo, addr, va);
0195 }
0196
0197
0198 static inline int __eblock(void *addr)
0199 {
0200 return __encls_ret_1(EBLOCK, addr);
0201 }
0202
0203
0204 static inline int __epa(void *addr)
0205 {
0206 unsigned long rbx = SGX_PAGE_TYPE_VA;
0207
0208 return __encls_2(EPA, rbx, addr);
0209 }
0210
0211
0212 static inline int __ewb(struct sgx_pageinfo *pginfo, void *addr,
0213 void *va)
0214 {
0215 return __encls_ret_3(EWB, pginfo, addr, va);
0216 }
0217
0218
0219 static inline int __emodpr(struct sgx_secinfo *secinfo, void *addr)
0220 {
0221 return __encls_ret_2(EMODPR, secinfo, addr);
0222 }
0223
0224
0225 static inline int __emodt(struct sgx_secinfo *secinfo, void *addr)
0226 {
0227 return __encls_ret_2(EMODT, secinfo, addr);
0228 }
0229
0230
0231 static inline int __eaug(struct sgx_pageinfo *pginfo, void *addr)
0232 {
0233 return __encls_2(EAUG, pginfo, addr);
0234 }
0235
0236 #endif