|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v2] x86: Perform mem_sharing teardown before paging teardown
An assert failure has been observed in p2m_teardown when performing vm
forking and then destroying the forked VM (p2m-basic.c:173). The assert
checks whether the domain's shared pages counter is 0. According to the
patch that originally added the assert (7bedbbb5c31) the p2m_teardown
should only happen after mem_sharing already relinquished all shared pages.
In this patch we flip the order in which relinquish ops are called to avoid
tripping the assert.
Signed-off-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx>
Fixes: e7aa55c0aab3 ("x86/p2m: free the paging memory pool preemptively")
---
v2: comsetic fixes
---
xen/arch/x86/domain.c | 56 ++++++++++++++++++++++---------------------
1 file changed, 29 insertions(+), 27 deletions(-)
diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c
index db3ebf062d..a42f03e8e5 100644
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -2289,9 +2289,9 @@ int domain_relinquish_resources(struct domain *d)
enum {
PROG_iommu_pagetables = 1,
+ PROG_shared,
PROG_paging,
PROG_vcpu_pagetables,
- PROG_shared,
PROG_xen,
PROG_l4,
PROG_l3,
@@ -2310,6 +2310,34 @@ int domain_relinquish_resources(struct domain *d)
if ( ret )
return ret;
+#ifdef CONFIG_MEM_SHARING
+ PROGRESS(shared):
+
+ if ( is_hvm_domain(d) )
+ {
+ /*
+ * If the domain has shared pages, relinquish them allowing
+ * for preemption.
+ */
+ ret = relinquish_shared_pages(d);
+ if ( ret )
+ return ret;
+
+ /*
+ * If the domain is forked, decrement the parent's pause count
+ * and release the domain.
+ */
+ if ( mem_sharing_is_fork(d) )
+ {
+ struct domain *parent = d->parent;
+
+ d->parent = NULL;
+ domain_unpause(parent);
+ put_domain(parent);
+ }
+ }
+#endif
+
PROGRESS(paging):
/* Tear down paging-assistance stuff. */
@@ -2350,32 +2378,6 @@ int domain_relinquish_resources(struct domain *d)
d->arch.auto_unmask = 0;
}
-#ifdef CONFIG_MEM_SHARING
- PROGRESS(shared):
-
- if ( is_hvm_domain(d) )
- {
- /* If the domain has shared pages, relinquish them allowing
- * for preemption. */
- ret = relinquish_shared_pages(d);
- if ( ret )
- return ret;
-
- /*
- * If the domain is forked, decrement the parent's pause count
- * and release the domain.
- */
- if ( mem_sharing_is_fork(d) )
- {
- struct domain *parent = d->parent;
-
- d->parent = NULL;
- domain_unpause(parent);
- put_domain(parent);
- }
- }
-#endif
-
spin_lock(&d->page_alloc_lock);
page_list_splice(&d->arch.relmem_list, &d->page_list);
INIT_PAGE_LIST_HEAD(&d->arch.relmem_list);
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |