diff --git a/xen/common/memory.c b/xen/common/memory.c index f0ff131188..1ad4b51c5b 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -388,6 +388,12 @@ static void populate_physmap(struct memop_args *a) goto out; } } + + if ( assign_page(page, a->extent_order, d, memflags) ) + { + free_domheap_pages(page, a->extent_order); + goto out; + } } if ( unlikely(a->memflags & MEMF_no_tlbflush) ) diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index 1316dfbd15..b1edef8712 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -2713,7 +2713,14 @@ struct page_info *alloc_domheap_pages( pg[i].count_info |= PGC_extra; } } - if ( assign_page(pg, order, d, memflags) ) + /* + * Don't add pages with the PGC_need_scrub bit set to the domain, the + * caller must clean the bit and then manually call assign_pages(). + * Otherwise pages still subject to scrubbing would be reachable using + * get_page(). + */ + if ( !(memflags & MEMF_keep_scrub) && + assign_page(pg, order, d, memflags) ) { free_heap_pages(pg, order, memflags & MEMF_no_scrub); return NULL; diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index 5e786c874a..b80bec00c1 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -208,7 +208,12 @@ struct npfec { #define MEMF_no_refcount (1U<<_MEMF_no_refcount) #define _MEMF_populate_on_demand 1 #define MEMF_populate_on_demand (1U<<_MEMF_populate_on_demand) -/* MEMF_keep_scrub is only valid when specified together with MEMF_no_scrub. */ +/* + * MEMF_keep_scrub is only valid when specified together with MEMF_no_scrub. + * Allocations with this flag never assign the pages to the domain, the caller + * must call assign_page() after the PGC_need_scrub bit is cleared if + * required. + */ #define _MEMF_keep_scrub 2 #define MEMF_keep_scrub (1U << _MEMF_keep_scrub) #define _MEMF_no_dma 3