Skip to content

Commit 51ab30e

Browse files
jarkkojssuryasaimadhu
authored andcommitted
x86/sgx: Replace section->init_laundry_list with sgx_dirty_page_list
During normal runtime, the "ksgxd" daemon behaves like a version of kswapd just for SGX. But, before it starts acting like kswapd, its first job is to initialize enclave memory. Currently, the SGX boot code places each enclave page on a epc_section->init_laundry_list. Once it starts up, the ksgxd code walks over that list and populates the actual SGX page allocator. However, the per-section structures are going away to make way for the SGX NUMA allocator. There's also little need to have a per-section structure; the enclave pages are all treated identically, and they can be placed on the correct allocator list from metadata stored in the enclave page (struct sgx_epc_page) itself. Modify sgx_sanitize_section() to take a single page list instead of taking a section and deriving the list from there. Signed-off-by: Jarkko Sakkinen <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Acked-by: Dave Hansen <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent 1e28eed commit 51ab30e

File tree

2 files changed

+25
-36
lines changed

2 files changed

+25
-36
lines changed

arch/x86/kernel/cpu/sgx/main.c

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -26,39 +26,43 @@ static LIST_HEAD(sgx_active_page_list);
2626

2727
static DEFINE_SPINLOCK(sgx_reclaimer_lock);
2828

29+
static LIST_HEAD(sgx_dirty_page_list);
30+
2931
/*
30-
* Reset dirty EPC pages to uninitialized state. Laundry can be left with SECS
31-
* pages whose child pages blocked EREMOVE.
32+
* Reset post-kexec EPC pages to the uninitialized state. The pages are removed
33+
* from the input list, and made available for the page allocator. SECS pages
34+
* prepending their children in the input list are left intact.
3235
*/
33-
static void sgx_sanitize_section(struct sgx_epc_section *section)
36+
static void __sgx_sanitize_pages(struct list_head *dirty_page_list)
3437
{
3538
struct sgx_epc_page *page;
3639
LIST_HEAD(dirty);
3740
int ret;
3841

39-
/* init_laundry_list is thread-local, no need for a lock: */
40-
while (!list_empty(&section->init_laundry_list)) {
42+
/* dirty_page_list is thread-local, no need for a lock: */
43+
while (!list_empty(dirty_page_list)) {
4144
if (kthread_should_stop())
4245
return;
4346

44-
/* needed for access to ->page_list: */
45-
spin_lock(&section->lock);
46-
47-
page = list_first_entry(&section->init_laundry_list,
48-
struct sgx_epc_page, list);
47+
page = list_first_entry(dirty_page_list, struct sgx_epc_page, list);
4948

5049
ret = __eremove(sgx_get_epc_virt_addr(page));
51-
if (!ret)
52-
list_move(&page->list, &section->page_list);
53-
else
50+
if (!ret) {
51+
/*
52+
* page is now sanitized. Make it available via the SGX
53+
* page allocator:
54+
*/
55+
list_del(&page->list);
56+
sgx_free_epc_page(page);
57+
} else {
58+
/* The page is not yet clean - move to the dirty list. */
5459
list_move_tail(&page->list, &dirty);
55-
56-
spin_unlock(&section->lock);
60+
}
5761

5862
cond_resched();
5963
}
6064

61-
list_splice(&dirty, &section->init_laundry_list);
65+
list_splice(&dirty, dirty_page_list);
6266
}
6367

6468
static bool sgx_reclaimer_age(struct sgx_epc_page *epc_page)
@@ -405,24 +409,17 @@ static bool sgx_should_reclaim(unsigned long watermark)
405409

406410
static int ksgxd(void *p)
407411
{
408-
int i;
409-
410412
set_freezable();
411413

412414
/*
413415
* Sanitize pages in order to recover from kexec(). The 2nd pass is
414416
* required for SECS pages, whose child pages blocked EREMOVE.
415417
*/
416-
for (i = 0; i < sgx_nr_epc_sections; i++)
417-
sgx_sanitize_section(&sgx_epc_sections[i]);
418-
419-
for (i = 0; i < sgx_nr_epc_sections; i++) {
420-
sgx_sanitize_section(&sgx_epc_sections[i]);
418+
__sgx_sanitize_pages(&sgx_dirty_page_list);
419+
__sgx_sanitize_pages(&sgx_dirty_page_list);
421420

422-
/* Should never happen. */
423-
if (!list_empty(&sgx_epc_sections[i].init_laundry_list))
424-
WARN(1, "EPC section %d has unsanitized pages.\n", i);
425-
}
421+
/* sanity check: */
422+
WARN_ON(!list_empty(&sgx_dirty_page_list));
426423

427424
while (!kthread_should_stop()) {
428425
if (try_to_freeze())
@@ -637,13 +634,12 @@ static bool __init sgx_setup_epc_section(u64 phys_addr, u64 size,
637634
section->phys_addr = phys_addr;
638635
spin_lock_init(&section->lock);
639636
INIT_LIST_HEAD(&section->page_list);
640-
INIT_LIST_HEAD(&section->init_laundry_list);
641637

642638
for (i = 0; i < nr_pages; i++) {
643639
section->pages[i].section = index;
644640
section->pages[i].flags = 0;
645641
section->pages[i].owner = NULL;
646-
list_add_tail(&section->pages[i].list, &section->init_laundry_list);
642+
list_add_tail(&section->pages[i].list, &sgx_dirty_page_list);
647643
}
648644

649645
section->free_cnt = nr_pages;

arch/x86/kernel/cpu/sgx/sgx.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,6 @@ struct sgx_epc_section {
4545
spinlock_t lock;
4646
struct list_head page_list;
4747
unsigned long free_cnt;
48-
49-
/*
50-
* Pages which need EREMOVE run on them before they can be
51-
* used. Only safe to be accessed in ksgxd and init code.
52-
* Not protected by locks.
53-
*/
54-
struct list_head init_laundry_list;
5548
};
5649

5750
extern struct sgx_epc_section sgx_epc_sections[SGX_MAX_EPC_SECTIONS];

0 commit comments

Comments
 (0)