|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/2] x86/mem_sharing: Add extra variable to track fork progress
When VM forking is initiated a VM is not supposed to try to perform mem_sharing
yet as the fork process hasn't completed all required steps. However, the vCPU
bring-up paths trigger guest memory accesses that can lead to such premature
sharing ops. However, the gating check to see whether a VM is a fork is set
already (ie. the domain has a parent).
In this patch we introduce a separate variable to store the information that
forking has been initiated so that the non-restartable part of the forking op
is not repeated and we avoid the premature sharing ops from triggering.
Signed-off-by: Tamas K Lengyel <tamas@xxxxxxxxxxxxx>
---
xen/arch/x86/include/asm/hvm/domain.h | 8 ++++++++
xen/arch/x86/mm/mem_sharing.c | 10 +++++++---
2 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/xen/arch/x86/include/asm/hvm/domain.h
b/xen/arch/x86/include/asm/hvm/domain.h
index 698455444e..76a08b55f9 100644
--- a/xen/arch/x86/include/asm/hvm/domain.h
+++ b/xen/arch/x86/include/asm/hvm/domain.h
@@ -33,6 +33,14 @@ struct mem_sharing_domain
{
bool enabled, block_interrupts;
+ /*
+ * We need to avoid trying to nominate pages for forking until the
+ * fork operation is completely finished. As parts of fork creation
+ * is restartable we mark here if the process started to skip the
+ * non-restartable portion.
+ */
+ bool fork_started;
+
/*
* When releasing shared gfn's in a preemptible manner, recall where
* to resume the search.
diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index 649d93dc54..b55c5bccdd 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -1888,11 +1888,12 @@ static int copy_settings(struct domain *cd, struct
domain *d)
static int fork(struct domain *cd, struct domain *d)
{
int rc = -EBUSY;
+ struct mem_sharing_domain *msd = &cd->arch.hvm.mem_sharing;
if ( !cd->controller_pause_count )
return rc;
- if ( !cd->parent )
+ if ( !msd->fork_started )
{
if ( !get_domain(d) )
{
@@ -1905,7 +1906,7 @@ static int fork(struct domain *cd, struct domain *d)
*cd->arch.cpuid = *d->arch.cpuid;
*cd->arch.msr = *d->arch.msr;
cd->vmtrace_size = d->vmtrace_size;
- cd->parent = d;
+ msd->fork_started = 1;
}
/* This is preemptible so it's the first to get done */
@@ -1918,8 +1919,11 @@ static int fork(struct domain *cd, struct domain *d)
rc = copy_settings(cd, d);
done:
- if ( rc && rc != -ERESTART )
+ if ( !rc )
+ cd->parent = d;
+ else if ( rc != -ERESTART )
{
+ msd->fork_started = 0;
cd->parent = NULL;
domain_unpause(d);
put_domain(d);
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |