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