Merge tag 'x86_sgx_for_v6.0-2022-08-03.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 SGX updates from Dave Hansen: "A set of x86/sgx changes focused on implementing the "SGX2" features, plus a minor cleanup: - SGX2 ISA support which makes enclave memory management much more dynamic. For instance, enclaves can now change enclave page permissions on the fly. - Removal of an unused structure member" * tag 'x86_sgx_for_v6.0-2022-08-03.1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (32 commits) x86/sgx: Drop 'page_index' from sgx_backing selftests/sgx: Page removal stress test selftests/sgx: Test reclaiming of untouched page selftests/sgx: Test invalid access to removed enclave page selftests/sgx: Test faulty enclave behavior selftests/sgx: Test complete changing of page type flow selftests/sgx: Introduce TCS initialization enclave operation selftests/sgx: Introduce dynamic entry point selftests/sgx: Test two different SGX2 EAUG flows selftests/sgx: Add test for TCS page permission changes selftests/sgx: Add test for EPCM permission changes Documentation/x86: Introduce enclave runtime management section x86/sgx: Free up EPC pages directly to support large page ranges x86/sgx: Support complete page removal x86/sgx: Support modifying SGX page type x86/sgx: Tighten accessible memory range after enclave initialization x86/sgx: Support adding of pages to an initialized enclave x86/sgx: Support restricting of enclave page permissions x86/sgx: Support VA page allocation without reclaiming x86/sgx: Export sgx_encl_page_alloc() ...
This commit is contained in:
@ -24,6 +24,9 @@ enum encl_op_type {
|
||||
ENCL_OP_PUT_TO_ADDRESS,
|
||||
ENCL_OP_GET_FROM_ADDRESS,
|
||||
ENCL_OP_NOP,
|
||||
ENCL_OP_EACCEPT,
|
||||
ENCL_OP_EMODPE,
|
||||
ENCL_OP_INIT_TCS_PAGE,
|
||||
ENCL_OP_MAX,
|
||||
};
|
||||
|
||||
@ -53,4 +56,24 @@ struct encl_op_get_from_addr {
|
||||
uint64_t addr;
|
||||
};
|
||||
|
||||
struct encl_op_eaccept {
|
||||
struct encl_op_header header;
|
||||
uint64_t epc_addr;
|
||||
uint64_t flags;
|
||||
uint64_t ret;
|
||||
};
|
||||
|
||||
struct encl_op_emodpe {
|
||||
struct encl_op_header header;
|
||||
uint64_t epc_addr;
|
||||
uint64_t flags;
|
||||
};
|
||||
|
||||
struct encl_op_init_tcs_page {
|
||||
struct encl_op_header header;
|
||||
uint64_t tcs_page;
|
||||
uint64_t ssa;
|
||||
uint64_t entry;
|
||||
};
|
||||
|
||||
#endif /* DEFINES_H */
|
||||
|
@ -130,6 +130,47 @@ static bool encl_ioc_add_pages(struct encl *encl, struct encl_segment *seg)
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the enclave code's symbol table to locate and return address of
|
||||
* the provided symbol
|
||||
*/
|
||||
uint64_t encl_get_entry(struct encl *encl, const char *symbol)
|
||||
{
|
||||
Elf64_Shdr *sections;
|
||||
Elf64_Sym *symtab;
|
||||
Elf64_Ehdr *ehdr;
|
||||
char *sym_names;
|
||||
int num_sym;
|
||||
int i;
|
||||
|
||||
ehdr = encl->bin;
|
||||
sections = encl->bin + ehdr->e_shoff;
|
||||
|
||||
for (i = 0; i < ehdr->e_shnum; i++) {
|
||||
if (sections[i].sh_type == SHT_SYMTAB) {
|
||||
symtab = (Elf64_Sym *)((char *)encl->bin + sections[i].sh_offset);
|
||||
num_sym = sections[i].sh_size / sections[i].sh_entsize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ehdr->e_shnum; i++) {
|
||||
if (sections[i].sh_type == SHT_STRTAB) {
|
||||
sym_names = (char *)encl->bin + sections[i].sh_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < num_sym; i++) {
|
||||
Elf64_Sym *sym = &symtab[i];
|
||||
|
||||
if (!strcmp(symbol, sym_names + sym->st_name))
|
||||
return (uint64_t)sym->st_value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool encl_load(const char *path, struct encl *encl, unsigned long heap_size)
|
||||
{
|
||||
const char device_path[] = "/dev/sgx_enclave";
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,7 @@ void encl_delete(struct encl *ctx);
|
||||
bool encl_load(const char *path, struct encl *encl, unsigned long heap_size);
|
||||
bool encl_measure(struct encl *encl);
|
||||
bool encl_build(struct encl *encl);
|
||||
uint64_t encl_get_entry(struct encl *encl, const char *symbol);
|
||||
|
||||
int sgx_enter_enclave(void *rdi, void *rsi, long rdx, u32 function, void *r8, void *r9,
|
||||
struct sgx_enclave_run *run);
|
||||
|
@ -11,6 +11,42 @@
|
||||
*/
|
||||
static uint8_t encl_buffer[8192] = { 1 };
|
||||
|
||||
enum sgx_enclu_function {
|
||||
EACCEPT = 0x5,
|
||||
EMODPE = 0x6,
|
||||
};
|
||||
|
||||
static void do_encl_emodpe(void *_op)
|
||||
{
|
||||
struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
|
||||
struct encl_op_emodpe *op = _op;
|
||||
|
||||
secinfo.flags = op->flags;
|
||||
|
||||
asm volatile(".byte 0x0f, 0x01, 0xd7"
|
||||
:
|
||||
: "a" (EMODPE),
|
||||
"b" (&secinfo),
|
||||
"c" (op->epc_addr));
|
||||
}
|
||||
|
||||
static void do_encl_eaccept(void *_op)
|
||||
{
|
||||
struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0};
|
||||
struct encl_op_eaccept *op = _op;
|
||||
int rax;
|
||||
|
||||
secinfo.flags = op->flags;
|
||||
|
||||
asm volatile(".byte 0x0f, 0x01, 0xd7"
|
||||
: "=a" (rax)
|
||||
: "a" (EACCEPT),
|
||||
"b" (&secinfo),
|
||||
"c" (op->epc_addr));
|
||||
|
||||
op->ret = rax;
|
||||
}
|
||||
|
||||
static void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
@ -21,6 +57,35 @@ static void *memcpy(void *dest, const void *src, size_t n)
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void *memset(void *dest, int c, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
((char *)dest)[i] = c;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
static void do_encl_init_tcs_page(void *_op)
|
||||
{
|
||||
struct encl_op_init_tcs_page *op = _op;
|
||||
void *tcs = (void *)op->tcs_page;
|
||||
uint32_t val_32;
|
||||
|
||||
memset(tcs, 0, 16); /* STATE and FLAGS */
|
||||
memcpy(tcs + 16, &op->ssa, 8); /* OSSA */
|
||||
memset(tcs + 24, 0, 4); /* CSSA */
|
||||
val_32 = 1;
|
||||
memcpy(tcs + 28, &val_32, 4); /* NSSA */
|
||||
memcpy(tcs + 32, &op->entry, 8); /* OENTRY */
|
||||
memset(tcs + 40, 0, 24); /* AEP, OFSBASE, OGSBASE */
|
||||
val_32 = 0xFFFFFFFF;
|
||||
memcpy(tcs + 64, &val_32, 4); /* FSLIMIT */
|
||||
memcpy(tcs + 68, &val_32, 4); /* GSLIMIT */
|
||||
memset(tcs + 72, 0, 4024); /* Reserved */
|
||||
}
|
||||
|
||||
static void do_encl_op_put_to_buf(void *op)
|
||||
{
|
||||
struct encl_op_put_to_buf *op2 = op;
|
||||
@ -62,6 +127,9 @@ void encl_body(void *rdi, void *rsi)
|
||||
do_encl_op_put_to_addr,
|
||||
do_encl_op_get_from_addr,
|
||||
do_encl_op_nop,
|
||||
do_encl_eaccept,
|
||||
do_encl_emodpe,
|
||||
do_encl_init_tcs_page,
|
||||
};
|
||||
|
||||
struct encl_op_header *op = (struct encl_op_header *)rdi;
|
||||
|
@ -45,6 +45,12 @@ encl_entry:
|
||||
# TCS #2. By adding the value of encl_stack to it, we get
|
||||
# the absolute address for the stack.
|
||||
lea (encl_stack)(%rbx), %rax
|
||||
jmp encl_entry_core
|
||||
encl_dyn_entry:
|
||||
# Entry point for dynamically created TCS page expected to follow
|
||||
# its stack directly.
|
||||
lea -1(%rbx), %rax
|
||||
encl_entry_core:
|
||||
xchg %rsp, %rax
|
||||
push %rax
|
||||
|
||||
|
Reference in New Issue
Block a user