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) <peterz@infradead.org> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Link: https://lore.kernel.org/r/20211110101325.961246679@infradead.org
This commit is contained in:
Родитель
fedb24cda1
Коммит
5ce8e39f55
|
@ -48,4 +48,6 @@
|
|||
#define EX_TYPE_ZERO_REG (EX_TYPE_IMM_REG | EX_DATA_IMM(0))
|
||||
#define EX_TYPE_ONE_REG (EX_TYPE_IMM_REG | EX_DATA_IMM(1))
|
||||
|
||||
#define EX_TYPE_FAULT_SGX 18
|
||||
|
||||
#endif
|
||||
|
|
|
@ -45,6 +45,24 @@ enum sgx_encls_function {
|
|||
EMODT = 0x0F,
|
||||
};
|
||||
|
||||
/**
|
||||
* SGX_ENCLS_FAULT_FLAG - flag signifying an ENCLS return code is a trapnr
|
||||
*
|
||||
* ENCLS has its own (positive value) error codes and also generates
|
||||
* ENCLS specific #GP and #PF faults. And the ENCLS values get munged
|
||||
* with system error codes as everything percolates back up the stack.
|
||||
* Unfortunately (for us), we need to precisely identify each unique
|
||||
* error code, e.g. the action taken if EWB fails varies based on the
|
||||
* type of fault and on the exact SGX error code, i.e. we can't simply
|
||||
* convert all faults to -EFAULT.
|
||||
*
|
||||
* To make all three error types coexist, we set bit 30 to identify an
|
||||
* ENCLS fault. Bit 31 (technically bits N:31) is used to differentiate
|
||||
* between positive (faults and SGX error codes) and negative (system
|
||||
* error codes) values.
|
||||
*/
|
||||
#define SGX_ENCLS_FAULT_FLAG 0x40000000
|
||||
|
||||
/**
|
||||
* enum sgx_return_code - The return code type for ENCLS, ENCLU and ENCLV
|
||||
* %SGX_NOT_TRACKED: Previous ETRACK's shootdown sequence has not
|
||||
|
|
|
@ -11,26 +11,8 @@
|
|||
#include <asm/traps.h>
|
||||
#include "sgx.h"
|
||||
|
||||
/**
|
||||
* ENCLS_FAULT_FLAG - flag signifying an ENCLS return code is a trapnr
|
||||
*
|
||||
* ENCLS has its own (positive value) error codes and also generates
|
||||
* ENCLS specific #GP and #PF faults. And the ENCLS values get munged
|
||||
* with system error codes as everything percolates back up the stack.
|
||||
* Unfortunately (for us), we need to precisely identify each unique
|
||||
* error code, e.g. the action taken if EWB fails varies based on the
|
||||
* type of fault and on the exact SGX error code, i.e. we can't simply
|
||||
* convert all faults to -EFAULT.
|
||||
*
|
||||
* To make all three error types coexist, we set bit 30 to identify an
|
||||
* ENCLS fault. Bit 31 (technically bits N:31) is used to differentiate
|
||||
* between positive (faults and SGX error codes) and negative (system
|
||||
* error codes) values.
|
||||
*/
|
||||
#define ENCLS_FAULT_FLAG 0x40000000
|
||||
|
||||
/* Retrieve the encoded trapnr from the specified return code. */
|
||||
#define ENCLS_TRAPNR(r) ((r) & ~ENCLS_FAULT_FLAG)
|
||||
#define ENCLS_TRAPNR(r) ((r) & ~SGX_ENCLS_FAULT_FLAG)
|
||||
|
||||
/* Issue a WARN() about an ENCLS function. */
|
||||
#define ENCLS_WARN(r, name) { \
|
||||
|
@ -50,7 +32,7 @@
|
|||
*/
|
||||
static inline bool encls_faulted(int ret)
|
||||
{
|
||||
return ret & ENCLS_FAULT_FLAG;
|
||||
return ret & SGX_ENCLS_FAULT_FLAG;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -88,11 +70,7 @@ static inline bool encls_failed(int ret)
|
|||
asm volatile( \
|
||||
"1: .byte 0x0f, 0x01, 0xcf;\n\t" \
|
||||
"2:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"3: orl $"__stringify(ENCLS_FAULT_FLAG)",%%eax\n" \
|
||||
" jmp 2b\n" \
|
||||
".previous\n" \
|
||||
_ASM_EXTABLE_FAULT(1b, 3b) \
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_SGX) \
|
||||
: "=a"(ret) \
|
||||
: "a"(rax), inputs \
|
||||
: "memory", "cc"); \
|
||||
|
@ -127,7 +105,7 @@ static inline bool encls_failed(int ret)
|
|||
*
|
||||
* Return:
|
||||
* 0 on success,
|
||||
* trapnr with ENCLS_FAULT_FLAG set on fault
|
||||
* trapnr with SGX_ENCLS_FAULT_FLAG set on fault
|
||||
*/
|
||||
#define __encls_N(rax, rbx_out, inputs...) \
|
||||
({ \
|
||||
|
@ -136,11 +114,7 @@ static inline bool encls_failed(int ret)
|
|||
"1: .byte 0x0f, 0x01, 0xcf;\n\t" \
|
||||
" xor %%eax,%%eax;\n" \
|
||||
"2:\n" \
|
||||
".section .fixup,\"ax\"\n" \
|
||||
"3: orl $"__stringify(ENCLS_FAULT_FLAG)",%%eax\n" \
|
||||
" jmp 2b\n" \
|
||||
".previous\n" \
|
||||
_ASM_EXTABLE_FAULT(1b, 3b) \
|
||||
_ASM_EXTABLE_TYPE(1b, 2b, EX_TYPE_FAULT_SGX) \
|
||||
: "=a"(ret), "=b"(rbx_out) \
|
||||
: "a"(rax), inputs \
|
||||
: "memory"); \
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <asm/traps.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/insn-eval.h>
|
||||
#include <asm/sgx.h>
|
||||
|
||||
static inline unsigned long *pt_regs_nr(struct pt_regs *regs, int nr)
|
||||
{
|
||||
|
@ -47,6 +48,13 @@ static bool ex_handler_fault(const struct exception_table_entry *fixup,
|
|||
return ex_handler_default(fixup, regs);
|
||||
}
|
||||
|
||||
static bool ex_handler_sgx(const struct exception_table_entry *fixup,
|
||||
struct pt_regs *regs, int trapnr)
|
||||
{
|
||||
regs->ax = trapnr | SGX_ENCLS_FAULT_FLAG;
|
||||
return ex_handler_default(fixup, regs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handler for when we fail to restore a task's FPU state. We should never get
|
||||
* 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,
|
|||
return ex_handler_pop_zero(e, regs);
|
||||
case EX_TYPE_IMM_REG:
|
||||
return ex_handler_imm_reg(e, regs, reg, imm);
|
||||
case EX_TYPE_FAULT_SGX:
|
||||
return ex_handler_sgx(e, regs, trapnr);
|
||||
}
|
||||
BUG();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче