* Interface to /dev/xen/gntdev.
*
* Copyright (c) 2007, D G Murray
+ * Copyright (c) 2018, Oleksandr Andrushchenko, EPAM Systems Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
struct ioctl_gntdev_grant_copy_segment *segments;
};
+/*
+ * Flags to be used while requesting memory mapping's backing storage
+ * to be allocated with DMA API.
+ */
+
+/*
+ * The buffer is backed with memory allocated with dma_alloc_wc.
+ */
+#define GNTDEV_DMA_FLAG_WC (1 << 0)
+
+/*
+ * The buffer is backed with memory allocated with dma_alloc_coherent.
+ */
+#define GNTDEV_DMA_FLAG_COHERENT (1 << 1)
+
+/*
+ * Create a dma-buf [1] from grant references @refs of count @count provided
+ * by the foreign domain @domid with flags @flags.
+ *
+ * By default dma-buf is backed by system memory pages, but by providing
+ * one of the GNTDEV_DMA_FLAG_XXX flags it can also be created as
+ * a DMA write-combine or coherent buffer, e.g. allocated with dma_alloc_wc/
+ * dma_alloc_coherent.
+ *
+ * Returns 0 if dma-buf was successfully created and the corresponding
+ * dma-buf's file descriptor is returned in @fd.
+ *
+ * [1] https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/dma-buf.rst
+ */
+
+#define IOCTL_GNTDEV_DMABUF_EXP_FROM_REFS \
+ _IOC(_IOC_NONE, 'G', 9, \
+ sizeof(struct ioctl_gntdev_dmabuf_exp_from_refs))
+struct ioctl_gntdev_dmabuf_exp_from_refs {
+ /* IN parameters. */
+ /* Specific options for this dma-buf: see GNTDEV_DMABUF_FLAG_XXX. */
+ uint32_t flags;
+ /* Number of grant references in @refs array. */
+ uint32_t count;
+ /* OUT parameters. */
+ /* File descriptor of the dma-buf. */
+ uint32_t fd;
+ /* The domain ID of the grant references to be mapped. */
+ uint32_t domid;
+ /* Variable IN parameter. */
+ /* Array of grant references of size @count. */
+ uint32_t refs[1];
+};
+
+/*
+ * This will block until the dma-buf with the file descriptor @fd is
+ * released. This is only valid for buffers created with
+ * IOCTL_GNTDEV_DMABUF_EXP_FROM_REFS.
+ *
+ * If withing @wait_to_ms milliseconds the buffer is not released
+ * then -ETIMEDOUT error is returned.
+ * If the buffer with file descriptor @fd does not exist or has already
+ * been released, then -ENOENT is returned. For valid file descriptors
+ * this must not be treated as error.
+ */
+#define IOCTL_GNTDEV_DMABUF_EXP_WAIT_RELEASED \
+ _IOC(_IOC_NONE, 'G', 10, \
+ sizeof(struct ioctl_gntdev_dmabuf_exp_wait_released))
+struct ioctl_gntdev_dmabuf_exp_wait_released {
+ /* IN parameters */
+ uint32_t fd;
+ uint32_t wait_to_ms;
+};
+
+/*
+ * Import a dma-buf with file descriptor @fd and export granted references
+ * to the pages of that dma-buf into array @refs of size @count.
+ */
+#define IOCTL_GNTDEV_DMABUF_IMP_TO_REFS \
+ _IOC(_IOC_NONE, 'G', 11, \
+ sizeof(struct ioctl_gntdev_dmabuf_imp_to_refs))
+struct ioctl_gntdev_dmabuf_imp_to_refs {
+ /* IN parameters. */
+ /* File descriptor of the dma-buf. */
+ uint32_t fd;
+ /* Number of grant references in @refs array. */
+ uint32_t count;
+ /* The domain ID for which references to be granted. */
+ uint32_t domid;
+ /* Reserved - must be zero. */
+ uint32_t reserved;
+ /* OUT parameters. */
+ /* Array of grant references of size @count. */
+ uint32_t refs[1];
+};
+
+/*
+ * This will close all references to an imported buffer, so it can be
+ * released by the owner. This is only valid for buffers created with
+ * IOCTL_GNTDEV_DMABUF_IMP_TO_REFS.
+ */
+#define IOCTL_GNTDEV_DMABUF_IMP_RELEASE \
+ _IOC(_IOC_NONE, 'G', 12, \
+ sizeof(struct ioctl_gntdev_dmabuf_imp_release))
+struct ioctl_gntdev_dmabuf_imp_release {
+ /* IN parameters */
+ uint32_t fd;
+ uint32_t reserved;
+};
+
#endif /* __LINUX_PUBLIC_GNTDEV_H__ */
include $(XEN_ROOT)/tools/Rules.mk
MAJOR = 1
-MINOR = 2
+MINOR = 3
SHLIB_LDFLAGS += -Wl,--version-script=libxengnttab.map
CFLAGS += -Werror -Wmissing-prototypes
/******************************************************************************
*
* Copyright (c) 2007-2008, D G Murray <Derek.Murray@cl.cam.ac.uk>
+ * Copyright (c) 2018, Oleksandr Andrushchenko, EPAM Systems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
{
return osdep_gnttab_grant_copy(xgt, count, segs);
}
+
+int xengnttab_dmabuf_exp_from_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t flags, uint32_t count,
+ const uint32_t *refs, uint32_t *fd)
+{
+ return osdep_gnttab_dmabuf_exp_from_refs(xgt, domid, flags, count,
+ refs, fd);
+}
+
+int xengnttab_dmabuf_exp_wait_released(xengnttab_handle *xgt, uint32_t fd,
+ uint32_t wait_to_ms)
+{
+ return osdep_gnttab_dmabuf_exp_wait_released(xgt, fd, wait_to_ms);
+}
+
+int xengnttab_dmabuf_imp_to_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t fd, uint32_t count, uint32_t *refs)
+{
+ return osdep_gnttab_dmabuf_imp_to_refs(xgt, domid, fd, count, refs);
+}
+
+int xengnttab_dmabuf_imp_release(xengnttab_handle *xgt, uint32_t fd)
+{
+ return osdep_gnttab_dmabuf_imp_release(xgt, fd);
+}
/*
* Local variables:
* mode: C
/******************************************************************************
*
* Copyright (c) 2007-2008, D G Murray <Derek.Murray@cl.cam.ac.uk>
+ * Copyright (c) 2018, Oleksandr Andrushchenko, EPAM Systems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
{
abort();
}
+
+int xengnttab_dmabuf_exp_from_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t flags, uint32_t count,
+ const uint32_t *refs, uint32_t *fd)
+{
+ abort();
+}
+
+int xengnttab_dmabuf_exp_wait_released(xengnttab_handle *xgt, uint32_t fd,
+ uint32_t wait_to_ms)
+{
+ abort();
+}
+
+int xengnttab_dmabuf_imp_to_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t fd, uint32_t count, uint32_t *refs)
+{
+ abort();
+}
+
+int xengnttab_dmabuf_imp_release(xengnttab_handle *xgt, uint32_t fd)
+{
+ abort();
+}
+
/*
* Local variables:
* mode: C
* A library for low-level access to the Xen control interfaces.
*
* Copyright (c) 2007-2008, D G Murray <Derek.Murray@cl.cam.ac.uk>
+ * Copyright (c) 2018, Oleksandr Andrushchenko, EPAM Systems Inc.
*/
#ifndef XENGNTTAB_H
#define XENGNTTAB_H
uint32_t count,
xengnttab_grant_copy_segment_t *segs);
+/*
+ * Flags to be used while requesting memory mapping's backing storage
+ * to be allocated with DMA API.
+ */
+
+/*
+ * The buffer is backed with memory allocated with dma_alloc_wc.
+ */
+#define GNTDEV_DMA_FLAG_WC (1 << 0)
+
+/*
+ * The buffer is backed with memory allocated with dma_alloc_coherent.
+ */
+#define GNTDEV_DMA_FLAG_COHERENT (1 << 1)
+
+/**
+ * Create a dma-buf [1] from grant references @refs of count @count provided
+ * by the foreign domain @domid with flags @flags.
+ *
+ * By default dma-buf is backed by system memory pages, but by providing
+ * one of the GNTDEV_DMA_FLAG_XXX flags it can also be created as
+ * a DMA write-combine or coherent buffer.
+ *
+ * Returns 0 if dma-buf was successfully created and the corresponding
+ * dma-buf's file descriptor is returned in @fd.
+ *
+ * [1] https://elixir.bootlin.com/linux/latest/source/Documentation/driver-api/dma-buf.rst
+ */
+int xengnttab_dmabuf_exp_from_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t flags, uint32_t count,
+ const uint32_t *refs, uint32_t *fd);
+
+/*
+ * This will block until the dma-buf with the file descriptor @fd is
+ * released. This is only valid for buffers created with
+ * IOCTL_GNTDEV_DMABUF_EXP_FROM_REFS.
+ *
+ * If withing @wait_to_ms milliseconds the buffer is not released
+ * then -ETIMEDOUT error is returned.
+ * If the buffer with file descriptor @fd does not exist or has already
+ * been released, then -ENOENT is returned. For valid file descriptors
+ * this must not be treated as error.
+ */
+int xengnttab_dmabuf_exp_wait_released(xengnttab_handle *xgt, uint32_t fd,
+ uint32_t wait_to_ms);
+
+/*
+ * Import a dma-buf with file descriptor @fd and export granted references
+ * to the pages of that dma-buf into array @refs of size @count.
+ */
+int xengnttab_dmabuf_imp_to_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t fd, uint32_t count, uint32_t *refs);
+
+/*
+ * This will close all references to an imported buffer, so it can be
+ * released by the owner. This is only valid for buffers created with
+ * IOCTL_GNTDEV_DMABUF_IMP_TO_REFS.
+ */
+int xengnttab_dmabuf_imp_release(xengnttab_handle *xgt, uint32_t fd);
+
/*
* Grant Sharing Interface (allocating and granting pages to others)
*/
xengnttab_fd;
xengntshr_fd;
} VERS_1.1;
+
+VERS_1.3 {
+ global:
+ xengnttab_dmabuf_exp_from_refs;
+ xengnttab_dmabuf_exp_wait_released;
+ xengnttab_dmabuf_imp_to_refs;
+ xengnttab_dmabuf_imp_release;
+} VERS_1.2;
/*
* Copyright (c) 2007-2008, D G Murray <Derek.Murray@cl.cam.ac.uk>
+ * Copyright (c) 2018, Oleksandr Andrushchenko, EPAM Systems Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
return rc;
}
+int osdep_gnttab_dmabuf_exp_from_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t flags, uint32_t count,
+ const uint32_t *refs,
+ uint32_t *dmabuf_fd)
+{
+ struct ioctl_gntdev_dmabuf_exp_from_refs *from_refs = NULL;
+ int rc = -1;
+
+ if ( !count )
+ {
+ errno = EINVAL;
+ goto out;
+ }
+
+ from_refs = malloc(sizeof(*from_refs) +
+ (count - 1) * sizeof(from_refs->refs[0]));
+ if ( !from_refs )
+ {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ from_refs->flags = flags;
+ from_refs->count = count;
+ from_refs->domid = domid;
+
+ memcpy(from_refs->refs, refs, count * sizeof(from_refs->refs[0]));
+
+ if ( (rc = ioctl(xgt->fd, IOCTL_GNTDEV_DMABUF_EXP_FROM_REFS, from_refs)) )
+ {
+ GTERROR(xgt->logger, "ioctl DMABUF_EXP_FROM_REFS failed");
+ goto out;
+ }
+
+ *dmabuf_fd = from_refs->fd;
+ rc = 0;
+
+out:
+ free(from_refs);
+ return rc;
+}
+
+int osdep_gnttab_dmabuf_exp_wait_released(xengnttab_handle *xgt,
+ uint32_t fd, uint32_t wait_to_ms)
+{
+ struct ioctl_gntdev_dmabuf_exp_wait_released wait;
+ int rc;
+
+ wait.fd = fd;
+ wait.wait_to_ms = wait_to_ms;
+
+ if ( (rc = ioctl(xgt->fd, IOCTL_GNTDEV_DMABUF_EXP_WAIT_RELEASED, &wait)) )
+ {
+ if ( errno == ENOENT )
+ {
+ /* The buffer may have already been released. */
+ errno = 0;
+ rc = 0;
+ } else
+ GTERROR(xgt->logger, "ioctl DMABUF_EXP_WAIT_RELEASED failed");
+ }
+
+ return rc;
+}
+
+int osdep_gnttab_dmabuf_imp_to_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t fd, uint32_t count, uint32_t *refs)
+{
+ struct ioctl_gntdev_dmabuf_imp_to_refs *to_refs = NULL;
+ int rc = -1;
+
+ if ( !count )
+ {
+ errno = EINVAL;
+ goto out;
+ }
+
+ to_refs = malloc(sizeof(*to_refs) +
+ (count - 1) * sizeof(to_refs->refs[0]));
+ if ( !to_refs )
+ {
+ errno = ENOMEM;
+ goto out;
+ }
+
+ to_refs->fd = fd;
+ to_refs->count = count;
+ to_refs->domid = domid;
+
+ if ( (rc = ioctl(xgt->fd, IOCTL_GNTDEV_DMABUF_IMP_TO_REFS, to_refs)) )
+ {
+ GTERROR(xgt->logger, "ioctl DMABUF_IMP_TO_REFS failed");
+ goto out;
+ }
+
+ memcpy(refs, to_refs->refs, count * sizeof(*refs));
+ rc = 0;
+
+out:
+ free(to_refs);
+ return rc;
+}
+
+int osdep_gnttab_dmabuf_imp_release(xengnttab_handle *xgt, uint32_t fd)
+{
+ struct ioctl_gntdev_dmabuf_imp_release release;
+ int rc;
+
+ release.fd = fd;
+
+ if ( (rc = ioctl(xgt->fd, IOCTL_GNTDEV_DMABUF_IMP_RELEASE, &release)) )
+ GTERROR(xgt->logger, "ioctl DMABUF_IMP_RELEASE failed");
+
+ return rc;
+}
+
int osdep_gntshr_open(xengntshr_handle *xgs)
{
int fd = open(DEVXEN "gntalloc", O_RDWR);
{
return -1;
}
+
+int osdep_gnttab_dmabuf_exp_from_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t flags, uint32_t count,
+ const uint32_t *refs, uint32_t *fd)
+{
+ return -1;
+}
+
+int osdep_gnttab_dmabuf_exp_wait_released(xengnttab_handle *xgt,
+ uint32_t fd, uint32_t wait_to_ms)
+{
+ return -1;
+}
+
+int osdep_gnttab_dmabuf_imp_to_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t fd, uint32_t count,
+ uint32_t *refs)
+{
+ return -1;
+}
+
+int osdep_gnttab_dmabuf_imp_release(xengnttab_handle *xgt, uint32_t fd)
+{
+ return -1;
+}
+
/*
* Local variables:
* mode: C
uint32_t count,
xengnttab_grant_copy_segment_t *segs);
+int osdep_gnttab_dmabuf_exp_from_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t flags, uint32_t count,
+ const uint32_t *refs, uint32_t *fd);
+
+int osdep_gnttab_dmabuf_exp_wait_released(xengnttab_handle *xgt,
+ uint32_t fd, uint32_t wait_to_ms);
+
+int osdep_gnttab_dmabuf_imp_to_refs(xengnttab_handle *xgt, uint32_t domid,
+ uint32_t fd, uint32_t count,
+ uint32_t *refs);
+
+int osdep_gnttab_dmabuf_imp_release(xengnttab_handle *xgt, uint32_t fd);
+
int osdep_gntshr_open(xengntshr_handle *xgs);
int osdep_gntshr_close(xengntshr_handle *xgs);