@@ -147,6 +147,17 @@ struct sgx_epc_bank {
unsigned long end;
};
+struct sgx_epc_lru {
+ spinlock_t lock;
+ struct list_head active_lru;
+};
+
+static inline void sgx_lru_init(struct sgx_epc_lru *lru)
+{
+ spin_lock_init(&lru->lock);
+ INIT_LIST_HEAD(&lru->active_lru);
+}
+
extern struct workqueue_struct *sgx_add_page_wq;
extern struct sgx_epc_bank sgx_epc_banks[];
extern int sgx_nr_epc_banks;
@@ -71,8 +71,7 @@
static LIST_HEAD(sgx_free_list);
static DEFINE_SPINLOCK(sgx_free_list_lock);
-static LIST_HEAD(sgx_active_list);
-static DEFINE_SPINLOCK(sgx_active_list_lock);
+static struct sgx_epc_lru sgx_global_lru;
LIST_HEAD(sgx_encl_list);
DEFINE_MUTEX(sgx_encl_mutex);
@@ -123,21 +122,25 @@ void sgx_activate_page(struct sgx_epc_page *epc_page,
struct sgx_encl *encl,
struct sgx_encl_page *encl_page)
{
+ struct sgx_epc_lru *lru = &sgx_global_lru;
+
epc_page->encl = encl;
epc_page->encl_page = encl_page;
sgx_test_and_clear_young(encl_page, encl);
- spin_lock(&sgx_active_list_lock);
- list_add_tail(&epc_page->list, &sgx_active_list);
- spin_unlock(&sgx_active_list_lock);
+ spin_lock(&lru->lock);
+ list_add_tail(&epc_page->list, &lru->active_lru);
+ spin_unlock(&lru->lock);
}
void sgx_deactivate_page(struct sgx_epc_page *epc_page)
{
- spin_lock(&sgx_active_list_lock);
+ struct sgx_epc_lru *lru = &sgx_global_lru;
+
+ spin_lock(&lru->lock);
list_del_init(&epc_page->list);
- spin_unlock(&sgx_active_list_lock);
+ spin_unlock(&lru->lock);
}
static void sgx_isolate_pages(struct list_head *dst,
@@ -145,14 +148,15 @@ static void sgx_isolate_pages(struct list_head *dst,
{
unsigned long i;
struct sgx_epc_page *entry;
+ struct sgx_epc_lru *lru = &sgx_global_lru;
- spin_lock(&sgx_active_list_lock);
+ spin_lock(&lru->lock);
for (i = 0; i < nr_to_scan; i++) {
- if (list_empty(&sgx_active_list))
+ if (list_empty(&lru->active_lru))
break;
- entry = list_first_entry(&sgx_active_list,
+ entry = list_first_entry(&lru->active_lru,
struct sgx_epc_page,
list);
@@ -163,7 +167,7 @@ static void sgx_isolate_pages(struct list_head *dst,
list_move_tail(&entry->list, dst);
}
- spin_unlock(&sgx_active_list_lock);
+ spin_unlock(&lru->lock);
}
static int __sgx_ewb(struct sgx_encl *encl,
@@ -320,6 +324,18 @@ static inline void sgx_del_if_dead(struct sgx_encl *encl,
}
}
+static inline void sgx_lru_putback(struct list_head *src)
+{
+ struct sgx_epc_lru *lru = &sgx_global_lru;
+
+ if (list_empty(src))
+ return;
+
+ spin_lock(&lru->lock);
+ list_splice_tail_init(src, &lru->active_lru);
+ spin_unlock(&lru->lock);
+}
+
static void sgx_swap_pages(unsigned long nr_to_scan)
{
struct sgx_epc_page *entry, *tmp;
@@ -360,11 +376,7 @@ static void sgx_swap_pages(unsigned long nr_to_scan)
up_read(&encl->mm->mmap_sem);
- if (!list_empty(&skip)) {
- spin_lock(&sgx_active_list_lock);
- list_splice_tail_init(&skip, &sgx_active_list);
- spin_unlock(&sgx_active_list_lock);
- }
+ sgx_lru_putback(&skip);
kref_put(&encl->refcount, sgx_encl_release);
}
@@ -418,6 +430,8 @@ int sgx_add_epc_bank(resource_size_t start, unsigned long size)
int sgx_page_cache_init(void)
{
+ sgx_lru_init(&sgx_global_lru);
+
sgx_nr_high_pages = 2 * sgx_nr_low_pages;
ksgxswapd_tsk = kthread_run(ksgxswapd, NULL, "ksgxswapd");
return PTR_ERR_OR_ZERO(ksgxswapd_tsk);
Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> --- drivers/platform/x86/intel_sgx/sgx.h | 11 ++++++ drivers/platform/x86/intel_sgx/sgx_page_cache.c | 46 ++++++++++++++++--------- 2 files changed, 41 insertions(+), 16 deletions(-)