From patchwork Fri Jul 24 09:03:09 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: PranavkumarSawargaonkar X-Patchwork-Id: 51406 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by patches.linaro.org (Postfix) with ESMTPS id 59CE120323 for ; Fri, 24 Jul 2015 09:03:44 +0000 (UTC) Received: by lbvb1 with SMTP id b1sf5277206lbv.3 for ; Fri, 24 Jul 2015 02:03:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:cc:subject :date:message-id:in-reply-to:references:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe; bh=G8ZSkKtYwcs1QbR3FCqyQoohD6gTlrfO2cfZWtGkdm4=; b=ZtfxqrVL3+yhvYperR6G9zQ90+yl9m0vvZvX5tSdiBXfnjEGKhXfWBnM6iBS5mpdlD 1mCuSmwdccrVXMATsegmlDLA97/qYZUF6RSqhY7uMCsPgCVzZVZPz6PlWeJwwPD1B9Ge vwJ6XIh5GwRT+KpWMuSkxdKef34irE2swux0Tt6sPb5Ken1rK2mnJLTxMEW2/qsSJBJq MBey7yOhl7qPukwP1mgOrDdfk0ZqHPmbv1rN7kmrGCGgHq9l+Hf3a80irw3GM3X+1UQV 2C9ZFYkNrJpfC3IZ9YoXYdIaa+/rDaOegLzOGEpeI787qUoqifzbgKhqphBigHUuYjOH 10fw== X-Gm-Message-State: ALoCoQlFGEiD+a7uCUp0eR1git1gGMpj5T6sSVl+YK/Bl0ZDZLLmiRsPI9b/HwcBfivGgwg5flAw X-Received: by 10.112.28.111 with SMTP id a15mr5723654lbh.21.1437728623298; Fri, 24 Jul 2015 02:03:43 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.4.199 with SMTP id m7ls347143lam.83.gmail; Fri, 24 Jul 2015 02:03:43 -0700 (PDT) X-Received: by 10.112.167.202 with SMTP id zq10mr12339935lbb.118.1437728623099; Fri, 24 Jul 2015 02:03:43 -0700 (PDT) Received: from mail-la0-f47.google.com (mail-la0-f47.google.com. [209.85.215.47]) by mx.google.com with ESMTPS id f1si6971800lab.6.2015.07.24.02.03.43 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 24 Jul 2015 02:03:43 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) client-ip=209.85.215.47; Received: by lahh5 with SMTP id h5so10277614lah.2 for ; Fri, 24 Jul 2015 02:03:43 -0700 (PDT) X-Received: by 10.152.120.135 with SMTP id lc7mr12322090lab.41.1437728622930; Fri, 24 Jul 2015 02:03:42 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.7.198 with SMTP id l6csp1030322lba; Fri, 24 Jul 2015 02:03:41 -0700 (PDT) X-Received: by 10.107.7.105 with SMTP id 102mr20643427ioh.81.1437728621208; Fri, 24 Jul 2015 02:03:41 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 72si7437371iot.129.2015.07.24.02.03.39; Fri, 24 Jul 2015 02:03:41 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754245AbbGXJDg (ORCPT + 26 others); Fri, 24 Jul 2015 05:03:36 -0400 Received: from mail-pa0-f51.google.com ([209.85.220.51]:33567 "EHLO mail-pa0-f51.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753765AbbGXJDb (ORCPT ); Fri, 24 Jul 2015 05:03:31 -0400 Received: by padck2 with SMTP id ck2so11387854pad.0 for ; Fri, 24 Jul 2015 02:03:30 -0700 (PDT) X-Received: by 10.70.108.137 with SMTP id hk9mr28826130pdb.105.1437728610847; Fri, 24 Jul 2015 02:03:30 -0700 (PDT) Received: from pnqlab006.amcc.com ([182.73.239.130]) by smtp.gmail.com with ESMTPSA id wp5sm13346655pab.22.2015.07.24.02.03.26 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 24 Jul 2015 02:03:30 -0700 (PDT) From: Pranavkumar Sawargaonkar To: kvm@vger.kernel.org, kvmarm@lists.cs.columbia.edu Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, alex.williamson@redhat.com, christoffer.dall@linaro.org, marc.zyngier@arm.com, will.deacon@arm.com, bhelgaas@google.com, arnd@arndb.de, rob.herring@linaro.org, eric.auger@linaro.org, patches@apm.com, Pranavkumar Sawargaonkar , Ankit Jindal Subject: [RFC 1/2] drivers: vfio: iommu map and unmap device specific memory from kernel. Date: Fri, 24 Jul 2015 14:33:09 +0530 Message-Id: <1437728590-23126-2-git-send-email-pranavkumar@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1437728590-23126-1-git-send-email-pranavkumar@linaro.org> References: <1437728590-23126-1-git-send-email-pranavkumar@linaro.org> Sender: linux-kernel-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: pranavkumar@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.47 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , In vfio we map and unmap various regions using "VFIO_IOMMU_MAP_DMA" and "VFIO_IOMMU_UNMAP_DMA" ioctls from userspace. Some device regions (like MSI in case of PCI), which we do not expose to the userspace with mmap. These regions might require vfio driver to create an iommu mapping, as their transactions goes through an iommu like in case of ARM/ARM64. As the memory is not mmaped in userspace and might needs to be mapped with different memory attributes than user memory, we can not use VFIO_IOMMU_MAP_DMA and VFIO_IOMMU_UNMAP_DMA ioctls. This patch extends "vfio_iommu_driver_ops" to provide - device_map() and device_unmap() methods by vfio iommu driver. These methods can be used by other vfio device drivers like PCI, to create and destroy simple iommu mappings for regions like MSI/MSI-X. This patch also implements these methods for vfio iommu type1 driver. Signed-off-by: Ankit Jindal Signed-off-by: Pranavkumar Sawargaonkar Cc: Alex Williamson Cc: Marc Zyngier Cc: Will Deacon Cc: Christoffer Dall --- drivers/vfio/vfio.c | 29 +++++++++++++++++++ drivers/vfio/vfio_iommu_type1.c | 60 +++++++++++++++++++++++++++++++++++++++ include/linux/vfio.h | 11 ++++++- 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/drivers/vfio/vfio.c b/drivers/vfio/vfio.c index 2fb29df..7897c47 100644 --- a/drivers/vfio/vfio.c +++ b/drivers/vfio/vfio.c @@ -143,6 +143,35 @@ void vfio_unregister_iommu_driver(const struct vfio_iommu_driver_ops *ops) } EXPORT_SYMBOL_GPL(vfio_unregister_iommu_driver); +int vfio_device_iommu_map(struct vfio_device *device, unsigned long iova, + phys_addr_t paddr, size_t size, int prot) +{ + struct vfio_container *container = device->group->container; + const struct vfio_iommu_driver_ops *ops = container->iommu_driver->ops; + int ret; + + if (!ops->device_map) + return -EINVAL; + + ret = ops->device_map(container->iommu_data, iova, paddr, size, prot); + + return ret; +} +EXPORT_SYMBOL_GPL(vfio_device_iommu_map); + +void vfio_device_iommu_unmap(struct vfio_device *device, unsigned long iova, + size_t size) +{ + struct vfio_container *container = device->group->container; + const struct vfio_iommu_driver_ops *ops = container->iommu_driver->ops; + + if (!ops->device_unmap) + return; + + ops->device_unmap(container->iommu_data, iova, size); +} +EXPORT_SYMBOL_GPL(vfio_device_iommu_unmap); + /** * Group minor allocation/free - both called with vfio.group_lock held */ diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index 57d8c37..e41995d 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -1025,6 +1025,64 @@ static long vfio_iommu_type1_ioctl(void *iommu_data, return -ENOTTY; } +static int vfio_iommu_type1_device_map(void *iommu_data, unsigned long iova, + phys_addr_t paddr, size_t size, + int prot) +{ + struct vfio_iommu *iommu = iommu_data; + struct vfio_domain *d; + int ret; + + mutex_lock(&iommu->lock); + + list_for_each_entry(d, &iommu->domain_list, next) { + + if (iommu_iova_to_phys(d->domain, iova)) + continue; + + ret = iommu_map(d->domain, iova, paddr, + size, prot | d->prot); + + if (ret) { + if (ret != -EBUSY) + goto unwind; + } + + cond_resched(); + } + + mutex_unlock(&iommu->lock); + + return 0; + +unwind: + list_for_each_entry_continue_reverse(d, &iommu->domain_list, next) + iommu_unmap(d->domain, iova, size); + + mutex_unlock(&iommu->lock); + return ret; +} + +static void vfio_iommu_type1_device_unmap(void *iommu_data, unsigned long iova, + size_t size) +{ + struct vfio_iommu *iommu = iommu_data; + struct vfio_domain *d; + + mutex_lock(&iommu->lock); + + list_for_each_entry(d, &iommu->domain_list, next) { + + if (!iommu_iova_to_phys(d->domain, iova)) + continue; + + iommu_unmap(d->domain, iova, size); + cond_resched(); + } + + mutex_unlock(&iommu->lock); +} + static const struct vfio_iommu_driver_ops vfio_iommu_driver_ops_type1 = { .name = "vfio-iommu-type1", .owner = THIS_MODULE, @@ -1033,6 +1091,8 @@ static const struct vfio_iommu_driver_ops vfio_iommu_driver_ops_type1 = { .ioctl = vfio_iommu_type1_ioctl, .attach_group = vfio_iommu_type1_attach_group, .detach_group = vfio_iommu_type1_detach_group, + .device_map = vfio_iommu_type1_device_map, + .device_unmap = vfio_iommu_type1_device_unmap, }; static int __init vfio_iommu_type1_init(void) diff --git a/include/linux/vfio.h b/include/linux/vfio.h index ddb4409..ef0d974 100644 --- a/include/linux/vfio.h +++ b/include/linux/vfio.h @@ -52,6 +52,12 @@ extern void *vfio_del_group_dev(struct device *dev); extern struct vfio_device *vfio_device_get_from_dev(struct device *dev); extern void vfio_device_put(struct vfio_device *device); extern void *vfio_device_data(struct vfio_device *device); +extern int vfio_device_iommu_map(struct vfio_device *device, + unsigned long iova, + phys_addr_t paddr, + size_t size, int prot); +extern void vfio_device_iommu_unmap(struct vfio_device *device, + unsigned long iova, size_t size); /** * struct vfio_iommu_driver_ops - VFIO IOMMU driver callbacks @@ -72,7 +78,10 @@ struct vfio_iommu_driver_ops { struct iommu_group *group); void (*detach_group)(void *iommu_data, struct iommu_group *group); - + int (*device_map)(void *iommu_data, unsigned long iova, + phys_addr_t paddr, size_t size, int prot); + void (*device_unmap)(void *iommu_data, unsigned long iova, + size_t size); }; extern int vfio_register_iommu_driver(const struct vfio_iommu_driver_ops *ops);