|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/2] xen/arm: p2m: Populate pages for GICv2 mapping in arch_domain_create()
From: Henry Wang <Henry.Wang@xxxxxxx>
The XSA-409 fixes discovered that the GICv2 path tries to create P2M mappings
in the domain_create() path. This fails, as the P2M pool is empty before a
XEN_DOMCTL_SHADOW_OP_SET_ALLOCATION hypercall.
As a stopgap, automatically give domains 16 pages of P2M memory. This is
large enough to allow the GICv2 case to work, but small enough to not
introduce a continuation worry.
A consequence is that, for later error paths domain_create(), we end up in
p2m_final_teardown() with a nonzero P2M pool. Such a domain has no vCPUs, and
has never been scheduled, so free the memory directly.
Fixes: cbea5a1149ca ("xen/arm: Allocate and free P2M pages from the P2M pool")
Suggested-by: Julien Grall <jgrall@xxxxxxxxxx>
Signed-off-by: Henry Wang <Henry.Wang@xxxxxxx>
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Stefano Stabellini <sstabellini@xxxxxxxxxx>
CC: Julien Grall <julien@xxxxxxx>
CC: Volodymyr Babchuk <Volodymyr_Babchuk@xxxxxxxx>
CC: Bertrand Marquis <bertrand.marquis@xxxxxxx>
CC: Henry Wang <Henry.Wang@xxxxxxx>
---
xen/arch/arm/p2m.c | 43 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 41 insertions(+), 2 deletions(-)
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 6826f6315080..76a0e31c6c8c 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -1736,8 +1736,36 @@ void p2m_final_teardown(struct domain *d)
if ( !p2m->domain )
return;
- ASSERT(page_list_empty(&p2m->pages));
- ASSERT(page_list_empty(&d->arch.paging.p2m_freelist));
+ /*
+ * On the domain_create() error path only, we can end up here with a
+ * non-zero P2M pool.
+ *
+ * At present, this is a maximum of 16 pages, spread between p2m->pages
+ * and the free list. The domain has never been scheduled (it has no
+ * vcpus), so there is TLB maintenance to perform; just free everything.
+ */
+ if ( !page_list_empty(&p2m->pages) ||
+ !page_list_empty(&d->arch.paging.p2m_freelist) )
+ {
+ struct page_info *pg;
+
+ /*
+ * There's no sensible "in the domain_create() error path" predicate,
+ * so simply sanity check that we don't have unexpected work to do.
+ */
+ ASSERT(d->arch.paging.p2m_total_pages <= 16);
+
+ spin_lock(&d->arch.paging.lock);
+
+ while ( (pg = page_list_remove_head(&p2m->pages)) )
+ free_domheap_page(pg);
+ while ( (pg = page_list_remove_head(&d->arch.paging.p2m_freelist)) )
+ free_domheap_page(pg);
+
+ d->arch.paging.p2m_total_pages = 0;
+
+ spin_unlock(&d->arch.paging.lock);
+ }
if ( p2m->root )
free_domheap_pages(p2m->root, P2M_ROOT_ORDER);
@@ -1803,6 +1831,17 @@ int p2m_init(struct domain *d)
if ( rc )
return rc;
+ /*
+ * Hardware using GICv2 wants to create an 8KB MMIO mapping during
+ * domain_create(), which requires some P2M pagetables. Allocate 16 page
+ * which is good enough for now.
+ */
+ spin_lock(&d->arch.paging.lock);
+ rc = p2m_set_allocation(d, 16, NULL);
+ spin_unlock(&d->arch.paging.lock);
+ if ( rc )
+ return rc;
+
return 0;
}
--
2.11.0
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |