[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v4] tools/foreignmem: Support querying the size of a resource
With the Xen side of this interface (soon to be) fixed to return real sizes, userspace needs to be able to make the query. Introduce xenforeignmemory_resource_size() for the purpose, bumping the library minor version. Update both all osdep_xenforeignmemory_map_resource() implementations to understand size requests, skip the mmap() operation, and copy back the nr_frames field. For NetBSD, also fix up the ioctl() error path to issue an unmap(), which was overlooked by c/s 4a64e2bb39 "libs/foreignmemory: Implement on NetBSD". Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- CC: Wei Liu <wl@xxxxxxx> CC: Paul Durrant <paul@xxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Juergen Gross <jgross@xxxxxxxx> CC: Ian Jackson <iwj@xxxxxxxxxxxxxx> CC: Michał Leszczyński <michal.leszczynski@xxxxxxx> CC: Hubert Jasudowicz <hubert.jasudowicz@xxxxxxx> CC: Tamas K Lengyel <tamas@xxxxxxxxxxxxx> CC: Manuel Bouyer <bouyer@xxxxxxxxxx> This depends on a bugfix to the Linux IOCTL to understand size requests and pass them on to Xen. https://lore.kernel.org/xen-devel/20210112115358.23346-1-roger.pau@xxxxxxxxxx/T/#u v4: * Rebase over NetBSD support being added. v3: * Rewrite from scratch, to avoid breaking restricted domid situations. In particular, we cannot open a xencall interface and issue blind hypercalls. --- tools/include/xenforeignmemory.h | 15 +++++++++++++++ tools/libs/foreignmemory/Makefile | 2 +- tools/libs/foreignmemory/core.c | 18 ++++++++++++++++++ tools/libs/foreignmemory/freebsd.c | 18 +++++++++++++++--- tools/libs/foreignmemory/libxenforeignmemory.map | 4 ++++ tools/libs/foreignmemory/linux.c | 18 +++++++++++++++--- tools/libs/foreignmemory/netbsd.c | 21 ++++++++++++++++++++- 7 files changed, 88 insertions(+), 8 deletions(-) diff --git a/tools/include/xenforeignmemory.h b/tools/include/xenforeignmemory.h index d594be8df0..0ab1dd19d3 100644 --- a/tools/include/xenforeignmemory.h +++ b/tools/include/xenforeignmemory.h @@ -179,6 +179,21 @@ xenforeignmemory_resource_handle *xenforeignmemory_map_resource( int xenforeignmemory_unmap_resource( xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres); +/** + * Determine the maximum size of a specific resource. + * + * @parm fmem handle to the open foreignmemory interface + * @parm domid the domain id + * @parm type the resource type + * @parm id the type-specific resource identifier + * + * Return 0 on success and fills in *size, with a value in bytes. Sets errno + * and return -1 on error. + */ +int xenforeignmemory_resource_size( + xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, + unsigned int id, size_t *size); + #endif /* diff --git a/tools/libs/foreignmemory/Makefile b/tools/libs/foreignmemory/Makefile index f191cdbed0..0eb9a3a712 100644 --- a/tools/libs/foreignmemory/Makefile +++ b/tools/libs/foreignmemory/Makefile @@ -2,7 +2,7 @@ XEN_ROOT = $(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk MAJOR = 1 -MINOR = 3 +MINOR = 4 SRCS-y += core.c SRCS-$(CONFIG_Linux) += linux.c diff --git a/tools/libs/foreignmemory/core.c b/tools/libs/foreignmemory/core.c index 63f12e2450..28ec311af1 100644 --- a/tools/libs/foreignmemory/core.c +++ b/tools/libs/foreignmemory/core.c @@ -188,6 +188,24 @@ int xenforeignmemory_unmap_resource( return rc; } +int xenforeignmemory_resource_size( + xenforeignmemory_handle *fmem, domid_t domid, unsigned int type, + unsigned int id, size_t *size) +{ + xenforeignmemory_resource_handle fres = { + .domid = domid, + .type = type, + .id = id, + }; + int rc = osdep_xenforeignmemory_map_resource(fmem, &fres); + + if ( rc ) + return rc; + + *size = fres.nr_frames << PAGE_SHIFT; + return 0; +} + /* * Local variables: * mode: C diff --git a/tools/libs/foreignmemory/freebsd.c b/tools/libs/foreignmemory/freebsd.c index 3d403a7cd0..9a2796f0b7 100644 --- a/tools/libs/foreignmemory/freebsd.c +++ b/tools/libs/foreignmemory/freebsd.c @@ -119,6 +119,10 @@ int osdep_xenforeignmemory_map_resource(xenforeignmemory_handle *fmem, }; int rc; + if ( !fres->addr && !fres->nr_frames ) + /* Request for resource size. Skip mmap(). */ + goto skip_mmap; + fres->addr = mmap(fres->addr, fres->nr_frames << PAGE_SHIFT, fres->prot, fres->flags | MAP_SHARED, fmem->fd, 0); if ( fres->addr == MAP_FAILED ) @@ -126,6 +130,7 @@ int osdep_xenforeignmemory_map_resource(xenforeignmemory_handle *fmem, mr.addr = (uintptr_t)fres->addr; + skip_mmap: rc = ioctl(fmem->fd, IOCTL_PRIVCMD_MMAP_RESOURCE, &mr); if ( rc ) { @@ -136,13 +141,20 @@ int osdep_xenforeignmemory_map_resource(xenforeignmemory_handle *fmem, else errno = EOPNOTSUPP; - saved_errno = errno; - osdep_xenforeignmemory_unmap_resource(fmem, fres); - errno = saved_errno; + if ( fres->addr ) + { + saved_errno = errno; + osdep_xenforeignmemory_unmap_resource(fmem, fres); + errno = saved_errno; + } return -1; } + /* If requesting size, copy back. */ + if ( !fres->addr ) + fres->nr_frames = mr.num; + return 0; } diff --git a/tools/libs/foreignmemory/libxenforeignmemory.map b/tools/libs/foreignmemory/libxenforeignmemory.map index d5323c87d9..8aca341b99 100644 --- a/tools/libs/foreignmemory/libxenforeignmemory.map +++ b/tools/libs/foreignmemory/libxenforeignmemory.map @@ -19,3 +19,7 @@ VERS_1.3 { xenforeignmemory_map_resource; xenforeignmemory_unmap_resource; } VERS_1.2; +VERS_1.4 { + global: + xenforeignmemory_resource_size; +} VERS_1.3; diff --git a/tools/libs/foreignmemory/linux.c b/tools/libs/foreignmemory/linux.c index fe73d5ab72..d0eead1196 100644 --- a/tools/libs/foreignmemory/linux.c +++ b/tools/libs/foreignmemory/linux.c @@ -312,6 +312,10 @@ int osdep_xenforeignmemory_map_resource( }; int rc; + if ( !fres->addr && !fres->nr_frames ) + /* Request for resource size. Skip mmap(). */ + goto skip_mmap; + fres->addr = mmap(fres->addr, fres->nr_frames << PAGE_SHIFT, fres->prot, fres->flags | MAP_SHARED, fmem->fd, 0); if ( fres->addr == MAP_FAILED ) @@ -319,6 +323,7 @@ int osdep_xenforeignmemory_map_resource( mr.addr = (uintptr_t)fres->addr; + skip_mmap: rc = ioctl(fmem->fd, IOCTL_PRIVCMD_MMAP_RESOURCE, &mr); if ( rc ) { @@ -329,13 +334,20 @@ int osdep_xenforeignmemory_map_resource( else errno = EOPNOTSUPP; - saved_errno = errno; - (void)osdep_xenforeignmemory_unmap_resource(fmem, fres); - errno = saved_errno; + if ( fres->addr ) + { + saved_errno = errno; + osdep_xenforeignmemory_unmap_resource(fmem, fres); + errno = saved_errno; + } return -1; } + /* If requesting size, copy back. */ + if ( !fres->addr ) + fres->nr_frames = mr.num; + return 0; } diff --git a/tools/libs/foreignmemory/netbsd.c b/tools/libs/foreignmemory/netbsd.c index d26566f601..4ae60aafdd 100644 --- a/tools/libs/foreignmemory/netbsd.c +++ b/tools/libs/foreignmemory/netbsd.c @@ -132,6 +132,10 @@ int osdep_xenforeignmemory_map_resource( }; int rc; + if ( !fres->addr && !fres->nr_frames ) + /* Request for resource size. Skip mmap(). */ + goto skip_mmap; + fres->addr = mmap(fres->addr, fres->nr_frames << PAGE_SHIFT, fres->prot, fres->flags | MAP_ANON | MAP_SHARED, -1, 0); if ( fres->addr == MAP_FAILED ) @@ -139,13 +143,28 @@ int osdep_xenforeignmemory_map_resource( mr.addr = (uintptr_t)fres->addr; + skip_mmap: rc = ioctl(fmem->fd, IOCTL_PRIVCMD_MMAP_RESOURCE, &mr); if ( rc ) { PERROR("ioctl failed"); + + if ( fres->addr ) + { + int saved_errno = errno; + + osdep_xenforeignmemory_unmap_resource(fmem, fres); + errno = saved_errno; + } + + return -1; } - return rc; + /* If requesting size, copy back. */ + if ( !fres->addr ) + fres->nr_frames = mr.num; + + return 0; } /* -- 2.11.0
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |