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

[Xen-devel] [PATCH V15 5/9] xen: Make gpfn related memops compatible with wider return values



The current implementation of three memops, XENMEM_current_reservation,
XENMEM_maximum_reservation and XENMEM_maximum_gpfn return values as an
int. However, in ARM64 we could potentially have 36-bit pfn's, thus
in preparation for the ARM patch, in this patch we update the existing
memop routines to use a struct, xen_get_gpfn, to exchange the gpfn info
as a uin64_t.

This patch also adds error checking on the toolside in case the memop
fails.

Signed-off-by: Tamas K Lengyel <tklengyel@xxxxxxxxxxxxx>
---
 tools/libxc/include/xenguest.h          |  2 +-
 tools/libxc/xc_core.h                   |  4 ++--
 tools/libxc/xc_core_arm.c               |  6 +++---
 tools/libxc/xc_core_x86.c               |  8 ++++----
 tools/libxc/xc_domain.c                 | 14 ++++++--------
 tools/libxc/xc_domain_save.c            |  3 ++-
 tools/libxc/xg_private.h                |  2 +-
 tools/tests/mce-test/tools/xen-mceinj.c | 28 ++++++++++++++++++----------
 xen/common/memory.c                     | 16 ++++++++++------
 xen/include/public/memory.h             | 24 ++++++++++++++++++++----
 10 files changed, 67 insertions(+), 40 deletions(-)

diff --git a/tools/libxc/include/xenguest.h b/tools/libxc/include/xenguest.h
index 601b108..5ee2848 100644
--- a/tools/libxc/include/xenguest.h
+++ b/tools/libxc/include/xenguest.h
@@ -315,7 +315,7 @@ struct xc_domain_meminfo {
     unsigned int guest_width;
     xen_pfn_t *pfn_type;
     xen_pfn_t *p2m_table;
-    unsigned long p2m_size;
+    xen_pfn_t p2m_size;
 };
 
 int xc_map_domain_meminfo(xc_interface *xch, int domid,
diff --git a/tools/libxc/xc_core.h b/tools/libxc/xc_core.h
index 5867030..99a87e6 100644
--- a/tools/libxc/xc_core.h
+++ b/tools/libxc/xc_core.h
@@ -141,12 +141,12 @@ int xc_core_arch_memory_map_get(xc_interface *xch,
                                 unsigned int *nr_entries);
 int xc_core_arch_map_p2m(xc_interface *xch, unsigned int guest_width,
                          xc_dominfo_t *info, shared_info_any_t *live_shinfo,
-                         xen_pfn_t **live_p2m, unsigned long *pfnp);
+                         xen_pfn_t **live_p2m, xen_pfn_t *pfnp);
 
 int xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned int guest_width,
                                   xc_dominfo_t *info,
                                   shared_info_any_t *live_shinfo,
-                                  xen_pfn_t **live_p2m, unsigned long *pfnp);
+                                  xen_pfn_t **live_p2m, xen_pfn_t *pfnp);
 
 int xc_core_arch_get_scratch_gpfn(xc_interface *xch, domid_t domid,
                                   xen_pfn_t *gpfn);
diff --git a/tools/libxc/xc_core_arm.c b/tools/libxc/xc_core_arm.c
index 57d4715..75ac630 100644
--- a/tools/libxc/xc_core_arm.c
+++ b/tools/libxc/xc_core_arm.c
@@ -66,7 +66,7 @@ xc_core_arch_memory_map_get(xc_interface *xch, struct 
xc_core_arch_context *unus
 static int
 xc_core_arch_map_p2m_rw(xc_interface *xch, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
                         shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
-                        unsigned long *pfnp, int rw)
+                        xen_pfn_t *pfnp, int rw)
 {
     errno = ENOSYS;
     return -1;
@@ -75,7 +75,7 @@ xc_core_arch_map_p2m_rw(xc_interface *xch, struct 
domain_info_context *dinfo, xc
 int
 xc_core_arch_map_p2m(xc_interface *xch, unsigned int guest_width, xc_dominfo_t 
*info,
                         shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
-                        unsigned long *pfnp)
+                        xen_pfn_t *pfnp)
 {
     struct domain_info_context _dinfo = { .guest_width = guest_width };
     struct domain_info_context *dinfo = &_dinfo;
@@ -86,7 +86,7 @@ xc_core_arch_map_p2m(xc_interface *xch, unsigned int 
guest_width, xc_dominfo_t *
 int
 xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned int guest_width, 
xc_dominfo_t *info,
                               shared_info_any_t *live_shinfo, xen_pfn_t 
**live_p2m,
-                              unsigned long *pfnp)
+                              xen_pfn_t *pfnp)
 {
     struct domain_info_context _dinfo = { .guest_width = guest_width };
     struct domain_info_context *dinfo = &_dinfo;
diff --git a/tools/libxc/xc_core_x86.c b/tools/libxc/xc_core_x86.c
index 93ebcbb..c2bb059 100644
--- a/tools/libxc/xc_core_x86.c
+++ b/tools/libxc/xc_core_x86.c
@@ -71,7 +71,7 @@ xc_core_arch_memory_map_get(xc_interface *xch, struct 
xc_core_arch_context *unus
 static int
 xc_core_arch_map_p2m_rw(xc_interface *xch, struct domain_info_context *dinfo, 
xc_dominfo_t *info,
                         shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
-                        unsigned long *pfnp, int rw)
+                        xen_pfn_t *pfnp, int rw)
 {
     /* Double and single indirect references to the live P2M table */
     xen_pfn_t *live_p2m_frame_list_list = NULL;
@@ -188,8 +188,8 @@ out:
 
 int
 xc_core_arch_map_p2m(xc_interface *xch, unsigned int guest_width, xc_dominfo_t 
*info,
-                        shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
-                        unsigned long *pfnp)
+                     shared_info_any_t *live_shinfo, xen_pfn_t **live_p2m,
+                     xen_pfn_t *pfnp)
 {
     struct domain_info_context _dinfo = { .guest_width = guest_width };
     struct domain_info_context *dinfo = &_dinfo;
@@ -200,7 +200,7 @@ xc_core_arch_map_p2m(xc_interface *xch, unsigned int 
guest_width, xc_dominfo_t *
 int
 xc_core_arch_map_p2m_writable(xc_interface *xch, unsigned int guest_width, 
xc_dominfo_t *info,
                               shared_info_any_t *live_shinfo, xen_pfn_t 
**live_p2m,
-                              unsigned long *pfnp)
+                              xen_pfn_t *pfnp)
 {
     struct domain_info_context _dinfo = { .guest_width = guest_width };
     struct domain_info_context *dinfo = &_dinfo;
diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 7cb36d9..2ebbe24 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -796,16 +796,14 @@ int xc_domain_get_tsc_info(xc_interface *xch,
     return rc;
 }
 
-
 int xc_domain_maximum_gpfn(xc_interface *xch, domid_t domid, xen_pfn_t *gpfns)
 {
-    int rc = do_memory_op(xch, XENMEM_maximum_gpfn, &domid, sizeof(domid));
+    struct xen_get_gpfn xgg = { .domid = domid };
+    int rc = do_memory_op(xch, XENMEM_maximum_gpfn, &xgg, sizeof(struct 
xen_get_gpfn));
+
+    if ( !rc )
+        *gpfns = xgg.gpfn;
 
-    if ( rc >= 0 )
-    {
-        *gpfns = rc;
-        rc = 0;
-    }
     return rc;
 }
 
@@ -813,7 +811,7 @@ int xc_domain_nr_gpfns(xc_interface *xch, domid_t domid, 
xen_pfn_t *gpfns)
 {
     int rc = xc_domain_maximum_gpfn(xch, domid, gpfns);
 
-    if ( rc >= 0 )
+    if ( !rc )
         *gpfns += 1;
 
     return rc;
diff --git a/tools/libxc/xc_domain_save.c b/tools/libxc/xc_domain_save.c
index 59323b8..a94c59a 100644
--- a/tools/libxc/xc_domain_save.c
+++ b/tools/libxc/xc_domain_save.c
@@ -811,7 +811,8 @@ int xc_domain_save(xc_interface *xch, int io_fd, uint32_t 
dom, uint32_t max_iter
     int live  = (flags & XCFLAGS_LIVE);
     int debug = (flags & XCFLAGS_DEBUG);
     int superpages = !!hvm;
-    int race = 0, sent_last_iter, skip_this_iter = 0;
+    int race = 0, skip_this_iter = 0;
+    xen_pfn_t sent_last_iter = 0;
     unsigned int sent_this_iter = 0;
     int tmem_saved = 0;
 
diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h
index 1910361..53893fc 100644
--- a/tools/libxc/xg_private.h
+++ b/tools/libxc/xg_private.h
@@ -129,7 +129,7 @@ typedef uint64_t l4_pgentry_64_t;
 
 struct domain_info_context {
     unsigned int guest_width;
-    unsigned long p2m_size;
+    xen_pfn_t p2m_size;
 };
 
 static inline xen_pfn_t xc_pfn_to_mfn(xen_pfn_t pfn, xen_pfn_t *p2m,
diff --git a/tools/tests/mce-test/tools/xen-mceinj.c 
b/tools/tests/mce-test/tools/xen-mceinj.c
index 8ad045f..722cc68 100644
--- a/tools/tests/mce-test/tools/xen-mceinj.c
+++ b/tools/tests/mce-test/tools/xen-mceinj.c
@@ -294,17 +294,21 @@ static uint64_t guest_mfn(xc_interface *xc_handle,
     unsigned long max_mfn = 0; /* max mfn of the whole machine */
     unsigned long m2p_mfn0;
     unsigned int guest_width;
-    long max_gpfn,i;
+    xen_pfn_t max_gpfn;
+    long i;
     uint64_t mfn = MCE_INVALID_MFN;
+    struct xen_get_gpfn xgg = { .domid = domain };
 
     if ( domain > DOMID_FIRST_RESERVED )
         return MCE_INVALID_MFN;
 
     /* Get max gpfn */
-    max_gpfn = do_memory_op(xc_handle, XENMEM_maximum_gpfn, &domain, 
-                               sizeof(domain)) + 1;
-    if ( max_gpfn <= 0 )
-        err(xc_handle, "Failed to get max_gpfn 0x%lx", max_gpfn);
+    rc = do_memory_op(xc_handle, XENMEM_maximum_gpfn, &xgg,
+                               sizeof(struct xen_get_gpfn));
+    if ( rc )
+        err(xc_handle, "Failed to get max_gpfn 0x%lx", rc);
+
+    max_gpfn = xgg.gpfn + 1;
 
     Lprintf("Maxium gpfn for dom %d is 0x%lx", domain, max_gpfn);
 
@@ -355,16 +359,20 @@ static uint64_t mca_gpfn_to_mfn(xc_interface *xc_handle,
                                 uint64_t gfn)
 {
     uint64_t index;
-    long max_gpfn;
+    xen_pfn_t max_gpfn;
+    struct xen_get_gpfn xgg = { .domid = domain };
 
     /* If domain is xen, means we want pass index directly */
     if ( domain == DOMID_XEN )
         return gfn;
 
-    max_gpfn = do_memory_op(xc_handle, XENMEM_maximum_gpfn, &domain, 
-                               sizeof(domain)) + 1;
-    if ( max_gpfn <= 0 )
-        err(xc_handle, "Failed to get max_gpfn 0x%lx", max_gpfn);
+    rc = do_memory_op(xc_handle, XENMEM_maximum_gpfn, &xgg,
+                               sizeof(struct xen_get_gpfn));
+    if ( rc )
+        err(xc_handle, "Failed to get max_gpfn 0x%lx", rc);
+
+    max_gpfn = xgg.gpfn + 1;
+
     index = gfn % max_gpfn;
 
     return guest_mfn(xc_handle, domain, index);
diff --git a/xen/common/memory.c b/xen/common/memory.c
index 063a1c5..0a79d73 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -838,12 +838,16 @@ long do_memory_op(unsigned long cmd, 
XEN_GUEST_HANDLE_PARAM(void) arg)
     case XENMEM_current_reservation:
     case XENMEM_maximum_reservation:
     case XENMEM_maximum_gpfn:
+    {
+        struct xen_get_gpfn xgg;
+
         if ( unlikely(start_extent) )
             return -ENOSYS;
 
-        if ( copy_from_guest(&domid, arg, 1) )
+        if ( copy_from_guest(&xgg, arg, 1) )
             return -EFAULT;
 
+        domid = xgg.domid;
         d = rcu_lock_domain_by_any_id(domid);
         if ( d == NULL )
             return -ESRCH;
@@ -858,20 +862,20 @@ long do_memory_op(unsigned long cmd, 
XEN_GUEST_HANDLE_PARAM(void) arg)
         switch ( op )
         {
         case XENMEM_current_reservation:
-            rc = d->tot_pages;
+            xgg.gpfn = d->tot_pages;
             break;
         case XENMEM_maximum_reservation:
-            rc = d->max_pages;
+            xgg.gpfn = d->max_pages;
             break;
         default:
             ASSERT(op == XENMEM_maximum_gpfn);
-            rc = domain_get_maximum_gpfn(d);
+            xgg.gpfn = domain_get_maximum_gpfn(d);
             break;
         }
 
         rcu_unlock_domain(d);
-
-        break;
+        return __copy_to_guest(arg, &xgg, 1) ? -EFAULT : 0;
+    }
 
     case XENMEM_add_to_physmap:
     {
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 832559a..6567d45 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -146,19 +146,35 @@ DEFINE_XEN_GUEST_HANDLE(xen_memory_exchange_t);
 #define XENMEM_maximum_ram_page     2
 
 /*
- * Returns the current or maximum memory reservation, in pages, of the
- * specified domain (may be DOMID_SELF). Returns -ve errcode on failure.
- * arg == addr of domid_t.
+ * Sets gpfn to the current or maximum memory reservation, in pages, of the
+ * specified domain (may be DOMID_SELF) on struct xen_get_gpfn.
+ * Returns -ve errcode on failure.
  */
 #define XENMEM_current_reservation  3
 #define XENMEM_maximum_reservation  4
 
 /*
- * Returns the maximum GPFN in use by the guest, or -ve errcode on failure.
+ * Sets gpfn to the maximum GPFN in use by the guest on struct xen_get_gpfn.
+ * Returns -ve errcode on failure.
  */
 #define XENMEM_maximum_gpfn         14
 
 /*
+ * Struct to hold gpfn return value for calls of
+ *  XENMEM_current_reservation
+ *  XENMEM_maximum_reservation
+ *  XENMEM_maximum_gpfn
+ */
+struct xen_get_gpfn {
+    /* OUT */
+    xen_pfn_t gpfn;
+    /* IN */
+    domid_t domid;
+};
+typedef struct xen_get_gpfn xen_get_gpfn_t;
+DEFINE_XEN_GUEST_HANDLE(xen_get_gpfn_t);
+
+/*
  * Returns a list of MFN bases of 2MB extents comprising the machine_to_phys
  * mapping table. Architectures which do not have a m2p table do not implement
  * this command.
-- 
2.1.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

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