mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
mem_sharing: map shared_info page to same gfn during fork
During a VM fork we copy the shared_info page; however, we also need to ensure that the page is mapped into the same GFN in the fork as its in the parent. Suggested-by: Roger Pau Monné <roger.pau@citrix.com> Signed-off-by: Tamas K Lengyel <tamas.lengyel@intel.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
This commit is contained in:
1 parent
5b58dad089
commit
1a0000ac77
1 file changed
+25
@@ -1656,6 +1656,7 @@ static void copy_tsc(struct domain *cd, struct domain *d)
|
||||
static int copy_special_pages(struct domain *cd, struct domain *d)
|
||||
{
|
||||
mfn_t new_mfn, old_mfn;
|
||||
gfn_t new_gfn, old_gfn;
|
||||
struct p2m_domain *p2m = p2m_get_hostp2m(cd);
|
||||
static const unsigned int params[] =
|
||||
{
|
||||
@@ -1701,6 +1702,30 @@ static int copy_special_pages(struct domain *cd, struct domain *d)
|
||||
new_mfn = _mfn(virt_to_mfn(cd->shared_info));
|
||||
copy_domain_page(new_mfn, old_mfn);
|
||||
|
||||
old_gfn = _gfn(get_gpfn_from_mfn(mfn_x(old_mfn)));
|
||||
new_gfn = _gfn(get_gpfn_from_mfn(mfn_x(new_mfn)));
|
||||
|
||||
if ( !gfn_eq(old_gfn, new_gfn) )
|
||||
{
|
||||
if ( !gfn_eq(new_gfn, INVALID_GFN) )
|
||||
{
|
||||
/* if shared_info is mapped to a different gfn just remove it */
|
||||
rc = p2m->set_entry(p2m, new_gfn, INVALID_MFN, PAGE_ORDER_4K,
|
||||
p2m_invalid, p2m->default_access, -1);
|
||||
if ( rc )
|
||||
return rc;
|
||||
}
|
||||
|
||||
if ( !gfn_eq(old_gfn, INVALID_GFN) )
|
||||
{
|
||||
/* now map it to the same gfn as the parent */
|
||||
rc = p2m->set_entry(p2m, old_gfn, new_mfn, PAGE_ORDER_4K,
|
||||
p2m_ram_rw, p2m->default_access, -1);
|
||||
if ( rc )
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||