[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] libxc: introduce a per architecture scratch pfn for temporary grant mapping



commit 5b5c40c0d10f5ffbd35b7eef6df34a086000442f
Author:     Julien Grall <julien.grall@xxxxxxxxxx>
AuthorDate: Wed Jan 21 13:25:44 2015 +0000
Commit:     Ian Campbell <ian.campbell@xxxxxxxxxx>
CommitDate: Tue Jan 27 16:30:35 2015 +0000

    libxc: introduce a per architecture scratch pfn for temporary grant mapping

    The code to initialize the grant table in libxc uses
    xc_domain_maximum_gpfn() + 1 to get a guest pfn for mapping the grant
    frame and to initialize it.

    This solution has two major issues:
        - The check of the return of xc_domain_maximum_gpfn is buggy because
        xen_pfn_t is unsigned and in case of an error -ERRNO is returned.
        Which is never catch with ( pfn <= 0 ).
        - The guest memory layout maybe filled up to the end, i.e
        xc_domain_maximum_gpfn() + 1 gives either 0 or an invalid PFN due to
        hardware limitation.

    Futhermore, on ARM, xc_domain_maximum_gpfn() is not implemented and
    return -ENOSYS. This will make libxc to use always the same PFN which
    may colapse with an already mapped region (see xen/include/public/arch-arm.h
    for the layout).

    This patch only address the problem for ARM, the x86 version use the same
    behavior (ie xc_domain_maximum_gpfn() + 1), as I'm not familiar with Xen 
x86.

    A new function xc_core_arch_get_scratch_gpfn is introduced to be able to
    choose the gpfn per architecture.

    For the ARM version, we use the GUEST_GNTTAB_GUEST which is the base of
    the region by the guest to map the grant table. At the build time,
    nothing is mapped there.

    At the same time correctly check the return of xc_domain_maximum_gpfn
    for x86.

    Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx>
    Cc: Jan Beulich <jbeulich@xxxxxxxx>
    Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Cc: Roger Pau Monné <roger.pau@xxxxxxxxxx>
    Cc: Ian Jackson <ian.jackson@xxxxxxxxxxxxx>
    Cc: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
    Cc: Ian Campbell <ian.campbell@xxxxxxxxxx>
    Cc: Wei Liu <wei.liu2@xxxxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 tools/libxc/xc_core.h     |    3 +++
 tools/libxc/xc_core_arm.c |   17 +++++++++++++++++
 tools/libxc/xc_core_x86.c |   17 +++++++++++++++++
 tools/libxc/xc_dom_boot.c |   18 ++++++++++++------
 4 files changed, 49 insertions(+), 6 deletions(-)

diff --git a/tools/libxc/xc_core.h b/tools/libxc/xc_core.h
index 10cbfca..5867030 100644
--- a/tools/libxc/xc_core.h
+++ b/tools/libxc/xc_core.h
@@ -148,6 +148,9 @@ int xc_core_arch_map_p2m_writable(xc_interface *xch, 
unsigned int guest_width,
                                   shared_info_any_t *live_shinfo,
                                   xen_pfn_t **live_p2m, unsigned long *pfnp);

+int xc_core_arch_get_scratch_gpfn(xc_interface *xch, domid_t domid,
+                                  xen_pfn_t *gpfn);
+

 #if defined (__i386__) || defined (__x86_64__)
 # include "xc_core_x86.h"
diff --git a/tools/libxc/xc_core_arm.c b/tools/libxc/xc_core_arm.c
index 2fbcf3f..16508e7 100644
--- a/tools/libxc/xc_core_arm.c
+++ b/tools/libxc/xc_core_arm.c
@@ -96,6 +96,23 @@ xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned 
int guest_width, xc_do
     return xc_core_arch_map_p2m_rw(xch, dinfo, info,
                                    live_shinfo, live_p2m, pfnp, 1);
 }
+
+int
+xc_core_arch_get_scratch_gpfn(xc_interface *xch, domid_t domid,
+                              xen_pfn_t *gpfn)
+{
+    /*
+     * The Grant Table region space is not used until the guest is
+     * booting. Use the first page for the scratch pfn.
+     */
+    XC_BUILD_BUG_ON(GUEST_GNTTAB_SIZE < XC_PAGE_SIZE);
+
+    *gpfn = GUEST_GNTTAB_BASE >> XC_PAGE_SHIFT;
+
+    return 0;
+}
+
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_core_x86.c b/tools/libxc/xc_core_x86.c
index f05060a..fac99ec 100644
--- a/tools/libxc/xc_core_x86.c
+++ b/tools/libxc/xc_core_x86.c
@@ -205,6 +205,23 @@ xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned 
int guest_width, xc_do
     return xc_core_arch_map_p2m_rw(xch, dinfo, info,
                                    live_shinfo, live_p2m, pfnp, 1);
 }
+
+int
+xc_core_arch_get_scratch_gpfn(xc_interface *xch, domid_t domid,
+                              xen_pfn_t *gpfn)
+{
+    int rc;
+
+    rc = xc_domain_maximum_gpfn(xch, domid);
+
+    if ( rc <= 0 )
+        return rc;
+
+    *gpfn = rc + 1;
+
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index f0a1c64..a141eb5 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -33,6 +33,7 @@

 #include "xg_private.h"
 #include "xc_dom.h"
+#include "xc_core.h"
 #include <xen/hvm/params.h>
 #include <xen/grant_table.h>

@@ -365,7 +366,7 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
                            domid_t xenstore_domid)
 {
     int rc;
-    xen_pfn_t max_gfn;
+    xen_pfn_t scratch_gpfn;
     struct xen_add_to_physmap xatp = {
         .domid = domid,
         .space = XENMAPSPACE_grant_table,
@@ -375,16 +376,21 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t 
domid,
         .domid = domid,
     };

-    max_gfn = xc_domain_maximum_gpfn(xch, domid);
-    if ( max_gfn <= 0 ) {
+    rc = xc_core_arch_get_scratch_gpfn(xch, domid, &scratch_gpfn);
+    if ( rc < 0 )
+    {
         xc_dom_panic(xch, XC_INTERNAL_ERROR,
-                     "%s: failed to get max gfn "
+                     "%s: failed to get a scratch gfn "
                      "[errno=%d]\n",
                      __FUNCTION__, errno);
         return -1;
     }
-    xatp.gpfn = max_gfn + 1;
-    xrfp.gpfn = max_gfn + 1;
+    xatp.gpfn = scratch_gpfn;
+    xrfp.gpfn = scratch_gpfn;
+
+    xc_dom_printf(xch, "%s: called, pfn=0x%"PRI_xen_pfn, __FUNCTION__,
+                  scratch_gpfn);
+

     rc = do_memory_op(xch, XENMEM_add_to_physmap, &xatp, sizeof(xatp));
     if ( rc != 0 )
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.