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:
Peter Zijlstra 2021-11-10 11:01:20 +01:00
parent fedb24cda1
commit 5ce8e39f55
4 changed files with 35 additions and 31 deletions

View File

@ -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

View File

@ -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

View File

@ -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"); \

View File

@ -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();
}