File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff 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.
You can’t perform that action at this time.
0 commit comments