All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mukesh Rathor <mukesh.rathor@oracle.com>
To: Xen-devel@lists.xensource.com
Subject: [PATCH 18/20] PVH xen: Add and remove foreign pages
Date: Tue, 14 May 2013 17:52:46 -0700	[thread overview]
Message-ID: <1368579168-30829-19-git-send-email-mukesh.rathor@oracle.com> (raw)
In-Reply-To: <1368579168-30829-1-git-send-email-mukesh.rathor@oracle.com>

In this patch, a new function, xenmem_add_foreign_to_pmap(), is added
to map pages from foreign guest into current dom0 for domU creation.
Also, allow XENMEM_remove_from_physmap to remove p2m_map_foreign
pages. Note, in this path, we must release the refcount that was taken
during the map phase.

Changes in V2:
  - Move the XENMEM_remove_from_physmap changes here instead of prev patch
  - Move grant changes from this to one of the next patches.
  - In xenmem_add_foreign_to_pmap(), do locked get_gfn
  - Fail the mappings for qemu mapping pages for memory not there.

Changes in V3:
  - remove mmio pages.
  - remove unrelated changes.
  - cleanup both add and remove.

Changes in V5:
  - add a comment in public/memory.h

Signed-off-by: Mukesh Rathor <mukesh.rathor@oracle.com>
---
 xen/arch/x86/mm.c           |   80 +++++++++++++++++++++++++++++++++++++++++++
 xen/common/memory.c         |   38 ++++++++++++++++++---
 xen/include/public/memory.h |    2 +-
 3 files changed, 114 insertions(+), 6 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 88c6f0c..501b510 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4520,6 +4520,78 @@ static int handle_iomem_range(unsigned long s, unsigned long e, void *p)
     return 0;
 }
 
+/*
+ * Add frames from foreign domain to current domain's physmap. Similar to
+ * XENMAPSPACE_gmfn but the frame is foreign being mapped into current,
+ * and is not removed from foreign domain.
+ * Usage: libxl on pvh dom0 creating a guest and doing privcmd_ioctl_mmap.
+ * Side Effect: the mfn for fgfn will be refcounted so it is not lost
+ *              while mapped here. The refcnt is released in do_memory_op()
+ *              via XENMEM_remove_from_physmap.
+ * Returns: 0 ==> success
+ */
+static int xenmem_add_foreign_to_pmap(domid_t foreign_domid,
+                                      unsigned long fgfn, unsigned long gpfn)
+{
+    p2m_type_t p2mt, p2mt_prev;
+    int rc = 0;
+    unsigned long prev_mfn, mfn = 0;
+    struct domain *fdom, *currd = current->domain;
+    struct page_info *page = NULL;
+
+    if ( currd->domain_id == foreign_domid || foreign_domid == DOMID_SELF ||
+         !is_pvh_domain(currd) )
+        return -EINVAL;
+
+    if ( !IS_PRIV(currd) || (fdom = get_pg_owner(foreign_domid)) == NULL )
+        return -EPERM;
+
+    /* following will take a refcnt on the mfn */
+    page = get_page_from_gfn(fdom, fgfn, &p2mt, P2M_ALLOC);
+    if ( !page || !p2m_is_valid(p2mt) )
+    {
+        if ( page )
+            put_page(page);
+        put_pg_owner(fdom);
+        return -EINVAL;
+    }
+    mfn = page_to_mfn(page);
+
+    /* Remove previously mapped page if it is present. */
+    prev_mfn = mfn_x(get_gfn(currd, gpfn, &p2mt_prev));
+    if ( mfn_valid(prev_mfn) )
+    {
+        if ( is_xen_heap_mfn(prev_mfn) )
+            /* Xen heap frames are simply unhooked from this phys slot */
+            guest_physmap_remove_page(currd, gpfn, prev_mfn, 0);
+        else
+            /* Normal domain memory is freed, to avoid leaking memory. */
+            guest_remove_page(currd, gpfn);
+    }
+    /*
+     * Create the new mapping. Can't use guest_physmap_add_page() because it
+     * will update the m2p table which will result in  mfn -> gpfn of dom0
+     * and not fgfn of domU.
+     */
+    if ( set_foreign_p2m_entry(currd, gpfn, _mfn(mfn)) == 0 )
+    {
+        dprintk(XENLOG_WARNING,
+                "guest_physmap_add_page failed. gpfn:%lx mfn:%lx fgfn:%lx\n",
+                gpfn, mfn, fgfn);
+        put_page(page);
+        rc = -EINVAL;
+    }
+
+    /*
+     * We must do this put_gfn after set_foreign_p2m_entry so another cpu
+     * doesn't populate the gpfn before us.
+     */
+    put_gfn(currd, gpfn);
+
+    put_pg_owner(fdom);
+    return rc;
+}
+
 static int xenmem_add_to_physmap_once(
     struct domain *d,
     const struct xen_add_to_physmap *xatp,
@@ -4582,6 +4654,14 @@ static int xenmem_add_to_physmap_once(
             page = mfn_to_page(mfn);
             break;
         }
+
+        case XENMAPSPACE_gmfn_foreign:
+        {
+            rc = xenmem_add_foreign_to_pmap(foreign_domid, xatp->idx,
+                                            xatp->gpfn);
+            return rc;
+        }
+
         default:
             break;
     }
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 68501d1..a321d33 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -675,9 +675,11 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 
     case XENMEM_remove_from_physmap:
     {
+        unsigned long mfn;
         struct xen_remove_from_physmap xrfp;
         struct page_info *page;
-        struct domain *d;
+        struct domain *d, *foreign_dom = NULL;
+        p2m_type_t p2mt, tp;
 
         if ( copy_from_guest(&xrfp, arg, 1) )
             return -EFAULT;
@@ -695,11 +697,37 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 
         domain_lock(d);
 
-        page = get_page_from_gfn(d, xrfp.gpfn, NULL, P2M_ALLOC);
-        if ( page )
+        /*
+         * if PVH, the gfn could be mapped to a mfn from foreign domain by the
+         * user space tool during domain creation. We need to check for that,
+         * free it up from the p2m, and release refcnt on it. In such a case,
+         * page would be NULL and the following call would not have refcnt'd
+         * the page. See also xenmem_add_foreign_to_pmap().
+         */
+        page = get_page_from_gfn(d, xrfp.gpfn, &p2mt, P2M_ALLOC);
+
+        if ( page || p2m_is_foreign(p2mt) )
         {
-            guest_physmap_remove_page(d, xrfp.gpfn, page_to_mfn(page), 0);
-            put_page(page);
+            if ( page )
+                mfn = page_to_mfn(page);
+            else
+            {
+                mfn = mfn_x(get_gfn_query(d, xrfp.gpfn, &tp));
+                foreign_dom = page_get_owner(mfn_to_page(mfn));
+                ASSERT(is_pvh_domain(d));
+                ASSERT(d != foreign_dom);
+                ASSERT(p2m_is_foreign(tp));
+            }
+
+            guest_physmap_remove_page(d, xrfp.gpfn, mfn, 0);
+            if (page)
+                put_page(page);
+
+            if ( p2m_is_foreign(p2mt) )
+            {
+                put_page(mfn_to_page(mfn));
+                put_gfn(d, xrfp.gpfn);
+            }
         }
         else
             rc = -ENOENT;
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 51d5254..b496551 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -208,7 +208,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
 #define XENMAPSPACE_gmfn_range   3 /* GMFN range, XENMEM_add_to_physmap only. */
 #define XENMAPSPACE_gmfn_foreign 4 /* GMFN from another dom,
                                     * XENMEM_add_to_physmap_range only.
-                                    */
+                                    * (PVH x86 only) */
 /* ` } */
 
 /*
-- 
1.7.2.3

  parent reply	other threads:[~2013-05-15  0:52 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-05-15  0:52 [PATCH 00/20][V5]: PVH xen: version 5 patches Mukesh Rathor
2013-05-15  0:52 ` [PATCH 01/20] PVH xen: turn gdb_frames/gdt_ents into union Mukesh Rathor
2013-05-15  0:52 ` [PATCH 02/20] PVH xen: add XENMEM_add_to_physmap_range Mukesh Rathor
2013-05-15  9:58   ` Jan Beulich
2013-05-15 23:05     ` Mukesh Rathor
2013-05-16  7:21       ` Jan Beulich
2013-05-16 11:03         ` Stefano Stabellini
2013-05-16 12:01           ` Jan Beulich
2013-05-16 15:04             ` Stefano Stabellini
2013-05-16 23:56         ` Mukesh Rathor
2013-05-17  6:37           ` Jan Beulich
2013-05-17 22:24             ` Mukesh Rathor
2013-05-15  0:52 ` [PATCH 03/20] PVH xen: create domctl_memory_mapping() function Mukesh Rathor
2013-05-15 10:07   ` Jan Beulich
2013-05-15  0:52 ` [PATCH 04/20] PVH xen: add params to read_segment_register Mukesh Rathor
2013-05-15  0:52 ` [PATCH 05/20] PVH xen: vmx realted preparatory changes for PVH Mukesh Rathor
2013-05-15  0:52 ` [PATCH 06/20] PVH xen: Move e820 fields out of pv_domain struct Mukesh Rathor
2013-05-15 10:27   ` Jan Beulich
2013-05-15  0:52 ` [PATCH 07/20] PVH xen: Introduce PVH guest type Mukesh Rathor
2013-05-15  0:52 ` [PATCH 08/20] PVH xen: tools changes to create PVH domain Mukesh Rathor
2013-05-15  0:52 ` [PATCH 09/20] PVH xen: domain creation code changes Mukesh Rathor
2013-05-15  0:52 ` [PATCH 10/20] PVH xen: create PVH vmcs, and also initialization Mukesh Rathor
2013-05-15  0:52 ` [PATCH 11/20] PVH xen: introduce pvh.c Mukesh Rathor
2013-05-15 10:42   ` Jan Beulich
2013-05-16  1:42     ` Mukesh Rathor
2013-05-16  8:00       ` Jan Beulich
2013-05-17  0:27         ` Mukesh Rathor
2013-05-17  6:43           ` Jan Beulich
2013-05-21  0:08             ` Mukesh Rathor
2013-05-21  7:07               ` Jan Beulich
2013-05-15  0:52 ` [PATCH 12/20] PVH xen: create read_descriptor_sel() Mukesh Rathor
2013-05-15  0:52 ` [PATCH 13/20] PVH xen: introduce vmx_pvh.c Mukesh Rathor
2013-05-15 11:46   ` Jan Beulich
2013-05-15  0:52 ` [PATCH 14/20] PVH xen: some misc changes like mtrr, intr, msi Mukesh Rathor
2013-05-15  0:52 ` [PATCH 15/20] PVH xen: hcall page initialize, create PVH guest type, etc Mukesh Rathor
2013-05-15  0:52 ` [PATCH 16/20] PVH xen: Miscellaneous changes Mukesh Rathor
2013-05-15 11:53   ` Jan Beulich
2013-05-16  1:51     ` Mukesh Rathor
2013-05-15  0:52 ` [PATCH 17/20] PVH xen: Introduce p2m_map_foreign Mukesh Rathor
2013-05-15 11:55   ` Jan Beulich
2013-05-15  0:52 ` Mukesh Rathor [this message]
2013-05-15 12:05   ` [PATCH 18/20] PVH xen: Add and remove foreign pages Jan Beulich
2013-05-15  0:52 ` [PATCH 19/20] PVH xen: elf and iommu related changes to prep for dom0 PVH Mukesh Rathor
2013-05-15 12:12   ` Jan Beulich
2013-05-16  1:58     ` Mukesh Rathor
2013-05-16  8:03       ` Jan Beulich
2013-05-17  1:14         ` Mukesh Rathor
2013-05-17  6:45           ` Jan Beulich
2013-05-18  2:01         ` Mukesh Rathor
2013-05-21  7:14           ` Jan Beulich
2013-05-15  0:52 ` [PATCH 20/20] PVH xen: PVH dom0 creation Mukesh Rathor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1368579168-30829-19-git-send-email-mukesh.rathor@oracle.com \
    --to=mukesh.rathor@oracle.com \
    --cc=Xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.