[PATCH 1/3] x86/sgx: Start the ksgxd() at the end of sgx_init()

From: Kai Huang
Date: Mon Oct 03 2022 - 18:04:55 EST


The ksgxd() kernel thread basically does two things: 1) sanitize all EPC
pages; 2) start the page reclaimer. Currently it is created and started
before initializing both the native SGX driver and the KVM driver, but
there's no reason to do that. It only needs to be started when at least
one of the native and the KVM driver has been initialized.

Move creating and running the ksgxd() to the end of sgx_init() after at
least one of the native and the KVM driver has been initialized. Also,
when kernel fails to create the ksgxd(), opportunistically improve the
behaviour to not disable SGX completely, but to continue to sanitize EPC
pages and run w/o reclaimer. This allows SGX to continue to work when
kernel is not running out of EPC (this is especially reasonable for KVM
virtual EPC driver as virtual EPC pages cannot be reclaimed anyway).

With above change, just remove the sgx_page_reclaimer_init() and open
code its logic at the end of sgx_init() as this way is more clear.

Signed-off-by: Kai Huang <kai.huang@xxxxxxxxx>
---
arch/x86/kernel/cpu/sgx/main.c | 41 ++++++++++++++++------------------
1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index 0aad028f04d4..713ca09f6d6e 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -420,19 +420,6 @@ static int ksgxd(void *p)
return 0;
}

-static bool __init sgx_page_reclaimer_init(void)
-{
- struct task_struct *tsk;
-
- tsk = kthread_run(ksgxd, NULL, "ksgxd");
- if (IS_ERR(tsk))
- return false;
-
- ksgxd_tsk = tsk;
-
- return true;
-}
-
bool current_is_ksgxd(void)
{
return current == ksgxd_tsk;
@@ -921,14 +908,9 @@ static int __init sgx_init(void)
if (!sgx_page_cache_init())
return -ENOMEM;

- if (!sgx_page_reclaimer_init()) {
- ret = -ENOMEM;
- goto err_page_cache;
- }
-
ret = misc_register(&sgx_dev_provision);
if (ret)
- goto err_kthread;
+ goto err_page_cache;

/*
* Always try to initialize the native *and* KVM drivers.
@@ -943,14 +925,29 @@ static int __init sgx_init(void)
if (sgx_vepc_init() && ret)
goto err_provision;

+ /*
+ * At least one of the native and the KVM driver has been
+ * initialized. Start the ksgxd().
+ */
+ ksgxd_tsk = kthread_run(ksgxd, NULL, "ksgxd");
+
+ /*
+ * If unable to create the ksgxd() thread, don't disable
+ * SGX completely. Instead, continue to sanitize all EPC
+ * pages and run w/o reclaimer.
+ */
+ if (IS_ERR(ksgxd_tsk)) {
+ ksgxd_tsk = NULL;
+ __sgx_sanitize_pages(&sgx_dirty_page_list);
+ WARN_ON(__sgx_sanitize_pages(&sgx_dirty_page_list));
+ pr_info("Running SGX w/o EPC page reclaimer.\n");
+ }
+
return 0;

err_provision:
misc_deregister(&sgx_dev_provision);

-err_kthread:
- kthread_stop(ksgxd_tsk);
-
err_page_cache:
for (i = 0; i < sgx_nr_epc_sections; i++) {
vfree(sgx_epc_sections[i].pages);
--
2.37.1