xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] mem_sharing: map shared_info page to same gfn during fork
@ 2020-04-27 16:36 Tamas K Lengyel
  2020-04-28 10:00 ` Roger Pau Monné
  0 siblings, 1 reply; 2+ messages in thread
From: Tamas K Lengyel @ 2020-04-27 16:36 UTC (permalink / raw)
  To: xen-devel
  Cc: Tamas K Lengyel, Tamas K Lengyel, Wei Liu, Andrew Cooper,
	George Dunlap, Jan Beulich, Roger Pau Monné

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.

Signed-off-by: Tamas K Lengyel <tamas.lengyel@intel.com>
Suggested-by: Roger Pau Monne <roger.pau@citrix.com>
---
 xen/arch/x86/mm/mem_sharing.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
index 344a5bfb3d..acbf21b22c 100644
--- a/xen/arch/x86/mm/mem_sharing.c
+++ b/xen/arch/x86/mm/mem_sharing.c
@@ -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 old_gfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(cd);
     static const unsigned int params[] =
     {
@@ -1701,6 +1702,34 @@ 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)));
+
+    if ( !gfn_eq(old_gfn, INVALID_GFN) )
+    {
+        /* let's make sure shared_info is mapped to the same gfn */
+        gfn_t new_gfn = _gfn(get_gpfn_from_mfn(mfn_x(new_mfn)));
+
+        if ( !gfn_eq(new_gfn, INVALID_GFN) && !gfn_eq(old_gfn, new_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;
+
+            new_gfn = INVALID_GFN;
+        }
+
+        if ( gfn_eq(new_gfn, INVALID_GFN) )
+        {
+            /* if shared info is not currently mapped then map it */
+            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;
 }
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] mem_sharing: map shared_info page to same gfn during fork
  2020-04-27 16:36 [PATCH] mem_sharing: map shared_info page to same gfn during fork Tamas K Lengyel
@ 2020-04-28 10:00 ` Roger Pau Monné
  0 siblings, 0 replies; 2+ messages in thread
From: Roger Pau Monné @ 2020-04-28 10:00 UTC (permalink / raw)
  To: Tamas K Lengyel
  Cc: Tamas K Lengyel, Wei Liu, Andrew Cooper, George Dunlap,
	Jan Beulich, xen-devel

On Mon, Apr 27, 2020 at 09:36:05AM -0700, Tamas K Lengyel wrote:
> 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.
> 
> Signed-off-by: Tamas K Lengyel <tamas.lengyel@intel.com>
> Suggested-by: Roger Pau Monne <roger.pau@citrix.com>
> ---
>  xen/arch/x86/mm/mem_sharing.c | 29 +++++++++++++++++++++++++++++
>  1 file changed, 29 insertions(+)
> 
> diff --git a/xen/arch/x86/mm/mem_sharing.c b/xen/arch/x86/mm/mem_sharing.c
> index 344a5bfb3d..acbf21b22c 100644
> --- a/xen/arch/x86/mm/mem_sharing.c
> +++ b/xen/arch/x86/mm/mem_sharing.c
> @@ -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 old_gfn;
>      struct p2m_domain *p2m = p2m_get_hostp2m(cd);
>      static const unsigned int params[] =
>      {
> @@ -1701,6 +1702,34 @@ 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)));
> +
> +    if ( !gfn_eq(old_gfn, INVALID_GFN) )

I think you need to compare the parent shared info gfn against the
child shared info gfn, in case the child has mapped the shared info
but the parent doesn't have it mapped. In which case you want to
remove the mapping when doing a fork reset.

> +    {
> +        /* let's make sure shared_info is mapped to the same gfn */
> +        gfn_t new_gfn = _gfn(get_gpfn_from_mfn(mfn_x(new_mfn)));
> +
> +        if ( !gfn_eq(new_gfn, INVALID_GFN) && !gfn_eq(old_gfn, new_gfn) )

You can then remove the last condition in this if.

> +        {
> +            /* 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;
> +
> +            new_gfn = INVALID_GFN;
> +        }
> +
> +        if ( gfn_eq(new_gfn, INVALID_GFN) )

And this should then be if ( !gfn_eq(old_gfn, INVALID_GFN) ) ...

Thanks, Roger.


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2020-04-28 10:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-27 16:36 [PATCH] mem_sharing: map shared_info page to same gfn during fork Tamas K Lengyel
2020-04-28 10:00 ` Roger Pau Monné

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).