diff mbox

[RFC,v2,4/9] hyper_dmabuf: user private data attached to hyper_DMABUF

Message ID 20180214015008.9513-5-dongwon.kim@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Kim, Dongwon Feb. 14, 2018, 1:50 a.m. UTC
Define a private data (e.g. meta data for the buffer) attached to
each hyper_DMABUF structure. This data is provided by userapace via
export_remote IOCTL and its size can be up to 192 bytes.

Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
Signed-off-by: Mateusz Polrola <mateuszx.potrola@intel.com>
---
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c  | 83 ++++++++++++++++++++--
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c    | 36 +++++++++-
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h    |  2 +-
 .../dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c   |  1 +
 drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h | 12 ++++
 include/uapi/linux/hyper_dmabuf.h                  |  4 ++
 6 files changed, 132 insertions(+), 6 deletions(-)

Comments

Oleksandr Andrushchenko April 10, 2018, 9:59 a.m. UTC | #1
On 02/14/2018 03:50 AM, Dongwon Kim wrote:
> Define a private data (e.g. meta data for the buffer) attached to
> each hyper_DMABUF structure. This data is provided by userapace via
> export_remote IOCTL and its size can be up to 192 bytes.
>
> Signed-off-by: Dongwon Kim <dongwon.kim@intel.com>
> Signed-off-by: Mateusz Polrola <mateuszx.potrola@intel.com>
> ---
>   drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c  | 83 ++++++++++++++++++++--
>   drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c    | 36 +++++++++-
>   drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h    |  2 +-
>   .../dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c   |  1 +
>   drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h | 12 ++++
>   include/uapi/linux/hyper_dmabuf.h                  |  4 ++
>   6 files changed, 132 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
> index 020a5590a254..168ccf98f710 100644
> --- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
> +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
> @@ -103,6 +103,11 @@ static int send_export_msg(struct exported_sgt_info *exported,
>   		}
>   	}
>   
> +	op[8] = exported->sz_priv;
> +
> +	/* driver/application specific private info */
> +	memcpy(&op[9], exported->priv, op[8]);
> +
>   	req = kcalloc(1, sizeof(*req), GFP_KERNEL);
>   
>   	if (!req)
> @@ -120,8 +125,9 @@ static int send_export_msg(struct exported_sgt_info *exported,
>   
>   /* Fast path exporting routine in case same buffer is already exported.
>    *
> - * If same buffer is still valid and exist in EXPORT LIST it returns 0 so
> - * that remaining normal export process can be skipped.
> + * If same buffer is still valid and exist in EXPORT LIST, it only updates
> + * user-private data for the buffer and returns 0 so that that it can skip
> + * normal export process.
>    *
>    * If "unexport" is scheduled for the buffer, it cancels it since the buffer
>    * is being re-exported.
> @@ -129,7 +135,7 @@ static int send_export_msg(struct exported_sgt_info *exported,
>    * return '1' if reexport is needed, return '0' if succeeds, return
>    * Kernel error code if something goes wrong
>    */
> -static int fastpath_export(hyper_dmabuf_id_t hid)
> +static int fastpath_export(hyper_dmabuf_id_t hid, int sz_priv, char *priv)
>   {
>   	int reexport = 1;
>   	int ret = 0;
> @@ -155,6 +161,46 @@ static int fastpath_export(hyper_dmabuf_id_t hid)
>   		exported->unexport_sched = false;
>   	}
>   
> +	/* if there's any change in size of private data.
> +	 * we reallocate space for private data with new size
> +	 */
> +	if (sz_priv != exported->sz_priv) {
> +		kfree(exported->priv);
> +
> +		/* truncating size */
> +		if (sz_priv > MAX_SIZE_PRIV_DATA)
> +			exported->sz_priv = MAX_SIZE_PRIV_DATA;
> +		else
> +			exported->sz_priv = sz_priv;
> +
> +		exported->priv = kcalloc(1, exported->sz_priv,
> +					 GFP_KERNEL);
> +
> +		if (!exported->priv) {
> +			hyper_dmabuf_remove_exported(exported->hid);
> +			hyper_dmabuf_cleanup_sgt_info(exported, true);
> +			kfree(exported);
> +			return -ENOMEM;
> +		}
> +	}
> +
> +	/* update private data in sgt_info with new ones */
> +	ret = copy_from_user(exported->priv, priv, exported->sz_priv);
> +	if (ret) {
> +		dev_err(hy_drv_priv->dev,
> +			"Failed to load a new private data\n");
> +		ret = -EINVAL;
> +	} else {
> +		/* send an export msg for updating priv in importer */
> +		ret = send_export_msg(exported, NULL);
> +
> +		if (ret < 0) {
> +			dev_err(hy_drv_priv->dev,
> +				"Failed to send a new private data\n");
> +			ret = -EBUSY;
> +		}
> +	}
> +
>   	return ret;
>   }
>   
> @@ -191,7 +237,8 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
>   					     export_remote_attr->remote_domain);
>   
>   	if (hid.id != -1) {
> -		ret = fastpath_export(hid);
> +		ret = fastpath_export(hid, export_remote_attr->sz_priv,
> +				      export_remote_attr->priv);
>   
>   		/* return if fastpath_export succeeds or
>   		 * gets some fatal error
> @@ -225,6 +272,24 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
>   		goto fail_sgt_info_creation;
>   	}
>   
> +	/* possible truncation */
> +	if (export_remote_attr->sz_priv > MAX_SIZE_PRIV_DATA)
> +		exported->sz_priv = MAX_SIZE_PRIV_DATA;
> +	else
> +		exported->sz_priv = export_remote_attr->sz_priv;
> +
> +	/* creating buffer for private data of buffer */
> +	if (exported->sz_priv != 0) {
> +		exported->priv = kcalloc(1, exported->sz_priv, GFP_KERNEL);
> +
> +		if (!exported->priv) {
> +			ret = -ENOMEM;
> +			goto fail_priv_creation;
> +		}
> +	} else {
> +		dev_err(hy_drv_priv->dev, "size is 0\n");
> +	}
> +
>   	exported->hid = hyper_dmabuf_get_hid();
>   
>   	/* no more exported dmabuf allowed */
> @@ -279,6 +344,10 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
>   	INIT_LIST_HEAD(&exported->va_kmapped->list);
>   	INIT_LIST_HEAD(&exported->va_vmapped->list);
>   
> +	/* copy private data to sgt_info */
> +	ret = copy_from_user(exported->priv, export_remote_attr->priv,
> +			     exported->sz_priv);
> +
>   	if (ret) {
>   		dev_err(hy_drv_priv->dev,
>   			"failed to load private data\n");
> @@ -337,6 +406,9 @@ static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
>   
>   fail_map_active_attached:
>   	kfree(exported->active_sgts);
> +	kfree(exported->priv);
> +
> +fail_priv_creation:
>   	kfree(exported);
>   
>   fail_map_active_sgts:
> @@ -567,6 +639,9 @@ static void delayed_unexport(struct work_struct *work)
>   		/* register hyper_dmabuf_id to the list for reuse */
>   		hyper_dmabuf_store_hid(exported->hid);
>   
> +		if (exported->sz_priv > 0 && !exported->priv)
> +			kfree(exported->priv);
> +
>   		kfree(exported);
>   	}
>   }
> diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
> index 129b2ff2af2b..7176fa8fb139 100644
> --- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
> +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
> @@ -60,9 +60,12 @@ void hyper_dmabuf_create_req(struct hyper_dmabuf_req *req,
>   		 * op5 : offset of data in the first page
>   		 * op6 : length of data in the last page
>   		 * op7 : top-level reference number for shared pages
> +		 * op8 : size of private data (from op9)
> +		 * op9 ~ : Driver-specific private data
> +		 *	   (e.g. graphic buffer's meta info)
>   		 */
>   
> -		memcpy(&req->op[0], &op[0], 8 * sizeof(int) + op[8]);
> +		memcpy(&req->op[0], &op[0], 9 * sizeof(int) + op[8]);
>   		break;
>   
>   	case HYPER_DMABUF_NOTIFY_UNEXPORT:
> @@ -116,6 +119,9 @@ static void cmd_process_work(struct work_struct *work)
>   		 * op5 : offset of data in the first page
>   		 * op6 : length of data in the last page
>   		 * op7 : top-level reference number for shared pages
> +		 * op8 : size of private data (from op9)
> +		 * op9 ~ : Driver-specific private data
> +		 *         (e.g. graphic buffer's meta info)
>   		 */
>   
>   		/* if nents == 0, it means it is a message only for
> @@ -135,6 +141,24 @@ static void cmd_process_work(struct work_struct *work)
>   				break;
>   			}
>   
> +			/* if size of new private data is different,
> +			 * we reallocate it.
> +			 */
> +			if (imported->sz_priv != req->op[8]) {
> +				kfree(imported->priv);
> +				imported->sz_priv = req->op[8];
> +				imported->priv = kcalloc(1, req->op[8],
> +							 GFP_KERNEL);
> +				if (!imported->priv) {
> +					/* set it invalid */
> +					imported->valid = 0;
> +					break;
> +				}
> +			}
> +
> +			/* updating priv data */
> +			memcpy(imported->priv, &req->op[9], req->op[8]);
> +
>   			break;
>   		}
>   
> @@ -143,6 +167,14 @@ static void cmd_process_work(struct work_struct *work)
>   		if (!imported)
>   			break;
>   
> +		imported->sz_priv = req->op[8];
> +		imported->priv = kcalloc(1, req->op[8], GFP_KERNEL);
BTW, there are plenty of the code using kcalloc with 1 element
Why not simply kzalloc?
> +
> +		if (!imported->priv) {
> +			kfree(imported);
> +			break;
> +		}
> +
>   		imported->hid.id = req->op[0];
>   
>   		for (i = 0; i < 3; i++)
> @@ -162,6 +194,8 @@ static void cmd_process_work(struct work_struct *work)
>   		dev_dbg(hy_drv_priv->dev, "\tlast len %d\n", req->op[6]);
>   		dev_dbg(hy_drv_priv->dev, "\tgrefid %d\n", req->op[7]);
>   
> +		memcpy(imported->priv, &req->op[9], req->op[8]);
> +
>   		imported->valid = true;
>   		hyper_dmabuf_register_imported(imported);
>   
> diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
> index 59f1528e9b1e..63a39d068d69 100644
> --- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
> +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
> @@ -27,7 +27,7 @@
>   #ifndef __HYPER_DMABUF_MSG_H__
>   #define __HYPER_DMABUF_MSG_H__
>   
> -#define MAX_NUMBER_OF_OPERANDS 8
> +#define MAX_NUMBER_OF_OPERANDS 64
>   
So now the req/resp below become (64 + 3) ints long, 268 bytes
4096 / 268...

>   struct hyper_dmabuf_req {
>   	unsigned int req_id;
> diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
> index d92ae13d8a30..9032f89e0cd0 100644
> --- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
> +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
> @@ -251,6 +251,7 @@ int hyper_dmabuf_cleanup_sgt_info(struct exported_sgt_info *exported,
>   	kfree(exported->active_attached);
>   	kfree(exported->va_kmapped);
>   	kfree(exported->va_vmapped);
> +	kfree(exported->priv);
>   
>   	return 0;
>   }
> diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
> index 144e3821fbc2..a1220bbf8d0c 100644
> --- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
> +++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
> @@ -101,6 +101,12 @@ struct exported_sgt_info {
>   	 * the buffer can be completely freed.
>   	 */
>   	struct file *filp;
> +
> +	/* size of private */
> +	size_t sz_priv;
> +
> +	/* private data associated with the exported buffer */
> +	char *priv;
>   };
>   
>   /* imported_sgt_info contains information about imported DMA_BUF
> @@ -126,6 +132,12 @@ struct imported_sgt_info {
>   	void *refs_info;
>   	bool valid;
>   	int importers;
> +
> +	/* size of private */
> +	size_t sz_priv;
> +
> +	/* private data associated with the exported buffer */
> +	char *priv;
>   };
>   
>   #endif /* __HYPER_DMABUF_STRUCT_H__ */
> diff --git a/include/uapi/linux/hyper_dmabuf.h b/include/uapi/linux/hyper_dmabuf.h
> index caaae2da9d4d..36794a4af811 100644
> --- a/include/uapi/linux/hyper_dmabuf.h
> +++ b/include/uapi/linux/hyper_dmabuf.h
> @@ -25,6 +25,8 @@
>   #ifndef __LINUX_PUBLIC_HYPER_DMABUF_H__
>   #define __LINUX_PUBLIC_HYPER_DMABUF_H__
>   
> +#define MAX_SIZE_PRIV_DATA 192
> +
>   typedef struct {
>   	int id;
>   	int rng_key[3]; /* 12bytes long random number */
> @@ -56,6 +58,8 @@ struct ioctl_hyper_dmabuf_export_remote {
>   	int remote_domain;
>   	/* exported dma buf id */
>   	hyper_dmabuf_id_t hid;
> +	int sz_priv;
> +	char *priv;
>   };
>   
>   #define IOCTL_HYPER_DMABUF_EXPORT_FD \
>
diff mbox

Patch

diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
index 020a5590a254..168ccf98f710 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_ioctl.c
@@ -103,6 +103,11 @@  static int send_export_msg(struct exported_sgt_info *exported,
 		}
 	}
 
+	op[8] = exported->sz_priv;
+
+	/* driver/application specific private info */
+	memcpy(&op[9], exported->priv, op[8]);
+
 	req = kcalloc(1, sizeof(*req), GFP_KERNEL);
 
 	if (!req)
@@ -120,8 +125,9 @@  static int send_export_msg(struct exported_sgt_info *exported,
 
 /* Fast path exporting routine in case same buffer is already exported.
  *
- * If same buffer is still valid and exist in EXPORT LIST it returns 0 so
- * that remaining normal export process can be skipped.
+ * If same buffer is still valid and exist in EXPORT LIST, it only updates
+ * user-private data for the buffer and returns 0 so that that it can skip
+ * normal export process.
  *
  * If "unexport" is scheduled for the buffer, it cancels it since the buffer
  * is being re-exported.
@@ -129,7 +135,7 @@  static int send_export_msg(struct exported_sgt_info *exported,
  * return '1' if reexport is needed, return '0' if succeeds, return
  * Kernel error code if something goes wrong
  */
-static int fastpath_export(hyper_dmabuf_id_t hid)
+static int fastpath_export(hyper_dmabuf_id_t hid, int sz_priv, char *priv)
 {
 	int reexport = 1;
 	int ret = 0;
@@ -155,6 +161,46 @@  static int fastpath_export(hyper_dmabuf_id_t hid)
 		exported->unexport_sched = false;
 	}
 
+	/* if there's any change in size of private data.
+	 * we reallocate space for private data with new size
+	 */
+	if (sz_priv != exported->sz_priv) {
+		kfree(exported->priv);
+
+		/* truncating size */
+		if (sz_priv > MAX_SIZE_PRIV_DATA)
+			exported->sz_priv = MAX_SIZE_PRIV_DATA;
+		else
+			exported->sz_priv = sz_priv;
+
+		exported->priv = kcalloc(1, exported->sz_priv,
+					 GFP_KERNEL);
+
+		if (!exported->priv) {
+			hyper_dmabuf_remove_exported(exported->hid);
+			hyper_dmabuf_cleanup_sgt_info(exported, true);
+			kfree(exported);
+			return -ENOMEM;
+		}
+	}
+
+	/* update private data in sgt_info with new ones */
+	ret = copy_from_user(exported->priv, priv, exported->sz_priv);
+	if (ret) {
+		dev_err(hy_drv_priv->dev,
+			"Failed to load a new private data\n");
+		ret = -EINVAL;
+	} else {
+		/* send an export msg for updating priv in importer */
+		ret = send_export_msg(exported, NULL);
+
+		if (ret < 0) {
+			dev_err(hy_drv_priv->dev,
+				"Failed to send a new private data\n");
+			ret = -EBUSY;
+		}
+	}
+
 	return ret;
 }
 
@@ -191,7 +237,8 @@  static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 					     export_remote_attr->remote_domain);
 
 	if (hid.id != -1) {
-		ret = fastpath_export(hid);
+		ret = fastpath_export(hid, export_remote_attr->sz_priv,
+				      export_remote_attr->priv);
 
 		/* return if fastpath_export succeeds or
 		 * gets some fatal error
@@ -225,6 +272,24 @@  static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 		goto fail_sgt_info_creation;
 	}
 
+	/* possible truncation */
+	if (export_remote_attr->sz_priv > MAX_SIZE_PRIV_DATA)
+		exported->sz_priv = MAX_SIZE_PRIV_DATA;
+	else
+		exported->sz_priv = export_remote_attr->sz_priv;
+
+	/* creating buffer for private data of buffer */
+	if (exported->sz_priv != 0) {
+		exported->priv = kcalloc(1, exported->sz_priv, GFP_KERNEL);
+
+		if (!exported->priv) {
+			ret = -ENOMEM;
+			goto fail_priv_creation;
+		}
+	} else {
+		dev_err(hy_drv_priv->dev, "size is 0\n");
+	}
+
 	exported->hid = hyper_dmabuf_get_hid();
 
 	/* no more exported dmabuf allowed */
@@ -279,6 +344,10 @@  static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 	INIT_LIST_HEAD(&exported->va_kmapped->list);
 	INIT_LIST_HEAD(&exported->va_vmapped->list);
 
+	/* copy private data to sgt_info */
+	ret = copy_from_user(exported->priv, export_remote_attr->priv,
+			     exported->sz_priv);
+
 	if (ret) {
 		dev_err(hy_drv_priv->dev,
 			"failed to load private data\n");
@@ -337,6 +406,9 @@  static int hyper_dmabuf_export_remote_ioctl(struct file *filp, void *data)
 
 fail_map_active_attached:
 	kfree(exported->active_sgts);
+	kfree(exported->priv);
+
+fail_priv_creation:
 	kfree(exported);
 
 fail_map_active_sgts:
@@ -567,6 +639,9 @@  static void delayed_unexport(struct work_struct *work)
 		/* register hyper_dmabuf_id to the list for reuse */
 		hyper_dmabuf_store_hid(exported->hid);
 
+		if (exported->sz_priv > 0 && !exported->priv)
+			kfree(exported->priv);
+
 		kfree(exported);
 	}
 }
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
index 129b2ff2af2b..7176fa8fb139 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.c
@@ -60,9 +60,12 @@  void hyper_dmabuf_create_req(struct hyper_dmabuf_req *req,
 		 * op5 : offset of data in the first page
 		 * op6 : length of data in the last page
 		 * op7 : top-level reference number for shared pages
+		 * op8 : size of private data (from op9)
+		 * op9 ~ : Driver-specific private data
+		 *	   (e.g. graphic buffer's meta info)
 		 */
 
-		memcpy(&req->op[0], &op[0], 8 * sizeof(int) + op[8]);
+		memcpy(&req->op[0], &op[0], 9 * sizeof(int) + op[8]);
 		break;
 
 	case HYPER_DMABUF_NOTIFY_UNEXPORT:
@@ -116,6 +119,9 @@  static void cmd_process_work(struct work_struct *work)
 		 * op5 : offset of data in the first page
 		 * op6 : length of data in the last page
 		 * op7 : top-level reference number for shared pages
+		 * op8 : size of private data (from op9)
+		 * op9 ~ : Driver-specific private data
+		 *         (e.g. graphic buffer's meta info)
 		 */
 
 		/* if nents == 0, it means it is a message only for
@@ -135,6 +141,24 @@  static void cmd_process_work(struct work_struct *work)
 				break;
 			}
 
+			/* if size of new private data is different,
+			 * we reallocate it.
+			 */
+			if (imported->sz_priv != req->op[8]) {
+				kfree(imported->priv);
+				imported->sz_priv = req->op[8];
+				imported->priv = kcalloc(1, req->op[8],
+							 GFP_KERNEL);
+				if (!imported->priv) {
+					/* set it invalid */
+					imported->valid = 0;
+					break;
+				}
+			}
+
+			/* updating priv data */
+			memcpy(imported->priv, &req->op[9], req->op[8]);
+
 			break;
 		}
 
@@ -143,6 +167,14 @@  static void cmd_process_work(struct work_struct *work)
 		if (!imported)
 			break;
 
+		imported->sz_priv = req->op[8];
+		imported->priv = kcalloc(1, req->op[8], GFP_KERNEL);
+
+		if (!imported->priv) {
+			kfree(imported);
+			break;
+		}
+
 		imported->hid.id = req->op[0];
 
 		for (i = 0; i < 3; i++)
@@ -162,6 +194,8 @@  static void cmd_process_work(struct work_struct *work)
 		dev_dbg(hy_drv_priv->dev, "\tlast len %d\n", req->op[6]);
 		dev_dbg(hy_drv_priv->dev, "\tgrefid %d\n", req->op[7]);
 
+		memcpy(imported->priv, &req->op[9], req->op[8]);
+
 		imported->valid = true;
 		hyper_dmabuf_register_imported(imported);
 
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
index 59f1528e9b1e..63a39d068d69 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_msg.h
@@ -27,7 +27,7 @@ 
 #ifndef __HYPER_DMABUF_MSG_H__
 #define __HYPER_DMABUF_MSG_H__
 
-#define MAX_NUMBER_OF_OPERANDS 8
+#define MAX_NUMBER_OF_OPERANDS 64
 
 struct hyper_dmabuf_req {
 	unsigned int req_id;
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
index d92ae13d8a30..9032f89e0cd0 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_sgl_proc.c
@@ -251,6 +251,7 @@  int hyper_dmabuf_cleanup_sgt_info(struct exported_sgt_info *exported,
 	kfree(exported->active_attached);
 	kfree(exported->va_kmapped);
 	kfree(exported->va_vmapped);
+	kfree(exported->priv);
 
 	return 0;
 }
diff --git a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
index 144e3821fbc2..a1220bbf8d0c 100644
--- a/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
+++ b/drivers/dma-buf/hyper_dmabuf/hyper_dmabuf_struct.h
@@ -101,6 +101,12 @@  struct exported_sgt_info {
 	 * the buffer can be completely freed.
 	 */
 	struct file *filp;
+
+	/* size of private */
+	size_t sz_priv;
+
+	/* private data associated with the exported buffer */
+	char *priv;
 };
 
 /* imported_sgt_info contains information about imported DMA_BUF
@@ -126,6 +132,12 @@  struct imported_sgt_info {
 	void *refs_info;
 	bool valid;
 	int importers;
+
+	/* size of private */
+	size_t sz_priv;
+
+	/* private data associated with the exported buffer */
+	char *priv;
 };
 
 #endif /* __HYPER_DMABUF_STRUCT_H__ */
diff --git a/include/uapi/linux/hyper_dmabuf.h b/include/uapi/linux/hyper_dmabuf.h
index caaae2da9d4d..36794a4af811 100644
--- a/include/uapi/linux/hyper_dmabuf.h
+++ b/include/uapi/linux/hyper_dmabuf.h
@@ -25,6 +25,8 @@ 
 #ifndef __LINUX_PUBLIC_HYPER_DMABUF_H__
 #define __LINUX_PUBLIC_HYPER_DMABUF_H__
 
+#define MAX_SIZE_PRIV_DATA 192
+
 typedef struct {
 	int id;
 	int rng_key[3]; /* 12bytes long random number */
@@ -56,6 +58,8 @@  struct ioctl_hyper_dmabuf_export_remote {
 	int remote_domain;
 	/* exported dma buf id */
 	hyper_dmabuf_id_t hid;
+	int sz_priv;
+	char *priv;
 };
 
 #define IOCTL_HYPER_DMABUF_EXPORT_FD \