From patchwork Mon Feb 12 18:33:16 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 10214963 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 C1BD66055C for ; Tue, 13 Feb 2018 00:38:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B151928732 for ; Tue, 13 Feb 2018 00:38:41 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A574A28E21; Tue, 13 Feb 2018 00:38:41 +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,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id D203828732 for ; Tue, 13 Feb 2018 00:38:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=casper.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=fZrDrTPjN1iwqrrQyvDxxEolFt7ZvgJ6cPDk+OSPbyA=; b=XFubvC5kdY42VUaekb3IfsqunS Nm2ItGdVbG7O46jW6MlmII9SOFhGe1lf14oGWSLJgdGOgAIr70imYLcnwhhCyhURT7uAuH1a8sNK9 ALxE9ecApE6bs2JfgaTNHWvZxxBHyzMXU2TPYpQKqJT4buiwsylsZeaWydLPdIWUVOa+BreTXVrtk Rst48UXyNkagi8pUMN4x29YQisjZnU9finI1CGpCWy3IIMTBSodX0C6RMHoymGPSnXhSt06FH6ykh 5Y1861ANBbwbZrvVFJvL361+vY4F2rNtxkePxULZxm3I/JcZ9r3E/WaKPKLIZee/HSfAlciMAkDBU b4LxzVwA==; Received: from [198.137.202.133] (helo=bombadil.infradead.org) by casper.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1elKxN-000135-Jn; Mon, 12 Feb 2018 20:44:09 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:References:In-Reply-To:Message-Id:Date:Subject:To: From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=fZrDrTPjN1iwqrrQyvDxxEolFt7ZvgJ6cPDk+OSPbyA=; b=HcbMv0dkrutvHPU7M7Rr2Jd89N ErDV+6MK3XlObkm5O/n4dP19XB1FshOOQl7EwCmapybhirpvYwI7zOd/bE7N4QTHYKaZl1ZgBTqnh +1XoKKtdoJAS0jWRZU9dFRmGTXZBdS5hwg9uXay3Zo9im/Wb7s8v6ma/INLQuVU9mpjuAe1ONDpA4 NZxH0CHWQvUxYBbChIlZyMnRjTjISD2iBQihcB696x/nFU3DLEq987PWeAdtJk9GOATjWusE5wO7I jYjXvuLlNzmaxWf2a5w4wqRsQtqYIRY9t0355Pa2cJMM1doivvUPeBsx5VyKnnWTXtgqK2HNQU6Y1 bQKgx1yQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1elItr-0003yk-0V; Mon, 12 Feb 2018 18:32:23 +0000 Received: from merlin.infradead.org ([2001:8b0:10b:1231::1]) by bombadil.infradead.org with esmtps (Exim 4.89 #1 (Red Hat Linux)) id 1elIsq-0002dt-HE for linux-arm-kernel@bombadil.infradead.org; Mon, 12 Feb 2018 18:31:20 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=merlin.20170209; h=References:In-Reply-To:Message-Id:Date: Subject:Cc:To:From:Sender:Reply-To:MIME-Version:Content-Type: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id: List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=B+RzUOz2Ivn+dsF6XpZNkDnHvXEPKX6xR/fqYXWmvEQ=; b=urhFixjaKYCwdhVFnxGWHgN8B eCdt4OPzxDzij5pHNacap4GcMRQHiiXJZ0Jpgod3JQsQEFJAF4Kc8Ykdiaq+eG3jISc9uR2o1/q/I rCpa2Af90C6lQbcZrTU9rHZrJjAqOt1E9/Rt0XziJO4A+2GsRhfZ8jIbAfrxdsil/ela98Qi26vXM 0fJ0z/phb7sxi2kek6QCcUs8+Ss3dRv7CPQTslSJZPYFWxS7p0yGplUjnurzdGqe5gadGWCWa7EkZ yItxo7MUMTsglxTPW0Unkt/cWGbJ/tmjbV5nRz/TB25hlWUfaCIc7jF4if9iOFma9yJ9xQdswjf19 06LuWSU2A==; Received: from foss.arm.com ([217.140.101.70]) by merlin.infradead.org with esmtp (Exim 4.89 #1 (Red Hat Linux)) id 1elIsn-0004fi-7A for linux-arm-kernel@lists.infradead.org; Mon, 12 Feb 2018 18:31:18 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id CDA03164F; Mon, 12 Feb 2018 10:30:57 -0800 (PST) Received: from e106794-lin.cambridge.arm.com (e106794-lin.cambridge.arm.com [10.1.210.24]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id F07653F24D; Mon, 12 Feb 2018 10:30:51 -0800 (PST) From: Jean-Philippe Brucker To: linux-arm-kernel@lists.infradead.org, linux-pci@vger.kernel.org, linux-acpi@vger.kernel.org, devicetree@vger.kernel.org, iommu@lists.linux-foundation.org, kvm@vger.kernel.org Subject: [PATCH 01/37] iommu: Introduce Shared Virtual Addressing API Date: Mon, 12 Feb 2018 18:33:16 +0000 Message-Id: <20180212183352.22730-2-jean-philippe.brucker@arm.com> X-Mailer: git-send-email 2.15.1 In-Reply-To: <20180212183352.22730-1-jean-philippe.brucker@arm.com> References: <20180212183352.22730-1-jean-philippe.brucker@arm.com> X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: mark.rutland@arm.com, xieyisheng1@huawei.com, ilias.apalodimas@linaro.org, catalin.marinas@arm.com, xuzaibo@huawei.com, jonathan.cameron@huawei.com, will.deacon@arm.com, okaya@codeaurora.org, yi.l.liu@intel.com, lorenzo.pieralisi@arm.com, ashok.raj@intel.com, tn@semihalf.com, joro@8bytes.org, bharatku@xilinx.com, rfranz@cavium.com, lenb@kernel.org, jacob.jun.pan@linux.intel.com, alex.williamson@redhat.com, robh+dt@kernel.org, thunder.leizhen@huawei.com, bhelgaas@google.com, shunyong.yang@hxt-semitech.com, dwmw2@infradead.org, liubo95@huawei.com, rjw@rjwysocki.net, jcrouse@codeaurora.org, robdclark@gmail.com, hanjun.guo@linaro.org, sudeep.holla@arm.com, robin.murphy@arm.com, christian.koenig@amd.com, nwatters@codeaurora.org MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Shared Virtual Addressing (SVA) provides a way for device drivers to bind process address spaces to devices. This requires the IOMMU to support the same page table format as CPUs, and requires the system to support I/O Page Faults (IOPF) and Process Address Space ID (PASID). When all of these are available, DMA can access virtual addresses of a process. A PASID is allocated for each process, and the device driver programs it into the device in an implementation-specific way. Add a new API for sharing process page tables with devices. Introduce two IOMMU operations, sva_device_init() and sva_device_shutdown(), that prepare the IOMMU driver for SVA. For example allocate PASID tables and fault queues. Subsequent patches will implement the bind() and unbind() operations. Signed-off-by: Jean-Philippe Brucker --- drivers/iommu/Kconfig | 10 ++++++ drivers/iommu/Makefile | 1 + drivers/iommu/iommu-sva.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++ include/linux/iommu.h | 32 +++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 drivers/iommu/iommu-sva.c diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig index f3a21343e636..555147a61f7c 100644 --- a/drivers/iommu/Kconfig +++ b/drivers/iommu/Kconfig @@ -74,6 +74,16 @@ config IOMMU_DMA select IOMMU_IOVA select NEED_SG_DMA_LENGTH +config IOMMU_SVA + bool "Shared Virtual Addressing API for the IOMMU" + select IOMMU_API + help + Enable process address space management for the IOMMU API. In systems + that support it, device drivers can bind process address spaces to + devices and share their page tables using this API. + + If unsure, say N here. + config FSL_PAMU bool "Freescale IOMMU support" depends on PCI diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile index 1fb695854809..1dbcc89ebe4c 100644 --- a/drivers/iommu/Makefile +++ b/drivers/iommu/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o +obj-$(CONFIG_IOMMU_SVA) += iommu-sva.o obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o obj-$(CONFIG_IOMMU_IO_PGTABLE_LPAE) += io-pgtable-arm.o diff --git a/drivers/iommu/iommu-sva.c b/drivers/iommu/iommu-sva.c new file mode 100644 index 000000000000..cab5d723520f --- /dev/null +++ b/drivers/iommu/iommu-sva.c @@ -0,0 +1,90 @@ +/* + * Track processes address spaces bound to devices and allocate PASIDs. + * + * Copyright (C) 2018 ARM Ltd. + * Author: Jean-Philippe Brucker + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include + +/** + * iommu_sva_device_init() - Initialize Shared Virtual Addressing for a device + * @dev: the device + * @features: bitmask of features that need to be initialized + * @max_pasid: max PASID value supported by the device + * + * Users of the bind()/unbind() API must call this function to initialize all + * features required for SVA. + * + * - If the device should support multiple address spaces (e.g. PCI PASID), + * IOMMU_SVA_FEAT_PASID must be requested. + * + * By default the PASID allocated during bind() is limited by the IOMMU + * capacity, and by the device PASID width defined in the PCI capability or in + * the firmware description. Setting @max_pasid to a non-zero value smaller + * than this limit overrides it. + * + * - If the device should support I/O Page Faults (e.g. PCI PRI), + * IOMMU_SVA_FEAT_IOPF must be requested. + * + * The device should not be be performing any DMA while this function is + * running. + * + * Return 0 if initialization succeeded, or an error. + */ +int iommu_sva_device_init(struct device *dev, unsigned long features, + unsigned int max_pasid) +{ + int ret; + unsigned int min_pasid = 0; + struct iommu_param *dev_param = dev->iommu_param; + struct iommu_domain *domain = iommu_get_domain_for_dev(dev); + + if (!domain || !dev_param || !domain->ops->sva_device_init) + return -ENODEV; + + /* + * IOMMU driver updates the limits depending on the IOMMU and device + * capabilities. + */ + ret = domain->ops->sva_device_init(dev, features, &min_pasid, + &max_pasid); + if (ret) + return ret; + + /* FIXME: racy. Next version should have a mutex (same as fault handler) */ + dev_param->sva_features = features; + dev_param->min_pasid = min_pasid; + dev_param->max_pasid = max_pasid; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_sva_device_init); + +/** + * iommu_sva_device_shutdown() - Shutdown Shared Virtual Addressing for a device + * @dev: the device + * + * Disable SVA. The device should not be performing any DMA while this function + * is running. + */ +int iommu_sva_device_shutdown(struct device *dev) +{ + struct iommu_param *dev_param = dev->iommu_param; + struct iommu_domain *domain = iommu_get_domain_for_dev(dev); + + if (!domain) + return -ENODEV; + + if (domain->ops->sva_device_shutdown) + domain->ops->sva_device_shutdown(dev); + + dev_param->sva_features = 0; + dev_param->min_pasid = 0; + dev_param->max_pasid = 0; + + return 0; +} +EXPORT_SYMBOL_GPL(iommu_sva_device_shutdown); diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 66ef406396e9..e9e09eecdece 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -60,6 +60,11 @@ typedef int (*iommu_fault_handler_t)(struct iommu_domain *, struct device *, unsigned long, int, void *); typedef int (*iommu_dev_fault_handler_t)(struct iommu_fault_event *, void *); +/* Request PASID support */ +#define IOMMU_SVA_FEAT_PASID (1 << 0) +/* Request I/O page fault support */ +#define IOMMU_SVA_FEAT_IOPF (1 << 1) + struct iommu_domain_geometry { dma_addr_t aperture_start; /* First address that can be mapped */ dma_addr_t aperture_end; /* Last address that can be mapped */ @@ -197,6 +202,8 @@ struct page_response_msg { * @domain_free: free iommu domain * @attach_dev: attach device to an iommu domain * @detach_dev: detach device from an iommu domain + * @sva_device_init: initialize Shared Virtual Adressing for a device + * @sva_device_shutdown: shutdown Shared Virtual Adressing for a device * @map: map a physically contiguous memory region to an iommu domain * @unmap: unmap a physically contiguous memory region from an iommu domain * @map_sg: map a scatter-gather list of physically contiguous memory chunks @@ -230,6 +237,10 @@ struct iommu_ops { int (*attach_dev)(struct iommu_domain *domain, struct device *dev); void (*detach_dev)(struct iommu_domain *domain, struct device *dev); + int (*sva_device_init)(struct device *dev, unsigned long features, + unsigned int *min_pasid, + unsigned int *max_pasid); + void (*sva_device_shutdown)(struct device *dev); int (*map)(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot); size_t (*unmap)(struct iommu_domain *domain, unsigned long iova, @@ -385,6 +396,9 @@ struct iommu_fault_param { */ struct iommu_param { struct iommu_fault_param *fault_param; + unsigned long sva_features; + unsigned int min_pasid; + unsigned int max_pasid; }; int iommu_device_register(struct iommu_device *iommu); @@ -878,4 +892,22 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) #endif /* CONFIG_IOMMU_API */ +#ifdef CONFIG_IOMMU_SVA +extern int iommu_sva_device_init(struct device *dev, unsigned long features, + unsigned int max_pasid); +extern int iommu_sva_device_shutdown(struct device *dev); +#else /* CONFIG_IOMMU_SVA */ +static inline int iommu_sva_device_init(struct device *dev, + unsigned long features, + unsigned int max_pasid) +{ + return -ENODEV; +} + +static inline int iommu_sva_device_shutdown(struct device *dev) +{ + return -ENODEV; +} +#endif /* CONFIG_IOMMU_SVA */ + #endif /* __LINUX_IOMMU_H */