mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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@citrix.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Paul Durrant <paul@xen.org> Acked-by: Wei Liu <wl@xen.org>
This commit is contained in:
1 parent
2b4b33ffe7
commit
75fc859985
7 files changed
+88
-8
No files matched your search
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||