Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753256AbdLSThB (ORCPT ); Tue, 19 Dec 2017 14:37:01 -0500 Received: from mga01.intel.com ([192.55.52.88]:17633 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752338AbdLSTgr (ORCPT ); Tue, 19 Dec 2017 14:36:47 -0500 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.45,428,1508828400"; d="scan'208";a="4018566" From: Dongwon Kim To: linux-kernel@vger.kernel.org Cc: dri-devel@lists.freedesktop.org, xen-devel@lists.xenproject.org, mateuszx.potrola@intel.com, dongwon.kim@intel.com Subject: [RFC PATCH 26/60] hyper_dmabuf: add mutexes to prevent several race conditions Date: Tue, 19 Dec 2017 11:29:42 -0800 Message-Id: <1513711816-2618-26-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 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5133 Lines: 151 From: Mateusz Polrola Added mutex to export_fd ioctl to prevent double pages mapping of the same buffer to prevent race condition when two consumers are trying to map the same buffer on importer VM. Also locked mutex before sending request via xen communication channel to prevent req_pending override by another caller. Signed-off-by: Dongwon Kim --- drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c | 2 ++ drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h | 1 + drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c | 6 ++++++ drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c | 10 ++++++++++ drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h | 1 + 5 files changed, 20 insertions(+) diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c index 569b95e..584d55d 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.c @@ -56,6 +56,8 @@ static int __init hyper_dmabuf_drv_init(void) printk( KERN_NOTICE "hyper_dmabuf_starting: Initialization started" ); + mutex_init(&hyper_dmabuf_private.lock); + ret = register_device(); if (ret < 0) { return -EINVAL; diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h index 0b1441e..8445416 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_drv.h @@ -76,6 +76,7 @@ struct hyper_dmabuf_private { /* backend ops - hypervisor specific */ struct hyper_dmabuf_backend_ops *backend_ops; + struct mutex lock; }; #endif /* __LINUX_PUBLIC_HYPER_DMABUF_DRV_H__ */ diff --git a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c index 018de8c..8851a9c 100644 --- a/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c +++ b/drivers/xen/hyper_dmabuf/hyper_dmabuf_ioctl.c @@ -260,6 +260,8 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) if (sgt_info == NULL || !sgt_info->valid) /* can't find sgt from the table */ return -1; + mutex_lock(&hyper_dmabuf_private.lock); + sgt_info->num_importers++; /* send notification for export_fd to exporter */ @@ -274,6 +276,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) kfree(req); dev_err(hyper_dmabuf_private.device, "Failed to create sgt or notify exporter\n"); sgt_info->num_importers--; + mutex_unlock(&hyper_dmabuf_private.lock); return -EINVAL; } kfree(req); @@ -282,6 +285,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) dev_err(hyper_dmabuf_private.device, "Buffer invalid\n"); sgt_info->num_importers--; + mutex_unlock(&hyper_dmabuf_private.lock); return -1; } else { dev_dbg(hyper_dmabuf_private.device, "Can import buffer\n"); @@ -303,6 +307,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) if (!data_pages) { sgt_info->num_importers--; + mutex_unlock(&hyper_dmabuf_private.lock); return -EINVAL; } @@ -318,6 +323,7 @@ static int hyper_dmabuf_export_fd_ioctl(void *data) ret = export_fd_attr->fd; } + mutex_unlock(&hyper_dmabuf_private.lock); dev_dbg(hyper_dmabuf_private.device, "%s exit\n", __func__); return 0; } diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c index a8cce26..9d67b47 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.c @@ -278,6 +278,8 @@ int hyper_dmabuf_xen_init_tx_rbuf(int domid) ring_info->irq = ret; ring_info->port = alloc_unbound.port; + mutex_init(&ring_info->lock); + dev_dbg(hyper_dmabuf_private.device, "%s: allocated eventchannel gref %d port: %d irq: %d\n", __func__, @@ -512,6 +514,9 @@ int hyper_dmabuf_xen_send_req(int domid, struct hyper_dmabuf_req *req, int wait) return -EINVAL; } + + mutex_lock(&ring_info->lock); + ring = &ring_info->ring_front; if (RING_FULL(ring)) @@ -519,6 +524,7 @@ int hyper_dmabuf_xen_send_req(int domid, struct hyper_dmabuf_req *req, int wait) new_req = RING_GET_REQUEST(ring, ring->req_prod_pvt); if (!new_req) { + mutex_unlock(&ring_info->lock); dev_err(hyper_dmabuf_private.device, "NULL REQUEST\n"); return -EIO; @@ -548,13 +554,17 @@ int hyper_dmabuf_xen_send_req(int domid, struct hyper_dmabuf_req *req, int wait) } if (timeout < 0) { + mutex_unlock(&ring_info->lock); dev_err(hyper_dmabuf_private.device, "request timed-out\n"); return -EBUSY; } + mutex_unlock(&ring_info->lock); return req_pending.status; } + mutex_unlock(&ring_info->lock); + return 0; } diff --git a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h index 9c93165..0533e4d 100644 --- a/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h +++ b/drivers/xen/hyper_dmabuf/xen/hyper_dmabuf_xen_comm.h @@ -39,6 +39,7 @@ struct xen_comm_tx_ring_info { int gref_ring; int irq; int port; + struct mutex lock; struct xenbus_watch watch; }; -- 2.7.4