summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarkko Sakkinen2022-05-13 09:11:26 +0300
committerJarkko Sakkinen2022-05-13 09:14:34 +0300
commit1c9f12ad04044fca8cbf602e3295c26b0829ea97 (patch)
tree4a0ec208cd7c2cb5d0354e98a03e4ed7a108dd70
parent1197ad7586a7c19e4877147b740e6cecef3814f5 (diff)
downloadaur-1c9f12ad04044fca8cbf602e3295c26b0829ea97.tar.gz
build: update to 5.17.7.arch1
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@iki.fi>
-rw-r--r--.SRCINFO6
-rw-r--r--0001-x86-sgx-Disconnect-backing-page-references-from-dirt.patch167
-rw-r--r--0002-x86-sgx-Mark-PCMD-page-as-dirty-when-modifying-conte.patch39
-rw-r--r--0003-x86-sgx-Obtain-backing-storage-page-with-enclave-mut.patch130
-rw-r--r--0004-x86-sgx-Fix-race-between-reclaimer-and-page-fault-ha.patch255
-rw-r--r--0005-x86-sgx-Ensure-no-data-in-PCMD-page-after-truncate.patch59
-rw-r--r--0006-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch (renamed from 0001-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch)8
-rw-r--r--0007-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch (renamed from 0002-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch)8
-rw-r--r--0008-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch (renamed from 0003-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch)8
-rw-r--r--0009-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch (renamed from 0004-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch)8
-rw-r--r--0010-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch (renamed from 0005-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch)20
-rw-r--r--0011-x86-sgx-Export-sgx_encl_ewb_cpumask.patch (renamed from 0006-x86-sgx-Export-sgx_encl_ewb_cpumask.patch)20
-rw-r--r--0012-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch (renamed from 0007-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch)24
-rw-r--r--0013-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch (renamed from 0008-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch)20
-rw-r--r--0014-x86-sgx-Make-sgx_ipi_cb-available-internally.patch (renamed from 0009-x86-sgx-Make-sgx_ipi_cb-available-internally.patch)12
-rw-r--r--0015-x86-sgx-Create-utility-to-validate-user-provided-off.patch (renamed from 0010-x86-sgx-Create-utility-to-validate-user-provided-off.patch)8
-rw-r--r--0016-x86-sgx-Keep-record-of-SGX-page-type.patch (renamed from 0011-x86-sgx-Keep-record-of-SGX-page-type.patch)11
-rw-r--r--0017-x86-sgx-Export-sgx_encl_-grow-shrink.patch (renamed from 0012-x86-sgx-Export-sgx_encl_-grow-shrink.patch)10
-rw-r--r--0018-x86-sgx-Export-sgx_encl_page_alloc.patch (renamed from 0013-x86-sgx-Export-sgx_encl_page_alloc.patch)16
-rw-r--r--0019-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch (renamed from 0014-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch)18
-rw-r--r--0020-x86-sgx-Support-restricting-of-enclave-page-permissi.patch (renamed from 0015-x86-sgx-Support-restricting-of-enclave-page-permissi.patch)22
-rw-r--r--0021-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch (renamed from 0016-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch)40
-rw-r--r--0022-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch (renamed from 0017-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch)12
-rw-r--r--0023-x86-sgx-Support-modifying-SGX-page-type.patch (renamed from 0018-x86-sgx-Support-modifying-SGX-page-type.patch)54
-rw-r--r--0024-x86-sgx-Support-complete-page-removal.patch (renamed from 0019-x86-sgx-Support-complete-page-removal.patch)25
-rw-r--r--0025-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch (renamed from 0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch)18
-rw-r--r--0026-Documentation-x86-Introduce-enclave-runtime-manageme.patch47
-rw-r--r--0027-selftests-sgx-Add-test-for-EPCM-permission-changes.patch356
-rw-r--r--0028-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch106
-rw-r--r--0029-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch302
-rw-r--r--0030-selftests-sgx-Introduce-dynamic-entry-point.patch50
-rw-r--r--0031-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch102
-rw-r--r--0032-selftests-sgx-Test-complete-changing-of-page-type-fl.patch448
-rw-r--r--0033-selftests-sgx-Test-faulty-enclave-behavior.patch149
-rw-r--r--0034-selftests-sgx-Test-invalid-access-to-removed-enclave.patch290
-rw-r--r--0035-selftests-sgx-Test-reclaiming-of-untouched-page.patch119
-rw-r--r--0036-selftests-sgx-Page-removal-stress-test.patch155
-rw-r--r--PKGBUILD60
38 files changed, 3003 insertions, 199 deletions
diff --git a/.SRCINFO b/.SRCINFO
index 82d2d12f7217..15e6dff4ce80 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,8 +1,8 @@
pkgbase = linux-sgx
pkgdesc = Linux
- pkgver = 5.17.4.arch1
+ pkgver = 5.17.7.arch1
pkgrel = 1
- url = https://github.com/archlinux/linux/commits/v5.17.4.arch1
+ url = https://github.com/archlinux/linux/commits/v5.17.7.arch1
arch = x86_64
license = GPL2
makedepends = bc
@@ -20,7 +20,7 @@ pkgbase = linux-sgx
makedepends = imagemagick
makedepends = git
options = !strip
- source = archlinux-linux::git+https://github.com/archlinux/linux?signed#tag=v5.17.4-arch1
+ source = archlinux-linux::git+https://github.com/archlinux/linux?signed#tag=v5.17.7-arch1
source = config
validpgpkeys = ABAF11C65A2970B130ABE3C479BE3E4300411886
validpgpkeys = 647F28654894E3BD457199BE38DBBDC86092693E
diff --git a/0001-x86-sgx-Disconnect-backing-page-references-from-dirt.patch b/0001-x86-sgx-Disconnect-backing-page-references-from-dirt.patch
new file mode 100644
index 000000000000..4d9839913e31
--- /dev/null
+++ b/0001-x86-sgx-Disconnect-backing-page-references-from-dirt.patch
@@ -0,0 +1,167 @@
+From 16c0d19cdf8ea458d7388593e7f9537bd545f3a7 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Thu, 12 May 2022 14:50:57 -0700
+Subject: [PATCH 01/36] x86/sgx: Disconnect backing page references from dirty
+ status
+
+SGX uses shmem backing storage to store encrypted enclave pages
+and their crypto metadata when enclave pages are moved out of
+enclave memory. Two shmem backing storage pages are associated with
+each enclave page - one backing page to contain the encrypted
+enclave page data and one backing page (shared by a few
+enclave pages) to contain the crypto metadata used by the
+processor to verify the enclave page when it is loaded back into
+the enclave.
+
+sgx_encl_put_backing() is used to release references to the
+backing storage and, optionally, mark both backing store pages
+as dirty.
+
+Managing references and dirty status together in this way results
+in both backing store pages marked as dirty, even if only one of
+the backing store pages are changed.
+
+Additionally, waiting until the page reference is dropped to set
+the page dirty risks a race with the page fault handler that
+may load outdated data into the enclave when a page is faulted
+right after it is reclaimed.
+
+Consider what happens if the reclaimer writes a page to the backing
+store and the page is immediately faulted back, before the reclaimer
+is able to set the dirty bit of the page:
+
+sgx_reclaim_pages() { sgx_vma_fault() {
+ ...
+ sgx_encl_get_backing();
+ ... ...
+ sgx_reclaimer_write() {
+ mutex_lock(&encl->lock);
+ /* Write data to backing store */
+ mutex_unlock(&encl->lock);
+ }
+ mutex_lock(&encl->lock);
+ __sgx_encl_eldu() {
+ ...
+ /*
+ * Enclave backing store
+ * page not released
+ * nor marked dirty -
+ * contents may not be
+ * up to date.
+ */
+ sgx_encl_get_backing();
+ ...
+ /*
+ * Enclave data restored
+ * from backing store
+ * and PCMD pages that
+ * are not up to date.
+ * ENCLS[ELDU] faults
+ * because of MAC or PCMD
+ * checking failure.
+ */
+ sgx_encl_put_backing();
+ }
+ ...
+ /* set page dirty */
+ sgx_encl_put_backing();
+ ...
+ mutex_unlock(&encl->lock);
+} }
+
+Remove the option to sgx_encl_put_backing() to set the backing
+pages as dirty and set the needed pages as dirty right after
+receiving important data while enclave mutex is held. This ensures that
+the page fault handler can get up to date data from a page and prepares
+the code for a following change where only one of the backing pages
+need to be marked as dirty.
+
+Cc: stable@vger.kernel.org
+Fixes: 1728ab54b4be ("x86/sgx: Add a page reclaimer")
+Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+Link: https://lore.kernel.org/linux-sgx/8922e48f-6646-c7cc-6393-7c78dcf23d23@intel.com/
+---
+ arch/x86/kernel/cpu/sgx/encl.c | 10 ++--------
+ arch/x86/kernel/cpu/sgx/encl.h | 2 +-
+ arch/x86/kernel/cpu/sgx/main.c | 6 ++++--
+ 3 files changed, 7 insertions(+), 11 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
+index 7c63a1911fae..398695a20605 100644
+--- a/arch/x86/kernel/cpu/sgx/encl.c
++++ b/arch/x86/kernel/cpu/sgx/encl.c
+@@ -94,7 +94,7 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
+ kunmap_atomic(pcmd_page);
+ kunmap_atomic((void *)(unsigned long)pginfo.contents);
+
+- sgx_encl_put_backing(&b, false);
++ sgx_encl_put_backing(&b);
+
+ sgx_encl_truncate_backing_page(encl, page_index);
+
+@@ -645,15 +645,9 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
+ /**
+ * sgx_encl_put_backing() - Unpin the backing storage
+ * @backing: data for accessing backing storage for the page
+- * @do_write: mark pages dirty
+ */
+-void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write)
++void sgx_encl_put_backing(struct sgx_backing *backing)
+ {
+- if (do_write) {
+- set_page_dirty(backing->pcmd);
+- set_page_dirty(backing->contents);
+- }
+-
+ put_page(backing->pcmd);
+ put_page(backing->contents);
+ }
+diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
+index fec43ca65065..d44e7372151f 100644
+--- a/arch/x86/kernel/cpu/sgx/encl.h
++++ b/arch/x86/kernel/cpu/sgx/encl.h
+@@ -107,7 +107,7 @@ void sgx_encl_release(struct kref *ref);
+ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm);
+ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
+ struct sgx_backing *backing);
+-void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write);
++void sgx_encl_put_backing(struct sgx_backing *backing);
+ int sgx_encl_test_and_clear_young(struct mm_struct *mm,
+ struct sgx_encl_page *page);
+
+diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
+index 8e4bc6453d26..e71df40a4f38 100644
+--- a/arch/x86/kernel/cpu/sgx/main.c
++++ b/arch/x86/kernel/cpu/sgx/main.c
+@@ -191,6 +191,8 @@ static int __sgx_encl_ewb(struct sgx_epc_page *epc_page, void *va_slot,
+ backing->pcmd_offset;
+
+ ret = __ewb(&pginfo, sgx_get_epc_virt_addr(epc_page), va_slot);
++ set_page_dirty(backing->pcmd);
++ set_page_dirty(backing->contents);
+
+ kunmap_atomic((void *)(unsigned long)(pginfo.metadata -
+ backing->pcmd_offset));
+@@ -320,7 +322,7 @@ static void sgx_reclaimer_write(struct sgx_epc_page *epc_page,
+ sgx_encl_free_epc_page(encl->secs.epc_page);
+ encl->secs.epc_page = NULL;
+
+- sgx_encl_put_backing(&secs_backing, true);
++ sgx_encl_put_backing(&secs_backing);
+ }
+
+ out:
+@@ -411,7 +413,7 @@ static void sgx_reclaim_pages(void)
+
+ encl_page = epc_page->owner;
+ sgx_reclaimer_write(epc_page, &backing[i]);
+- sgx_encl_put_backing(&backing[i], true);
++ sgx_encl_put_backing(&backing[i]);
+
+ kref_put(&encl_page->encl->refcount, sgx_encl_release);
+ epc_page->flags &= ~SGX_EPC_PAGE_RECLAIMER_TRACKED;
+--
+2.36.1
+
diff --git a/0002-x86-sgx-Mark-PCMD-page-as-dirty-when-modifying-conte.patch b/0002-x86-sgx-Mark-PCMD-page-as-dirty-when-modifying-conte.patch
new file mode 100644
index 000000000000..b1dabf98c596
--- /dev/null
+++ b/0002-x86-sgx-Mark-PCMD-page-as-dirty-when-modifying-conte.patch
@@ -0,0 +1,39 @@
+From 29ebcc3dd06578be9cb3d59007e9466cb336f618 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Thu, 12 May 2022 14:50:58 -0700
+Subject: [PATCH 02/36] x86/sgx: Mark PCMD page as dirty when modifying
+ contents
+
+Recent commit 08999b2489b4 ("x86/sgx: Free backing memory
+after faulting the enclave page") expanded __sgx_encl_eldu()
+to clear an enclave page's PCMD (Paging Crypto MetaData)
+from the PCMD page in the backing store after the enclave
+page is restored to the enclave.
+
+Since the PCMD page in the backing store is modified the page
+should be marked as dirty to ensure the modified data is retained.
+
+Cc: stable@vger.kernel.org
+Fixes: 08999b2489b4 ("x86/sgx: Free backing memory after faulting the enclave page")
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ arch/x86/kernel/cpu/sgx/encl.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
+index 398695a20605..5104a428b72c 100644
+--- a/arch/x86/kernel/cpu/sgx/encl.c
++++ b/arch/x86/kernel/cpu/sgx/encl.c
+@@ -84,6 +84,7 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
+ }
+
+ memset(pcmd_page + b.pcmd_offset, 0, sizeof(struct sgx_pcmd));
++ set_page_dirty(b.pcmd);
+
+ /*
+ * The area for the PCMD in the page was zeroed above. Check if the
+--
+2.36.1
+
diff --git a/0003-x86-sgx-Obtain-backing-storage-page-with-enclave-mut.patch b/0003-x86-sgx-Obtain-backing-storage-page-with-enclave-mut.patch
new file mode 100644
index 000000000000..622b25abd6b5
--- /dev/null
+++ b/0003-x86-sgx-Obtain-backing-storage-page-with-enclave-mut.patch
@@ -0,0 +1,130 @@
+From a455a2c6f55a696cfe170f3f62c1390760dab06c Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Thu, 12 May 2022 14:50:59 -0700
+Subject: [PATCH 03/36] x86/sgx: Obtain backing storage page with enclave mutex
+ held
+
+Haitao reported encountering a WARN triggered by the ENCLS[ELDU]
+instruction faulting with a #GP.
+
+The WARN is encountered when the reclaimer evicts a range of
+pages from the enclave when the same pages are faulted back
+right away.
+
+The SGX backing storage is accessed on two paths: when there
+are insufficient free pages in the EPC the reclaimer works
+to move enclave pages to the backing storage and as enclaves
+access pages that have been moved to the backing storage
+they are retrieved from there as part of page fault handling.
+
+An oversubscribed SGX system will often run the reclaimer and
+page fault handler concurrently and needs to ensure that the
+backing store is accessed safely between the reclaimer and
+the page fault handler. This is not the case because the
+reclaimer accesses the backing store without the enclave mutex
+while the page fault handler accesses the backing store with
+the enclave mutex.
+
+Consider the scenario where a page is faulted while a page sharing
+a PCMD page with the faulted page is being reclaimed. The
+consequence is a race between the reclaimer and page fault
+handler, the reclaimer attempting to access a PCMD at the
+same time it is truncated by the page fault handler. This
+could result in lost PCMD data. Data may still be
+lost if the reclaimer wins the race, this is addressed in
+the following patch.
+
+The reclaimer accesses pages from the backing storage without
+holding the enclave mutex and runs the risk of concurrently
+accessing the backing storage with the page fault handler that
+does access the backing storage with the enclave mutex held.
+
+In the scenario below a PCMD page is truncated from the backing
+store after all its pages have been loaded in to the enclave
+at the same time the PCMD page is loaded from the backing store
+when one of its pages are reclaimed:
+
+sgx_reclaim_pages() { sgx_vma_fault() {
+ ...
+ mutex_lock(&encl->lock);
+ ...
+ __sgx_encl_eldu() {
+ ...
+ if (pcmd_page_empty) {
+/*
+ * EPC page being reclaimed /*
+ * shares a PCMD page with an * PCMD page truncated
+ * enclave page that is being * while requested from
+ * faulted in. * reclaimer.
+ */ */
+sgx_encl_get_backing() <----------> sgx_encl_truncate_backing_page()
+ }
+ mutex_unlock(&encl->lock);
+} }
+
+In this scenario there is a race between the reclaimer and the page fault
+handler when the reclaimer attempts to get access to the same PCMD page
+that is being truncated. This could result in the reclaimer writing to
+the PCMD page that is then truncated, causing the PCMD data to be lost,
+or in a new PCMD page being allocated. The lost PCMD data may still occur
+after protecting the backing store access with the mutex - this is fixed
+in the next patch. By ensuring the backing store is accessed with the mutex
+held the enclave page state can be made accurate with the
+SGX_ENCL_PAGE_BEING_RECLAIMED flag accurately reflecting that a page
+is in the process of being reclaimed.
+
+Consistently protect the reclaimer's backing store access with the
+enclave's mutex to ensure that it can safely run concurrently with the
+page fault handler.
+
+Cc: stable@vger.kernel.org
+Fixes: 1728ab54b4be ("x86/sgx: Add a page reclaimer")
+Reported-by: Haitao Huang <haitao.huang@intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ arch/x86/kernel/cpu/sgx/main.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
+index e71df40a4f38..ab4ec54bbdd9 100644
+--- a/arch/x86/kernel/cpu/sgx/main.c
++++ b/arch/x86/kernel/cpu/sgx/main.c
+@@ -310,6 +310,7 @@ static void sgx_reclaimer_write(struct sgx_epc_page *epc_page,
+ sgx_encl_ewb(epc_page, backing);
+ encl_page->epc_page = NULL;
+ encl->secs_child_cnt--;
++ sgx_encl_put_backing(backing);
+
+ if (!encl->secs_child_cnt && test_bit(SGX_ENCL_INITIALIZED, &encl->flags)) {
+ ret = sgx_encl_get_backing(encl, PFN_DOWN(encl->size),
+@@ -381,11 +382,14 @@ static void sgx_reclaim_pages(void)
+ goto skip;
+
+ page_index = PFN_DOWN(encl_page->desc - encl_page->encl->base);
++
++ mutex_lock(&encl_page->encl->lock);
+ ret = sgx_encl_get_backing(encl_page->encl, page_index, &backing[i]);
+- if (ret)
++ if (ret) {
++ mutex_unlock(&encl_page->encl->lock);
+ goto skip;
++ }
+
+- mutex_lock(&encl_page->encl->lock);
+ encl_page->desc |= SGX_ENCL_PAGE_BEING_RECLAIMED;
+ mutex_unlock(&encl_page->encl->lock);
+ continue;
+@@ -413,7 +417,6 @@ static void sgx_reclaim_pages(void)
+
+ encl_page = epc_page->owner;
+ sgx_reclaimer_write(epc_page, &backing[i]);
+- sgx_encl_put_backing(&backing[i]);
+
+ kref_put(&encl_page->encl->refcount, sgx_encl_release);
+ epc_page->flags &= ~SGX_EPC_PAGE_RECLAIMER_TRACKED;
+--
+2.36.1
+
diff --git a/0004-x86-sgx-Fix-race-between-reclaimer-and-page-fault-ha.patch b/0004-x86-sgx-Fix-race-between-reclaimer-and-page-fault-ha.patch
new file mode 100644
index 000000000000..85cc8359b731
--- /dev/null
+++ b/0004-x86-sgx-Fix-race-between-reclaimer-and-page-fault-ha.patch
@@ -0,0 +1,255 @@
+From c5894032c2cbbc1836785f2d0150bc34305760ae Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Thu, 12 May 2022 14:51:00 -0700
+Subject: [PATCH 04/36] x86/sgx: Fix race between reclaimer and page fault
+ handler
+
+Haitao reported encountering a WARN triggered by the ENCLS[ELDU]
+instruction faulting with a #GP.
+
+The WARN is encountered when the reclaimer evicts a range of
+pages from the enclave when the same pages are faulted back right away.
+
+Consider two enclave pages (ENCLAVE_A and ENCLAVE_B)
+sharing a PCMD page (PCMD_AB). ENCLAVE_A is in the
+enclave memory and ENCLAVE_B is in the backing store. PCMD_AB contains
+just one entry, that of ENCLAVE_B.
+
+Scenario proceeds where ENCLAVE_A is being evicted from the enclave
+while ENCLAVE_B is faulted in.
+
+sgx_reclaim_pages() {
+
+ ...
+
+ /*
+ * Reclaim ENCLAVE_A
+ */
+ mutex_lock(&encl->lock);
+ /*
+ * Get a reference to ENCLAVE_A's
+ * shmem page where enclave page
+ * encrypted data will be stored
+ * as well as a reference to the
+ * enclave page's PCMD data page,
+ * PCMD_AB.
+ * Release mutex before writing
+ * any data to the shmem pages.
+ */
+ sgx_encl_get_backing(...);
+ encl_page->desc |= SGX_ENCL_PAGE_BEING_RECLAIMED;
+ mutex_unlock(&encl->lock);
+
+ /*
+ * Fault ENCLAVE_B
+ */
+
+ sgx_vma_fault() {
+
+ mutex_lock(&encl->lock);
+ /*
+ * Get reference to
+ * ENCLAVE_B's shmem page
+ * as well as PCMD_AB.
+ */
+ sgx_encl_get_backing(...)
+ /*
+ * Load page back into
+ * enclave via ELDU.
+ */
+ /*
+ * Release reference to
+ * ENCLAVE_B' shmem page and
+ * PCMD_AB.
+ */
+ sgx_encl_put_backing(...);
+ /*
+ * PCMD_AB is found empty so
+ * it and ENCLAVE_B's shmem page
+ * are truncated.
+ */
+ /* Truncate ENCLAVE_B backing page */
+ sgx_encl_truncate_backing_page();
+ /* Truncate PCMD_AB */
+ sgx_encl_truncate_backing_page();
+
+ mutex_unlock(&encl->lock);
+
+ ...
+ }
+ mutex_lock(&encl->lock);
+ encl_page->desc &=
+ ~SGX_ENCL_PAGE_BEING_RECLAIMED;
+ /*
+ * Write encrypted contents of
+ * ENCLAVE_A to ENCLAVE_A shmem
+ * page and its PCMD data to
+ * PCMD_AB.
+ */
+ sgx_encl_put_backing(...)
+
+ /*
+ * Reference to PCMD_AB is
+ * dropped and it is truncated.
+ * ENCLAVE_A's PCMD data is lost.
+ */
+ mutex_unlock(&encl->lock);
+}
+
+What happens next depends on whether it is ENCLAVE_A being faulted
+in or ENCLAVE_B being evicted - but both end up with ENCLS[ELDU] faulting
+with a #GP.
+
+If ENCLAVE_A is faulted then at the time sgx_encl_get_backing() is called
+a new PCMD page is allocated and providing the empty PCMD data for
+ENCLAVE_A would cause ENCLS[ELDU] to #GP
+
+If ENCLAVE_B is evicted first then a new PCMD_AB would be allocated by the
+reclaimer but later when ENCLAVE_A is faulted the ENCLS[ELDU] instruction
+would #GP during its checks of the PCMD value and the WARN would be
+encountered.
+
+Noting that the reclaimer sets SGX_ENCL_PAGE_BEING_RECLAIMED at the time
+it obtains a reference to the backing store pages of an enclave page it
+is in the process of reclaiming, fix the race by only truncating the PCMD
+page after ensuring that no page sharing the PCMD page is in the process
+of being reclaimed.
+
+Cc: stable@vger.kernel.org
+Fixes: 08999b2489b4 ("x86/sgx: Free backing memory after faulting the enclave page")
+Reported-by: Haitao Huang <haitao.huang@intel.com>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ arch/x86/kernel/cpu/sgx/encl.c | 94 +++++++++++++++++++++++++++++++++-
+ 1 file changed, 93 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
+index 5104a428b72c..243f3bd78145 100644
+--- a/arch/x86/kernel/cpu/sgx/encl.c
++++ b/arch/x86/kernel/cpu/sgx/encl.c
+@@ -12,6 +12,92 @@
+ #include "encls.h"
+ #include "sgx.h"
+
++#define PCMDS_PER_PAGE (PAGE_SIZE / sizeof(struct sgx_pcmd))
++/*
++ * 32 PCMD entries share a PCMD page. PCMD_FIRST_MASK is used to
++ * determine the page index associated with the first PCMD entry
++ * within a PCMD page.
++ */
++#define PCMD_FIRST_MASK GENMASK(4, 0)
++
++/**
++ * reclaimer_writing_to_pcmd() - Query if any enclave page associated with
++ * a PCMD page is in process of being reclaimed.
++ * @encl: Enclave to which PCMD page belongs
++ * @start_addr: Address of enclave page using first entry within the PCMD page
++ *
++ * When an enclave page is reclaimed some Paging Crypto MetaData (PCMD) is
++ * stored. The PCMD data of a reclaimed enclave page contains enough
++ * information for the processor to verify the page at the time
++ * it is loaded back into the Enclave Page Cache (EPC).
++ *
++ * The backing storage to which enclave pages are reclaimed is laid out as
++ * follows:
++ * Encrypted enclave pages:SECS page:PCMD pages
++ *
++ * Each PCMD page contains the PCMD metadata of
++ * PAGE_SIZE/sizeof(struct sgx_pcmd) enclave pages.
++ *
++ * A PCMD page can only be truncated if it is (a) empty, and (b) not in the
++ * process of getting data (and thus soon being non-empty). (b) is tested with
++ * a check if an enclave page sharing the PCMD page is in the process of being
++ * reclaimed.
++ *
++ * The reclaimer sets the SGX_ENCL_PAGE_BEING_RECLAIMED flag when it
++ * intends to reclaim that enclave page - it means that the PCMD page
++ * associated with that enclave page is about to get some data and thus
++ * even if the PCMD page is empty, it should not be truncated.
++ *
++ * Context: Enclave mutex (&sgx_encl->lock) must be held.
++ * Return: 1 if the reclaimer is about to write to the PCMD page
++ * 0 if the reclaimer has no intention to write to the PCMD page
++ */
++static int reclaimer_writing_to_pcmd(struct sgx_encl *encl,
++ unsigned long start_addr)
++{
++ int reclaimed = 0;
++ int i;
++
++ /*
++ * PCMD_FIRST_MASK is based on number of PCMD entries within
++ * PCMD page being 32.
++ */
++ BUILD_BUG_ON(PCMDS_PER_PAGE != 32);
++
++ for (i = 0; i < PCMDS_PER_PAGE; i++) {
++ struct sgx_encl_page *entry;
++ unsigned long addr;
++
++ addr = start_addr + i * PAGE_SIZE;
++
++ /*
++ * Stop when reaching the SECS page - it does not
++ * have a page_array entry and its reclaim is
++ * started and completed with enclave mutex held so
++ * it does not use the SGX_ENCL_PAGE_BEING_RECLAIMED
++ * flag.
++ */
++ if (addr == encl->base + encl->size)
++ break;
++
++ entry = xa_load(&encl->page_array, PFN_DOWN(addr));
++ if (!entry)
++ continue;
++
++ /*
++ * VA page slot ID uses same bit as the flag so it is important
++ * to ensure that the page is not already in backing store.
++ */
++ if (entry->epc_page &&
++ (entry->desc & SGX_ENCL_PAGE_BEING_RECLAIMED)) {
++ reclaimed = 1;
++ break;
++ }
++ }
++
++ return reclaimed;
++}
++
+ /*
+ * Calculate byte offset of a PCMD struct associated with an enclave page. PCMD's
+ * follow right after the EPC data in the backing storage. In addition to the
+@@ -47,6 +133,7 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
+ unsigned long va_offset = encl_page->desc & SGX_ENCL_PAGE_VA_OFFSET_MASK;
+ struct sgx_encl *encl = encl_page->encl;
+ pgoff_t page_index, page_pcmd_off;
++ unsigned long pcmd_first_page;
+ struct sgx_pageinfo pginfo;
+ struct sgx_backing b;
+ bool pcmd_page_empty;
+@@ -58,6 +145,11 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
+ else
+ page_index = PFN_DOWN(encl->size);
+
++ /*
++ * Address of enclave page using the first entry within the PCMD page.
++ */
++ pcmd_first_page = PFN_PHYS(page_index & ~PCMD_FIRST_MASK) + encl->base;
++
+ page_pcmd_off = sgx_encl_get_backing_page_pcmd_offset(encl, page_index);
+
+ ret = sgx_encl_get_backing(encl, page_index, &b);
+@@ -99,7 +191,7 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
+
+ sgx_encl_truncate_backing_page(encl, page_index);
+
+- if (pcmd_page_empty)
++ if (pcmd_page_empty && !reclaimer_writing_to_pcmd(encl, pcmd_first_page))
+ sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off));
+
+ return ret;
+--
+2.36.1
+
diff --git a/0005-x86-sgx-Ensure-no-data-in-PCMD-page-after-truncate.patch b/0005-x86-sgx-Ensure-no-data-in-PCMD-page-after-truncate.patch
new file mode 100644
index 000000000000..64d68a2b75ba
--- /dev/null
+++ b/0005-x86-sgx-Ensure-no-data-in-PCMD-page-after-truncate.patch
@@ -0,0 +1,59 @@
+From 5e9c8f738e0c7feee2121685e15e653cdbb998e9 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Thu, 12 May 2022 14:51:01 -0700
+Subject: [PATCH 05/36] x86/sgx: Ensure no data in PCMD page after truncate
+
+A PCMD (Paging Crypto MetaData) page contains the PCMD
+structures of enclave pages that have been encrypted and
+moved to the shmem backing store. When all enclave pages
+sharing a PCMD page are loaded in the enclave, there is no
+need for the PCMD page and it can be truncated from the
+backing store.
+
+A few issues appeared around the truncation of PCMD pages. The
+known issues have been addressed but the PCMD handling code could
+be made more robust by loudly complaining if any new issue appears
+in this area.
+
+Add a check that will complain with a warning if the PCMD page is not
+actually empty after it has been truncated. There should never be data
+in the PCMD page at this point since it is was just checked to be empty
+and truncated with enclave mutex held and is updated with the
+enclave mutex held.
+
+Suggested-by: Dave Hansen <dave.hansen@linux.intel.com>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ arch/x86/kernel/cpu/sgx/encl.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
+index 243f3bd78145..3c24e6124d95 100644
+--- a/arch/x86/kernel/cpu/sgx/encl.c
++++ b/arch/x86/kernel/cpu/sgx/encl.c
+@@ -187,12 +187,20 @@ static int __sgx_encl_eldu(struct sgx_encl_page *encl_page,
+ kunmap_atomic(pcmd_page);
+ kunmap_atomic((void *)(unsigned long)pginfo.contents);
+
++ get_page(b.pcmd);
+ sgx_encl_put_backing(&b);
+
+ sgx_encl_truncate_backing_page(encl, page_index);
+
+- if (pcmd_page_empty && !reclaimer_writing_to_pcmd(encl, pcmd_first_page))
++ if (pcmd_page_empty && !reclaimer_writing_to_pcmd(encl, pcmd_first_page)) {
+ sgx_encl_truncate_backing_page(encl, PFN_DOWN(page_pcmd_off));
++ pcmd_page = kmap_atomic(b.pcmd);
++ if (memchr_inv(pcmd_page, 0, PAGE_SIZE))
++ pr_warn("PCMD page not empty after truncate.\n");
++ kunmap_atomic(pcmd_page);
++ }
++
++ put_page(b.pcmd);
+
+ return ret;
+ }
+--
+2.36.1
+
diff --git a/0001-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch b/0006-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch
index 1e3220adb8c7..6c46a0df4fc4 100644
--- a/0001-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch
+++ b/0006-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch
@@ -1,7 +1,7 @@
-From 51105664980e12f8f34730c20725ae3ca2229c3e Mon Sep 17 00:00:00 2001
+From 911e551ff47ec3e18b776b9d86b4c2e64cd675be Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:01 -0700
-Subject: [PATCH 01/31] x86/sgx: Add short descriptions to ENCLS wrappers
+Date: Tue, 10 May 2022 11:08:37 -0700
+Subject: [PATCH 06/36] x86/sgx: Add short descriptions to ENCLS wrappers
The SGX ENCLS instruction uses EAX to specify an SGX function and
may require additional registers, depending on the SGX function.
@@ -105,5 +105,5 @@ index fa04a73daf9c..0e22fa8f77c5 100644
void *va)
{
--
-2.35.2
+2.36.1
diff --git a/0002-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch b/0007-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch
index 02a8bd059f9d..3fe683efeab0 100644
--- a/0002-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch
+++ b/0007-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch
@@ -1,7 +1,7 @@
-From 7f9ca1bdebe92d16d0e176e7dbb0425e3563a2b5 Mon Sep 17 00:00:00 2001
+From 5c8cc5465580ccb7614303a2ba49f9ec253a6ff1 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:02 -0700
-Subject: [PATCH 02/31] x86/sgx: Add wrapper for SGX2 EMODPR function
+Date: Tue, 10 May 2022 11:08:38 -0700
+Subject: [PATCH 07/36] x86/sgx: Add wrapper for SGX2 EMODPR function
Add a wrapper for the EMODPR ENCLS leaf function used to
restrict enclave page permissions as maintained in the
@@ -79,5 +79,5 @@ index 0e22fa8f77c5..2b091912f038 100644
+
#endif /* _X86_ENCLS_H */
--
-2.35.2
+2.36.1
diff --git a/0003-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch b/0008-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch
index 0bd84703ff56..b9e5783f860f 100644
--- a/0003-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch
+++ b/0008-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch
@@ -1,7 +1,7 @@
-From 65f997c50816e3314722b49a4f55ea51eb865d1d Mon Sep 17 00:00:00 2001
+From 86327191b4402a01042948f410f810837105b97d Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:03 -0700
-Subject: [PATCH 03/31] x86/sgx: Add wrapper for SGX2 EMODT function
+Date: Tue, 10 May 2022 11:08:39 -0700
+Subject: [PATCH 08/36] x86/sgx: Add wrapper for SGX2 EMODT function
Add a wrapper for the EMODT ENCLS leaf function used to
change the type of an enclave page as maintained in the
@@ -46,5 +46,5 @@ index 2b091912f038..7a1ecf704ec1 100644
+
#endif /* _X86_ENCLS_H */
--
-2.35.2
+2.36.1
diff --git a/0004-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch b/0009-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch
index 09d7a58080e8..6c025947f265 100644
--- a/0004-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch
+++ b/0009-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch
@@ -1,7 +1,7 @@
-From c2eaa596a76f7f407e8e590d8b78839a8ac034a8 Mon Sep 17 00:00:00 2001
+From 904af2dd1bb04758ad2327793ee10f24a944f7b6 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:04 -0700
-Subject: [PATCH 04/31] x86/sgx: Add wrapper for SGX2 EAUG function
+Date: Tue, 10 May 2022 11:08:40 -0700
+Subject: [PATCH 09/36] x86/sgx: Add wrapper for SGX2 EAUG function
Add a wrapper for the EAUG ENCLS leaf function used to
add a page to an initialized enclave.
@@ -38,5 +38,5 @@ index 7a1ecf704ec1..99004b02e2ed 100644
+
#endif /* _X86_ENCLS_H */
--
-2.35.2
+2.36.1
diff --git a/0005-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch b/0010-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch
index aebc50bcdeb6..3b096adb8f8b 100644
--- a/0005-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch
+++ b/0010-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch
@@ -1,7 +1,7 @@
-From 836478d4e8f9a6b1ce067e597f29e59eb1422423 Mon Sep 17 00:00:00 2001
+From d88ad0efa7127c861cd5aaf241349b5f9a0fbd53 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:05 -0700
-Subject: [PATCH 05/31] x86/sgx: Support loading enclave page without VMA
+Date: Tue, 10 May 2022 11:08:41 -0700
+Subject: [PATCH 10/36] x86/sgx: Support loading enclave page without VMA
permissions check
sgx_encl_load_page() is used to find and load an enclave page into
@@ -30,10 +30,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
2 files changed, 40 insertions(+), 19 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index 001808e3901c..b45fcecea4bd 100644
+index 3c24e6124d95..7ad8b475306a 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -90,25 +90,10 @@ static struct sgx_epc_page *sgx_encl_eldu(struct sgx_encl_page *encl_page,
+@@ -232,25 +232,10 @@ static struct sgx_epc_page *sgx_encl_eldu(struct sgx_encl_page *encl_page,
return epc_page;
}
@@ -61,7 +61,7 @@ index 001808e3901c..b45fcecea4bd 100644
/* Entry successfully located. */
if (entry->epc_page) {
-@@ -134,6 +119,40 @@ static struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
+@@ -276,6 +261,40 @@ static struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
return entry;
}
@@ -102,7 +102,7 @@ index 001808e3901c..b45fcecea4bd 100644
static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
{
unsigned long addr = (unsigned long)vmf->address;
-@@ -155,7 +174,7 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
+@@ -297,7 +316,7 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
mutex_lock(&encl->lock);
@@ -111,7 +111,7 @@ index 001808e3901c..b45fcecea4bd 100644
if (IS_ERR(entry)) {
mutex_unlock(&encl->lock);
-@@ -303,7 +322,7 @@ static struct sgx_encl_page *sgx_encl_reserve_page(struct sgx_encl *encl,
+@@ -445,7 +464,7 @@ static struct sgx_encl_page *sgx_encl_reserve_page(struct sgx_encl *encl,
for ( ; ; ) {
mutex_lock(&encl->lock);
@@ -121,7 +121,7 @@ index 001808e3901c..b45fcecea4bd 100644
break;
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index fec43ca65065..6b34efba1602 100644
+index d44e7372151f..522a17e4fd2d 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -116,5 +116,7 @@ unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page);
@@ -133,5 +133,5 @@ index fec43ca65065..6b34efba1602 100644
#endif /* _X86_ENCL_H */
--
-2.35.2
+2.36.1
diff --git a/0006-x86-sgx-Export-sgx_encl_ewb_cpumask.patch b/0011-x86-sgx-Export-sgx_encl_ewb_cpumask.patch
index fa2f045f83ac..2d636c371e62 100644
--- a/0006-x86-sgx-Export-sgx_encl_ewb_cpumask.patch
+++ b/0011-x86-sgx-Export-sgx_encl_ewb_cpumask.patch
@@ -1,7 +1,7 @@
-From 100959e3e9bf237de44f769e204aee46e61b5765 Mon Sep 17 00:00:00 2001
+From 3d04d12e9ee7efadb490cba7ba12e8d4b833b9af Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:06 -0700
-Subject: [PATCH 06/31] x86/sgx: Export sgx_encl_ewb_cpumask()
+Date: Tue, 10 May 2022 11:08:42 -0700
+Subject: [PATCH 11/36] x86/sgx: Export sgx_encl_ewb_cpumask()
Using sgx_encl_ewb_cpumask() to learn which CPUs might have executed
an enclave is useful to ensure that TLBs are cleared when changes are
@@ -31,10 +31,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
3 files changed, 68 insertions(+), 29 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index b45fcecea4bd..2845ec4faf24 100644
+index 7ad8b475306a..6953d331f8d5 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -570,6 +570,73 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
+@@ -714,6 +714,73 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
return 0;
}
@@ -109,7 +109,7 @@ index b45fcecea4bd..2845ec4faf24 100644
pgoff_t index)
{
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index 6b34efba1602..d2acb4debde5 100644
+index 522a17e4fd2d..c6afa58ea3e6 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -105,6 +105,7 @@ int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start,
@@ -119,12 +119,12 @@ index 6b34efba1602..d2acb4debde5 100644
+const cpumask_t *sgx_encl_ewb_cpumask(struct sgx_encl *encl);
int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
struct sgx_backing *backing);
- void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write);
+ void sgx_encl_put_backing(struct sgx_backing *backing);
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
-index 4b41efc9e367..d481e8b0e7bc 100644
+index ab4ec54bbdd9..2a926278dd29 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
-@@ -203,35 +203,6 @@ static void sgx_ipi_cb(void *info)
+@@ -205,35 +205,6 @@ static void sgx_ipi_cb(void *info)
{
}
@@ -161,5 +161,5 @@ index 4b41efc9e367..d481e8b0e7bc 100644
* Swap page to the regular memory transformed to the blocked state by using
* EBLOCK, which means that it can no longer be referenced (no new TLB entries).
--
-2.35.2
+2.36.1
diff --git a/0007-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch b/0012-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch
index 7575ed87b0ed..1e5e7875039f 100644
--- a/0007-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch
+++ b/0012-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch
@@ -1,7 +1,7 @@
-From b87d36265a3ceb1574d68772f29c61a24433070e Mon Sep 17 00:00:00 2001
+From c8182e673630ff65fad540a4773ac7d2888ac7e5 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:07 -0700
-Subject: [PATCH 07/31] x86/sgx: Rename sgx_encl_ewb_cpumask() as
+Date: Tue, 10 May 2022 11:08:43 -0700
+Subject: [PATCH 12/36] x86/sgx: Rename sgx_encl_ewb_cpumask() as
sgx_encl_cpumask()
sgx_encl_ewb_cpumask() is no longer unique to the reclaimer where it
@@ -27,10 +27,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index 2845ec4faf24..f241596ba411 100644
+index 6953d331f8d5..7539cef6e66b 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -571,7 +571,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
+@@ -715,7 +715,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
}
/**
@@ -39,7 +39,7 @@ index 2845ec4faf24..f241596ba411 100644
* @encl: the enclave
*
* Some SGX functions require that no cached linear-to-physical address
-@@ -596,7 +596,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
+@@ -740,7 +740,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
* The following flow is used to support SGX functions that require that
* no cached linear-to-physical address mappings are present:
* 1) Execute ENCLS[ETRACK] to initiate hardware tracking.
@@ -48,7 +48,7 @@ index 2845ec4faf24..f241596ba411 100644
* accessing the enclave.
* 3) Send IPI to identified CPUs, kicking them out of the enclave and
* thus flushing all locally cached linear-to-physical address mappings.
-@@ -613,7 +613,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
+@@ -757,7 +757,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
*
* Return: cpumask of CPUs that might be accessing @encl
*/
@@ -58,7 +58,7 @@ index 2845ec4faf24..f241596ba411 100644
cpumask_t *cpumask = &encl->cpumask;
struct sgx_encl_mm *encl_mm;
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index d2acb4debde5..e59c2cbf71e2 100644
+index c6afa58ea3e6..ef8cf106904b 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -105,7 +105,7 @@ int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start,
@@ -69,12 +69,12 @@ index d2acb4debde5..e59c2cbf71e2 100644
+const cpumask_t *sgx_encl_cpumask(struct sgx_encl *encl);
int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
struct sgx_backing *backing);
- void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write);
+ void sgx_encl_put_backing(struct sgx_backing *backing);
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
-index d481e8b0e7bc..60b166bff7b4 100644
+index 2a926278dd29..7b53a69d501f 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
-@@ -249,7 +249,7 @@ static void sgx_encl_ewb(struct sgx_epc_page *epc_page,
+@@ -251,7 +251,7 @@ static void sgx_encl_ewb(struct sgx_epc_page *epc_page,
* miss cpus that entered the enclave between
* generating the mask and incrementing epoch.
*/
@@ -84,5 +84,5 @@ index d481e8b0e7bc..60b166bff7b4 100644
ret = __sgx_encl_ewb(epc_page, va_slot, backing);
}
--
-2.35.2
+2.36.1
diff --git a/0008-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch b/0013-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch
index d9f052f0eed2..d3884fb03a10 100644
--- a/0008-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch
+++ b/0013-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch
@@ -1,7 +1,7 @@
-From 1e61402b92958e49b5cbb4e47fb8238273e279f4 Mon Sep 17 00:00:00 2001
+From 3068bc10f54b083eb4d7b85e1420fa1d57ff5b1d Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:08 -0700
-Subject: [PATCH 08/31] x86/sgx: Move PTE zap code to new
+Date: Tue, 10 May 2022 11:08:44 -0700
+Subject: [PATCH 13/36] x86/sgx: Move PTE zap code to new
sgx_zap_enclave_ptes()
The SGX reclaimer removes page table entries pointing to pages that are
@@ -32,10 +32,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
3 files changed, 47 insertions(+), 31 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index f241596ba411..a872bd7e953a 100644
+index 7539cef6e66b..c6cac43b40d6 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -562,7 +562,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
+@@ -706,7 +706,7 @@ int sgx_encl_mm_add(struct sgx_encl *encl, struct mm_struct *mm)
spin_lock(&encl->mm_lock);
list_add_rcu(&encl_mm->list, &encl->mm_list);
@@ -44,7 +44,7 @@ index f241596ba411..a872bd7e953a 100644
smp_wmb();
encl->mm_list_version++;
spin_unlock(&encl->mm_lock);
-@@ -751,6 +751,49 @@ int sgx_encl_test_and_clear_young(struct mm_struct *mm,
+@@ -887,6 +887,49 @@ int sgx_encl_test_and_clear_young(struct mm_struct *mm,
return ret;
}
@@ -95,11 +95,11 @@ index f241596ba411..a872bd7e953a 100644
* sgx_alloc_va_page() - Allocate a Version Array (VA) page
*
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index e59c2cbf71e2..1b15d22f6757 100644
+index ef8cf106904b..f72a674e2605 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -111,7 +111,7 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
- void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write);
+ void sgx_encl_put_backing(struct sgx_backing *backing);
int sgx_encl_test_and_clear_young(struct mm_struct *mm,
struct sgx_encl_page *page);
-
@@ -108,7 +108,7 @@ index e59c2cbf71e2..1b15d22f6757 100644
unsigned int sgx_alloc_va_slot(struct sgx_va_page *va_page);
void sgx_free_va_slot(struct sgx_va_page *va_page, unsigned int offset);
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
-index 60b166bff7b4..06492dcffcf1 100644
+index 7b53a69d501f..9df2221af498 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -137,36 +137,9 @@ static void sgx_reclaimer_block(struct sgx_epc_page *epc_page)
@@ -151,5 +151,5 @@ index 60b166bff7b4..06492dcffcf1 100644
mutex_lock(&encl->lock);
--
-2.35.2
+2.36.1
diff --git a/0009-x86-sgx-Make-sgx_ipi_cb-available-internally.patch b/0014-x86-sgx-Make-sgx_ipi_cb-available-internally.patch
index b52276685cbc..914073b8ea0a 100644
--- a/0009-x86-sgx-Make-sgx_ipi_cb-available-internally.patch
+++ b/0014-x86-sgx-Make-sgx_ipi_cb-available-internally.patch
@@ -1,7 +1,7 @@
-From 8f56418b1b9d2f70f0b81f6f7f04c2f7ba7e1746 Mon Sep 17 00:00:00 2001
+From f3aa084da6b464114361270c037e177de0dbfa5f Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:09 -0700
-Subject: [PATCH 09/31] x86/sgx: Make sgx_ipi_cb() available internally
+Date: Tue, 10 May 2022 11:08:45 -0700
+Subject: [PATCH 14/36] x86/sgx: Make sgx_ipi_cb() available internally
The ETRACK function followed by an IPI to all CPUs within an enclave
is a common pattern with more frequent use in support of SGX2.
@@ -17,10 +17,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
-index 06492dcffcf1..1a3014aec490 100644
+index 9df2221af498..180ad840b226 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
-@@ -172,7 +172,7 @@ static int __sgx_encl_ewb(struct sgx_epc_page *epc_page, void *va_slot,
+@@ -174,7 +174,7 @@ static int __sgx_encl_ewb(struct sgx_epc_page *epc_page, void *va_slot,
return ret;
}
@@ -43,5 +43,5 @@ index 0f17def9fe6f..b30cee4de903 100644
int __init sgx_vepc_init(void);
#else
--
-2.35.2
+2.36.1
diff --git a/0010-x86-sgx-Create-utility-to-validate-user-provided-off.patch b/0015-x86-sgx-Create-utility-to-validate-user-provided-off.patch
index 341d82ac56f6..8610e8b5d785 100644
--- a/0010-x86-sgx-Create-utility-to-validate-user-provided-off.patch
+++ b/0015-x86-sgx-Create-utility-to-validate-user-provided-off.patch
@@ -1,7 +1,7 @@
-From 87e7f3c34d6cdd9e2e4d5ff630e85c954c087122 Mon Sep 17 00:00:00 2001
+From 7e214d2e919619ab3dbc4547f0f03986009245f3 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:10 -0700
-Subject: [PATCH 10/31] x86/sgx: Create utility to validate user provided
+Date: Tue, 10 May 2022 11:08:46 -0700
+Subject: [PATCH 15/36] x86/sgx: Create utility to validate user provided
offset and length
User provided offset and length is validated when parsing the parameters
@@ -64,5 +64,5 @@ index 83df20e3e633..a66795e0b685 100644
if (copy_from_user(&secinfo, (void __user *)add_arg.secinfo,
--
-2.35.2
+2.36.1
diff --git a/0011-x86-sgx-Keep-record-of-SGX-page-type.patch b/0016-x86-sgx-Keep-record-of-SGX-page-type.patch
index 5ad1c20ab63d..1b68f9062ccb 100644
--- a/0011-x86-sgx-Keep-record-of-SGX-page-type.patch
+++ b/0016-x86-sgx-Keep-record-of-SGX-page-type.patch
@@ -1,7 +1,7 @@
-From 588655546cf6bda0ae880233e40240b6a0a6cbbe Mon Sep 17 00:00:00 2001
+From f00cceb541c0ed451da982dd4bcf2df721c23902 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:11 -0700
-Subject: [PATCH 11/31] x86/sgx: Keep record of SGX page type
+Date: Tue, 10 May 2022 11:08:47 -0700
+Subject: [PATCH 16/36] x86/sgx: Keep record of SGX page type
SGX2 functions are not allowed on all page types. For example,
ENCLS[EMODPR] is only allowed on regular SGX enclave pages and
@@ -27,7 +27,6 @@ while only using three bits. Transition to a bitfield for the two
members to support the additional information without increasing
the space consumed by the struct.
-Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
@@ -51,7 +50,7 @@ index d67810b50a81..eae20fa52b93 100644
enum sgx_page_type {
SGX_PAGE_TYPE_SECS,
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index 1b15d22f6757..07abfc70c8e3 100644
+index f72a674e2605..799d4cdb12d5 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -27,7 +27,8 @@
@@ -85,5 +84,5 @@ index a66795e0b685..21078c6643f7 100644
if (flags & SGX_PAGE_MEASURE) {
--
-2.35.2
+2.36.1
diff --git a/0012-x86-sgx-Export-sgx_encl_-grow-shrink.patch b/0017-x86-sgx-Export-sgx_encl_-grow-shrink.patch
index a096dc6633ba..a3088a91009e 100644
--- a/0012-x86-sgx-Export-sgx_encl_-grow-shrink.patch
+++ b/0017-x86-sgx-Export-sgx_encl_-grow-shrink.patch
@@ -1,7 +1,7 @@
-From 224652fefdf04993c3e61f8a5beefe395489c7d0 Mon Sep 17 00:00:00 2001
+From f2b77aae84955b467adb8e9b570c04d84cebb863 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:12 -0700
-Subject: [PATCH 12/31] x86/sgx: Export sgx_encl_{grow,shrink}()
+Date: Tue, 10 May 2022 11:08:48 -0700
+Subject: [PATCH 17/36] x86/sgx: Export sgx_encl_{grow,shrink}()
In order to use sgx_encl_{grow,shrink}() in the page augmentation code
located in encl.c, export these functions.
@@ -15,7 +15,7 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index 07abfc70c8e3..9d673d9531f0 100644
+index 799d4cdb12d5..b6b53c0346ad 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -120,5 +120,7 @@ bool sgx_va_page_full(struct sgx_va_page *va_page);
@@ -49,5 +49,5 @@ index 21078c6643f7..2df27dd8b30d 100644
encl->page_cnt--;
--
-2.35.2
+2.36.1
diff --git a/0013-x86-sgx-Export-sgx_encl_page_alloc.patch b/0018-x86-sgx-Export-sgx_encl_page_alloc.patch
index 50c010eac95b..0098ef6799b7 100644
--- a/0013-x86-sgx-Export-sgx_encl_page_alloc.patch
+++ b/0018-x86-sgx-Export-sgx_encl_page_alloc.patch
@@ -1,7 +1,7 @@
-From 25c6413856fe1d73bef5dfb3c8a6bddc728fe37a Mon Sep 17 00:00:00 2001
+From dd73a72bdd8afde9390e4cb281a858ba1482413c Mon Sep 17 00:00:00 2001
From: Jarkko Sakkinen <jarkko@kernel.org>
-Date: Wed, 13 Apr 2022 14:10:13 -0700
-Subject: [PATCH 13/31] x86/sgx: Export sgx_encl_page_alloc()
+Date: Tue, 10 May 2022 11:08:49 -0700
+Subject: [PATCH 18/36] x86/sgx: Export sgx_encl_page_alloc()
Move sgx_encl_page_alloc() to encl.c and export it so that it can be
used in the implementation for support of adding pages to initialized
@@ -16,10 +16,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
3 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index a872bd7e953a..38e42c2d3592 100644
+index c6cac43b40d6..5e6a64d8e3d6 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -751,6 +751,38 @@ int sgx_encl_test_and_clear_young(struct mm_struct *mm,
+@@ -887,6 +887,38 @@ int sgx_encl_test_and_clear_young(struct mm_struct *mm,
return ret;
}
@@ -59,11 +59,11 @@ index a872bd7e953a..38e42c2d3592 100644
* sgx_zap_enclave_ptes() - remove PTEs mapping the address from enclave
* @encl: the enclave
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index 9d673d9531f0..253ebdd1c5be 100644
+index b6b53c0346ad..2cb58ab868e5 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -112,6 +112,9 @@ int sgx_encl_get_backing(struct sgx_encl *encl, unsigned long page_index,
- void sgx_encl_put_backing(struct sgx_backing *backing, bool do_write);
+ void sgx_encl_put_backing(struct sgx_backing *backing);
int sgx_encl_test_and_clear_young(struct mm_struct *mm,
struct sgx_encl_page *page);
+struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl,
@@ -116,5 +116,5 @@ index 2df27dd8b30d..bb8cdb2ad0d1 100644
{
u64 perm = secinfo->flags & SGX_SECINFO_PERMISSION_MASK;
--
-2.35.2
+2.36.1
diff --git a/0014-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch b/0019-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch
index bad182536397..7fe43ad0f976 100644
--- a/0014-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch
+++ b/0019-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch
@@ -1,7 +1,7 @@
-From dc8e57ec148e5f440afaedea7705742bf2f00236 Mon Sep 17 00:00:00 2001
+From fd4616da8dc62cdf1976b27742a567efd5aac146 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:14 -0700
-Subject: [PATCH 14/31] x86/sgx: Support VA page allocation without reclaiming
+Date: Tue, 10 May 2022 11:08:50 -0700
+Subject: [PATCH 19/36] x86/sgx: Support VA page allocation without reclaiming
struct sgx_encl should be protected with the mutex
sgx_encl->lock. One exception is sgx_encl->page_cnt that
@@ -34,7 +34,7 @@ initialization.
No functional change.
Reported-by: Haitao Huang <haitao.huang@intel.com>
-Tested-by: Haitao Huang <haitao.huang@intel.com>
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
arch/x86/kernel/cpu/sgx/encl.c | 6 ++++--
@@ -43,10 +43,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
3 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index 38e42c2d3592..8729b254b0cc 100644
+index 5e6a64d8e3d6..ea81e597dd18 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -828,6 +828,8 @@ void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr)
+@@ -964,6 +964,8 @@ void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr)
/**
* sgx_alloc_va_page() - Allocate a Version Array (VA) page
@@ -55,7 +55,7 @@ index 38e42c2d3592..8729b254b0cc 100644
*
* Allocate a free EPC page and convert it to a Version Array (VA) page.
*
-@@ -835,12 +837,12 @@ void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr)
+@@ -971,12 +973,12 @@ void sgx_zap_enclave_ptes(struct sgx_encl *encl, unsigned long addr)
* a VA page,
* -errno otherwise
*/
@@ -71,7 +71,7 @@ index 38e42c2d3592..8729b254b0cc 100644
return ERR_CAST(epc_page);
diff --git a/arch/x86/kernel/cpu/sgx/encl.h b/arch/x86/kernel/cpu/sgx/encl.h
-index 253ebdd1c5be..66adb8faec45 100644
+index 2cb58ab868e5..3d0e0ba3edf5 100644
--- a/arch/x86/kernel/cpu/sgx/encl.h
+++ b/arch/x86/kernel/cpu/sgx/encl.h
@@ -116,14 +116,14 @@ struct sgx_encl_page *sgx_encl_page_alloc(struct sgx_encl *encl,
@@ -132,5 +132,5 @@ index bb8cdb2ad0d1..5d41aa204761 100644
ret = PTR_ERR(va_page);
goto err_out_free;
--
-2.35.2
+2.36.1
diff --git a/0015-x86-sgx-Support-restricting-of-enclave-page-permissi.patch b/0020-x86-sgx-Support-restricting-of-enclave-page-permissi.patch
index 1efe9f470ce2..943aed066ea8 100644
--- a/0015-x86-sgx-Support-restricting-of-enclave-page-permissi.patch
+++ b/0020-x86-sgx-Support-restricting-of-enclave-page-permissi.patch
@@ -1,7 +1,7 @@
-From 8ff9ec59a55ea1ccc5f17f8053e747a963efc327 Mon Sep 17 00:00:00 2001
+From f77e5b90440a4709d58907d7a467bedbfe8ed4d8 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:15 -0700
-Subject: [PATCH 15/31] x86/sgx: Support restricting of enclave page
+Date: Tue, 10 May 2022 11:08:51 -0700
+Subject: [PATCH 20/36] x86/sgx: Support restricting of enclave page
permissions
In the initial (SGX1) version of SGX, pages in an enclave need to be
@@ -43,6 +43,10 @@ the EPCM permissions from within the enclave without the kernel
knowing. An attempt to relax permissions using this call will
be ignored by the hardware.
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Tested-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
arch/x86/include/uapi/asm/sgx.h | 21 ++++
@@ -89,7 +93,7 @@ index f4b81587e90b..82648c006470 100644
/**
diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
-index 5d41aa204761..395b4e58a295 100644
+index 5d41aa204761..720188d86ed4 100644
--- a/arch/x86/kernel/cpu/sgx/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
@@ -660,6 +660,218 @@ static long sgx_ioc_enclave_provision(struct sgx_encl *encl, void __user *arg)
@@ -290,11 +294,11 @@ index 5d41aa204761..395b4e58a295 100644
+ return -EINVAL;
+
+ /*
-+ * Read access is required for the enclave to be able to use the page.
-+ * SGX instructions like ENCLU[EMODPE] and ENCLU[EACCEPT] require
-+ * read access.
++ * Fail early if invalid permissions requested to prevent ENCLS[EMODPR]
++ * from faulting later when the CPU does the same check.
+ */
-+ if (!(params.permissions & SGX_SECINFO_R))
++ if ((params.permissions & SGX_SECINFO_W) &&
++ !(params.permissions & SGX_SECINFO_R))
+ return -EINVAL;
+
+ if (params.result || params.count)
@@ -323,5 +327,5 @@ index 5d41aa204761..395b4e58a295 100644
ret = -ENOIOCTLCMD;
break;
--
-2.35.2
+2.36.1
diff --git a/0016-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch b/0021-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch
index 38ad636ed843..d8a57679dd30 100644
--- a/0016-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch
+++ b/0021-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch
@@ -1,7 +1,7 @@
-From 467c051f0ccb4a65846d9c174fbb4587e028d008 Mon Sep 17 00:00:00 2001
+From a819692d9ebd58f1791a63fdaf5d412ac41a0147 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:16 -0700
-Subject: [PATCH 16/31] x86/sgx: Support adding of pages to an initialized
+Date: Tue, 10 May 2022 11:08:52 -0700
+Subject: [PATCH 21/36] x86/sgx: Support adding of pages to an initialized
enclave
With SGX1 an enclave needs to be created with its maximum memory demands
@@ -42,16 +42,18 @@ ENCLU[EACCEPT].
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Tested-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
arch/x86/kernel/cpu/sgx/encl.c | 117 +++++++++++++++++++++++++++++++++
1 file changed, 117 insertions(+)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index 8729b254b0cc..91d648f68080 100644
+index ea81e597dd18..e5b61a59199f 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -153,6 +153,112 @@ struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
+@@ -295,6 +295,112 @@ struct sgx_encl_page *sgx_encl_load_page(struct sgx_encl *encl,
return __sgx_encl_load_page(encl, entry);
}
@@ -71,13 +73,13 @@ index 8729b254b0cc..91d648f68080 100644
+static vm_fault_t sgx_encl_eaug_page(struct vm_area_struct *vma,
+ struct sgx_encl *encl, unsigned long addr)
+{
++ vm_fault_t vmret = VM_FAULT_SIGBUS;
+ struct sgx_pageinfo pginfo = {0};
+ struct sgx_encl_page *encl_page;
+ struct sgx_epc_page *epc_page;
+ struct sgx_va_page *va_page;
+ unsigned long phys_addr;
+ u64 secinfo_flags;
-+ vm_fault_t vmret;
+ int ret;
+
+ if (!test_bit(SGX_ENCL_INITIALIZED, &encl->flags))
@@ -94,20 +96,19 @@ index 8729b254b0cc..91d648f68080 100644
+ if (IS_ERR(encl_page))
+ return VM_FAULT_OOM;
+
-+ epc_page = sgx_alloc_epc_page(encl_page, true);
-+ if (IS_ERR(epc_page)) {
-+ kfree(encl_page);
-+ return VM_FAULT_SIGBUS;
-+ }
-+
+ mutex_lock(&encl->lock);
+
-+ va_page = sgx_encl_grow(encl, false);
-+ if (IS_ERR(va_page)) {
-+ ret = PTR_ERR(va_page);
++ epc_page = sgx_alloc_epc_page(encl_page, false);
++ if (IS_ERR(epc_page)) {
++ if (PTR_ERR(epc_page) == -EBUSY)
++ vmret = VM_FAULT_NOPAGE;
+ goto err_out_unlock;
+ }
+
++ va_page = sgx_encl_grow(encl, false);
++ if (IS_ERR(va_page))
++ goto err_out_epc;
++
+ if (va_page)
+ list_add(&va_page->list, &encl->va_pages);
+
@@ -153,18 +154,19 @@ index 8729b254b0cc..91d648f68080 100644
+
+err_out_shrink:
+ sgx_encl_shrink(encl, va_page);
++err_out_epc:
++ sgx_encl_free_epc_page(epc_page);
+err_out_unlock:
+ mutex_unlock(&encl->lock);
-+ sgx_encl_free_epc_page(epc_page);
+ kfree(encl_page);
+
-+ return VM_FAULT_SIGBUS;
++ return vmret;
+}
+
static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
{
unsigned long addr = (unsigned long)vmf->address;
-@@ -172,6 +278,17 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
+@@ -314,6 +420,17 @@ static vm_fault_t sgx_vma_fault(struct vm_fault *vmf)
if (unlikely(!encl))
return VM_FAULT_SIGBUS;
@@ -183,5 +185,5 @@ index 8729b254b0cc..91d648f68080 100644
entry = sgx_encl_load_page_in_vma(encl, addr, vma->vm_flags);
--
-2.35.2
+2.36.1
diff --git a/0017-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch b/0022-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch
index 66ea43b7d590..c7de7fe6289f 100644
--- a/0017-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch
+++ b/0022-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch
@@ -1,7 +1,7 @@
-From e190e78cfceb89eb658cb27afe5456dc2ba24dd4 Mon Sep 17 00:00:00 2001
+From 1f35f20bc83570295e19d6fbf5fb053527975e9b Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:17 -0700
-Subject: [PATCH 17/31] x86/sgx: Tighten accessible memory range after enclave
+Date: Tue, 10 May 2022 11:08:53 -0700
+Subject: [PATCH 22/36] x86/sgx: Tighten accessible memory range after enclave
initialization
Before an enclave is initialized the enclave's memory range is unknown.
@@ -38,10 +38,10 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
1 file changed, 5 insertions(+)
diff --git a/arch/x86/kernel/cpu/sgx/encl.c b/arch/x86/kernel/cpu/sgx/encl.c
-index 91d648f68080..ae4f444f4a43 100644
+index e5b61a59199f..295a9c946cef 100644
--- a/arch/x86/kernel/cpu/sgx/encl.c
+++ b/arch/x86/kernel/cpu/sgx/encl.c
-@@ -361,6 +361,11 @@ int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start,
+@@ -503,6 +503,11 @@ int sgx_encl_may_map(struct sgx_encl *encl, unsigned long start,
XA_STATE(xas, &encl->page_array, PFN_DOWN(start));
@@ -54,5 +54,5 @@ index 91d648f68080..ae4f444f4a43 100644
* Disallow READ_IMPLIES_EXEC tasks as their VMA permissions might
* conflict with the enclave page permissions.
--
-2.35.2
+2.36.1
diff --git a/0018-x86-sgx-Support-modifying-SGX-page-type.patch b/0023-x86-sgx-Support-modifying-SGX-page-type.patch
index d4f871756959..900563e5980d 100644
--- a/0018-x86-sgx-Support-modifying-SGX-page-type.patch
+++ b/0023-x86-sgx-Support-modifying-SGX-page-type.patch
@@ -1,7 +1,7 @@
-From 710eae1c72f307515eda27b51dac3b320ddd3305 Mon Sep 17 00:00:00 2001
+From f53f0d00eb02b3893c2a424b84661df18216cd24 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:18 -0700
-Subject: [PATCH 18/31] x86/sgx: Support modifying SGX page type
+Date: Tue, 10 May 2022 11:08:54 -0700
+Subject: [PATCH 23/36] x86/sgx: Support modifying SGX page type
Every enclave contains one or more Thread Control Structures (TCS). The
TCS contains meta-data used by the hardware to save and restore thread
@@ -50,14 +50,18 @@ from the kernel perspective with page table entries and internal
state. The page may be moved to swap. Any access until ENCLU[EACCEPT]
will encounter a page fault with SGX flag set in error code.
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Tested-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
- arch/x86/include/uapi/asm/sgx.h | 19 +++
- arch/x86/kernel/cpu/sgx/ioctl.c | 201 ++++++++++++++++++++++++++++++++
- 2 files changed, 220 insertions(+)
+ arch/x86/include/uapi/asm/sgx.h | 20 ++++
+ arch/x86/kernel/cpu/sgx/ioctl.c | 202 ++++++++++++++++++++++++++++++++
+ 2 files changed, 222 insertions(+)
diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h
-index 82648c006470..de4d1af628d5 100644
+index 82648c006470..567f6166c24a 100644
--- a/arch/x86/include/uapi/asm/sgx.h
+++ b/arch/x86/include/uapi/asm/sgx.h
@@ -31,6 +31,8 @@ enum sgx_page_flags {
@@ -65,16 +69,17 @@ index 82648c006470..de4d1af628d5 100644
#define SGX_IOC_ENCLAVE_RESTRICT_PERMISSIONS \
_IOWR(SGX_MAGIC, 0x05, struct sgx_enclave_restrict_permissions)
+#define SGX_IOC_ENCLAVE_MODIFY_TYPES \
-+ _IOWR(SGX_MAGIC, 0x06, struct sgx_enclave_modify_type)
++ _IOWR(SGX_MAGIC, 0x06, struct sgx_enclave_modify_types)
/**
* struct sgx_enclave_create - parameter structure for the
-@@ -97,6 +99,23 @@ struct sgx_enclave_restrict_permissions {
+@@ -97,6 +99,24 @@ struct sgx_enclave_restrict_permissions {
__u64 count;
};
+/**
-+ * struct sgx_enclave_modify_type - parameters for %SGX_IOC_ENCLAVE_MODIFY_TYPES
++ * struct sgx_enclave_modify_types - parameters for ioctl
++ * %SGX_IOC_ENCLAVE_MODIFY_TYPES
+ * @offset: starting page offset (page aligned relative to enclave base
+ * address defined in SECS)
+ * @length: length of memory (multiple of the page size)
@@ -82,7 +87,7 @@ index 82648c006470..de4d1af628d5 100644
+ * @result: (output) SGX result code of ENCLS[EMODT] function
+ * @count: (output) bytes successfully changed (multiple of page size)
+ */
-+struct sgx_enclave_modify_type {
++struct sgx_enclave_modify_types {
+ __u64 offset;
+ __u64 length;
+ __u64 page_type;
@@ -94,15 +99,15 @@ index 82648c006470..de4d1af628d5 100644
/**
diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
-index 395b4e58a295..8709f131ae40 100644
+index 720188d86ed4..9ccafbfc4811 100644
--- a/arch/x86/kernel/cpu/sgx/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
-@@ -872,6 +872,204 @@ static long sgx_ioc_enclave_restrict_permissions(struct sgx_encl *encl,
+@@ -872,6 +872,205 @@ static long sgx_ioc_enclave_restrict_permissions(struct sgx_encl *encl,
return ret;
}
+/**
-+ * sgx_enclave_modify_type() - Modify type of SGX enclave pages
++ * sgx_enclave_modify_types() - Modify type of SGX enclave pages
+ * @encl: Enclave to which the pages belong.
+ * @modt: Checked parameters from user about which pages need modifying
+ * and their new page type.
@@ -111,8 +116,8 @@ index 395b4e58a295..8709f131ae40 100644
+ * - 0: Success
+ * - -errno: Otherwise
+ */
-+static long sgx_enclave_modify_type(struct sgx_encl *encl,
-+ struct sgx_enclave_modify_type *modt)
++static long sgx_enclave_modify_types(struct sgx_encl *encl,
++ struct sgx_enclave_modify_types *modt)
+{
+ unsigned long max_prot_restore;
+ enum sgx_page_type page_type;
@@ -248,9 +253,9 @@ index 395b4e58a295..8709f131ae40 100644
+}
+
+/**
-+ * sgx_ioc_enclave_modify_type() - handler for %SGX_IOC_ENCLAVE_MODIFY_TYPES
++ * sgx_ioc_enclave_modify_types() - handler for %SGX_IOC_ENCLAVE_MODIFY_TYPES
+ * @encl: an enclave pointer
-+ * @arg: userspace pointer to a &struct sgx_enclave_modify_type instance
++ * @arg: userspace pointer to a &struct sgx_enclave_modify_types instance
+ *
+ * Ability to change the enclave page type supports the following use cases:
+ *
@@ -270,9 +275,10 @@ index 395b4e58a295..8709f131ae40 100644
+ * - 0: Success
+ * - -errno: Otherwise
+ */
-+static long sgx_ioc_enclave_modify_type(struct sgx_encl *encl, void __user *arg)
++static long sgx_ioc_enclave_modify_types(struct sgx_encl *encl,
++ void __user *arg)
+{
-+ struct sgx_enclave_modify_type params;
++ struct sgx_enclave_modify_types params;
+ long ret;
+
+ ret = sgx_ioc_sgx2_ready(encl);
@@ -291,7 +297,7 @@ index 395b4e58a295..8709f131ae40 100644
+ if (params.result || params.count)
+ return -EINVAL;
+
-+ ret = sgx_enclave_modify_type(encl, &params);
++ ret = sgx_enclave_modify_types(encl, &params);
+
+ if (copy_to_user(arg, &params, sizeof(params)))
+ return -EFAULT;
@@ -302,16 +308,16 @@ index 395b4e58a295..8709f131ae40 100644
long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
struct sgx_encl *encl = filep->private_data;
-@@ -897,6 +1095,9 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+@@ -897,6 +1096,9 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
ret = sgx_ioc_enclave_restrict_permissions(encl,
(void __user *)arg);
break;
+ case SGX_IOC_ENCLAVE_MODIFY_TYPES:
-+ ret = sgx_ioc_enclave_modify_type(encl, (void __user *)arg);
++ ret = sgx_ioc_enclave_modify_types(encl, (void __user *)arg);
+ break;
default:
ret = -ENOIOCTLCMD;
break;
--
-2.35.2
+2.36.1
diff --git a/0019-x86-sgx-Support-complete-page-removal.patch b/0024-x86-sgx-Support-complete-page-removal.patch
index bd641e00b777..fc69b5333f0f 100644
--- a/0019-x86-sgx-Support-complete-page-removal.patch
+++ b/0024-x86-sgx-Support-complete-page-removal.patch
@@ -1,7 +1,7 @@
-From 9a8e4129b4520df5f77037e8be9a69d9878dc949 Mon Sep 17 00:00:00 2001
+From 7d00f6a6de9df6f5daf6f6d866220de01cedd7c7 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:19 -0700
-Subject: [PATCH 19/31] x86/sgx: Support complete page removal
+Date: Tue, 10 May 2022 11:08:55 -0700
+Subject: [PATCH 24/36] x86/sgx: Support complete page removal
The SGX2 page removal flow was introduced in previous patch and is
as follows:
@@ -32,6 +32,9 @@ If the user omits running SGX_IOC_ENCLAVE_REMOVE_PAGES the pages will
still be removed when the enclave is unloaded.
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Tested-by: Haitao Huang <haitao.huang@intel.com>
+Tested-by: Vijay Dhanraj <vijay.dhanraj@intel.com>
+Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
---
arch/x86/include/uapi/asm/sgx.h | 21 +++++
@@ -39,19 +42,19 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
2 files changed, 166 insertions(+)
diff --git a/arch/x86/include/uapi/asm/sgx.h b/arch/x86/include/uapi/asm/sgx.h
-index de4d1af628d5..ec708bd30528 100644
+index 567f6166c24a..2dd35bbdc822 100644
--- a/arch/x86/include/uapi/asm/sgx.h
+++ b/arch/x86/include/uapi/asm/sgx.h
@@ -33,6 +33,8 @@ enum sgx_page_flags {
_IOWR(SGX_MAGIC, 0x05, struct sgx_enclave_restrict_permissions)
#define SGX_IOC_ENCLAVE_MODIFY_TYPES \
- _IOWR(SGX_MAGIC, 0x06, struct sgx_enclave_modify_type)
+ _IOWR(SGX_MAGIC, 0x06, struct sgx_enclave_modify_types)
+#define SGX_IOC_ENCLAVE_REMOVE_PAGES \
+ _IOWR(SGX_MAGIC, 0x07, struct sgx_enclave_remove_pages)
/**
* struct sgx_enclave_create - parameter structure for the
-@@ -116,6 +118,25 @@ struct sgx_enclave_modify_type {
+@@ -117,6 +119,25 @@ struct sgx_enclave_modify_types {
__u64 count;
};
@@ -78,10 +81,10 @@ index de4d1af628d5..ec708bd30528 100644
/**
diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
-index 8709f131ae40..f9a1654a49b7 100644
+index 9ccafbfc4811..1a2595f261d3 100644
--- a/arch/x86/kernel/cpu/sgx/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
-@@ -1070,6 +1070,148 @@ static long sgx_ioc_enclave_modify_type(struct sgx_encl *encl, void __user *arg)
+@@ -1071,6 +1071,148 @@ static long sgx_ioc_enclave_modify_types(struct sgx_encl *encl,
return ret;
}
@@ -230,9 +233,9 @@ index 8709f131ae40..f9a1654a49b7 100644
long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
{
struct sgx_encl *encl = filep->private_data;
-@@ -1098,6 +1240,9 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
+@@ -1099,6 +1241,9 @@ long sgx_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
case SGX_IOC_ENCLAVE_MODIFY_TYPES:
- ret = sgx_ioc_enclave_modify_type(encl, (void __user *)arg);
+ ret = sgx_ioc_enclave_modify_types(encl, (void __user *)arg);
break;
+ case SGX_IOC_ENCLAVE_REMOVE_PAGES:
+ ret = sgx_ioc_enclave_remove_pages(encl, (void __user *)arg);
@@ -241,5 +244,5 @@ index 8709f131ae40..f9a1654a49b7 100644
ret = -ENOIOCTLCMD;
break;
--
-2.35.2
+2.36.1
diff --git a/0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch b/0025-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
index bd86089962d2..b5400b4daf6f 100644
--- a/0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
+++ b/0025-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
@@ -1,7 +1,7 @@
-From 0ed2b241836b30d344da4f8f73ce87878aea5c87 Mon Sep 17 00:00:00 2001
+From 1414f7b29435dc53d5e0d685244210e50f55c1e5 Mon Sep 17 00:00:00 2001
From: Reinette Chatre <reinette.chatre@intel.com>
-Date: Wed, 13 Apr 2022 14:10:20 -0700
-Subject: [PATCH 20/31] x86/sgx: Free up EPC pages directly to support large
+Date: Tue, 10 May 2022 11:08:56 -0700
+Subject: [PATCH 25/36] x86/sgx: Free up EPC pages directly to support large
page ranges
The page reclaimer ensures availability of EPC pages across all
@@ -32,7 +32,7 @@ Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
3 files changed, 18 insertions(+)
diff --git a/arch/x86/kernel/cpu/sgx/ioctl.c b/arch/x86/kernel/cpu/sgx/ioctl.c
-index f9a1654a49b7..83674d054c13 100644
+index 1a2595f261d3..ebe79d60619f 100644
--- a/arch/x86/kernel/cpu/sgx/ioctl.c
+++ b/arch/x86/kernel/cpu/sgx/ioctl.c
@@ -745,6 +745,8 @@ sgx_enclave_restrict_permissions(struct sgx_encl *encl,
@@ -44,7 +44,7 @@ index f9a1654a49b7..83674d054c13 100644
mutex_lock(&encl->lock);
entry = sgx_encl_load_page(encl, addr);
-@@ -910,6 +912,8 @@ static long sgx_enclave_modify_type(struct sgx_encl *encl,
+@@ -910,6 +912,8 @@ static long sgx_enclave_modify_types(struct sgx_encl *encl,
for (c = 0 ; c < modt->length; c += PAGE_SIZE) {
addr = encl->base + modt->offset + c;
@@ -53,7 +53,7 @@ index f9a1654a49b7..83674d054c13 100644
mutex_lock(&encl->lock);
entry = sgx_encl_load_page(encl, addr);
-@@ -1095,6 +1099,8 @@ static long sgx_encl_remove_pages(struct sgx_encl *encl,
+@@ -1096,6 +1100,8 @@ static long sgx_encl_remove_pages(struct sgx_encl *encl,
for (c = 0 ; c < params->length; c += PAGE_SIZE) {
addr = encl->base + params->offset + c;
@@ -63,10 +63,10 @@ index f9a1654a49b7..83674d054c13 100644
entry = sgx_encl_load_page(encl, addr);
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
-index 1a3014aec490..c6adb7edebca 100644
+index 180ad840b226..5acd4c54d904 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
-@@ -378,6 +378,17 @@ static bool sgx_should_reclaim(unsigned long watermark)
+@@ -375,6 +375,17 @@ static bool sgx_should_reclaim(unsigned long watermark)
!list_empty(&sgx_active_page_list);
}
@@ -97,5 +97,5 @@ index b30cee4de903..0f2020653fba 100644
int sgx_unmark_page_reclaimable(struct sgx_epc_page *page);
struct sgx_epc_page *sgx_alloc_epc_page(void *owner, bool reclaim);
--
-2.35.2
+2.36.1
diff --git a/0026-Documentation-x86-Introduce-enclave-runtime-manageme.patch b/0026-Documentation-x86-Introduce-enclave-runtime-manageme.patch
new file mode 100644
index 000000000000..a4d973cf42f0
--- /dev/null
+++ b/0026-Documentation-x86-Introduce-enclave-runtime-manageme.patch
@@ -0,0 +1,47 @@
+From 77a37ace712749fe260acdf83b1a59e1b4340342 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:08:57 -0700
+Subject: [PATCH 26/36] Documentation/x86: Introduce enclave runtime management
+ section
+
+Enclave runtime management is introduced following the pattern
+of the section describing enclave building. Provide a brief
+summary of enclave runtime management, pointing to the functions
+implementing the ioctl()s that will contain details within their
+kernel-doc.
+
+Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ Documentation/x86/sgx.rst | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/Documentation/x86/sgx.rst b/Documentation/x86/sgx.rst
+index 265568a9292c..2bcbffacbed5 100644
+--- a/Documentation/x86/sgx.rst
++++ b/Documentation/x86/sgx.rst
+@@ -100,6 +100,21 @@ pages and establish enclave page permissions.
+ sgx_ioc_enclave_init
+ sgx_ioc_enclave_provision
+
++Enclave runtime management
++--------------------------
++
++Systems supporting SGX2 additionally support changes to initialized
++enclaves: modifying enclave page permissions and type, and dynamically
++adding and removing of enclave pages. When an enclave accesses an address
++within its address range that does not have a backing page then a new
++regular page will be dynamically added to the enclave. The enclave is
++still required to run EACCEPT on the new page before it can be used.
++
++.. kernel-doc:: arch/x86/kernel/cpu/sgx/ioctl.c
++ :functions: sgx_ioc_enclave_restrict_permissions
++ sgx_ioc_enclave_modify_types
++ sgx_ioc_enclave_remove_pages
++
+ Enclave vDSO
+ ------------
+
+--
+2.36.1
+
diff --git a/0027-selftests-sgx-Add-test-for-EPCM-permission-changes.patch b/0027-selftests-sgx-Add-test-for-EPCM-permission-changes.patch
new file mode 100644
index 000000000000..06016886a48a
--- /dev/null
+++ b/0027-selftests-sgx-Add-test-for-EPCM-permission-changes.patch
@@ -0,0 +1,356 @@
+From d2441d3dc8f024a09ddb07268947c76f19c36555 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:08:58 -0700
+Subject: [PATCH 27/36] 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. 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 needed
+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.
+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 EPCM permissions since the page
+ table entry continues to allow RW access.
+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 succeed since both EPCM and PTE permissions allow this access.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ tools/testing/selftests/sgx/defines.h | 15 ++
+ tools/testing/selftests/sgx/main.c | 214 ++++++++++++++++++++++++
+ tools/testing/selftests/sgx/test_encl.c | 38 +++++
+ 3 files changed, 267 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..46eac09cd955 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,206 @@ 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]). Check for page fault if
++ * VMA allows access but EPCM permissions do not.
++ */
++TEST_F(enclave, epcm_permissions)
++{
++ struct sgx_enclave_restrict_permissions restrict_ioc;
++ 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 encl_op_emodpe emodpe_op;
++ 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));
++
++ 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 and
++ * VMA 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. Kernel still considers
++ * the page writable.
++ */
++ memset(&restrict_ioc, 0, sizeof(restrict_ioc));
++
++ restrict_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
++ restrict_ioc.length = PAGE_SIZE;
++ restrict_ioc.permissions = SGX_SECINFO_R;
++
++ 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 = SGX_SECINFO_R | 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 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, 0x8007);
++ 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 = SGX_SECINFO_R | SGX_SECINFO_W;
++ 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, PTE should continue to allow writing to the page.
++ */
++ self->run.tcs = self->encl.encl_base;
++
++ /*
++ * Wrong page permissions that caused original fault has
++ * now been fixed via EPCM permissions.
++ * 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.36.1
+
diff --git a/0028-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch b/0028-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch
new file mode 100644
index 000000000000..ebdf31843b1f
--- /dev/null
+++ b/0028-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch
@@ -0,0 +1,106 @@
+From 9df29e1b7db7988ade8f497ff8f29752c7fab17e Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:08:59 -0700
+Subject: [PATCH 28/36] selftests/sgx: Add test for TCS page permission changes
+
+Kernel should not allow permission changes on TCS pages. Add test to
+confirm this behavior.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ tools/testing/selftests/sgx/main.c | 71 ++++++++++++++++++++++++++++++
+ 1 file changed, 71 insertions(+)
+
+diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
+index 46eac09cd955..016ae3e5f398 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,59 @@ 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_permissions ioc;
++ 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));
++
++ /*
++ * 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.
++ */
++ ioc.offset = encl_get_tcs_offset(&self->encl);
++ ioc.length = PAGE_SIZE;
++ ioc.permissions = SGX_SECINFO_R;
++
++ 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.36.1
+
diff --git a/0029-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch b/0029-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch
new file mode 100644
index 000000000000..daf53975f4bd
--- /dev/null
+++ b/0029-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch
@@ -0,0 +1,302 @@
+From 322b7009f14f32e6de0e323703e902c0c4515852 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:00 -0700
+Subject: [PATCH 29/36] 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.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ tools/testing/selftests/sgx/main.c | 250 +++++++++++++++++++++++++++++
+ 1 file changed, 250 insertions(+)
+
+diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
+index 016ae3e5f398..79c08e347112 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;
+@@ -840,4 +849,245 @@ 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.
++ * Kernel will allow new mapping using any permissions if it
++ * falls into the enclave's address range but not backed
++ * by existing enclave pages.
++ */
++ 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.
++ *
++ * Kernel will allow new mapping using any permissions if it
++ * falls into the enclave's address range but not backed
++ * by existing enclave pages.
++ */
++
++ 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.36.1
+
diff --git a/0030-selftests-sgx-Introduce-dynamic-entry-point.patch b/0030-selftests-sgx-Introduce-dynamic-entry-point.patch
new file mode 100644
index 000000000000..4bfcfbe42560
--- /dev/null
+++ b/0030-selftests-sgx-Introduce-dynamic-entry-point.patch
@@ -0,0 +1,50 @@
+From ec26d201dbda5703a17e31aeba91b6f8ad0ed47e Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:01 -0700
+Subject: [PATCH 30/36] 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.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+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.36.1
+
diff --git a/0031-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch b/0031-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch
new file mode 100644
index 000000000000..2f7205e28264
--- /dev/null
+++ b/0031-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch
@@ -0,0 +1,102 @@
+From 6a11aaed59fdac23b4ec6c5605381061488e3c07 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:02 -0700
+Subject: [PATCH 31/36] 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.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+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.36.1
+
diff --git a/0032-selftests-sgx-Test-complete-changing-of-page-type-fl.patch b/0032-selftests-sgx-Test-complete-changing-of-page-type-fl.patch
new file mode 100644
index 000000000000..ac5aaf1ab695
--- /dev/null
+++ b/0032-selftests-sgx-Test-complete-changing-of-page-type-fl.patch
@@ -0,0 +1,448 @@
+From 7e1e0ea10dad3e8d2b372c220153e1455fab0619 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:03 -0700
+Subject: [PATCH 32/36] 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).
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ tools/testing/selftests/sgx/load.c | 41 ++++
+ tools/testing/selftests/sgx/main.c | 343 +++++++++++++++++++++++++++++
+ tools/testing/selftests/sgx/main.h | 1 +
+ 3 files changed, 385 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 79c08e347112..8bf43646e0bb 100644
+--- a/tools/testing/selftests/sgx/main.c
++++ b/tools/testing/selftests/sgx/main.c
+@@ -1090,4 +1090,347 @@ 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 sgx_enclave_modify_types modt_ioc;
++ 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;
++ 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_TYPES, &modt_ioc);
++
++ if (ret == -1) {
++ if (errno == ENOTTY)
++ SKIP(return,
++ "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPES 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));
++
++ modt_ioc.offset = total_size + PAGE_SIZE;
++ modt_ioc.length = PAGE_SIZE;
++ modt_ioc.page_type = SGX_PAGE_TYPE_TCS;
++
++ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPES, &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));
++
++ modt_ioc.offset = total_size;
++ modt_ioc.length = 3 * PAGE_SIZE;
++ modt_ioc.page_type = SGX_PAGE_TYPE_TRIM;
++
++ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPES, &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.36.1
+
diff --git a/0033-selftests-sgx-Test-faulty-enclave-behavior.patch b/0033-selftests-sgx-Test-faulty-enclave-behavior.patch
new file mode 100644
index 000000000000..adf4755a6198
--- /dev/null
+++ b/0033-selftests-sgx-Test-faulty-enclave-behavior.patch
@@ -0,0 +1,149 @@
+From aedac9dcb6fcb4be2650b05d71a85c77026282bc Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:04 -0700
+Subject: [PATCH 33/36] 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.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ tools/testing/selftests/sgx/main.c | 114 +++++++++++++++++++++++++++++
+ 1 file changed, 114 insertions(+)
+
+diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
+index 8bf43646e0bb..3a82bae915d1 100644
+--- a/tools/testing/selftests/sgx/main.c
++++ b/tools/testing/selftests/sgx/main.c
+@@ -1433,4 +1433,118 @@ 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 sgx_enclave_modify_types modt_ioc;
++ struct encl_op_put_to_addr put_addr_op;
++ 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_TYPES, &modt_ioc);
++
++ if (ret == -1) {
++ if (errno == ENOTTY)
++ SKIP(return,
++ "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPES 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));
++
++ modt_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
++ modt_ioc.length = PAGE_SIZE;
++ modt_ioc.page_type = SGX_PAGE_TYPE_TRIM;
++
++ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPES, &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.36.1
+
diff --git a/0034-selftests-sgx-Test-invalid-access-to-removed-enclave.patch b/0034-selftests-sgx-Test-invalid-access-to-removed-enclave.patch
new file mode 100644
index 000000000000..17d72bdc2ccf
--- /dev/null
+++ b/0034-selftests-sgx-Test-invalid-access-to-removed-enclave.patch
@@ -0,0 +1,290 @@
+From 8dabc1d4d87c7e7aabcee17020b76e1ce9b1bb1a Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:05 -0700
+Subject: [PATCH 34/36] 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_TYPES 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.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+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 3a82bae915d1..2c69045253b2 100644
+--- a/tools/testing/selftests/sgx/main.c
++++ b/tools/testing/selftests/sgx/main.c
+@@ -1547,4 +1547,247 @@ 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_modify_types ioc;
++ 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_TYPES, &ioc);
++
++ if (ret == -1) {
++ if (errno == ENOTTY)
++ SKIP(return,
++ "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPES 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));
++
++ ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
++ ioc.length = PAGE_SIZE;
++ ioc.page_type = SGX_PAGE_TYPE_TRIM;
++
++ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPES, &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 sgx_enclave_modify_types ioc;
++ struct encl_op_eaccept eaccept_op;
++ 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_TYPES, &ioc);
++
++ if (ret == -1) {
++ if (errno == ENOTTY)
++ SKIP(return,
++ "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPES 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));
++
++ ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
++ ioc.length = PAGE_SIZE;
++ ioc.page_type = SGX_PAGE_TYPE_TRIM;
++
++ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPES, &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.36.1
+
diff --git a/0035-selftests-sgx-Test-reclaiming-of-untouched-page.patch b/0035-selftests-sgx-Test-reclaiming-of-untouched-page.patch
new file mode 100644
index 000000000000..acc9b95fe5c4
--- /dev/null
+++ b/0035-selftests-sgx-Test-reclaiming-of-untouched-page.patch
@@ -0,0 +1,119 @@
+From dd6d57606c6704b5e53e71fd4501b4d96242d007 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:06 -0700
+Subject: [PATCH 35/36] 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_TYPES 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>
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ tools/testing/selftests/sgx/main.c | 80 ++++++++++++++++++++++++++++++
+ 1 file changed, 80 insertions(+)
+
+diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
+index 2c69045253b2..ba16671aef79 100644
+--- a/tools/testing/selftests/sgx/main.c
++++ b/tools/testing/selftests/sgx/main.c
+@@ -1790,4 +1790,84 @@ 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 sgx_enclave_modify_types modt_ioc;
++ struct encl_op_eaccept eaccept_op;
++ 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_TYPES, &modt_ioc);
++
++ if (ret == -1) {
++ if (errno == ENOTTY)
++ SKIP(return,
++ "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPES 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));
++
++ modt_ioc.offset = encl_get_data_offset(&self->encl) + PAGE_SIZE;
++ modt_ioc.length = PAGE_SIZE;
++ modt_ioc.page_type = SGX_PAGE_TYPE_TRIM;
++ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPES, &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.36.1
+
diff --git a/0036-selftests-sgx-Page-removal-stress-test.patch b/0036-selftests-sgx-Page-removal-stress-test.patch
new file mode 100644
index 000000000000..de29fe7a8ecc
--- /dev/null
+++ b/0036-selftests-sgx-Page-removal-stress-test.patch
@@ -0,0 +1,155 @@
+From 60d3fab7ef151f02110786f64633d70e0a0f8f14 Mon Sep 17 00:00:00 2001
+From: Reinette Chatre <reinette.chatre@intel.com>
+Date: Tue, 10 May 2022 11:09:07 -0700
+Subject: [PATCH 36/36] 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.
+
+Acked-by: Jarkko Sakkinen <jarkko@kernel.org>
+Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
+---
+ tools/testing/selftests/sgx/main.c | 120 +++++++++++++++++++++++++++++
+ 1 file changed, 120 insertions(+)
+
+diff --git a/tools/testing/selftests/sgx/main.c b/tools/testing/selftests/sgx/main.c
+index ba16671aef79..9820b3809c69 100644
+--- a/tools/testing/selftests/sgx/main.c
++++ b/tools/testing/selftests/sgx/main.c
+@@ -378,7 +378,127 @@ 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 sgx_enclave_modify_types modt_ioc;
++ struct encl_op_get_from_buf get_op;
++ struct encl_op_eaccept eaccept_op;
++ struct encl_op_put_to_buf put_op;
++ 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_TYPES, &modt_ioc);
++
++ if (ret == -1) {
++ if (errno == ENOTTY)
++ SKIP(return,
++ "Kernel does not support SGX_IOC_ENCLAVE_MODIFY_TYPES 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));
++
++ modt_ioc.offset = heap->offset;
++ modt_ioc.length = heap->size;
++ modt_ioc.page_type = SGX_PAGE_TYPE_TRIM;
++
++ TH_LOG("Changing type of %zd bytes to trimmed may take a while ...",
++ heap->size);
++ ret = ioctl(self->encl.fd, SGX_IOC_ENCLAVE_MODIFY_TYPES, &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.36.1
+
diff --git a/PKGBUILD b/PKGBUILD
index 0663cf7bbf7c..4a5dd970990e 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,7 +1,7 @@
# Maintainer: Jarkko Sakkinen <jarkko.sakkinen@iki.fi>
pkgbase=linux-sgx
-pkgver=5.17.4.arch1
+pkgver=5.17.7.arch1
pkgrel=1
pkgdesc='Linux'
_srctag=v${pkgver%.*}-${pkgver##*.}
@@ -18,26 +18,42 @@ _srcname=archlinux-linux
source=(
"$_srcname::git+https://github.com/archlinux/linux?signed#tag=$_srctag"
config # the main kernel config file
- 0001-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch
- 0002-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch
- 0003-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch
- 0004-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch
- 0005-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch
- 0006-x86-sgx-Export-sgx_encl_ewb_cpumask.patch
- 0007-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch
- 0008-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch
- 0009-x86-sgx-Make-sgx_ipi_cb-available-internally.patch
- 0010-x86-sgx-Create-utility-to-validate-user-provided-off.patch
- 0011-x86-sgx-Keep-record-of-SGX-page-type.patch
- 0012-x86-sgx-Export-sgx_encl_-grow-shrink.patch
- 0013-x86-sgx-Export-sgx_encl_page_alloc.patch
- 0014-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch
- 0015-x86-sgx-Support-restricting-of-enclave-page-permissi.patch
- 0016-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch
- 0017-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch
- 0018-x86-sgx-Support-modifying-SGX-page-type.patch
- 0019-x86-sgx-Support-complete-page-removal.patch
- 0020-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
+ 0001-x86-sgx-Disconnect-backing-page-references-from-dirt.patch
+ 0002-x86-sgx-Mark-PCMD-page-as-dirty-when-modifying-conte.patch
+ 0003-x86-sgx-Obtain-backing-storage-page-with-enclave-mut.patch
+ 0004-x86-sgx-Fix-race-between-reclaimer-and-page-fault-ha.patch
+ 0005-x86-sgx-Ensure-no-data-in-PCMD-page-after-truncate.patch
+ 0006-x86-sgx-Add-short-descriptions-to-ENCLS-wrappers.patch
+ 0007-x86-sgx-Add-wrapper-for-SGX2-EMODPR-function.patch
+ 0008-x86-sgx-Add-wrapper-for-SGX2-EMODT-function.patch
+ 0009-x86-sgx-Add-wrapper-for-SGX2-EAUG-function.patch
+ 0010-x86-sgx-Support-loading-enclave-page-without-VMA-per.patch
+ 0011-x86-sgx-Export-sgx_encl_ewb_cpumask.patch
+ 0012-x86-sgx-Rename-sgx_encl_ewb_cpumask-as-sgx_encl_cpum.patch
+ 0013-x86-sgx-Move-PTE-zap-code-to-new-sgx_zap_enclave_pte.patch
+ 0014-x86-sgx-Make-sgx_ipi_cb-available-internally.patch
+ 0015-x86-sgx-Create-utility-to-validate-user-provided-off.patch
+ 0016-x86-sgx-Keep-record-of-SGX-page-type.patch
+ 0017-x86-sgx-Export-sgx_encl_-grow-shrink.patch
+ 0018-x86-sgx-Export-sgx_encl_page_alloc.patch
+ 0019-x86-sgx-Support-VA-page-allocation-without-reclaimin.patch
+ 0020-x86-sgx-Support-restricting-of-enclave-page-permissi.patch
+ 0021-x86-sgx-Support-adding-of-pages-to-an-initialized-en.patch
+ 0022-x86-sgx-Tighten-accessible-memory-range-after-enclav.patch
+ 0023-x86-sgx-Support-modifying-SGX-page-type.patch
+ 0024-x86-sgx-Support-complete-page-removal.patch
+ 0025-x86-sgx-Free-up-EPC-pages-directly-to-support-large-.patch
+ 0026-Documentation-x86-Introduce-enclave-runtime-manageme.patch
+ 0027-selftests-sgx-Add-test-for-EPCM-permission-changes.patch
+ 0028-selftests-sgx-Add-test-for-TCS-page-permission-chang.patch
+ 0029-selftests-sgx-Test-two-different-SGX2-EAUG-flows.patch
+ 0030-selftests-sgx-Introduce-dynamic-entry-point.patch
+ 0031-selftests-sgx-Introduce-TCS-initialization-enclave-o.patch
+ 0032-selftests-sgx-Test-complete-changing-of-page-type-fl.patch
+ 0033-selftests-sgx-Test-faulty-enclave-behavior.patch
+ 0034-selftests-sgx-Test-invalid-access-to-removed-enclave.patch
+ 0035-selftests-sgx-Test-reclaiming-of-untouched-page.patch
+ 0036-selftests-sgx-Page-removal-stress-test.patch
)
validpgpkeys=(
'ABAF11C65A2970B130ABE3C479BE3E4300411886' # Linus Torvalds
@@ -46,7 +62,7 @@ validpgpkeys=(
'C7E7849466FE2358343588377258734B41C31549' # David Runge <dvzrv@archlinux.org>
)
sha256sums=('SKIP'
- '3f02a0f2fe820f678d15fb0efce04e3716bdc7590d452317bf1b0b63f3b31cd2')
+ 'fb37785c43d90085ab4e7d7cee522cb8232713b6c601d74cfc7234eeaeb1e6b5')
export KBUILD_BUILD_HOST=archlinux
export KBUILD_BUILD_USER=$pkgbase