Skip to content

Commit 93d86ef

Browse files
committed
x86/mem_sharing: reinitialize guest handle on fork completion
Signed-off-by: Ariadne Conill <ariadne@ariadne.space>
1 parent 22bd028 commit 93d86ef

1 file changed

Lines changed: 18 additions & 0 deletions

File tree

xen/arch/x86/mm/mem_sharing.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2015,6 +2015,7 @@ int mem_sharing_fork_complete(struct domain *d)
20152015
struct domain *pd = d->parent;
20162016
struct mem_sharing_domain *msd = &d->arch.hvm.mem_sharing;
20172017
unsigned long gfn, max_pfn, count = 0;
2018+
struct vcpu *v;
20182019

20192020
if ( !mem_sharing_is_fork(d) )
20202021
return -EINVAL;
@@ -2048,6 +2049,23 @@ int mem_sharing_fork_complete(struct domain *d)
20482049
}
20492050
}
20502051

2052+
/*
2053+
* The child inherited the parent's registered vcpu_info and runstate
2054+
* areas (copied by the fork). When the child resumes through the guest's
2055+
* restore path it re-registers both, but VCPUOP_register_vcpu_info rejects
2056+
* an already-mapped area with -EBUSY, panicking the guest. Unmap them here
2057+
* -- exactly as domain_soft_reset() does before a guest restart -- so the
2058+
* areas revert to the shared_info default and the guest's re-registration
2059+
* succeeds. The child is paused throughout, satisfying unmap_guest_area()'s
2060+
* pause precondition.
2061+
*/
2062+
for_each_vcpu ( d, v )
2063+
{
2064+
set_xen_guest_handle(runstate_guest(v), NULL);
2065+
unmap_guest_area(v, &v->vcpu_info_area);
2066+
unmap_guest_area(v, &v->runstate_guest_area);
2067+
}
2068+
20512069
/*
20522070
* The child is now self-contained. Drop the parent link and release the
20532071
* pause + reference the fork took, so the parent can be scheduled again.

0 commit comments

Comments
 (0)