From patchwork Tue Dec 19 19:30:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kim, Dongwon" X-Patchwork-Id: 10124145 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 479AD6019C for ; Tue, 19 Dec 2017 19:40:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 38A7D293F6 for ; Tue, 19 Dec 2017 19:40:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2DD3B29553; Tue, 19 Dec 2017 19:40:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id E4DC029551 for ; Tue, 19 Dec 2017 19:40:17 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 22D646E363; Tue, 19 Dec 2017 19:37:06 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5C0416E351 for ; Tue, 19 Dec 2017 19:37:03 +0000 (UTC) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga101.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Dec 2017 11:37:03 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,428,1508828400"; d="scan'208";a="4018653" Received: from downor-z87x-ud5h.fm.intel.com ([10.1.122.11]) by orsmga007.jf.intel.com with ESMTP; 19 Dec 2017 11:37:02 -0800 From: Dongwon Kim To: linux-kernel@vger.kernel.org Subject: [RFC PATCH 48/60] hyper_dmabuf: add query items for buffer private info. Date: Tue, 19 Dec 2017 11:30:04 -0800 Message-Id: <1513711816-2618-48-git-send-email-dongwon.kim@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> References: <1513711816-2618-1-git-send-email-dongwon.kim@intel.com> MIME-Version: 1.0 Cc: xen-devel@lists.xenproject.org, mateuszx.potrola@intel.com, dri-devel@lists.freedesktop.org, dongwon.kim@intel.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Mateusz Polrola This change adds two query items, 'HYPER_DMABUF_QUERY_PRIV_INFO_SIZE' and 'HYPER_DMABUF_QUERY_PRIV_INFO', for retrieving buffer's private info and its size. 'info' is an address of user-space buffer (user application provides this) ,where private data will be copied in case query item is 'HYPER_DMABUF_QUERY_PRIV_INFO'. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 7 +- drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c | 6 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 12 ++-- drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c | 97 +++++++++++++++++++++------ drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h | 6 +- include/uapi/xen/hyper_dmabuf.h | 4 +- 6 files changed, 100 insertions(+), 32 deletions(-) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 87ea6ca..1c35a59 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -168,8 +168,11 @@ ssize_t hyper_dmabuf_event_read(struct file *filp, char __user *buffer, ret -= sizeof(struct hyper_dmabuf_event_hdr); /* nullifying hdr of the event in user buffer */ - copy_to_user(buffer + ret, &dummy_hdr, - sizeof(dummy_hdr)); + if (copy_to_user(buffer + ret, &dummy_hdr, + sizeof(dummy_hdr))) { + dev_err(hyper_dmabuf_private.device, + "failed to nullify invalid hdr already in userspace\n"); + } ret = -EFAULT; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c index 8998a7d..3e1498c 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_event.c @@ -104,6 +104,12 @@ int hyper_dmabuf_import_event(hyper_dmabuf_id_t hid) e = kzalloc(sizeof(*e), GFP_KERNEL); + if (!e) { + dev_err(hyper_dmabuf_private.device, + "no space left\n"); + return -ENOMEM; + } + e->event_data.hdr.event_type = HYPER_DMABUF_NEW_IMPORT; e->event_data.hdr.hid = hid; e->event_data.data = (void*)imported_sgt_info->priv; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 06f95ca..15191c2 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -671,9 +671,8 @@ static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) /* query for exported dmabuf */ sgt_info = hyper_dmabuf_find_exported(query_attr->hid); if (sgt_info) { - ret = hyper_dmabuf_query_exported(sgt_info, query_attr->item); - if (ret != -EINVAL) - query_attr->info = ret; + ret = hyper_dmabuf_query_exported(sgt_info, + query_attr->item, &query_attr->info); } else { dev_err(hyper_dmabuf_private.device, "DMA BUF {id:%d key:%d %d %d} can't be found in the export list\n", @@ -685,9 +684,8 @@ static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) /* query for imported dmabuf */ imported_sgt_info = hyper_dmabuf_find_imported(query_attr->hid); if (imported_sgt_info) { - ret = hyper_dmabuf_query_imported(imported_sgt_info, query_attr->item); - if (ret != -EINVAL) - query_attr->info = ret; + ret = hyper_dmabuf_query_imported(imported_sgt_info, + query_attr->item, &query_attr->info); } else { dev_err(hyper_dmabuf_private.device, "DMA BUF {id:%d key:%d %d %d} can't be found in the imported list\n", @@ -697,7 +695,7 @@ static int hyper_dmabuf_query_ioctl(struct file *filp, void *data) } } - return 0; + return ret; } void hyper_dmabuf_emergency_release(struct hyper_dmabuf_sgt_info* sgt_info, diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c index 2a5201b..39c9dee 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.c @@ -27,6 +27,7 @@ */ #include +#include #include "hyper_dmabuf_drv.h" #include "hyper_dmabuf_struct.h" #include "hyper_dmabuf_id.h" @@ -36,56 +37,91 @@ extern struct hyper_dmabuf_private hyper_dmabuf_private; #define HYPER_DMABUF_SIZE(nents, first_offset, last_len) \ ((nents)*PAGE_SIZE - (first_offset) - PAGE_SIZE + (last_len)) -int hyper_dmabuf_query_exported(struct hyper_dmabuf_sgt_info *sgt_info, int query) +int hyper_dmabuf_query_exported(struct hyper_dmabuf_sgt_info *sgt_info, + int query, unsigned long* info) { + int n; + switch (query) { case HYPER_DMABUF_QUERY_TYPE: - return EXPORTED; + *info = EXPORTED; + break; /* exporting domain of this specific dmabuf*/ case HYPER_DMABUF_QUERY_EXPORTER: - return HYPER_DMABUF_DOM_ID(sgt_info->hid); + *info = HYPER_DMABUF_DOM_ID(sgt_info->hid); + break; /* importing domain of this specific dmabuf */ case HYPER_DMABUF_QUERY_IMPORTER: - return sgt_info->hyper_dmabuf_rdomain; + *info = sgt_info->hyper_dmabuf_rdomain; + break; /* size of dmabuf in byte */ case HYPER_DMABUF_QUERY_SIZE: - return sgt_info->dma_buf->size; + *info = sgt_info->dma_buf->size; + break; /* whether the buffer is used by importer */ case HYPER_DMABUF_QUERY_BUSY: - return (sgt_info->importer_exported == 0) ? false : true; + *info = (sgt_info->importer_exported == 0) ? false : true; + break; /* whether the buffer is unexported */ case HYPER_DMABUF_QUERY_UNEXPORTED: - return !sgt_info->valid; + *info = !sgt_info->valid; + break; /* whether the buffer is scheduled to be unexported */ case HYPER_DMABUF_QUERY_DELAYED_UNEXPORTED: - return !sgt_info->unexport_scheduled; + *info = !sgt_info->unexport_scheduled; + break; + + /* size of private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO_SIZE: + *info = sgt_info->sz_priv; + break; + + /* copy private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO: + if (sgt_info->sz_priv > 0) { + n = copy_to_user((void __user*) *info, + sgt_info->priv, + sgt_info->sz_priv); + if (n != 0) + return -EINVAL; + } + break; + + default: + return -EINVAL; } - return -EINVAL; + return 0; } -int hyper_dmabuf_query_imported(struct hyper_dmabuf_imported_sgt_info *imported_sgt_info, int query) +int hyper_dmabuf_query_imported(struct hyper_dmabuf_imported_sgt_info *imported_sgt_info, + int query, unsigned long *info) { + int n; + switch (query) { case HYPER_DMABUF_QUERY_TYPE: - return IMPORTED; + *info = IMPORTED; + break; /* exporting domain of this specific dmabuf*/ case HYPER_DMABUF_QUERY_EXPORTER: - return HYPER_DMABUF_DOM_ID(imported_sgt_info->hid); + *info = HYPER_DMABUF_DOM_ID(imported_sgt_info->hid); + break; /* importing domain of this specific dmabuf */ case HYPER_DMABUF_QUERY_IMPORTER: - return hyper_dmabuf_private.domid; + *info = hyper_dmabuf_private.domid; + break; /* size of dmabuf in byte */ case HYPER_DMABUF_QUERY_SIZE: @@ -93,23 +129,44 @@ int hyper_dmabuf_query_imported(struct hyper_dmabuf_imported_sgt_info *imported_ /* if local dma_buf is created (if it's ever mapped), * retrieve it directly from struct dma_buf * */ - return imported_sgt_info->dma_buf->size; + *info = imported_sgt_info->dma_buf->size; } else { /* calcuate it from given nents, frst_ofst and last_len */ - return HYPER_DMABUF_SIZE(imported_sgt_info->nents, - imported_sgt_info->frst_ofst, - imported_sgt_info->last_len); + *info = HYPER_DMABUF_SIZE(imported_sgt_info->nents, + imported_sgt_info->frst_ofst, + imported_sgt_info->last_len); } + break; /* whether the buffer is used or not */ case HYPER_DMABUF_QUERY_BUSY: /* checks if it's used by importer */ - return (imported_sgt_info->num_importers > 0) ? true : false; + *info = (imported_sgt_info->num_importers > 0) ? true : false; + break; /* whether the buffer is unexported */ case HYPER_DMABUF_QUERY_UNEXPORTED: - return !imported_sgt_info->valid; + *info = !imported_sgt_info->valid; + break; + /* size of private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO_SIZE: + *info = imported_sgt_info->sz_priv; + break; + + /* copy private info attached to buffer */ + case HYPER_DMABUF_QUERY_PRIV_INFO: + if (imported_sgt_info->sz_priv > 0) { + n = copy_to_user((void __user*) *info, + imported_sgt_info->priv, + imported_sgt_info->sz_priv); + if (n != 0) + return -EINVAL; + } + break; + + default: + return -EINVAL; } - return -EINVAL; + return 0; } diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h index 295e923..7bbb322 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_query.h @@ -1,8 +1,10 @@ #ifndef __HYPER_DMABUF_QUERY_H__ #define __HYPER_DMABUF_QUERY_H__ -int hyper_dmabuf_query_imported(struct hyper_dmabuf_imported_sgt_info *imported_sgt_info, int query); +int hyper_dmabuf_query_imported(struct hyper_dmabuf_imported_sgt_info *imported_sgt_info, + int query, unsigned long *info); -int hyper_dmabuf_query_exported(struct hyper_dmabuf_sgt_info *sgt_info, int query); +int hyper_dmabuf_query_exported(struct hyper_dmabuf_sgt_info *sgt_info, + int query, unsigned long *info); #endif // __HYPER_DMABUF_QUERY_H__ diff --git a/include/uapi/xen/hyper_dmabuf.h b/include/uapi/xen/hyper_dmabuf.h index df01b17..e18dd9b 100644 --- a/include/uapi/xen/hyper_dmabuf.h +++ b/include/uapi/xen/hyper_dmabuf.h @@ -109,7 +109,7 @@ struct ioctl_hyper_dmabuf_query { int item; /* OUT parameters */ /* Value of queried item */ - int info; + unsigned long info; }; /* DMABUF query */ @@ -122,6 +122,8 @@ enum hyper_dmabuf_query { 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 {