[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 |