[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 |