@@ -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);
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@intel.com> --- arch/x86/kernel/cpu/sgx/main.c | 41 ++++++++++++++++------------------ 1 file changed, 19 insertions(+), 22 deletions(-)