summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Sakkinen2022-03-13 19:08:30 +0200
committerJarkko Sakkinen2022-03-13 19:08:30 +0200
commit9b2edd347b4f5ce31365e5e64397c5ee9f2d1b62 (patch)
tree77dbf26660dc219fdc137633fda7f3c4003d9305
parentc3aedcb42fdf3f2539141ee0fa0a3b12e247f7a6 (diff)
downloadaur-9b2edd347b4f5ce31365e5e64397c5ee9f2d1b62.tar.gz
Remove SGX2 selftests.
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@iki.fi>
-rw-r--r--0017-selftests-sgx-Add-test-for-EPCM-permission-changes.patch401
-rw-r--r--0018-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch108
-rw-r--r--0021-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch294
-rw-r--r--0025-selftests-sgx-Introduce-dynamic-entry-point.patch49
-rw-r--r--0026-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch101
-rw-r--r--0027-selftests-sgx-Test-complete-changing-of-page-type-fl.patch451
-rw-r--r--0028-selftests-sgx-Test-faulty-enclave-behavior.patch150
-rw-r--r--0029-selftests-sgx-Test-invalid-access-to-removed-enclave.patch293
-rw-r--r--0030-selftests-sgx-Test-reclaiming-of-untouched-page.patch120
-rw-r--r--0032-selftests-sgx-Page-removal-stress-test.patch156
10 files changed, 0 insertions, 2123 deletions
diff --git a/0017-selftests-sgx-Add-test-for-EPCM-permission-changes.patch b/0017-selftests-sgx-Add-test-for-EPCM-permission-changes.patch
deleted file mode 100644
index ea5c39188f31..000000000000
--- a/0017-selftests-sgx-Add-test-for-EPCM-permission-changes.patch
+++ /dev/null
@@ -1,401 +0,0 @@
-From c6ad8031ecdc735fb70305c95be5a54c704a9ebc Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:39 -0800
-Subject: [PATCH 17/34] selftests/sgx: Add test for EPCM permission changes
-
-EPCM permission changes could be made from within (to relax
-permissions) or out (to restrict permissions) the enclave. Kernel
-support is needed when permissions are restricted to be able to
-call the privileged ENCLS[EMODPR] instruction and ensure PTEs
-allowing the restricted permissions are flushed. EPCM permissions
-can be relaxed via ENCLU[EMODPE] from within the enclave but the
-enclave still depends on the kernel to install PTEs with the new
-permissions.
-
-Add a test that exercises a few of the enclave page permission flows:
-1) Test starts with a RW (from enclave and kernel perspective)
- enclave page that is mapped via a RW VMA.
-2) Use the SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS ioctl() to restrict
- the enclave (EPCM) page permissions to read-only (kernel removes
- PTE in the process).
-3) Run ENCLU[EACCEPT] from within the enclave to accept the new page
- permissions.
-4) Attempt to write to the enclave page from within the enclave - this
- should fail with a page fault on the PTE since the page
- table entry accurately reflects the (read-only) EPCM permissions.
-5) Restore EPCM permissions to RW by running ENCLU[EMODPE] from within
- the enclave.
-6) Attempt to write to the enclave page from within the enclave - this
- should fail again with a page fault because even though the EPCM
- permissions are RW the PTE does not yet reflect that.
-7) Use the SGX_IOC_ENCLAVE_RELAX_PERMISSIONS ioctl() to inform the
- kernel of new page permissions and PTEs will accurately reflect
- RW EPCM permissions.
-8) Writing to enclave page from within enclave succeeds.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/defines.h | 15 ++
- tools/testing/selftests/sgx/main.c | 253 ++++++++++++++++++++++++
- tools/testing/selftests/sgx/test_encl.c | 38 ++++
- 3 files changed, 306 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/defines.h b/tools/testing/selftests/sgx/defines.h
-index 02d775789ea7..b638eb98c80c 100644
---- a/tools/testing/selftests/sgx/defines.h
-+++ b/tools/testing/selftests/sgx/defines.h
-@@ -24,6 +24,8 @@ 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_MAX,
- };
-
-@@ -53,4 +55,17 @@ 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;
-+};
-+
- #endif /* DEFINES_H */
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index dd74fa42302e..4f348ed1dc29 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -25,6 +25,18 @@ static const uint64_t MAGIC = 0x1122334455667788ULL;
- static const uint64_t MAGIC2 = 0x8877665544332211ULL;
- vdso_sgx_enter_enclave_t vdso_sgx_enter_enclave;
-
-+/*
-+ * Security Information (SECINFO) data structure needed by a few SGX
-+ * instructions (eg. ENCLU[EACCEPT] and ENCLU[EMODPE]) holds meta-data
-+ * about an enclave page. &enum sgx_secinfo_page_state specifies the
-+ * secinfo flags used for page state.
-+ */
-+enum sgx_secinfo_page_state {
-+ SGX_SECINFO_PENDING = (1 << 3),
-+ SGX_SECINFO_MODIFIED = (1 << 4),
-+ SGX_SECINFO_PR = (1 << 5),
-+};
-+
- struct vdso_symtab {
- Elf64_Sym *elf_symtab;
- const char *elf_symstrtab;
-@@ -555,4 +567,245 @@ TEST_F(enclave, pte_permissions)
- EXPECT_EQ(self->run.exception_addr, 0);
- }
-
-+/*
-+ * Enclave page permission test.
-+ *
-+ * Modify and restore enclave page's EPCM (enclave) permissions from
-+ * outside enclave (ENCLS[EMODPR] via kernel) as well as from within
-+ * enclave (via ENCLU[EMODPE]). Kernel should ensure PTE permissions
-+ * are the same as the EPCM permissions so check for page fault if
-+ * VMA allows access but EPCM and PTE does not.
-+ */
-+TEST_F(enclave, epcm_permissions)
-+{
-+ struct sgx_enclave_restrict_perm restrict_ioc;
-+ struct encl_op_get_from_addr get_addr_op;
-+ struct sgx_enclave_relax_perm relax_ioc;
-+ struct encl_op_put_to_addr put_addr_op;
-+ struct encl_op_eaccept eaccept_op;
-+ struct encl_op_emodpe emodpe_op;
-+ struct sgx_secinfo secinfo;
-+ unsigned long data_start;
-+ int ret, errno_save;
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ /*
-+ * Ensure kernel supports needed ioctl() and system supports needed
-+ * commands.
-+ */
-+ memset(&restrict_ioc, 0, sizeof(restrict_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS,
-+ &restrict_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ ASSERT_EQ(ret, -1);
-+
-+ /* ret == -1 */
-+ if (errno_save == ENOTTY)
-+ SKIP(return,
-+ "Kernel does not support SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS ioctl()");
-+ else if (errno_save == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+
-+ /*
-+ * Page that will have its permissions changed is the second data
-+ * page in the .data segment. This forms part of the local encl_buffer
-+ * within the enclave.
-+ *
-+ * At start of test @data_start should have EPCM as well as PTE
-+ * permissions of RW.
-+ */
-+
-+ data_start = self->encl.encl_base +
-+ encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+
-+ /*
-+ * Sanity check that page at @data_start is writable before making
-+ * any changes to page permissions.
-+ *
-+ * Start by writing MAGIC to test page.
-+ */
-+ put_addr_op.value = MAGIC;
-+ put_addr_op.addr = data_start;
-+ put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Read memory that was just written to, confirming that
-+ * page is writable.
-+ */
-+ get_addr_op.value = 0;
-+ get_addr_op.addr = data_start;
-+ get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Change EPCM permissions to read-only, PTE entry flushed by
-+ * kernel in the process.
-+ */
-+ memset(&restrict_ioc, 0, sizeof(restrict_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = PROT_READ;
-+ restrict_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ restrict_ioc.length = PAGE_SIZE;
-+ restrict_ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS,
-+ &restrict_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(restrict_ioc.result, 0);
-+ EXPECT_EQ(restrict_ioc.count, 4096);
-+
-+ /*
-+ * EPCM permissions changed from kernel, need to EACCEPT from enclave.
-+ */
-+ eaccept_op.epc_addr = data_start;
-+ eaccept_op.flags = PROT_READ | SGX_SECINFO_REG | SGX_SECINFO_PR;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /*
-+ * EPCM permissions of page is now read-only, expect #PF
-+ * on PTE (not EPCM) when attempting to write to page from
-+ * within enclave.
-+ */
-+ put_addr_op.value = MAGIC2;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(self->run.function, ERESUME);
-+ EXPECT_EQ(self->run.exception_vector, 14);
-+ EXPECT_EQ(self->run.exception_error_code, 0x7);
-+ EXPECT_EQ(self->run.exception_addr, data_start);
-+
-+ self->run.exception_vector = 0;
-+ self->run.exception_error_code = 0;
-+ self->run.exception_addr = 0;
-+
-+ /*
-+ * Received AEX but cannot return to enclave at same entrypoint,
-+ * need different TCS from where EPCM permission can be made writable
-+ * again.
-+ */
-+ self->run.tcs = self->encl.encl_base + PAGE_SIZE;
-+
-+ /*
-+ * Enter enclave at new TCS to change EPCM permissions to be
-+ * writable again and thus fix the page fault that triggered the
-+ * AEX.
-+ */
-+
-+ emodpe_op.epc_addr = data_start;
-+ emodpe_op.flags = PROT_READ | PROT_WRITE;
-+ emodpe_op.header.type = ENCL_OP_EMODPE;
-+
-+ EXPECT_EQ(ENCL_CALL(&emodpe_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Attempt to return to main TCS to resume execution at faulting
-+ * instruction, but PTE should still prevent writing to the page.
-+ */
-+ self->run.tcs = self->encl.encl_base;
-+
-+ EXPECT_EQ(vdso_sgx_enter_enclave((unsigned long)&put_addr_op, 0, 0,
-+ ERESUME, 0, 0,
-+ &self->run),
-+ 0);
-+
-+ EXPECT_EQ(self->run.function, ERESUME);
-+ EXPECT_EQ(self->run.exception_vector, 14);
-+ EXPECT_EQ(self->run.exception_error_code, 0x7);
-+ EXPECT_EQ(self->run.exception_addr, data_start);
-+
-+ self->run.exception_vector = 0;
-+ self->run.exception_error_code = 0;
-+ self->run.exception_addr = 0;
-+ /*
-+ * Inform kernel about new permissions to have PTEs match EPCM.
-+ */
-+ memset(&relax_ioc, 0, sizeof(relax_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = PROT_READ | PROT_WRITE;
-+ relax_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ relax_ioc.length = PAGE_SIZE;
-+ relax_ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_RELAX_PERMISSIONS,
-+ &relax_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(relax_ioc.count, 4096);
-+
-+ /*
-+ * Wrong page permissions that caused original fault has
-+ * now been fixed via EPCM permissions as well as PTE.
-+ * Resume execution in main TCS to re-attempt the memory access.
-+ */
-+ self->run.tcs = self->encl.encl_base;
-+
-+ EXPECT_EQ(vdso_sgx_enter_enclave((unsigned long)&put_addr_op, 0, 0,
-+ ERESUME, 0, 0,
-+ &self->run),
-+ 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ get_addr_op.value = 0;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC2);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.user_data, 0);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+}
-+
- TEST_HARNESS_MAIN
-diff --git a/tools/testing/selftests/sgx/test_encl.c b/tools/testing/selftests/sgx/test_encl.c
-index 4fca01cfd898..5b6c65331527 100644
---- a/tools/testing/selftests/sgx/test_encl.c
-+++ b/tools/testing/selftests/sgx/test_encl.c
-@@ -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;
-@@ -62,6 +98,8 @@ 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,
- };
-
- struct encl_op_header *op = (struct encl_op_header *)rdi;
---
-2.35.1
-
diff --git a/0018-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch b/0018-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch
deleted file mode 100644
index 0c23834714fc..000000000000
--- a/0018-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch
+++ /dev/null
@@ -1,108 +0,0 @@
-From 0b54ab006b8b54ffbeb8abf57ba07221c2eae035 Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:40 -0800
-Subject: [PATCH 18/34] selftests/sgx: Add test for TCS page permission changes
-
-Kernel should not allow permission changes on TCS pages. Add test to
-confirm this behavior.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/main.c | 74 ++++++++++++++++++++++++++++++
- 1 file changed, 74 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index 4f348ed1dc29..1398cd1b0983 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -121,6 +121,24 @@ static Elf64_Sym *vdso_symtab_get(struct vdso_symtab *symtab, const char *name)
- return NULL;
- }
-
-+/*
-+ * Return the offset in the enclave where the TCS segment can be found.
-+ * The first RW segment loaded is the TCS.
-+ */
-+static off_t encl_get_tcs_offset(struct encl *encl)
-+{
-+ int i;
-+
-+ for (i = 0; i < encl->nr_segments; i++) {
-+ struct encl_segment *seg = &encl->segment_tbl[i];
-+
-+ if (i == 0 && seg->prot == (PROT_READ | PROT_WRITE))
-+ return seg->offset;
-+ }
-+
-+ return -1;
-+}
-+
- /*
- * Return the offset in the enclave where the data segment can be found.
- * The first RW segment loaded is the TCS, skip that to get info on the
-@@ -567,6 +585,62 @@ TEST_F(enclave, pte_permissions)
- EXPECT_EQ(self->run.exception_addr, 0);
- }
-
-+/*
-+ * Modifying permissions of TCS page should not be possible.
-+ */
-+TEST_F(enclave, tcs_permissions)
-+{
-+ struct sgx_enclave_restrict_perm ioc;
-+ struct sgx_secinfo secinfo;
-+ int ret, errno_save;
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ memset(&ioc, 0, sizeof(ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ /*
-+ * Ensure kernel supports needed ioctl() and system supports needed
-+ * commands.
-+ */
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS, &ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ ASSERT_EQ(ret, -1);
-+
-+ /* ret == -1 */
-+ if (errno_save == ENOTTY)
-+ SKIP(return,
-+ "Kernel does not support SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS ioctl()");
-+ else if (errno_save == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+
-+ /*
-+ * Attempt to make TCS page read-only. This is not allowed and
-+ * should be prevented by the kernel.
-+ */
-+ secinfo.flags = PROT_READ;
-+ ioc.offset = encl_get_tcs_offset(&self->encl);
-+ ioc.length = PAGE_SIZE;
-+ ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS, &ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, -1);
-+ EXPECT_EQ(errno_save, EINVAL);
-+ EXPECT_EQ(ioc.result, 0);
-+ EXPECT_EQ(ioc.count, 0);
-+}
-+
- /*
- * Enclave page permission test.
- *
---
-2.35.1
-
diff --git a/0021-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch b/0021-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch
deleted file mode 100644
index ef31e923a9c5..000000000000
--- a/0021-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-From 3913725f6fcade6d3ce8139862320e48845c9ad9 Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:43 -0800
-Subject: [PATCH 21/34] selftests/sgx: Test two different SGX2 EAUG flows
-
-Enclave pages can be added to an initialized enclave when an address
-belonging to the enclave but without a backing page is accessed from
-within the enclave.
-
-Accessing memory without a backing enclave page from within an enclave
-can be in different ways:
-1) Pre-emptively run ENCLU[EACCEPT]. Since the addition of a page
- always needs to be accepted by the enclave via ENCLU[EACCEPT] this
- flow is efficient since the first execution of ENCLU[EACCEPT]
- triggers the addition of the page and when execution returns to the
- same instruction the second execution would be successful as an
- acceptance of the page.
-
-2) A direct read or write. The flow where a direct read or write
- triggers the page addition execution cannot resume from the
- instruction (read/write) that triggered the fault but instead
- the enclave needs to be entered at a different entry point to
- run needed ENCLU[EACCEPT] before execution can return to the
- original entry point and the read/write instruction that faulted.
-
-Add tests for both flows.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/main.c | 243 +++++++++++++++++++++++++++++
- 1 file changed, 243 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index 1398cd1b0983..68285603b3f0 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -86,6 +86,15 @@ static bool vdso_get_symtab(void *addr, struct vdso_symtab *symtab)
- return true;
- }
-
-+static inline int sgx2_supported(void)
-+{
-+ unsigned int eax, ebx, ecx, edx;
-+
-+ __cpuid_count(SGX_CPUID, 0x0, eax, ebx, ecx, edx);
-+
-+ return eax & 0x2;
-+}
-+
- static unsigned long elf_sym_hash(const char *name)
- {
- unsigned long h = 0, high;
-@@ -882,4 +891,238 @@ TEST_F(enclave, epcm_permissions)
- EXPECT_EQ(self->run.exception_addr, 0);
- }
-
-+/*
-+ * Test the addition of pages to an initialized enclave via writing to
-+ * a page belonging to the enclave's address space but was not added
-+ * during enclave creation.
-+ */
-+TEST_F(enclave, augment)
-+{
-+ struct encl_op_get_from_addr get_addr_op;
-+ struct encl_op_put_to_addr put_addr_op;
-+ struct encl_op_eaccept eaccept_op;
-+ size_t total_size = 0;
-+ void *addr;
-+ int i;
-+
-+ if (!sgx2_supported())
-+ SKIP(return, "SGX2 not supported");
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ for (i = 0; i < self->encl.nr_segments; i++) {
-+ struct encl_segment *seg = &self->encl.segment_tbl[i];
-+
-+ total_size += seg->size;
-+ }
-+
-+ /*
-+ * Actual enclave size is expected to be larger than the loaded
-+ * test enclave since enclave size must be a power of 2 in bytes
-+ * and test_encl does not consume it all.
-+ */
-+ EXPECT_LT(total_size + PAGE_SIZE, self->encl.encl_size);
-+
-+ /*
-+ * Create memory mapping for the page that will be added. New
-+ * memory mapping is for one page right after all existing
-+ * mappings.
-+ */
-+ addr = mmap((void *)self->encl.encl_base + total_size, PAGE_SIZE,
-+ PROT_READ | PROT_WRITE | PROT_EXEC,
-+ MAP_SHARED | MAP_FIXED, self->encl.fd, 0);
-+ EXPECT_NE(addr, MAP_FAILED);
-+
-+ self->run.exception_vector = 0;
-+ self->run.exception_error_code = 0;
-+ self->run.exception_addr = 0;
-+
-+ /*
-+ * Attempt to write to the new page from within enclave.
-+ * Expected to fail since page is not (yet) part of the enclave.
-+ * The first #PF will trigger the addition of the page to the
-+ * enclave, but since the new page needs an EACCEPT from within the
-+ * enclave before it can be used it would not be possible
-+ * to successfully return to the failing instruction. This is the
-+ * cause of the second #PF captured here having the SGX bit set,
-+ * it is from hardware preventing the page from being used.
-+ */
-+ put_addr_op.value = MAGIC;
-+ put_addr_op.addr = (unsigned long)addr;
-+ put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(self->run.function, ERESUME);
-+ EXPECT_EQ(self->run.exception_vector, 14);
-+ EXPECT_EQ(self->run.exception_addr, (unsigned long)addr);
-+
-+ if (self->run.exception_error_code == 0x6) {
-+ munmap(addr, PAGE_SIZE);
-+ SKIP(return, "Kernel does not support adding pages to initialized enclave");
-+ }
-+
-+ EXPECT_EQ(self->run.exception_error_code, 0x8007);
-+
-+ self->run.exception_vector = 0;
-+ self->run.exception_error_code = 0;
-+ self->run.exception_addr = 0;
-+
-+ /* Handle AEX by running EACCEPT from new entry point. */
-+ self->run.tcs = self->encl.encl_base + PAGE_SIZE;
-+
-+ eaccept_op.epc_addr = self->encl.encl_base + total_size;
-+ eaccept_op.flags = SGX_SECINFO_R | SGX_SECINFO_W | SGX_SECINFO_REG | SGX_SECINFO_PENDING;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /* Can now return to main TCS to resume execution. */
-+ self->run.tcs = self->encl.encl_base;
-+
-+ EXPECT_EQ(vdso_sgx_enter_enclave((unsigned long)&put_addr_op, 0, 0,
-+ ERESUME, 0, 0,
-+ &self->run),
-+ 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Read memory from newly added page that was just written to,
-+ * confirming that data previously written (MAGIC) is present.
-+ */
-+ get_addr_op.value = 0;
-+ get_addr_op.addr = (unsigned long)addr;
-+ get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ munmap(addr, PAGE_SIZE);
-+}
-+
-+/*
-+ * Test for the addition of pages to an initialized enclave via a
-+ * pre-emptive run of EACCEPT on page to be added.
-+ */
-+TEST_F(enclave, augment_via_eaccept)
-+{
-+ struct encl_op_get_from_addr get_addr_op;
-+ struct encl_op_put_to_addr put_addr_op;
-+ struct encl_op_eaccept eaccept_op;
-+ size_t total_size = 0;
-+ void *addr;
-+ int i;
-+
-+ if (!sgx2_supported())
-+ SKIP(return, "SGX2 not supported");
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ for (i = 0; i < self->encl.nr_segments; i++) {
-+ struct encl_segment *seg = &self->encl.segment_tbl[i];
-+
-+ total_size += seg->size;
-+ }
-+
-+ /*
-+ * Actual enclave size is expected to be larger than the loaded
-+ * test enclave since enclave size must be a power of 2 in bytes while
-+ * test_encl does not consume it all.
-+ */
-+ EXPECT_LT(total_size + PAGE_SIZE, self->encl.encl_size);
-+
-+ /*
-+ * mmap() a page at end of existing enclave to be used for dynamic
-+ * EPC page.
-+ */
-+
-+ addr = mmap((void *)self->encl.encl_base + total_size, PAGE_SIZE,
-+ PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED | MAP_FIXED,
-+ self->encl.fd, 0);
-+ EXPECT_NE(addr, MAP_FAILED);
-+
-+ self->run.exception_vector = 0;
-+ self->run.exception_error_code = 0;
-+ self->run.exception_addr = 0;
-+
-+ /*
-+ * Run EACCEPT on new page to trigger the #PF->EAUG->EACCEPT(again
-+ * without a #PF). All should be transparent to userspace.
-+ */
-+ eaccept_op.epc_addr = self->encl.encl_base + total_size;
-+ eaccept_op.flags = SGX_SECINFO_R | SGX_SECINFO_W | SGX_SECINFO_REG | SGX_SECINFO_PENDING;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ if (self->run.exception_vector == 14 &&
-+ self->run.exception_error_code == 4 &&
-+ self->run.exception_addr == self->encl.encl_base + total_size) {
-+ munmap(addr, PAGE_SIZE);
-+ SKIP(return, "Kernel does not support adding pages to initialized enclave");
-+ }
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /*
-+ * New page should be accessible from within enclave - attempt to
-+ * write to it.
-+ */
-+ put_addr_op.value = MAGIC;
-+ put_addr_op.addr = (unsigned long)addr;
-+ put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Read memory from newly added page that was just written to,
-+ * confirming that data previously written (MAGIC) is present.
-+ */
-+ get_addr_op.value = 0;
-+ get_addr_op.addr = (unsigned long)addr;
-+ get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ munmap(addr, PAGE_SIZE);
-+}
-+
- TEST_HARNESS_MAIN
---
-2.35.1
-
diff --git a/0025-selftests-sgx-Introduce-dynamic-entry-point.patch b/0025-selftests-sgx-Introduce-dynamic-entry-point.patch
deleted file mode 100644
index 2567c11ba574..000000000000
--- a/0025-selftests-sgx-Introduce-dynamic-entry-point.patch
+++ /dev/null
@@ -1,49 +0,0 @@
-From 4667ff92d36ebd3a891da823ccad82453860603d Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:47 -0800
-Subject: [PATCH 25/34] selftests/sgx: Introduce dynamic entry point
-
-The test enclave (test_encl.elf) is built with two initialized
-Thread Control Structures (TCS) included in the binary. Both TCS are
-initialized with the same entry point, encl_entry, that correctly
-computes the absolute address of the stack based on the stack of each
-TCS that is also built into the binary.
-
-A new TCS can be added dynamically to the enclave and requires to be
-initialized with an entry point used to enter the enclave. Since the
-existing entry point, encl_entry, assumes that the TCS and its stack
-exists at particular offsets within the binary it is not able to handle
-a dynamically added TCS and its stack.
-
-Introduce a new entry point, encl_dyn_entry, that initializes the
-absolute address of that thread's stack to the address immediately
-preceding the TCS itself. It is now possible to dynamically add a
-contiguous memory region to the enclave with the new stack preceding
-the new TCS. With the new TCS initialized with encl_dyn_entry as entry
-point the absolute address of the stack is computed correctly on entry.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/test_encl_bootstrap.S | 6 ++++++
- 1 file changed, 6 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/test_encl_bootstrap.S b/tools/testing/selftests/sgx/test_encl_bootstrap.S
-index 82fb0dfcbd23..03ae0f57e29d 100644
---- a/tools/testing/selftests/sgx/test_encl_bootstrap.S
-+++ b/tools/testing/selftests/sgx/test_encl_bootstrap.S
-@@ -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
-
---
-2.35.1
-
diff --git a/0026-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch b/0026-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch
deleted file mode 100644
index 90cded650823..000000000000
--- a/0026-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch
+++ /dev/null
@@ -1,101 +0,0 @@
-From 8144b5b0b7ada1d19f79a080aab412eb7cf04fa8 Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:48 -0800
-Subject: [PATCH 26/34] selftests/sgx: Introduce TCS initialization enclave
- operation
-
-The Thread Control Structure (TCS) contains meta-data used by the
-hardware to save and restore thread specific information when
-entering/exiting the enclave. A TCS can be added to an initialized
-enclave by first adding a new regular enclave page, initializing the
-content of the new page from within the enclave, and then changing that
-page's type to a TCS.
-
-Support the initialization of a TCS from within the enclave.
-The variable information needed that should be provided from outside
-the enclave is the address of the TCS, address of the State Save Area
-(SSA), and the entry point that the thread should use to enter the
-enclave. With this information provided all needed fields of a TCS
-can be initialized.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/defines.h | 8 +++++++
- tools/testing/selftests/sgx/test_encl.c | 30 +++++++++++++++++++++++++
- 2 files changed, 38 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/defines.h b/tools/testing/selftests/sgx/defines.h
-index b638eb98c80c..d8587c971941 100644
---- a/tools/testing/selftests/sgx/defines.h
-+++ b/tools/testing/selftests/sgx/defines.h
-@@ -26,6 +26,7 @@ enum encl_op_type {
- ENCL_OP_NOP,
- ENCL_OP_EACCEPT,
- ENCL_OP_EMODPE,
-+ ENCL_OP_INIT_TCS_PAGE,
- ENCL_OP_MAX,
- };
-
-@@ -68,4 +69,11 @@ struct encl_op_emodpe {
- 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 */
-diff --git a/tools/testing/selftests/sgx/test_encl.c b/tools/testing/selftests/sgx/test_encl.c
-index 5b6c65331527..c0d6397295e3 100644
---- a/tools/testing/selftests/sgx/test_encl.c
-+++ b/tools/testing/selftests/sgx/test_encl.c
-@@ -57,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;
-@@ -100,6 +129,7 @@ void encl_body(void *rdi, void *rsi)
- 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;
---
-2.35.1
-
diff --git a/0027-selftests-sgx-Test-complete-changing-of-page-type-fl.patch b/0027-selftests-sgx-Test-complete-changing-of-page-type-fl.patch
deleted file mode 100644
index 2e815342d31b..000000000000
--- a/0027-selftests-sgx-Test-complete-changing-of-page-type-fl.patch
+++ /dev/null
@@ -1,451 +0,0 @@
-From eac764a6b526bdeed60743c0452e75d991c8a5fa Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:49 -0800
-Subject: [PATCH 27/34] selftests/sgx: Test complete changing of page type flow
-
-Support for changing an enclave page's type enables an initialized
-enclave to be expanded with support for more threads by changing the
-type of a regular enclave page to that of a Thread Control Structure
-(TCS). Additionally, being able to change a TCS or regular enclave
-page's type to be trimmed (SGX_PAGE_TYPE_TRIM) initiates the removal
-of the page from the enclave.
-
-Test changing page type to TCS as well as page removal flows
-in two phases: In the first phase support for a new thread is
-dynamically added to an initialized enclave and in the second phase
-the pages associated with the new thread are removed from the enclave.
-As an additional sanity check after the second phase the page used as
-a TCS page during the first phase is added back as a regular page and
-ensured that it can be written to (which is not possible if it was a
-TCS page).
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/load.c | 41 ++++
- tools/testing/selftests/sgx/main.c | 347 +++++++++++++++++++++++++++++
- tools/testing/selftests/sgx/main.h | 1 +
- 3 files changed, 389 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/load.c b/tools/testing/selftests/sgx/load.c
-index 006b464c8fc9..94bdeac1cf04 100644
---- a/tools/testing/selftests/sgx/load.c
-+++ b/tools/testing/selftests/sgx/load.c
-@@ -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";
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index 68285603b3f0..53a581bd56c5 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -1125,4 +1125,351 @@ TEST_F(enclave, augment_via_eaccept)
- munmap(addr, PAGE_SIZE);
- }
-
-+/*
-+ * SGX2 page type modification test in two phases:
-+ * Phase 1:
-+ * Create a new TCS, consisting out of three new pages (stack page with regular
-+ * page type, SSA page with regular page type, and TCS page with TCS page
-+ * type) in an initialized enclave and run a simple workload within it.
-+ * Phase 2:
-+ * Remove the three pages added in phase 1, add a new regular page at the
-+ * same address that previously hosted the TCS page and verify that it can
-+ * be modified.
-+ */
-+TEST_F(enclave, tcs_create)
-+{
-+ struct encl_op_init_tcs_page init_tcs_page_op;
-+ struct sgx_enclave_remove_pages remove_ioc;
-+ struct encl_op_get_from_addr get_addr_op;
-+ struct encl_op_put_to_addr put_addr_op;
-+ struct encl_op_get_from_buf get_buf_op;
-+ struct encl_op_put_to_buf put_buf_op;
-+ void *addr, *tcs, *stack_end, *ssa;
-+ struct encl_op_eaccept eaccept_op;
-+ struct sgx_enclave_modt modt_ioc;
-+ struct sgx_secinfo secinfo;
-+ size_t total_size = 0;
-+ uint64_t val_64;
-+ int errno_save;
-+ int ret, i;
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl,
-+ _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ /*
-+ * Hardware (SGX2) and kernel support is needed for this test. Start
-+ * with check that test has a chance of succeeding.
-+ */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+
-+ if (ret == -1) {
-+ if (errno == ENOTTY)
-+ SKIP(return, "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()");
-+ else if (errno == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+ }
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ EXPECT_EQ(ret, -1);
-+
-+ /*
-+ * Add three regular pages via EAUG: one will be the TCS stack, one
-+ * will be the TCS SSA, and one will be the new TCS. The stack and
-+ * SSA will remain as regular pages, the TCS page will need its
-+ * type changed after populated with needed data.
-+ */
-+ for (i = 0; i < self->encl.nr_segments; i++) {
-+ struct encl_segment *seg = &self->encl.segment_tbl[i];
-+
-+ total_size += seg->size;
-+ }
-+
-+ /*
-+ * Actual enclave size is expected to be larger than the loaded
-+ * test enclave since enclave size must be a power of 2 in bytes while
-+ * test_encl does not consume it all.
-+ */
-+ EXPECT_LT(total_size + 3 * PAGE_SIZE, self->encl.encl_size);
-+
-+ /*
-+ * mmap() three pages at end of existing enclave to be used for the
-+ * three new pages.
-+ */
-+ addr = mmap((void *)self->encl.encl_base + total_size, 3 * PAGE_SIZE,
-+ PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED,
-+ self->encl.fd, 0);
-+ EXPECT_NE(addr, MAP_FAILED);
-+
-+ self->run.exception_vector = 0;
-+ self->run.exception_error_code = 0;
-+ self->run.exception_addr = 0;
-+
-+ stack_end = (void *)self->encl.encl_base + total_size;
-+ tcs = (void *)self->encl.encl_base + total_size + PAGE_SIZE;
-+ ssa = (void *)self->encl.encl_base + total_size + 2 * PAGE_SIZE;
-+
-+ /*
-+ * Run EACCEPT on each new page to trigger the
-+ * EACCEPT->(#PF)->EAUG->EACCEPT(again without a #PF) flow.
-+ */
-+
-+ eaccept_op.epc_addr = (unsigned long)stack_end;
-+ eaccept_op.flags = SGX_SECINFO_R | SGX_SECINFO_W | SGX_SECINFO_REG | SGX_SECINFO_PENDING;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ if (self->run.exception_vector == 14 &&
-+ self->run.exception_error_code == 4 &&
-+ self->run.exception_addr == (unsigned long)stack_end) {
-+ munmap(addr, 3 * PAGE_SIZE);
-+ SKIP(return, "Kernel does not support adding pages to initialized enclave");
-+ }
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ eaccept_op.epc_addr = (unsigned long)ssa;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ eaccept_op.epc_addr = (unsigned long)tcs;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /*
-+ * Three new pages added to enclave. Now populate the TCS page with
-+ * needed data. This should be done from within enclave. Provide
-+ * the function that will do the actual data population with needed
-+ * data.
-+ */
-+
-+ /*
-+ * New TCS will use the "encl_dyn_entry" entrypoint that expects
-+ * stack to begin in page before TCS page.
-+ */
-+ val_64 = encl_get_entry(&self->encl, "encl_dyn_entry");
-+ EXPECT_NE(val_64, 0);
-+
-+ init_tcs_page_op.tcs_page = (unsigned long)tcs;
-+ init_tcs_page_op.ssa = (unsigned long)total_size + 2 * PAGE_SIZE;
-+ init_tcs_page_op.entry = val_64;
-+ init_tcs_page_op.header.type = ENCL_OP_INIT_TCS_PAGE;
-+
-+ EXPECT_EQ(ENCL_CALL(&init_tcs_page_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /* Change TCS page type to TCS. */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = SGX_PAGE_TYPE_TCS << 8;
-+ modt_ioc.offset = total_size + PAGE_SIZE;
-+ modt_ioc.length = PAGE_SIZE;
-+ modt_ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(modt_ioc.result, 0);
-+ EXPECT_EQ(modt_ioc.count, 4096);
-+
-+ /* EACCEPT new TCS page from enclave. */
-+ eaccept_op.epc_addr = (unsigned long)tcs;
-+ eaccept_op.flags = SGX_SECINFO_TCS | SGX_SECINFO_MODIFIED;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /* Run workload from new TCS. */
-+ self->run.tcs = (unsigned long)tcs;
-+
-+ /*
-+ * Simple workload to write to data buffer and read value back.
-+ */
-+ put_buf_op.header.type = ENCL_OP_PUT_TO_BUFFER;
-+ put_buf_op.value = MAGIC;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_buf_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ get_buf_op.header.type = ENCL_OP_GET_FROM_BUFFER;
-+ get_buf_op.value = 0;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_buf_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_buf_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Phase 2 of test:
-+ * Remove pages associated with new TCS, create a regular page
-+ * where TCS page used to be and verify it can be used as a regular
-+ * page.
-+ */
-+
-+ /* Start page removal by requesting change of page type to PT_TRIM. */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = SGX_PAGE_TYPE_TRIM << 8;
-+ modt_ioc.offset = total_size;
-+ modt_ioc.length = 3 * PAGE_SIZE;
-+ modt_ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(modt_ioc.result, 0);
-+ EXPECT_EQ(modt_ioc.count, 3 * PAGE_SIZE);
-+
-+ /*
-+ * Enter enclave via TCS #1 and approve page removal by sending
-+ * EACCEPT for each of three removed pages.
-+ */
-+ self->run.tcs = self->encl.encl_base;
-+
-+ eaccept_op.epc_addr = (unsigned long)stack_end;
-+ eaccept_op.flags = SGX_SECINFO_TRIM | SGX_SECINFO_MODIFIED;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ eaccept_op.epc_addr = (unsigned long)tcs;
-+ eaccept_op.ret = 0;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ eaccept_op.epc_addr = (unsigned long)ssa;
-+ eaccept_op.ret = 0;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /* Send final ioctl() to complete page removal. */
-+ memset(&remove_ioc, 0, sizeof(remove_ioc));
-+
-+ remove_ioc.offset = total_size;
-+ remove_ioc.length = 3 * PAGE_SIZE;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_REMOVE_PAGES, &remove_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(remove_ioc.count, 3 * PAGE_SIZE);
-+
-+ /*
-+ * Enter enclave via TCS #1 and access location where TCS #3 was to
-+ * trigger dynamic add of regular page at that location.
-+ */
-+ eaccept_op.epc_addr = (unsigned long)tcs;
-+ eaccept_op.flags = SGX_SECINFO_R | SGX_SECINFO_W | SGX_SECINFO_REG | SGX_SECINFO_PENDING;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /*
-+ * New page should be accessible from within enclave - write to it.
-+ */
-+ put_addr_op.value = MAGIC;
-+ put_addr_op.addr = (unsigned long)tcs;
-+ put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Read memory from newly added page that was just written to,
-+ * confirming that data previously written (MAGIC) is present.
-+ */
-+ get_addr_op.value = 0;
-+ get_addr_op.addr = (unsigned long)tcs;
-+ get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ munmap(addr, 3 * PAGE_SIZE);
-+}
-+
- TEST_HARNESS_MAIN
-diff --git a/tools/testing/selftests/sgx/main.h b/tools/testing/selftests/sgx/main.h
-index b45c52ec7ab3..fc585be97e2f 100644
---- a/tools/testing/selftests/sgx/main.h
-+++ b/tools/testing/selftests/sgx/main.h
-@@ -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);
---
-2.35.1
-
diff --git a/0028-selftests-sgx-Test-faulty-enclave-behavior.patch b/0028-selftests-sgx-Test-faulty-enclave-behavior.patch
deleted file mode 100644
index 6a2e38d86227..000000000000
--- a/0028-selftests-sgx-Test-faulty-enclave-behavior.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-From a0c9bfe1e732cbfb9fd5f021373ac71be68daab6 Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:50 -0800
-Subject: [PATCH 28/34] selftests/sgx: Test faulty enclave behavior
-
-Removing a page from an initialized enclave involves three steps:
-first the user requests changing the page type to SGX_PAGE_TYPE_TRIM
-via an ioctl(), on success the ENCLU[EACCEPT] instruction needs to be
-run from within the enclave to accept the page removal, finally the
-user requests page removal to be completed via an ioctl(). Only after
-acceptance (ENCLU[EACCEPT]) from within the enclave can the kernel
-remove the page from a running enclave.
-
-Test the behavior when the user's request to change the page type
-succeeds, but the ENCLU[EACCEPT] instruction is not run before the
-ioctl() requesting page removal is run. This should not be permitted.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/main.c | 116 +++++++++++++++++++++++++++++
- 1 file changed, 116 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index 53a581bd56c5..e9513ced1853 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -1472,4 +1472,120 @@ TEST_F(enclave, tcs_create)
- munmap(addr, 3 * PAGE_SIZE);
- }
-
-+/*
-+ * Ensure sane behavior if user requests page removal, does not run
-+ * EACCEPT from within enclave but still attempts to finalize page removal
-+ * with the SGX_IOC_ENCLAVE_REMOVE_PAGES ioctl(). The latter should fail
-+ * because the removal was not EACCEPTed from within the enclave.
-+ */
-+TEST_F(enclave, remove_added_page_no_eaccept)
-+{
-+ struct sgx_enclave_remove_pages remove_ioc;
-+ struct encl_op_get_from_addr get_addr_op;
-+ struct encl_op_put_to_addr put_addr_op;
-+ struct sgx_enclave_modt modt_ioc;
-+ struct sgx_secinfo secinfo;
-+ unsigned long data_start;
-+ int ret, errno_save;
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ /*
-+ * Hardware (SGX2) and kernel support is needed for this test. Start
-+ * with check that test has a chance of succeeding.
-+ */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+
-+ if (ret == -1) {
-+ if (errno == ENOTTY)
-+ SKIP(return, "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()");
-+ else if (errno == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+ }
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ EXPECT_EQ(ret, -1);
-+
-+ /*
-+ * Page that will be removed is the second data page in the .data
-+ * segment. This forms part of the local encl_buffer within the
-+ * enclave.
-+ */
-+ data_start = self->encl.encl_base +
-+ encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+
-+ /*
-+ * Sanity check that page at @data_start is writable before
-+ * removing it.
-+ *
-+ * Start by writing MAGIC to test page.
-+ */
-+ put_addr_op.value = MAGIC;
-+ put_addr_op.addr = data_start;
-+ put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Read memory that was just written to, confirming that data
-+ * previously written (MAGIC) is present.
-+ */
-+ get_addr_op.value = 0;
-+ get_addr_op.addr = data_start;
-+ get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /* Start page removal by requesting change of page type to PT_TRIM */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = SGX_PAGE_TYPE_TRIM << 8;
-+ modt_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ modt_ioc.length = PAGE_SIZE;
-+ modt_ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(modt_ioc.result, 0);
-+ EXPECT_EQ(modt_ioc.count, 4096);
-+
-+ /* Skip EACCEPT */
-+
-+ /* Send final ioctl() to complete page removal */
-+ memset(&remove_ioc, 0, sizeof(remove_ioc));
-+
-+ remove_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ remove_ioc.length = PAGE_SIZE;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_REMOVE_PAGES, &remove_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ /* Operation not permitted since EACCEPT was omitted. */
-+ EXPECT_EQ(ret, -1);
-+ EXPECT_EQ(errno_save, EPERM);
-+ EXPECT_EQ(remove_ioc.count, 0);
-+}
-+
- TEST_HARNESS_MAIN
---
-2.35.1
-
diff --git a/0029-selftests-sgx-Test-invalid-access-to-removed-enclave.patch b/0029-selftests-sgx-Test-invalid-access-to-removed-enclave.patch
deleted file mode 100644
index bf5b43a91dbe..000000000000
--- a/0029-selftests-sgx-Test-invalid-access-to-removed-enclave.patch
+++ /dev/null
@@ -1,293 +0,0 @@
-From c2acf1ff5207096387acf34a2f5f3492b626cf38 Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:51 -0800
-Subject: [PATCH 29/34] selftests/sgx: Test invalid access to removed enclave
- page
-
-Removing a page from an initialized enclave involves three steps:
-(1) the user requests changing the page type to SGX_PAGE_TYPE_TRIM
-via the SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl(), (2) on success the
-ENCLU[EACCEPT] instruction is run from within the enclave to accept
-the page removal, (3) the user initiates the actual removal of the
-page via the SGX_IOC_ENCLAVE_REMOVE_PAGES ioctl().
-
-Test two possible invalid accesses during the page removal flow:
-* Test the behavior when a request to remove the page by changing its
- type to SGX_PAGE_TYPE_TRIM completes successfully but instead of
- executing ENCLU[EACCEPT] from within the enclave the enclave attempts
- to read from the page. Even though the page is accessible from the
- page table entries its type is SGX_PAGE_TYPE_TRIM and thus not
- accessible according to SGX. The expected behavior is a page fault
- with the SGX flag set in the error code.
-* Test the behavior when the page type is changed successfully and
- ENCLU[EACCEPT] was run from within the enclave. The final ioctl(),
- SGX_IOC_ENCLAVE_REMOVE_PAGES, is omitted and replaced with an
- attempt to access the page. Even though the page is accessible
- from the page table entries its type is SGX_PAGE_TYPE_TRIM and
- thus not accessible according to SGX. The expected behavior is
- a page fault with the SGX flag set in the error code.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/main.c | 247 +++++++++++++++++++++++++++++
- 1 file changed, 247 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index e9513ced1853..239d3c9df169 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -1588,4 +1588,251 @@ TEST_F(enclave, remove_added_page_no_eaccept)
- EXPECT_EQ(remove_ioc.count, 0);
- }
-
-+/*
-+ * Request enclave page removal but instead of correctly following with
-+ * EACCEPT a read attempt to page is made from within the enclave.
-+ */
-+TEST_F(enclave, remove_added_page_invalid_access)
-+{
-+ struct encl_op_get_from_addr get_addr_op;
-+ struct encl_op_put_to_addr put_addr_op;
-+ struct sgx_enclave_modt ioc;
-+ struct sgx_secinfo secinfo;
-+ unsigned long data_start;
-+ int ret, errno_save;
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ /*
-+ * Hardware (SGX2) and kernel support is needed for this test. Start
-+ * with check that test has a chance of succeeding.
-+ */
-+ memset(&ioc, 0, sizeof(ioc));
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &ioc);
-+
-+ if (ret == -1) {
-+ if (errno == ENOTTY)
-+ SKIP(return, "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()");
-+ else if (errno == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+ }
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ EXPECT_EQ(ret, -1);
-+
-+ /*
-+ * Page that will be removed is the second data page in the .data
-+ * segment. This forms part of the local encl_buffer within the
-+ * enclave.
-+ */
-+ data_start = self->encl.encl_base +
-+ encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+
-+ /*
-+ * Sanity check that page at @data_start is writable before
-+ * removing it.
-+ *
-+ * Start by writing MAGIC to test page.
-+ */
-+ put_addr_op.value = MAGIC;
-+ put_addr_op.addr = data_start;
-+ put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Read memory that was just written to, confirming that data
-+ * previously written (MAGIC) is present.
-+ */
-+ get_addr_op.value = 0;
-+ get_addr_op.addr = data_start;
-+ get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /* Start page removal by requesting change of page type to PT_TRIM. */
-+ memset(&ioc, 0, sizeof(ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = SGX_PAGE_TYPE_TRIM << 8;
-+ ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ ioc.length = PAGE_SIZE;
-+ ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(ioc.result, 0);
-+ EXPECT_EQ(ioc.count, 4096);
-+
-+ /*
-+ * Read from page that was just removed.
-+ */
-+ get_addr_op.value = 0;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ /*
-+ * From kernel perspective the page is present but according to SGX the
-+ * page should not be accessible so a #PF with SGX bit set is
-+ * expected.
-+ */
-+
-+ EXPECT_EQ(self->run.function, ERESUME);
-+ EXPECT_EQ(self->run.exception_vector, 14);
-+ EXPECT_EQ(self->run.exception_error_code, 0x8005);
-+ EXPECT_EQ(self->run.exception_addr, data_start);
-+}
-+
-+/*
-+ * Request enclave page removal and correctly follow with
-+ * EACCEPT but do not follow with removal ioctl() but instead a read attempt
-+ * to removed page is made from within the enclave.
-+ */
-+TEST_F(enclave, remove_added_page_invalid_access_after_eaccept)
-+{
-+ struct encl_op_get_from_addr get_addr_op;
-+ struct encl_op_put_to_addr put_addr_op;
-+ struct encl_op_eaccept eaccept_op;
-+ struct sgx_enclave_modt ioc;
-+ struct sgx_secinfo secinfo;
-+ unsigned long data_start;
-+ int ret, errno_save;
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ /*
-+ * Hardware (SGX2) and kernel support is needed for this test. Start
-+ * with check that test has a chance of succeeding.
-+ */
-+ memset(&ioc, 0, sizeof(ioc));
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &ioc);
-+
-+ if (ret == -1) {
-+ if (errno == ENOTTY)
-+ SKIP(return, "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()");
-+ else if (errno == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+ }
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ EXPECT_EQ(ret, -1);
-+
-+ /*
-+ * Page that will be removed is the second data page in the .data
-+ * segment. This forms part of the local encl_buffer within the
-+ * enclave.
-+ */
-+ data_start = self->encl.encl_base +
-+ encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+
-+ /*
-+ * Sanity check that page at @data_start is writable before
-+ * removing it.
-+ *
-+ * Start by writing MAGIC to test page.
-+ */
-+ put_addr_op.value = MAGIC;
-+ put_addr_op.addr = data_start;
-+ put_addr_op.header.type = ENCL_OP_PUT_TO_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /*
-+ * Read memory that was just written to, confirming that data
-+ * previously written (MAGIC) is present.
-+ */
-+ get_addr_op.value = 0;
-+ get_addr_op.addr = data_start;
-+ get_addr_op.header.type = ENCL_OP_GET_FROM_ADDRESS;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(get_addr_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+
-+ /* Start page removal by requesting change of page type to PT_TRIM. */
-+ memset(&ioc, 0, sizeof(ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = SGX_PAGE_TYPE_TRIM << 8;
-+ ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ ioc.length = PAGE_SIZE;
-+ ioc.secinfo = (unsigned long)&secinfo;
-+
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(ioc.result, 0);
-+ EXPECT_EQ(ioc.count, 4096);
-+
-+ eaccept_op.epc_addr = (unsigned long)data_start;
-+ eaccept_op.ret = 0;
-+ eaccept_op.flags = SGX_SECINFO_TRIM | SGX_SECINFO_MODIFIED;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ /* Skip ioctl() to remove page. */
-+
-+ /*
-+ * Read from page that was just removed.
-+ */
-+ get_addr_op.value = 0;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_addr_op, &self->run, true), 0);
-+
-+ /*
-+ * From kernel perspective the page is present but according to SGX the
-+ * page should not be accessible so a #PF with SGX bit set is
-+ * expected.
-+ */
-+
-+ EXPECT_EQ(self->run.function, ERESUME);
-+ EXPECT_EQ(self->run.exception_vector, 14);
-+ EXPECT_EQ(self->run.exception_error_code, 0x8005);
-+ EXPECT_EQ(self->run.exception_addr, data_start);
-+}
-+
- TEST_HARNESS_MAIN
---
-2.35.1
-
diff --git a/0030-selftests-sgx-Test-reclaiming-of-untouched-page.patch b/0030-selftests-sgx-Test-reclaiming-of-untouched-page.patch
deleted file mode 100644
index 76b5d00101ae..000000000000
--- a/0030-selftests-sgx-Test-reclaiming-of-untouched-page.patch
+++ /dev/null
@@ -1,120 +0,0 @@
-From 88e756e4e0a3a54a226635cd8e3a1a0c26f15032 Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:52 -0800
-Subject: [PATCH 30/34] selftests/sgx: Test reclaiming of untouched page
-
-Removing a page from an initialized enclave involves three steps:
-(1) the user requests changing the page type to PT_TRIM via the
- SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()
-(2) on success the ENCLU[EACCEPT] instruction is run from within
- the enclave to accept the page removal
-(3) the user initiates the actual removal of the page via the
- SGX_IOC_ENCLAVE_REMOVE_PAGES ioctl().
-
-Remove a page that has never been accessed. This means that when the
-first ioctl() requesting page removal arrives, there will be no page
-table entry, yet a valid page table entry needs to exist for the
-ENCLU[EACCEPT] function to succeed. In this test it is verified that
-a page table entry can still be installed for a page that is in the
-process of being removed.
-
-Suggested-by: Haitao Huang <haitao.huang@intel.com>
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/main.c | 82 ++++++++++++++++++++++++++++++
- 1 file changed, 82 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index 239d3c9df169..4fe5a0324c97 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -1835,4 +1835,86 @@ TEST_F(enclave, remove_added_page_invalid_access_after_eaccept)
- EXPECT_EQ(self->run.exception_addr, data_start);
- }
-
-+TEST_F(enclave, remove_untouched_page)
-+{
-+ struct sgx_enclave_remove_pages remove_ioc;
-+ struct encl_op_eaccept eaccept_op;
-+ struct sgx_enclave_modt modt_ioc;
-+ struct sgx_secinfo secinfo;
-+ unsigned long data_start;
-+ int ret, errno_save;
-+
-+ ASSERT_TRUE(setup_test_encl(ENCL_HEAP_SIZE_DEFAULT, &self->encl, _metadata));
-+
-+ /*
-+ * Hardware (SGX2) and kernel support is needed for this test. Start
-+ * with check that test has a chance of succeeding.
-+ */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+
-+ if (ret == -1) {
-+ if (errno == ENOTTY)
-+ SKIP(return, "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()");
-+ else if (errno == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+ }
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ EXPECT_EQ(ret, -1);
-+
-+ /* SGX2 is supported by kernel and hardware, test can proceed. */
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ data_start = self->encl.encl_base +
-+ encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = SGX_PAGE_TYPE_TRIM << 8;
-+ modt_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ modt_ioc.length = PAGE_SIZE;
-+ modt_ioc.secinfo = (unsigned long)&secinfo;
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(modt_ioc.result, 0);
-+ EXPECT_EQ(modt_ioc.count, 4096);
-+
-+ /*
-+ * Enter enclave via TCS #1 and approve page removal by sending
-+ * EACCEPT for removed page.
-+ */
-+
-+ eaccept_op.epc_addr = data_start;
-+ eaccept_op.flags = SGX_SECINFO_TRIM | SGX_SECINFO_MODIFIED;
-+ eaccept_op.ret = 0;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ EXPECT_EQ(eaccept_op.ret, 0);
-+
-+ memset(&remove_ioc, 0, sizeof(remove_ioc));
-+
-+ remove_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
-+ remove_ioc.length = PAGE_SIZE;
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_REMOVE_PAGES, &remove_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(remove_ioc.count, 4096);
-+}
-+
- TEST_HARNESS_MAIN
---
-2.35.1
-
diff --git a/0032-selftests-sgx-Page-removal-stress-test.patch b/0032-selftests-sgx-Page-removal-stress-test.patch
deleted file mode 100644
index 538943044a94..000000000000
--- a/0032-selftests-sgx-Page-removal-stress-test.patch
+++ /dev/null
@@ -1,156 +0,0 @@
-From b8bce2280c7d601d875229921cc6126ac55e84c3 Mon Sep 17 00:00:00 2001
-From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Mon, 7 Feb 2022 16:45:54 -0800
-Subject: [PATCH 32/34] selftests/sgx: Page removal stress test
-
-Create enclave with additional heap that consumes all physical SGX
-memory and then remove it.
-
-Depending on the available SGX memory this test could take a
-significant time to run (several minutes) as it (1) creates the
-enclave, (2) changes the type of every page to be trimmed,
-(3) enters the enclave once per page to run EACCEPT, before
-(4) the pages are finally removed.
-
-Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
----
- tools/testing/selftests/sgx/main.c | 122 +++++++++++++++++++++++++++++
- 1 file changed, 122 insertions(+)
-
-diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
-index 4fe5a0324c97..22abda2696e2 100644
---- a/tools/testing/selftests/sgx/main.c
-+++ b/tools/testing/selftests/sgx/main.c
-@@ -378,7 +378,129 @@ TEST_F(enclave, unclobbered_vdso_oversubscribed)
- EXPECT_EQ(get_op.value, MAGIC);
- EXPECT_EEXIT(&self->run);
- EXPECT_EQ(self->run.user_data, 0);
-+}
-+
-+TEST_F_TIMEOUT(enclave, unclobbered_vdso_oversubscribed_remove, 900)
-+{
-+ struct sgx_enclave_remove_pages remove_ioc;
-+ struct encl_op_get_from_buf get_op;
-+ struct encl_op_eaccept eaccept_op;
-+ struct encl_op_put_to_buf put_op;
-+ struct sgx_enclave_modt modt_ioc;
-+ struct sgx_secinfo secinfo;
-+ struct encl_segment *heap;
-+ unsigned long total_mem;
-+ int ret, errno_save;
-+ unsigned long addr;
-+ unsigned long i;
-+
-+ /*
-+ * Create enclave with additional heap that is as big as all
-+ * available physical SGX memory.
-+ */
-+ total_mem = get_total_epc_mem();
-+ ASSERT_NE(total_mem, 0);
-+ TH_LOG("Creating an enclave with %lu bytes heap may take a while ...",
-+ total_mem);
-+ ASSERT_TRUE(setup_test_encl(total_mem, &self->encl, _metadata));
-+
-+ /*
-+ * Hardware (SGX2) and kernel support is needed for this test. Start
-+ * with check that test has a chance of succeeding.
-+ */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+
-+ if (ret == -1) {
-+ if (errno == ENOTTY)
-+ SKIP(return, "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPE ioctl()");
-+ else if (errno == ENODEV)
-+ SKIP(return, "System does not support SGX2");
-+ }
-+
-+ /*
-+ * Invalid parameters were provided during sanity check,
-+ * expect command to fail.
-+ */
-+ EXPECT_EQ(ret, -1);
-+
-+ /* SGX2 is supported by kernel and hardware, test can proceed. */
-+ memset(&self->run, 0, sizeof(self->run));
-+ self->run.tcs = self->encl.encl_base;
-+
-+ heap = &self->encl.segment_tbl[self->encl.nr_segments - 1];
-+
-+ put_op.header.type = ENCL_OP_PUT_TO_BUFFER;
-+ put_op.value = MAGIC;
-+
-+ EXPECT_EQ(ENCL_CALL(&put_op, &self->run, false), 0);
-+
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.user_data, 0);
-+
-+ get_op.header.type = ENCL_OP_GET_FROM_BUFFER;
-+ get_op.value = 0;
-+
-+ EXPECT_EQ(ENCL_CALL(&get_op, &self->run, false), 0);
-+
-+ EXPECT_EQ(get_op.value, MAGIC);
-+ EXPECT_EEXIT(&self->run);
-+ EXPECT_EQ(self->run.user_data, 0);
-+
-+ /* Trim entire heap. */
-+ memset(&modt_ioc, 0, sizeof(modt_ioc));
-+ memset(&secinfo, 0, sizeof(secinfo));
-+
-+ secinfo.flags = SGX_PAGE_TYPE_TRIM << 8;
-+ modt_ioc.offset = heap->offset;
-+ modt_ioc.length = heap->size;
-+ modt_ioc.secinfo = (unsigned long)&secinfo;
-+
-+ TH_LOG("Changing type of %zd bytes to trimmed may take a while ...",
-+ heap->size);
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPE, &modt_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(modt_ioc.result, 0);
-+ EXPECT_EQ(modt_ioc.count, heap->size);
-+
-+ /* EACCEPT all removed pages. */
-+ addr = self->encl.encl_base + heap->offset;
-+
-+ eaccept_op.flags = SGX_SECINFO_TRIM | SGX_SECINFO_MODIFIED;
-+ eaccept_op.header.type = ENCL_OP_EACCEPT;
-+
-+ TH_LOG("Entering enclave to run EACCEPT for each page of %zd bytes may take a while ...",
-+ heap->size);
-+ for (i = 0; i < heap->size; i += 4096) {
-+ eaccept_op.epc_addr = addr + i;
-+ eaccept_op.ret = 0;
-
-+ EXPECT_EQ(ENCL_CALL(&eaccept_op, &self->run, true), 0);
-+
-+ EXPECT_EQ(self->run.exception_vector, 0);
-+ EXPECT_EQ(self->run.exception_error_code, 0);
-+ EXPECT_EQ(self->run.exception_addr, 0);
-+ ASSERT_EQ(eaccept_op.ret, 0);
-+ ASSERT_EQ(self->run.function, EEXIT);
-+ }
-+
-+ /* Complete page removal. */
-+ memset(&remove_ioc, 0, sizeof(remove_ioc));
-+
-+ remove_ioc.offset = heap->offset;
-+ remove_ioc.length = heap->size;
-+
-+ TH_LOG("Removing %zd bytes from enclave may take a while ...",
-+ heap->size);
-+ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_REMOVE_PAGES, &remove_ioc);
-+ errno_save = ret == -1 ? errno : 0;
-+
-+ EXPECT_EQ(ret, 0);
-+ EXPECT_EQ(errno_save, 0);
-+ EXPECT_EQ(remove_ioc.count, heap->size);
- }
-
- TEST_F(enclave, clobbered_vdso)
---
-2.35.1
-