From: Jarkko Sakkinen <jarkko@kernel.org>
To: linux-sgx@vger.kernel.org
Cc: Jarkko Sakkinen <jarkko@kernel.org>,
Dave Hansen <dave.hansen@linux.intel.com>,
Thomas Gleixner <tglx@linutronix.de>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH v3 3/5] x86/sgx: Replace section->init_laundry_list with a temp list
Date: Wed, 3 Mar 2021 17:03:21 +0200 [thread overview]
Message-ID: <20210303150323.433207-4-jarkko@kernel.org> (raw)
In-Reply-To: <20210303150323.433207-1-jarkko@kernel.org>
Build a local laundry list in sgx_init(), and transfer its ownsership to
ksgxd for sanitization, thus getting rid of useless member in struct
sgx_epc_section.
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
---
arch/x86/kernel/cpu/sgx/main.c | 64 ++++++++++++++++++----------------
arch/x86/kernel/cpu/sgx/sgx.h | 7 ----
2 files changed, 34 insertions(+), 37 deletions(-)
diff --git a/arch/x86/kernel/cpu/sgx/main.c b/arch/x86/kernel/cpu/sgx/main.c
index ed99c60024dc..a649010949c2 100644
--- a/arch/x86/kernel/cpu/sgx/main.c
+++ b/arch/x86/kernel/cpu/sgx/main.c
@@ -30,35 +30,33 @@ static DEFINE_SPINLOCK(sgx_reclaimer_lock);
* Reset dirty EPC pages to uninitialized state. Laundry can be left with SECS
* pages whose child pages blocked EREMOVE.
*/
-static void sgx_sanitize_section(struct sgx_epc_section *section)
+static void sgx_sanitize_section(struct list_head *laundry)
{
struct sgx_epc_page *page;
LIST_HEAD(dirty);
int ret;
/* init_laundry_list is thread-local, no need for a lock: */
- while (!list_empty(§ion->init_laundry_list)) {
+ while (!list_empty(laundry)) {
if (kthread_should_stop())
return;
- /* needed for access to ->page_list: */
- spin_lock(§ion->lock);
-
- page = list_first_entry(§ion->init_laundry_list,
- struct sgx_epc_page, list);
+ page = list_first_entry(laundry, struct sgx_epc_page, list);
ret = __eremove(sgx_get_epc_virt_addr(page));
- if (!ret)
- list_move(&page->list, §ion->page_list);
- else
+ if (!ret) {
+ /* The page is clean - move to the free list. */
+ list_del(&page->list);
+ sgx_free_epc_page(page);
+ } else {
+ /* The page is not yet clean - move to the dirty list. */
list_move_tail(&page->list, &dirty);
-
- spin_unlock(§ion->lock);
+ }
cond_resched();
}
- list_splice(&dirty, §ion->init_laundry_list);
+ list_splice(&dirty, laundry);
}
static bool sgx_reclaimer_age(struct sgx_epc_page *epc_page)
@@ -400,6 +398,7 @@ static bool sgx_should_reclaim(unsigned long watermark)
static int ksgxd(void *p)
{
+ struct list_head *laundry = p;
int i;
set_freezable();
@@ -408,16 +407,13 @@ static int ksgxd(void *p)
* Sanitize pages in order to recover from kexec(). The 2nd pass is
* required for SECS pages, whose child pages blocked EREMOVE.
*/
- for (i = 0; i < sgx_nr_epc_sections; i++)
- sgx_sanitize_section(&sgx_epc_sections[i]);
+ sgx_sanitize_section(laundry);
+ sgx_sanitize_section(laundry);
- for (i = 0; i < sgx_nr_epc_sections; i++) {
- sgx_sanitize_section(&sgx_epc_sections[i]);
+ if (!list_empty(laundry))
+ WARN(1, "EPC section %d has unsanitized pages.\n", i);
- /* Should never happen. */
- if (!list_empty(&sgx_epc_sections[i].init_laundry_list))
- WARN(1, "EPC section %d has unsanitized pages.\n", i);
- }
+ kfree(laundry);
while (!kthread_should_stop()) {
if (try_to_freeze())
@@ -436,11 +432,11 @@ static int ksgxd(void *p)
return 0;
}
-static bool __init sgx_page_reclaimer_init(void)
+static bool __init sgx_page_reclaimer_init(struct list_head *laundry)
{
struct task_struct *tsk;
- tsk = kthread_run(ksgxd, NULL, "ksgxd");
+ tsk = kthread_run(ksgxd, laundry, "ksgxd");
if (IS_ERR(tsk))
return false;
@@ -614,7 +610,8 @@ void sgx_free_epc_page(struct sgx_epc_page *page)
static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,
unsigned long index,
- struct sgx_epc_section *section)
+ struct sgx_epc_section *section,
+ struct list_head *laundry)
{
unsigned long nr_pages = size >> PAGE_SHIFT;
unsigned long i;
@@ -632,13 +629,12 @@ static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,
section->phys_addr = phys_addr;
spin_lock_init(§ion->lock);
INIT_LIST_HEAD(§ion->page_list);
- INIT_LIST_HEAD(§ion->init_laundry_list);
for (i = 0; i < nr_pages; i++) {
section->pages[i].section = index;
section->pages[i].flags = 0;
section->pages[i].owner = NULL;
- list_add_tail(§ion->pages[i].list, §ion->init_laundry_list);
+ list_add_tail(§ion->pages[i].list, laundry);
}
section->free_cnt = nr_pages;
@@ -656,7 +652,7 @@ static inline u64 __init sgx_calc_section_metric(u64 low, u64 high)
((high & GENMASK_ULL(19, 0)) << 32);
}
-static bool __init sgx_page_cache_init(void)
+static bool __init sgx_page_cache_init(struct list_head *laundry)
{
u32 eax, ebx, ecx, edx, type;
u64 pa, size;
@@ -679,7 +675,7 @@ static bool __init sgx_page_cache_init(void)
pr_info("EPC section 0x%llx-0x%llx\n", pa, pa + size - 1);
- if (!sgx_setup_epc_section(pa, size, i, &sgx_epc_sections[i])) {
+ if (!sgx_setup_epc_section(pa, size, i, &sgx_epc_sections[i], laundry)) {
pr_err("No free memory for an EPC section\n");
break;
}
@@ -697,18 +693,25 @@ static bool __init sgx_page_cache_init(void)
static int __init sgx_init(void)
{
+ struct list_head *laundry;
int ret;
int i;
if (!cpu_feature_enabled(X86_FEATURE_SGX))
return -ENODEV;
- if (!sgx_page_cache_init()) {
+ laundry = kzalloc(sizeof(*laundry), GFP_KERNEL);
+ if (!laundry)
+ return -ENOMEM;
+
+ INIT_LIST_HEAD(laundry);
+
+ if (!sgx_page_cache_init(laundry)) {
ret = -ENOMEM;
goto err_page_cache;
}
- if (!sgx_page_reclaimer_init()) {
+ if (!sgx_page_reclaimer_init(laundry)) {
ret = -ENOMEM;
goto err_page_cache;
}
@@ -728,6 +731,7 @@ static int __init sgx_init(void)
memunmap(sgx_epc_sections[i].virt_addr);
}
+ kfree(laundry);
return ret;
}
diff --git a/arch/x86/kernel/cpu/sgx/sgx.h b/arch/x86/kernel/cpu/sgx/sgx.h
index 5fa42d143feb..bc8af0428640 100644
--- a/arch/x86/kernel/cpu/sgx/sgx.h
+++ b/arch/x86/kernel/cpu/sgx/sgx.h
@@ -45,13 +45,6 @@ struct sgx_epc_section {
spinlock_t lock;
struct list_head page_list;
unsigned long free_cnt;
-
- /*
- * Pages which need EREMOVE run on them before they can be
- * used. Only safe to be accessed in ksgxd and init code.
- * Not protected by locks.
- */
- struct list_head init_laundry_list;
};
extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];
--
2.30.1
next prev parent reply other threads:[~2021-03-04 0:49 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-03 15:03 [PATCH v3 0/5] x86/sgx: NUMA Jarkko Sakkinen
2021-03-03 15:03 ` [PATCH v3 1/5] x86/sgx: Fix a resource leak in sgx_init() Jarkko Sakkinen
2021-03-03 16:56 ` Dave Hansen
2021-03-10 15:00 ` Jarkko Sakkinen
2021-03-10 15:49 ` Sean Christopherson
2021-03-10 21:52 ` Jarkko Sakkinen
2021-03-03 15:03 ` [PATCH v3 2/5] x86/sgx: Use sgx_free_epc_page() in sgx_reclaim_pages() Jarkko Sakkinen
2021-03-03 16:59 ` Dave Hansen
2021-03-10 15:11 ` Jarkko Sakkinen
2021-03-10 15:55 ` Dave Hansen
2021-03-10 21:56 ` Jarkko Sakkinen
2021-03-10 20:36 ` Kai Huang
2021-03-10 22:10 ` Jarkko Sakkinen
2021-03-10 22:12 ` Jarkko Sakkinen
2021-03-10 22:35 ` Jarkko Sakkinen
2021-03-10 22:43 ` Kai Huang
2021-03-10 22:52 ` Kai Huang
2021-03-03 15:03 ` Jarkko Sakkinen [this message]
2021-03-03 18:02 ` [PATCH v3 3/5] x86/sgx: Replace section->init_laundry_list with a temp list Dave Hansen
2021-03-10 14:50 ` Jarkko Sakkinen
2021-03-03 15:03 ` [PATCH v3 4/5] x86/sgx: Replace section->page_list with a global free page list Jarkko Sakkinen
2021-03-03 23:48 ` Dave Hansen
2021-03-10 10:54 ` Jarkko Sakkinen
2021-03-03 15:03 ` [PATCH v3 5/5] x86/sgx: Add a basic NUMA allocation scheme to sgx_alloc_epc_page() Jarkko Sakkinen
2021-03-04 0:20 ` Dave Hansen
2021-03-10 11:30 ` Jarkko Sakkinen
2021-03-10 15:44 ` Dave Hansen
2021-03-10 21:48 ` Jarkko Sakkinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210303150323.433207-4-jarkko@kernel.org \
--to=jarkko@kernel.org \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-sgx@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.