|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 13/16] xen/page_alloc: add a path for xenheap when there is no direct map
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>
---
xen/common/page_alloc.c | 45 ++++++++++++++++++++++++++++++++++++++---
1 file changed, 42 insertions(+), 3 deletions(-)
diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c
index 10b7aeca48..1285fc5977 100644
--- a/xen/common/page_alloc.c
+++ b/xen/common/page_alloc.c
@@ -2143,6 +2143,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;
ASSERT(!in_irq());
@@ -2151,14 +2152,27 @@ void *alloc_xenheap_pages(unsigned int order, unsigned
int memflags)
if ( unlikely(pg == NULL) )
return NULL;
- memguard_unguard_range(page_to_virt(pg), 1 << (order + PAGE_SHIFT));
+ ret = page_to_virt(pg);
- return page_to_virt(pg);
+ if ( !arch_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;
+ }
+
+ memguard_unguard_range(ret, 1 << (order + PAGE_SHIFT));
+
+ return ret;
}
void free_xenheap_pages(void *v, unsigned int order)
{
+ unsigned long va = (unsigned long)v & PAGE_MASK;
+
ASSERT(!in_irq());
if ( v == NULL )
@@ -2166,6 +2180,12 @@ void free_xenheap_pages(void *v, unsigned int order)
memguard_guard_range(v, 1 << (order + PAGE_SHIFT));
+ if ( !arch_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);
}
@@ -2189,6 +2209,7 @@ void *alloc_xenheap_pages(unsigned int order, unsigned
int memflags)
{
struct page_info *pg;
unsigned int i;
+ void *ret;
ASSERT(!in_irq());
@@ -2201,16 +2222,28 @@ void *alloc_xenheap_pages(unsigned int order, unsigned
int memflags)
if ( unlikely(pg == NULL) )
return NULL;
+ ret = page_to_virt(pg);
+
+ if ( !arch_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(!in_irq());
@@ -2222,6 +2255,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 ( !arch_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(pg, order, true);
}
--
2.24.1.AMZN
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |