[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH V3 (resend) 10/19] xen/page_alloc: Add a path for xenheap when there is no direct map
On Mon, May 13, 2024 at 01:40:37PM +0000, Elias El Yandouzi wrote: > From: Hongyan Xia <hongyxia@xxxxxxxxxx> > > When there is not an always-mapped direct map, xenheap allocations need > to be mapped and unmapped on-demand. > > Signed-off-by: Hongyan Xia <hongyxia@xxxxxxxxxx> > Signed-off-by: Julien Grall <jgrall@xxxxxxxxxx> > Signed-off-by: Elias El Yandouzi <eliasely@xxxxxxxxxx> > > ---- > > I have left the call to map_pages_to_xen() and destroy_xen_mappings() > in the split heap for now. I am not entirely convinced this is necessary > because in that setup only the xenheap would be always mapped and > this doesn't contain any guest memory (aside the grant-table). > So map/unmapping for every allocation seems unnecessary. I'm also concerned by this, did you test that CONFIG_SEPARATE_XENHEAP=y works properly with the added {,un}map calls? If CONFIG_SEPARATE_XENHEAP=y I would expect the memory returned by alloc_heap_pages(MEMZONE_XEN...) to already have the virtual mappings created ahead? The comment at the top of page_alloc.c also needs to be updated to notice how the removal of the direct map affects xenheap allocations, AFAICT a new combination is now possible: CONFIG_SEPARATE_XENHEAP=n & CONFIG_NO_DIRECTMAP=y > Changes in v2: > * Fix remaining wrong indentation in alloc_xenheap_pages() > > Changes since Hongyan's version: > * Rebase > * Fix indentation in alloc_xenheap_pages() > * Fix build for arm32 > > diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c > index 9b7e4721cd..dfb2c05322 100644 > --- a/xen/common/page_alloc.c > +++ b/xen/common/page_alloc.c > @@ -2242,6 +2242,7 @@ void init_xenheap_pages(paddr_t ps, paddr_t pe) > void *alloc_xenheap_pages(unsigned int order, unsigned int memflags) > { > struct page_info *pg; > + void *ret; virt_addr maybe? ret is what I would expect to store the return value of the function usually. > > ASSERT_ALLOC_CONTEXT(); > > @@ -2250,17 +2251,36 @@ void *alloc_xenheap_pages(unsigned int order, > unsigned int memflags) > if ( unlikely(pg == NULL) ) > return NULL; > > + ret = page_to_virt(pg); > + > + if ( !has_directmap() && > + map_pages_to_xen((unsigned long)ret, page_to_mfn(pg), 1UL << order, > + PAGE_HYPERVISOR) ) > + { > + /* Failed to map xenheap pages. */ > + free_heap_pages(pg, order, false); > + return NULL; > + } > + > return page_to_virt(pg); > } > > > void free_xenheap_pages(void *v, unsigned int order) > { > + unsigned long va = (unsigned long)v & PAGE_MASK; > + > ASSERT_ALLOC_CONTEXT(); > > if ( v == NULL ) > return; > > + if ( !has_directmap() && > + destroy_xen_mappings(va, va + (1UL << (order + PAGE_SHIFT))) ) > + dprintk(XENLOG_WARNING, > + "Error while destroying xenheap mappings at %p, order %u\n", > + v, order); > + > free_heap_pages(virt_to_page(v), order, false); > } > > @@ -2284,6 +2304,7 @@ void *alloc_xenheap_pages(unsigned int order, unsigned > int memflags) > { > struct page_info *pg; > unsigned int i; > + void *ret; > > ASSERT_ALLOC_CONTEXT(); > > @@ -2296,16 +2317,28 @@ void *alloc_xenheap_pages(unsigned int order, > unsigned int memflags) > if ( unlikely(pg == NULL) ) > return NULL; > > + ret = page_to_virt(pg); > + > + if ( !has_directmap() && > + map_pages_to_xen((unsigned long)ret, page_to_mfn(pg), 1UL << order, > + PAGE_HYPERVISOR) ) > + { > + /* Failed to map xenheap pages. */ > + free_domheap_pages(pg, order); > + return NULL; > + } > + > for ( i = 0; i < (1u << order); i++ ) > pg[i].count_info |= PGC_xen_heap; > > - return page_to_virt(pg); > + return ret; > } > > void free_xenheap_pages(void *v, unsigned int order) > { > struct page_info *pg; > unsigned int i; > + unsigned long va = (unsigned long)v & PAGE_MASK; > > ASSERT_ALLOC_CONTEXT(); > > @@ -2317,6 +2350,12 @@ void free_xenheap_pages(void *v, unsigned int order) > for ( i = 0; i < (1u << order); i++ ) > pg[i].count_info &= ~PGC_xen_heap; > > + if ( !has_directmap() && > + destroy_xen_mappings(va, va + (1UL << (order + PAGE_SHIFT))) ) > + dprintk(XENLOG_WARNING, > + "Error while destroying xenheap mappings at %p, order %u\n", > + v, order); I don't think this should be a dprintk(), leaving mappings behind could be a severe issue given the point of this work is to prevent leaking data by having everything mapped on the direct map. This needs to be a printk() IMO, I'm unsure whether freeing the memory would need to be avoided if destroying the mappings failed, I can't think of how we could recover from this gracefully. Thanks, Roger.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |