12adcba79SJarkko Sakkinen // SPDX-License-Identifier: GPL-2.0 22adcba79SJarkko Sakkinen /* Copyright(c) 2016-20 Intel Corporation. */ 32adcba79SJarkko Sakkinen 42adcba79SJarkko Sakkinen #include <stddef.h> 52adcba79SJarkko Sakkinen #include "defines.h" 62adcba79SJarkko Sakkinen 7abc5cec4SReinette Chatre /* 8abc5cec4SReinette Chatre * Data buffer spanning two pages that will be placed first in .data 9abc5cec4SReinette Chatre * segment. Even if not used internally the second page is needed by 10abc5cec4SReinette Chatre * external test manipulating page permissions. 11abc5cec4SReinette Chatre */ 1222118ce1SJarkko Sakkinen static uint8_t encl_buffer[8192] = { 1 }; 1322118ce1SJarkko Sakkinen 14*20404a80SReinette Chatre enum sgx_enclu_function { 15*20404a80SReinette Chatre EACCEPT = 0x5, 16*20404a80SReinette Chatre EMODPE = 0x6, 17*20404a80SReinette Chatre }; 18*20404a80SReinette Chatre 19*20404a80SReinette Chatre static void do_encl_emodpe(void *_op) 20*20404a80SReinette Chatre { 21*20404a80SReinette Chatre struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0}; 22*20404a80SReinette Chatre struct encl_op_emodpe *op = _op; 23*20404a80SReinette Chatre 24*20404a80SReinette Chatre secinfo.flags = op->flags; 25*20404a80SReinette Chatre 26*20404a80SReinette Chatre asm volatile(".byte 0x0f, 0x01, 0xd7" 27*20404a80SReinette Chatre : 28*20404a80SReinette Chatre : "a" (EMODPE), 29*20404a80SReinette Chatre "b" (&secinfo), 30*20404a80SReinette Chatre "c" (op->epc_addr)); 31*20404a80SReinette Chatre } 32*20404a80SReinette Chatre 33*20404a80SReinette Chatre static void do_encl_eaccept(void *_op) 34*20404a80SReinette Chatre { 35*20404a80SReinette Chatre struct sgx_secinfo secinfo __aligned(sizeof(struct sgx_secinfo)) = {0}; 36*20404a80SReinette Chatre struct encl_op_eaccept *op = _op; 37*20404a80SReinette Chatre int rax; 38*20404a80SReinette Chatre 39*20404a80SReinette Chatre secinfo.flags = op->flags; 40*20404a80SReinette Chatre 41*20404a80SReinette Chatre asm volatile(".byte 0x0f, 0x01, 0xd7" 42*20404a80SReinette Chatre : "=a" (rax) 43*20404a80SReinette Chatre : "a" (EACCEPT), 44*20404a80SReinette Chatre "b" (&secinfo), 45*20404a80SReinette Chatre "c" (op->epc_addr)); 46*20404a80SReinette Chatre 47*20404a80SReinette Chatre op->ret = rax; 48*20404a80SReinette Chatre } 49*20404a80SReinette Chatre 502adcba79SJarkko Sakkinen static void *memcpy(void *dest, const void *src, size_t n) 512adcba79SJarkko Sakkinen { 522adcba79SJarkko Sakkinen size_t i; 532adcba79SJarkko Sakkinen 542adcba79SJarkko Sakkinen for (i = 0; i < n; i++) 552adcba79SJarkko Sakkinen ((char *)dest)[i] = ((char *)src)[i]; 562adcba79SJarkko Sakkinen 572adcba79SJarkko Sakkinen return dest; 582adcba79SJarkko Sakkinen } 592adcba79SJarkko Sakkinen 60c085dfc7SReinette Chatre static void do_encl_op_put_to_buf(void *op) 6141493a09SJarkko Sakkinen { 62c085dfc7SReinette Chatre struct encl_op_put_to_buf *op2 = op; 6341493a09SJarkko Sakkinen 6441493a09SJarkko Sakkinen memcpy(&encl_buffer[0], &op2->value, 8); 6541493a09SJarkko Sakkinen } 6641493a09SJarkko Sakkinen 67c085dfc7SReinette Chatre static void do_encl_op_get_from_buf(void *op) 6841493a09SJarkko Sakkinen { 69c085dfc7SReinette Chatre struct encl_op_get_from_buf *op2 = op; 7041493a09SJarkko Sakkinen 7141493a09SJarkko Sakkinen memcpy(&op2->value, &encl_buffer[0], 8); 7241493a09SJarkko Sakkinen } 7341493a09SJarkko Sakkinen 74abc5cec4SReinette Chatre static void do_encl_op_put_to_addr(void *_op) 75abc5cec4SReinette Chatre { 76abc5cec4SReinette Chatre struct encl_op_put_to_addr *op = _op; 77abc5cec4SReinette Chatre 78abc5cec4SReinette Chatre memcpy((void *)op->addr, &op->value, 8); 79abc5cec4SReinette Chatre } 80abc5cec4SReinette Chatre 81abc5cec4SReinette Chatre static void do_encl_op_get_from_addr(void *_op) 82abc5cec4SReinette Chatre { 83abc5cec4SReinette Chatre struct encl_op_get_from_addr *op = _op; 84abc5cec4SReinette Chatre 85abc5cec4SReinette Chatre memcpy(&op->value, (void *)op->addr, 8); 86abc5cec4SReinette Chatre } 87abc5cec4SReinette Chatre 88688542e2SReinette Chatre static void do_encl_op_nop(void *_op) 89688542e2SReinette Chatre { 90688542e2SReinette Chatre 91688542e2SReinette Chatre } 92688542e2SReinette Chatre 932adcba79SJarkko Sakkinen void encl_body(void *rdi, void *rsi) 942adcba79SJarkko Sakkinen { 9541493a09SJarkko Sakkinen const void (*encl_op_array[ENCL_OP_MAX])(void *) = { 96c085dfc7SReinette Chatre do_encl_op_put_to_buf, 97c085dfc7SReinette Chatre do_encl_op_get_from_buf, 98abc5cec4SReinette Chatre do_encl_op_put_to_addr, 99abc5cec4SReinette Chatre do_encl_op_get_from_addr, 100688542e2SReinette Chatre do_encl_op_nop, 101*20404a80SReinette Chatre do_encl_eaccept, 102*20404a80SReinette Chatre do_encl_emodpe, 10341493a09SJarkko Sakkinen }; 10422118ce1SJarkko Sakkinen 10541493a09SJarkko Sakkinen struct encl_op_header *op = (struct encl_op_header *)rdi; 10622118ce1SJarkko Sakkinen 10741493a09SJarkko Sakkinen if (op->type < ENCL_OP_MAX) 10841493a09SJarkko Sakkinen (*encl_op_array[op->type])(op); 1092adcba79SJarkko Sakkinen } 110