Skip to content

Commit 5ce8e39

Browse files
author
Peter Zijlstra
committed
x86/sgx: Remove .fixup usage
Create EX_TYPE_FAULT_SGX which does as EX_TYPE_FAULT does, except adds this extra bit that SGX really fancies having. Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Reviewed-by: Josh Poimboeuf <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent fedb24c commit 5ce8e39

File tree

4 files changed

+35
-31
lines changed

4 files changed

+35
-31
lines changed

arch/x86/include/asm/extable_fixup_types.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,6 @@
4848
#define EX_TYPE_ZERO_REG (EX_TYPE_IMM_REG | EX_DATA_IMM(0))
4949
#define EX_TYPE_ONE_REG (EX_TYPE_IMM_REG | EX_DATA_IMM(1))
5050

51+
#define EX_TYPE_FAULT_SGX 18
52+
5153
#endif

arch/x86/include/asm/sgx.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,24 @@ enum sgx_encls_function {
4545
EMODT = 0x0F,
4646
};
4747

48+
/**
49+
* SGX_ENCLS_FAULT_FLAG - flag signifying an ENCLS return code is a trapnr
50+
*
51+
* ENCLS has its own (positive value) error codes and also generates
52+
* ENCLS specific #GP and #PF faults. And the ENCLS values get munged
53+
* with system error codes as everything percolates back up the stack.
54+
* Unfortunately (for us), we need to precisely identify each unique
55+
* error code, e.g. the action taken if EWB fails varies based on the
56+
* type of fault and on the exact SGX error code, i.e. we can't simply
57+
* convert all faults to -EFAULT.
58+
*
59+
* To make all three error types coexist, we set bit 30 to identify an
60+
* ENCLS fault. Bit 31 (technically bits N:31) is used to differentiate
61+
* between positive (faults and SGX error codes) and negative (system
62+
* error codes) values.
63+
*/
64+
#define SGX_ENCLS_FAULT_FLAG 0x40000000
65+
4866
/**
4967
* enum sgx_return_code - The return code type for ENCLS, ENCLU and ENCLV
5068
* %SGX_NOT_TRACKED: Previous ETRACK's shootdown sequence has not

arch/x86/kernel/cpu/sgx/encls.h

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,26 +11,8 @@
1111
#include <asm/traps.h>
1212
#include "sgx.h"
1313

14-
/**
15-
* ENCLS_FAULT_FLAG - flag signifying an ENCLS return code is a trapnr
16-
*
17-
* ENCLS has its own (positive value) error codes and also generates
18-
* ENCLS specific #GP and #PF faults. And the ENCLS values get munged
19-
* with system error codes as everything percolates back up the stack.
20-
* Unfortunately (for us), we need to precisely identify each unique
21-
* error code, e.g. the action taken if EWB fails varies based on the
22-
* type of fault and on the exact SGX error code, i.e. we can't simply
23-
* convert all faults to -EFAULT.
24-
*
25-
* To make all three error types coexist, we set bit 30 to identify an
26-
* ENCLS fault. Bit 31 (technically bits N:31) is used to differentiate
27-
* between positive (faults and SGX error codes) and negative (system
28-
* error codes) values.
29-
*/
30-
#define ENCLS_FAULT_FLAG 0x40000000
31-
3214
/* Retrieve the encoded trapnr from the specified return code. */
33-
#define ENCLS_TRAPNR(r) ((r) & ~ENCLS_FAULT_FLAG)
15+
#define ENCLS_TRAPNR(r) ((r) & ~SGX_ENCLS_FAULT_FLAG)
3416

3517
/* Issue a WARN() about an ENCLS function. */
3618
#define ENCLS_WARN(r, name) { \
@@ -50,7 +32,7 @@
5032
*/
5133
static inline bool encls_faulted(int ret)
5234
{
53-
return ret & ENCLS_FAULT_FLAG;
35+
return ret & SGX_ENCLS_FAULT_FLAG;
5436
}
5537

5638
/**
@@ -88,11 +70,7 @@ static inline bool encls_failed(int ret)
8870
asm volatile( \
8971
"1: .byte 0x0f, 0x01, 0xcf;\n\t" \
9072
"2:\n" \
91-
".section .fixup,\"ax\"\n" \
92-
"3: orl $"__stringify(ENCLS_FAULT_FLAG)",%%eax\n" \
93-
" jmp 2b\n" \
94-
".previous\n" \
95-
_ASM_EXTABLE_FAULT(1b, 3b) \
73+
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_SGX) \
9674
: "=a"(ret) \
9775
: "a"(rax), inputs \
9876
: "memory", "cc"); \
@@ -127,7 +105,7 @@ static inline bool encls_failed(int ret)
127105
*
128106
* Return:
129107
* 0 on success,
130-
* trapnr with ENCLS_FAULT_FLAG set on fault
108+
* trapnr with SGX_ENCLS_FAULT_FLAG set on fault
131109
*/
132110
#define __encls_N(rax, rbx_out, inputs...) \
133111
({ \
@@ -136,11 +114,7 @@ static inline bool encls_failed(int ret)
136114
"1: .byte 0x0f, 0x01, 0xcf;\n\t" \
137115
" xor %%eax,%%eax;\n" \
138116
"2:\n" \
139-
".section .fixup,\"ax\"\n" \
140-
"3: orl $"__stringify(ENCLS_FAULT_FLAG)",%%eax\n" \
141-
" jmp 2b\n" \
142-
".previous\n" \
143-
_ASM_EXTABLE_FAULT(1b, 3b) \
117+
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_SGX) \
144118
: "=a"(ret), "=b"(rbx_out) \
145119
: "a"(rax), inputs \
146120
: "memory"); \

arch/x86/mm/extable.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <asm/traps.h>
1111
#include <asm/kdebug.h>
1212
#include <asm/insn-eval.h>
13+
#include <asm/sgx.h>
1314

1415
static inline unsigned long *pt_regs_nr(struct pt_regs *regs, int nr)
1516
{
@@ -47,6 +48,13 @@ static bool ex_handler_fault(const struct exception_table_entry *fixup,
4748
return ex_handler_default(fixup, regs);
4849
}
4950

51+
static bool ex_handler_sgx(const struct exception_table_entry *fixup,
52+
struct pt_regs *regs, int trapnr)
53+
{
54+
regs->ax = trapnr | SGX_ENCLS_FAULT_FLAG;
55+
return ex_handler_default(fixup, regs);
56+
}
57+
5058
/*
5159
* Handler for when we fail to restore a task's FPU state. We should never get
5260
* here because the FPU state of a task using the FPU (task->thread.fpu.state)
@@ -207,6 +215,8 @@ int fixup_exception(struct pt_regs *regs, int trapnr, unsigned long error_code,
207215
return ex_handler_pop_zero(e, regs);
208216
case EX_TYPE_IMM_REG:
209217
return ex_handler_imm_reg(e, regs, reg, imm);
218+
case EX_TYPE_FAULT_SGX:
219+
return ex_handler_sgx(e, regs, trapnr);
210220
}
211221
BUG();
212222
}

0 commit comments

Comments
 (0)