[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 06/17] xen: mm: introduce non-scrubbable pages
We are about to use the existing heap allocator for EPC page management, and we need to prevent EPC pages from being scrubbed or merged with normal memory pages, because EPC pages can not be accessed outside Enclaves. To do so, we use one bit in 'page_info::u::free' to record whether a page could be scrubbed or not. 'page_scrubbable' is also introduced to test this bit, however, it will always return 'true' for architectures without unscrubbable pages like EPC pages for now(i.e. ARM). Besides, during the page merging stage, we can not allow scrubbable pages and unscrubbable pages to get merged, therefore 'page_mergeable' is introduced, and it simply test whether two pages have the same scrubbable attributes. In 'scrub_one_page', scrubbing is aborted once the page is found unscrubbable. Signed-off-by: Boqun Feng <boqun.feng@xxxxxxxxx> --- xen/common/page_alloc.c | 10 +++++++--- xen/include/asm-arm/mm.h | 7 +++++++ xen/include/asm-x86/mm.h | 7 +++++++ 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 5616a8226376..220d7d91c62b 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -1364,6 +1364,8 @@ static void free_heap_pages( if ( pg[i].u.free.need_tlbflush ) page_set_tlbflush_timestamp(&pg[i]); + pg[i].u.free.scrubbable = true; + /* This page is not a guest frame any more. */ page_set_owner(&pg[i], NULL); /* set_gpfn_from_mfn snoops pg owner */ set_gpfn_from_mfn(mfn + i, INVALID_M2P_ENTRY); @@ -1402,7 +1404,8 @@ static void free_heap_pages( if ( !mfn_valid(_mfn(page_to_mfn(predecessor))) || !page_state_is(predecessor, free) || (PFN_ORDER(predecessor) != order) || - (phys_to_nid(page_to_maddr(predecessor)) != node) ) + (phys_to_nid(page_to_maddr(predecessor)) != node) || + !page_mergeable(predecessor, pg) ) break; check_and_stop_scrub(predecessor); @@ -1425,7 +1428,8 @@ static void free_heap_pages( if ( !mfn_valid(_mfn(page_to_mfn(successor))) || !page_state_is(successor, free) || (PFN_ORDER(successor) != order) || - (phys_to_nid(page_to_maddr(successor)) != node) ) + (phys_to_nid(page_to_maddr(successor)) != node) || + !page_mergeable(successor, pg) ) break; check_and_stop_scrub(successor); @@ -2379,7 +2383,7 @@ __initcall(pagealloc_keyhandler_init); void scrub_one_page(struct page_info *pg) { - if ( unlikely(pg->count_info & PGC_broken) ) + if ( !page_scrubbable(pg) || unlikely(pg->count_info & PGC_broken) ) return; #ifndef NDEBUG diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h index ad2f2a43dcbc..c715e2290510 100644 --- a/xen/include/asm-arm/mm.h +++ b/xen/include/asm-arm/mm.h @@ -55,6 +55,9 @@ struct page_info /* Do TLBs need flushing for safety before next page use? */ bool need_tlbflush:1; + /* Could this page be scrubbed when it's free? */ + bool scrubbable:1; + #define BUDDY_NOT_SCRUBBING 0 #define BUDDY_SCRUBBING 1 #define BUDDY_SCRUB_ABORT 2 @@ -150,6 +153,10 @@ extern vaddr_t xenheap_virt_start; (mfn_valid(_mfn(mfn)) && is_xen_heap_page(__mfn_to_page(mfn))) #endif +#define page_scrubbable(_p) true + +#define page_mergeable(_p1, _p2) true + #define is_xen_fixed_mfn(mfn) \ ((pfn_to_paddr(mfn) >= virt_to_maddr(&_start)) && \ (pfn_to_paddr(mfn) <= virt_to_maddr(&_end))) diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 77e3c3ba68d1..b0f0ea0a8b5d 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -98,6 +98,8 @@ struct page_info /* Do TLBs need flushing for safety before next page use? */ bool need_tlbflush; + /* Could this page be scrubbed when it's free? */ + bool scrubbable; #define BUDDY_NOT_SCRUBBING 0 #define BUDDY_SCRUBBING 1 @@ -283,6 +285,11 @@ struct page_info /* OOS fixup entries */ #define SHADOW_OOS_FIXUPS 2 +#define page_scrubbable(_p) ((_p)->u.free.scrubbable) + +#define page_mergeable(_p1, _p2) \ + (page_scrubbable(_p1) == page_scrubbable(_p2)) + #define page_get_owner(_p) \ ((struct domain *)((_p)->v.inuse._domain ? \ pdx_to_virt((_p)->v.inuse._domain) : NULL)) -- 2.15.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |