|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] tools/foreignmem: Support querying the size of a resource
commit 75fc85998546878ca5417071a6ca60c34065c2c3
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Thu Jul 23 15:58:48 2020 +0100
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Thu Jan 28 13:08:11 2021 +0000
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>
Reviewed-by: Paul Durrant <paul@xxxxxxx>
Acked-by: Wei Liu <wl@xxxxxxx>
---
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;
}
/*
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |