|
[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
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |