Add a new ioctl, "IOCTL_HYPER_DMABUF_QUERY" for the userspace to retreive various information about hyper_DMABUF, currently being shared across VMs.
Supported query items are as followed:
enum hyper_dmabuf_query { HYPER_DMABUF_QUERY_TYPE = 0x10, HYPER_DMABUF_QUERY_EXPORTER, HYPER_DMABUF_QUERY_IMPORTER, HYPER_DMABUF_QUERY_SIZE, HYPER_DMABUF_QUERY_BUSY, HYPER_DMABUF_QUERY_UNEXPORTED, HYPER_DMABUF_QUERY_DELAYED_UNEXPORTED, HYPER_DMABUF_QUERY_PRIV_INFO_SIZE, HYPER_DMABUF_QUERY_PRIV_INFO, };
Query IOCTL call with each query item above returns,
HYPER_DMABUF_QUERY_TYPE - type - EXPORTED/IMPORTED of hyper_DMABUF from current VM's perspective.
HYPER_DMABUF_QUERY_EXPORTER - ID of exporting VM
HYPER_DMABUF_QUERY_IMPORTER - ID of importing VM
HYPER_DMABUF_QUERY_SIZE - size of shared buffer in byte
HYPER_DMABUF_QUERY_BUSY - true if hyper_DMABUF is being actively used (e.g. attached and mapped by end-consumer)
HYPER_DMABUF_QUERY_UNEXPORTED - true if hyper_DMABUF has been unexported on exporting VM's side.
HYPER_DMABUF_QUERY_DELAYED_UNEXPORTED - true if hyper_DMABUF is scheduled to be unexported (still valid but will be unexported soon)
HYPER_DMABUF_QUERY_PRIV_INFO_SIZE - size of private information (given by user application on exporter's side) attached to hyper_DMABUF
HYPER_DMABUF_QUERY_PRIV_INFO - private information attached to hyper_DMABUF
Signed-off-by: Dongwon Kim dongwon.kim@intel.com Signed-off-by: Mateusz Polrola mateuszx.potrola@intel.com --- drivers/dma-buf/hyper_dmabuf/Makefile | 1 + drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c | 49 +++++- drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.c | 174 ++++++++++++++++++++++ drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.h | 36 +++++ include/uapi/linux/hyper_dmabuf.h | 32 ++++ 5 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.c create mode 100644 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.h
diff --git a/drivers/dma-buf/hyper_dmabuf/Makefile b/drivers/dma-buf/hyper_dmabuf/Makefile index 702696f29215..578a669a0d3e 100644 --- a/drivers/dma-buf/hyper_dmabuf/Makefile +++ b/drivers/dma-buf/hyper_dmabuf/Makefile @@ -10,6 +10,7 @@ ifneq ($(KERNELRELEASE),) hyper_dmabuf_msg.o \ hyper_dmabuf_id.o \ hyper_dmabuf_remote_sync.o \ + hyper_dmabuf_query.o \
ifeq ($(CONFIG_HYPER_DMABUF_XEN), y) $(TARGET_MODULE)-objs += backends/xen/hyper_dmabuf_xen_comm.o \ diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c index 168ccf98f710..e90e59cd0568 100644 --- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -41,6 +41,7 @@ #include "hyper_dmabuf_msg.h" #include "hyper_dmabuf_sgl_proc.h" #include "hyper_dmabuf_ops.h" +#include "hyper_dmabuf_query.h"
static int hyper_dmabuf_tx_ch_setup_ioctl(struct file *filp, void *data) { @@ -543,7 +544,6 @@ static int hyper_dmabuf_export_fd_ioctl(struct file *filp, void *data) hyper_dmabuf_create_req(req, HYPER_DMABUF_EXPORT_FD_FAILED, &op[0]); - bknd_ops->send_req(HYPER_DMABUF_DOM_ID(imported->hid), req, false); kfree(req); @@ -682,6 +682,51 @@ int hyper_dmabuf_unexport_ioctl(struct file *filp, void *data) return 0; }
+static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) +{ + struct ioctl_hyper_dmabuf_query *query_attr = + (struct ioctl_hyper_dmabuf_query *)data; + struct exported_sgt_info *exported = NULL; + struct imported_sgt_info *imported = NULL; + int ret = 0; + + if (HYPER_DMABUF_DOM_ID(query_attr->hid) == hy_drv_priv->domid) { + /* query for exported dmabuf */ + exported = hyper_dmabuf_find_exported(query_attr->hid); + if (exported) { + ret = hyper_dmabuf_query_exported(exported, + query_attr->item, + &query_attr->info); + } else { + dev_err(hy_drv_priv->dev, + "hid {id:%d key:%d %d %d} not in exp list\n", + query_attr->hid.id, + query_attr->hid.rng_key[0], + query_attr->hid.rng_key[1], + query_attr->hid.rng_key[2]); + return -ENOENT; + } + } else { + /* query for imported dmabuf */ + imported = hyper_dmabuf_find_imported(query_attr->hid); + if (imported) { + ret = hyper_dmabuf_query_imported(imported, + query_attr->item, + &query_attr->info); + } else { + dev_err(hy_drv_priv->dev, + "hid {id:%d key:%d %d %d} not in imp list\n", + query_attr->hid.id, + query_attr->hid.rng_key[0], + query_attr->hid.rng_key[1], + query_attr->hid.rng_key[2]); + return -ENOENT; + } + } + + return ret; +} + const struct hyper_dmabuf_ioctl_desc hyper_dmabuf_ioctls[] = { HYPER_DMABUF_IOCTL_DEF(IOCTL_HYPER_DMABUF_TX_CH_SETUP, hyper_dmabuf_tx_ch_setup_ioctl, 0), @@ -693,6 +738,8 @@ const struct hyper_dmabuf_ioctl_desc hyper_dmabuf_ioctls[] = { hyper_dmabuf_export_fd_ioctl, 0), HYPER_DMABUF_IOCTL_DEF(IOCTL_HYPER_DMABUF_UNEXPORT, hyper_dmabuf_unexport_ioctl, 0), + HYPER_DMABUF_IOCTL_DEF(IOCTL_HYPER_DMABUF_QUERY, + hyper_dmabuf_query_ioctl, 0), };
long hyper_dmabuf_ioctl(struct file *filp, diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.c new file mode 100644 index 000000000000..edf92318d4cd --- /dev/null +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.c @@ -0,0 +1,174 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * SPDX-License-Identifier: (MIT OR GPL-2.0) + * + * Authors: + * Dongwon Kim dongwon.kim@intel.com + * Mateusz Polrola mateuszx.potrola@intel.com + * + */ + +#include <linux/dma-buf.h> +#include <linux/uaccess.h> +#include "hyper_dmabuf_drv.h" +#include "hyper_dmabuf_struct.h" +#include "hyper_dmabuf_id.h" + +#define HYPER_DMABUF_SIZE(nents, first_offset, last_len) \ + ((nents)*PAGE_SIZE - (first_offset) - PAGE_SIZE + (last_len)) + +int hyper_dmabuf_query_exported(struct exported_sgt_info *exported, + int query, unsigned long *info) +{ + switch (query) { + case HYPER_DMABUF_QUERY_TYPE: + *info = EXPORTED; + break; + + /* exporting domain of this specific dmabuf*/ + case HYPER_DMABUF_QUERY_EXPORTER: + *info = HYPER_DMABUF_DOM_ID(exported->hid); + break; + + /* importing domain of this specific dmabuf */ + case HYPER_DMABUF_QUERY_IMPORTER: + *info = exported->rdomid; + break; + + /* size of dmabuf in byte */ + case HYPER_DMABUF_QUERY_SIZE: + *info = exported->dma_buf->size; + break; + + /* whether the buffer is used by importer */ + case HYPER_DMABUF_QUERY_BUSY: + *info = (exported->active > 0); + break; + + /* whether the buffer is unexported */ + case HYPER_DMABUF_QUERY_UNEXPORTED: + *info = !exported->valid; + break; + + /* whether the buffer is scheduled to be unexported */ + case HYPER_DMABUF_QUERY_DELAYED_UNEXPORTED: + *info = !exported->unexport_sched; + break; + + /* size of private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO_SIZE: + *info = exported->sz_priv; + break; + + /* copy private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO: + if (exported->sz_priv > 0) { + int n; + + n = copy_to_user((void __user *) *info, + exported->priv, + exported->sz_priv); + if (n != 0) + return -EINVAL; + } + break; + + default: + return -EINVAL; + } + + return 0; +} + + +int hyper_dmabuf_query_imported(struct imported_sgt_info *imported, + int query, unsigned long *info) +{ + switch (query) { + case HYPER_DMABUF_QUERY_TYPE: + *info = IMPORTED; + break; + + /* exporting domain of this specific dmabuf*/ + case HYPER_DMABUF_QUERY_EXPORTER: + *info = HYPER_DMABUF_DOM_ID(imported->hid); + break; + + /* importing domain of this specific dmabuf */ + case HYPER_DMABUF_QUERY_IMPORTER: + *info = hy_drv_priv->domid; + break; + + /* size of dmabuf in byte */ + case HYPER_DMABUF_QUERY_SIZE: + if (imported->dma_buf) { + /* if local dma_buf is created (if it's + * ever mapped), retrieve it directly + * from struct dma_buf * + */ + *info = imported->dma_buf->size; + } else { + /* calcuate it from given nents, frst_ofst + * and last_len + */ + *info = HYPER_DMABUF_SIZE(imported->nents, + imported->frst_ofst, + imported->last_len); + } + break; + + /* whether the buffer is used or not */ + case HYPER_DMABUF_QUERY_BUSY: + /* checks if it's used by importer */ + *info = (imported->importers > 0); + break; + + /* whether the buffer is unexported */ + case HYPER_DMABUF_QUERY_UNEXPORTED: + *info = !imported->valid; + break; + + /* size of private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO_SIZE: + *info = imported->sz_priv; + break; + + /* copy private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO: + if (imported->sz_priv > 0) { + int n; + + n = copy_to_user((void __user *)*info, + imported->priv, + imported->sz_priv); + if (n != 0) + return -EINVAL; + } + break; + + default: + return -EINVAL; + } + + return 0; +} diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.h b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.h new file mode 100644 index 000000000000..b9687db7e7d5 --- /dev/null +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_query.h @@ -0,0 +1,36 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * SPDX-License-Identifier: (MIT OR GPL-2.0) + * + */ + +#ifndef __HYPER_DMABUF_QUERY_H__ +#define __HYPER_DMABUF_QUERY_H__ + +int hyper_dmabuf_query_imported(struct imported_sgt_info *imported, + int query, unsigned long *info); + +int hyper_dmabuf_query_exported(struct exported_sgt_info *exported, + int query, unsigned long *info); + +#endif // __HYPER_DMABUF_QUERY_H__ diff --git a/include/uapi/linux/hyper_dmabuf.h b/include/uapi/linux/hyper_dmabuf.h index 36794a4af811..4f8e8ac0375b 100644 --- a/include/uapi/linux/hyper_dmabuf.h +++ b/include/uapi/linux/hyper_dmabuf.h @@ -88,4 +88,36 @@ struct ioctl_hyper_dmabuf_unexport { int status; };
+#define IOCTL_HYPER_DMABUF_QUERY \ +_IOC(_IOC_NONE, 'G', 5, sizeof(struct ioctl_hyper_dmabuf_query)) +struct ioctl_hyper_dmabuf_query { + /* in parameters */ + /* hyper dmabuf id to be queried */ + hyper_dmabuf_id_t hid; + /* item to be queried */ + int item; + /* OUT parameters */ + /* Value of queried item */ + unsigned long info; +}; + +/* DMABUF query */ + +enum hyper_dmabuf_query { + HYPER_DMABUF_QUERY_TYPE = 0x10, + HYPER_DMABUF_QUERY_EXPORTER, + HYPER_DMABUF_QUERY_IMPORTER, + HYPER_DMABUF_QUERY_SIZE, + HYPER_DMABUF_QUERY_BUSY, + HYPER_DMABUF_QUERY_UNEXPORTED, + HYPER_DMABUF_QUERY_DELAYED_UNEXPORTED, + HYPER_DMABUF_QUERY_PRIV_INFO_SIZE, + HYPER_DMABUF_QUERY_PRIV_INFO, +}; + +enum hyper_dmabuf_status { + EXPORTED = 0x01, + IMPORTED, +}; + #endif //__LINUX_PUBLIC_HYPER_DMABUF_H__