All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
To: linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org
Cc: mark.rutland-5wv7dgnIgG8@public.gmane.org,
	gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA@public.gmane.org,
	catalin.marinas-5wv7dgnIgG8@public.gmane.org,
	will.deacon-5wv7dgnIgG8@public.gmane.org,
	okaya-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	rfranz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org,
	lenb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org,
	dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org,
	rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org,
	sudeep.holla-5wv7dgnIgG8@public.gmane.org
Subject: [RFCv2 PATCH 01/36] iommu: Keep track of processes and PASIDs
Date: Fri,  6 Oct 2017 14:31:28 +0100	[thread overview]
Message-ID: <20171006133203.22803-2-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20171006133203.22803-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>

IOMMU drivers need a way to bind Linux processes to devices. This is used
for Shared Virtual Memory (SVM), where devices support paging. In that
mode, DMA can directly target virtual addresses of a process.

Introduce boilerplate code for allocating process structures and binding
them to devices. Four operations are added to IOMMU drivers:

* process_alloc, process_free: to create an iommu_process structure and
  perform architecture-specific operations required to grab the process
  (for instance on ARM SMMU, pin down the CPU ASID). There is a single
  iommu_process structure per Linux process.

* process_attach: attach a process to a device. The IOMMU driver checks
  that the device is capable of sharing an address space with this
  process, and writes the PASID table entry to install the process page
  directory.

  Some IOMMU drivers (e.g. ARM SMMU and virtio-iommu) will have a single
  PASID table per domain, for convenience. Other can implement it
  differently but to help these drivers, process_attach and process_detach
  take a 'first' or 'last' parameter telling whether they need to
  install/remove the PASID entry or only send the required TLB
  invalidations.

* process_detach: detach a process from a device. The IOMMU driver removes
  the PASID table entry and invalidates the IOTLBs.

process_attach and process_detach operations are serialized with a
spinlock. At the moment it is global, but if we try to optimize it, the
core should at least prevent concurrent attach/detach on the same domain.
(so multi-level PASID table code can allocate tables lazily without having
to go through the io-pgtable concurrency nightmare). process_alloc can
sleep, but process_free must not (because we'll have to call it from
call_srcu.)

At the moment we use an IDR for allocating PASIDs and retrieving contexts.
We also use a single spinlock. These can be refined and optimized later (a
custom allocator will be needed for top-down PASID allocation).

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
 drivers/iommu/Kconfig         |  10 ++
 drivers/iommu/Makefile        |   1 +
 drivers/iommu/iommu-process.c | 225 ++++++++++++++++++++++++++++++++++++++++++
 drivers/iommu/iommu.c         |   1 +
 include/linux/iommu.h         |  24 +++++
 5 files changed, 261 insertions(+)
 create mode 100644 drivers/iommu/iommu-process.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..1ea5c90e37be 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_PROCESS
+	bool "Process management API for the IOMMU"
+	select IOMMU_API
+	help
+	  Enable process management for the IOMMU API. In systems that support
+	  it, device drivers can bind processes 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 b910aea813a1..a2832edbfaa2 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_PROCESS) += iommu-process.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-process.c b/drivers/iommu/iommu-process.c
new file mode 100644
index 000000000000..a7e5a1c94305
--- /dev/null
+++ b/drivers/iommu/iommu-process.c
@@ -0,0 +1,225 @@
+/*
+ * Track processes bound to devices
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Copyright (C) 2017 ARM Ltd.
+ *
+ * Author: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
+ */
+
+#include <linux/idr.h>
+#include <linux/iommu.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* Link between a domain and a process */
+struct iommu_context {
+	struct iommu_process	*process;
+	struct iommu_domain	*domain;
+
+	struct list_head	process_head;
+	struct list_head	domain_head;
+
+	/* Number of devices that use this context */
+	refcount_t		ref;
+};
+
+/*
+ * Because we're using an IDR, PASIDs are limited to 31 bits (the sign bit is
+ * used for returning errors). In practice implementations will use at most 20
+ * bits, which is the PCI limit.
+ */
+static DEFINE_IDR(iommu_process_idr);
+
+/*
+ * For the moment this is an all-purpose lock. It serializes
+ * access/modifications to contexts (process-domain links), access/modifications
+ * to the PASID IDR, and changes to process refcount as well.
+ */
+static DEFINE_SPINLOCK(iommu_process_lock);
+
+/*
+ * Allocate a iommu_process structure for the given task.
+ *
+ * Ideally we shouldn't need the domain parameter, since iommu_process is
+ * system-wide, but we use it to retrieve the driver's allocation ops and a
+ * PASID range.
+ */
+static struct iommu_process *
+iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
+{
+	int err;
+	int pasid;
+	struct iommu_process *process;
+
+	if (WARN_ON(!domain->ops->process_alloc || !domain->ops->process_free))
+		return ERR_PTR(-ENODEV);
+
+	process = domain->ops->process_alloc(task);
+	if (IS_ERR(process))
+		return process;
+	if (!process)
+		return ERR_PTR(-ENOMEM);
+
+	process->pid		= get_task_pid(task, PIDTYPE_PID);
+	process->release	= domain->ops->process_free;
+	INIT_LIST_HEAD(&process->domains);
+	kref_init(&process->kref);
+
+	if (!process->pid) {
+		err = -EINVAL;
+		goto err_free_process;
+	}
+
+	idr_preload(GFP_KERNEL);
+	spin_lock(&iommu_process_lock);
+	pasid = idr_alloc_cyclic(&iommu_process_idr, process, domain->min_pasid,
+				 domain->max_pasid + 1, GFP_ATOMIC);
+	process->pasid = pasid;
+	spin_unlock(&iommu_process_lock);
+	idr_preload_end();
+
+	if (pasid < 0) {
+		err = pasid;
+		goto err_put_pid;
+	}
+
+	return process;
+
+err_put_pid:
+	put_pid(process->pid);
+
+err_free_process:
+	domain->ops->process_free(process);
+
+	return ERR_PTR(err);
+}
+
+static void iommu_process_release(struct kref *kref)
+{
+	struct iommu_process *process;
+	void (*release)(struct iommu_process *);
+
+	assert_spin_locked(&iommu_process_lock);
+
+	process = container_of(kref, struct iommu_process, kref);
+	release = process->release;
+
+	WARN_ON(!list_empty(&process->domains));
+
+	idr_remove(&iommu_process_idr, process->pasid);
+	put_pid(process->pid);
+	release(process);
+}
+
+/*
+ * Returns non-zero if a reference to the process was successfully taken.
+ * Returns zero if the process is being freed and should not be used.
+ */
+static int iommu_process_get_locked(struct iommu_process *process)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	if (process)
+		return kref_get_unless_zero(&process->kref);
+
+	return 0;
+}
+
+static void iommu_process_put_locked(struct iommu_process *process)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	kref_put(&process->kref, iommu_process_release);
+}
+
+static int iommu_process_attach(struct iommu_domain *domain, struct device *dev,
+				struct iommu_process *process)
+{
+	int err;
+	int pasid = process->pasid;
+	struct iommu_context *context;
+
+	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach))
+		return -ENODEV;
+
+	if (pasid > domain->max_pasid || pasid < domain->min_pasid)
+		return -ENOSPC;
+
+	context = kzalloc(sizeof(*context), GFP_KERNEL);
+	if (!context)
+		return -ENOMEM;
+
+	context->process	= process;
+	context->domain		= domain;
+	refcount_set(&context->ref, 1);
+
+	spin_lock(&iommu_process_lock);
+	err = domain->ops->process_attach(domain, dev, process, true);
+	if (err) {
+		kfree(context);
+		spin_unlock(&iommu_process_lock);
+		return err;
+	}
+
+	list_add(&context->process_head, &process->domains);
+	list_add(&context->domain_head, &domain->processes);
+	spin_unlock(&iommu_process_lock);
+
+	return 0;
+}
+
+static void iommu_context_free(struct iommu_context *context)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	if (WARN_ON(!context->process || !context->domain))
+		return;
+
+	list_del(&context->process_head);
+	list_del(&context->domain_head);
+	iommu_process_put_locked(context->process);
+
+	kfree(context);
+}
+
+/* Attach an existing context to the device */
+static int iommu_process_attach_locked(struct iommu_context *context,
+				       struct device *dev)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	refcount_inc(&context->ref);
+	return context->domain->ops->process_attach(context->domain, dev,
+						    context->process, false);
+}
+
+/* Detach device from context and release it if necessary */
+static void iommu_process_detach_locked(struct iommu_context *context,
+					struct device *dev)
+{
+	bool last = false;
+	struct iommu_domain *domain = context->domain;
+
+	assert_spin_locked(&iommu_process_lock);
+
+	if (refcount_dec_and_test(&context->ref))
+		last = true;
+
+	domain->ops->process_detach(domain, dev, context->process, last);
+
+	if (last)
+		iommu_context_free(context);
+}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3de5c0bcb5cc..b2b34cf7c978 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1264,6 +1264,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	domain->type = type;
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
+	INIT_LIST_HEAD(&domain->processes);
 
 	return domain;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 41b8c5757859..3978dc094706 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -94,6 +94,19 @@ struct iommu_domain {
 	void *handler_token;
 	struct iommu_domain_geometry geometry;
 	void *iova_cookie;
+
+	unsigned int min_pasid, max_pasid;
+	struct list_head processes;
+};
+
+struct iommu_process {
+	struct pid		*pid;
+	int			pasid;
+	struct list_head	domains;
+	struct kref		kref;
+
+	/* Release callback for this process */
+	void (*release)(struct iommu_process *process);
 };
 
 enum iommu_cap {
@@ -164,6 +177,11 @@ struct iommu_resv_region {
  * @domain_free: free iommu domain
  * @attach_dev: attach device to an iommu domain
  * @detach_dev: detach device from an iommu domain
+ * @process_alloc: allocate iommu process
+ * @process_free: free iommu process
+ * @process_attach: attach iommu process to a domain
+ * @process_detach: detach iommu process from a domain. Remove PASID entry and
+ *                  flush associated TLB entries.
  * @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
@@ -197,6 +215,12 @@ struct iommu_ops {
 
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
+	struct iommu_process *(*process_alloc)(struct task_struct *task);
+	void (*process_free)(struct iommu_process *process);
+	int (*process_attach)(struct iommu_domain *domain, struct device *dev,
+			      struct iommu_process *process, bool first);
+	void (*process_detach)(struct iommu_domain *domain, struct device *dev,
+			       struct iommu_process *process, bool last);
 	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,
-- 
2.13.3

WARNING: multiple messages have this Message-ID (diff)
From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
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
Cc: joro@8bytes.org, robh+dt@kernel.org, mark.rutland@arm.com,
	catalin.marinas@arm.com, will.deacon@arm.com,
	lorenzo.pieralisi@arm.com, hanjun.guo@linaro.org,
	sudeep.holla@arm.com, rjw@rjwysocki.net, lenb@kernel.org,
	robin.murphy@arm.com, bhelgaas@google.com,
	alex.williamson@redhat.com, tn@semihalf.com, liubo95@huawei.com,
	thunder.leizhen@huawei.com, xieyisheng1@huawei.com,
	gabriele.paoloni@huawei.com, nwatters@codeaurora.org,
	okaya@codeaurora.org, rfranz@cavium.com, dwmw2@infradead.org,
	jacob.jun.pan@linux.intel.com, yi.l.liu@intel.com,
	ashok.raj@intel.com, robdclark@gmail.com
Subject: [RFCv2 PATCH 01/36] iommu: Keep track of processes and PASIDs
Date: Fri,  6 Oct 2017 14:31:28 +0100	[thread overview]
Message-ID: <20171006133203.22803-2-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20171006133203.22803-1-jean-philippe.brucker@arm.com>

IOMMU drivers need a way to bind Linux processes to devices. This is used
for Shared Virtual Memory (SVM), where devices support paging. In that
mode, DMA can directly target virtual addresses of a process.

Introduce boilerplate code for allocating process structures and binding
them to devices. Four operations are added to IOMMU drivers:

* process_alloc, process_free: to create an iommu_process structure and
  perform architecture-specific operations required to grab the process
  (for instance on ARM SMMU, pin down the CPU ASID). There is a single
  iommu_process structure per Linux process.

* process_attach: attach a process to a device. The IOMMU driver checks
  that the device is capable of sharing an address space with this
  process, and writes the PASID table entry to install the process page
  directory.

  Some IOMMU drivers (e.g. ARM SMMU and virtio-iommu) will have a single
  PASID table per domain, for convenience. Other can implement it
  differently but to help these drivers, process_attach and process_detach
  take a 'first' or 'last' parameter telling whether they need to
  install/remove the PASID entry or only send the required TLB
  invalidations.

* process_detach: detach a process from a device. The IOMMU driver removes
  the PASID table entry and invalidates the IOTLBs.

process_attach and process_detach operations are serialized with a
spinlock. At the moment it is global, but if we try to optimize it, the
core should at least prevent concurrent attach/detach on the same domain.
(so multi-level PASID table code can allocate tables lazily without having
to go through the io-pgtable concurrency nightmare). process_alloc can
sleep, but process_free must not (because we'll have to call it from
call_srcu.)

At the moment we use an IDR for allocating PASIDs and retrieving contexts.
We also use a single spinlock. These can be refined and optimized later (a
custom allocator will be needed for top-down PASID allocation).

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 drivers/iommu/Kconfig         |  10 ++
 drivers/iommu/Makefile        |   1 +
 drivers/iommu/iommu-process.c | 225 ++++++++++++++++++++++++++++++++++++++++++
 drivers/iommu/iommu.c         |   1 +
 include/linux/iommu.h         |  24 +++++
 5 files changed, 261 insertions(+)
 create mode 100644 drivers/iommu/iommu-process.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..1ea5c90e37be 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_PROCESS
+	bool "Process management API for the IOMMU"
+	select IOMMU_API
+	help
+	  Enable process management for the IOMMU API. In systems that support
+	  it, device drivers can bind processes 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 b910aea813a1..a2832edbfaa2 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_PROCESS) += iommu-process.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-process.c b/drivers/iommu/iommu-process.c
new file mode 100644
index 000000000000..a7e5a1c94305
--- /dev/null
+++ b/drivers/iommu/iommu-process.c
@@ -0,0 +1,225 @@
+/*
+ * Track processes bound to devices
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Copyright (C) 2017 ARM Ltd.
+ *
+ * Author: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
+ */
+
+#include <linux/idr.h>
+#include <linux/iommu.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* Link between a domain and a process */
+struct iommu_context {
+	struct iommu_process	*process;
+	struct iommu_domain	*domain;
+
+	struct list_head	process_head;
+	struct list_head	domain_head;
+
+	/* Number of devices that use this context */
+	refcount_t		ref;
+};
+
+/*
+ * Because we're using an IDR, PASIDs are limited to 31 bits (the sign bit is
+ * used for returning errors). In practice implementations will use at most 20
+ * bits, which is the PCI limit.
+ */
+static DEFINE_IDR(iommu_process_idr);
+
+/*
+ * For the moment this is an all-purpose lock. It serializes
+ * access/modifications to contexts (process-domain links), access/modifications
+ * to the PASID IDR, and changes to process refcount as well.
+ */
+static DEFINE_SPINLOCK(iommu_process_lock);
+
+/*
+ * Allocate a iommu_process structure for the given task.
+ *
+ * Ideally we shouldn't need the domain parameter, since iommu_process is
+ * system-wide, but we use it to retrieve the driver's allocation ops and a
+ * PASID range.
+ */
+static struct iommu_process *
+iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
+{
+	int err;
+	int pasid;
+	struct iommu_process *process;
+
+	if (WARN_ON(!domain->ops->process_alloc || !domain->ops->process_free))
+		return ERR_PTR(-ENODEV);
+
+	process = domain->ops->process_alloc(task);
+	if (IS_ERR(process))
+		return process;
+	if (!process)
+		return ERR_PTR(-ENOMEM);
+
+	process->pid		= get_task_pid(task, PIDTYPE_PID);
+	process->release	= domain->ops->process_free;
+	INIT_LIST_HEAD(&process->domains);
+	kref_init(&process->kref);
+
+	if (!process->pid) {
+		err = -EINVAL;
+		goto err_free_process;
+	}
+
+	idr_preload(GFP_KERNEL);
+	spin_lock(&iommu_process_lock);
+	pasid = idr_alloc_cyclic(&iommu_process_idr, process, domain->min_pasid,
+				 domain->max_pasid + 1, GFP_ATOMIC);
+	process->pasid = pasid;
+	spin_unlock(&iommu_process_lock);
+	idr_preload_end();
+
+	if (pasid < 0) {
+		err = pasid;
+		goto err_put_pid;
+	}
+
+	return process;
+
+err_put_pid:
+	put_pid(process->pid);
+
+err_free_process:
+	domain->ops->process_free(process);
+
+	return ERR_PTR(err);
+}
+
+static void iommu_process_release(struct kref *kref)
+{
+	struct iommu_process *process;
+	void (*release)(struct iommu_process *);
+
+	assert_spin_locked(&iommu_process_lock);
+
+	process = container_of(kref, struct iommu_process, kref);
+	release = process->release;
+
+	WARN_ON(!list_empty(&process->domains));
+
+	idr_remove(&iommu_process_idr, process->pasid);
+	put_pid(process->pid);
+	release(process);
+}
+
+/*
+ * Returns non-zero if a reference to the process was successfully taken.
+ * Returns zero if the process is being freed and should not be used.
+ */
+static int iommu_process_get_locked(struct iommu_process *process)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	if (process)
+		return kref_get_unless_zero(&process->kref);
+
+	return 0;
+}
+
+static void iommu_process_put_locked(struct iommu_process *process)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	kref_put(&process->kref, iommu_process_release);
+}
+
+static int iommu_process_attach(struct iommu_domain *domain, struct device *dev,
+				struct iommu_process *process)
+{
+	int err;
+	int pasid = process->pasid;
+	struct iommu_context *context;
+
+	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach))
+		return -ENODEV;
+
+	if (pasid > domain->max_pasid || pasid < domain->min_pasid)
+		return -ENOSPC;
+
+	context = kzalloc(sizeof(*context), GFP_KERNEL);
+	if (!context)
+		return -ENOMEM;
+
+	context->process	= process;
+	context->domain		= domain;
+	refcount_set(&context->ref, 1);
+
+	spin_lock(&iommu_process_lock);
+	err = domain->ops->process_attach(domain, dev, process, true);
+	if (err) {
+		kfree(context);
+		spin_unlock(&iommu_process_lock);
+		return err;
+	}
+
+	list_add(&context->process_head, &process->domains);
+	list_add(&context->domain_head, &domain->processes);
+	spin_unlock(&iommu_process_lock);
+
+	return 0;
+}
+
+static void iommu_context_free(struct iommu_context *context)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	if (WARN_ON(!context->process || !context->domain))
+		return;
+
+	list_del(&context->process_head);
+	list_del(&context->domain_head);
+	iommu_process_put_locked(context->process);
+
+	kfree(context);
+}
+
+/* Attach an existing context to the device */
+static int iommu_process_attach_locked(struct iommu_context *context,
+				       struct device *dev)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	refcount_inc(&context->ref);
+	return context->domain->ops->process_attach(context->domain, dev,
+						    context->process, false);
+}
+
+/* Detach device from context and release it if necessary */
+static void iommu_process_detach_locked(struct iommu_context *context,
+					struct device *dev)
+{
+	bool last = false;
+	struct iommu_domain *domain = context->domain;
+
+	assert_spin_locked(&iommu_process_lock);
+
+	if (refcount_dec_and_test(&context->ref))
+		last = true;
+
+	domain->ops->process_detach(domain, dev, context->process, last);
+
+	if (last)
+		iommu_context_free(context);
+}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3de5c0bcb5cc..b2b34cf7c978 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1264,6 +1264,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	domain->type = type;
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
+	INIT_LIST_HEAD(&domain->processes);
 
 	return domain;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 41b8c5757859..3978dc094706 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -94,6 +94,19 @@ struct iommu_domain {
 	void *handler_token;
 	struct iommu_domain_geometry geometry;
 	void *iova_cookie;
+
+	unsigned int min_pasid, max_pasid;
+	struct list_head processes;
+};
+
+struct iommu_process {
+	struct pid		*pid;
+	int			pasid;
+	struct list_head	domains;
+	struct kref		kref;
+
+	/* Release callback for this process */
+	void (*release)(struct iommu_process *process);
 };
 
 enum iommu_cap {
@@ -164,6 +177,11 @@ struct iommu_resv_region {
  * @domain_free: free iommu domain
  * @attach_dev: attach device to an iommu domain
  * @detach_dev: detach device from an iommu domain
+ * @process_alloc: allocate iommu process
+ * @process_free: free iommu process
+ * @process_attach: attach iommu process to a domain
+ * @process_detach: detach iommu process from a domain. Remove PASID entry and
+ *                  flush associated TLB entries.
  * @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
@@ -197,6 +215,12 @@ struct iommu_ops {
 
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
+	struct iommu_process *(*process_alloc)(struct task_struct *task);
+	void (*process_free)(struct iommu_process *process);
+	int (*process_attach)(struct iommu_domain *domain, struct device *dev,
+			      struct iommu_process *process, bool first);
+	void (*process_detach)(struct iommu_domain *domain, struct device *dev,
+			       struct iommu_process *process, bool last);
 	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,
-- 
2.13.3

WARNING: multiple messages have this Message-ID (diff)
From: jean-philippe.brucker@arm.com (Jean-Philippe Brucker)
To: linux-arm-kernel@lists.infradead.org
Subject: [RFCv2 PATCH 01/36] iommu: Keep track of processes and PASIDs
Date: Fri,  6 Oct 2017 14:31:28 +0100	[thread overview]
Message-ID: <20171006133203.22803-2-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20171006133203.22803-1-jean-philippe.brucker@arm.com>

IOMMU drivers need a way to bind Linux processes to devices. This is used
for Shared Virtual Memory (SVM), where devices support paging. In that
mode, DMA can directly target virtual addresses of a process.

Introduce boilerplate code for allocating process structures and binding
them to devices. Four operations are added to IOMMU drivers:

* process_alloc, process_free: to create an iommu_process structure and
  perform architecture-specific operations required to grab the process
  (for instance on ARM SMMU, pin down the CPU ASID). There is a single
  iommu_process structure per Linux process.

* process_attach: attach a process to a device. The IOMMU driver checks
  that the device is capable of sharing an address space with this
  process, and writes the PASID table entry to install the process page
  directory.

  Some IOMMU drivers (e.g. ARM SMMU and virtio-iommu) will have a single
  PASID table per domain, for convenience. Other can implement it
  differently but to help these drivers, process_attach and process_detach
  take a 'first' or 'last' parameter telling whether they need to
  install/remove the PASID entry or only send the required TLB
  invalidations.

* process_detach: detach a process from a device. The IOMMU driver removes
  the PASID table entry and invalidates the IOTLBs.

process_attach and process_detach operations are serialized with a
spinlock. At the moment it is global, but if we try to optimize it, the
core should at least prevent concurrent attach/detach on the same domain.
(so multi-level PASID table code can allocate tables lazily without having
to go through the io-pgtable concurrency nightmare). process_alloc can
sleep, but process_free must not (because we'll have to call it from
call_srcu.)

At the moment we use an IDR for allocating PASIDs and retrieving contexts.
We also use a single spinlock. These can be refined and optimized later (a
custom allocator will be needed for top-down PASID allocation).

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 drivers/iommu/Kconfig         |  10 ++
 drivers/iommu/Makefile        |   1 +
 drivers/iommu/iommu-process.c | 225 ++++++++++++++++++++++++++++++++++++++++++
 drivers/iommu/iommu.c         |   1 +
 include/linux/iommu.h         |  24 +++++
 5 files changed, 261 insertions(+)
 create mode 100644 drivers/iommu/iommu-process.c

diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index f3a21343e636..1ea5c90e37be 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_PROCESS
+	bool "Process management API for the IOMMU"
+	select IOMMU_API
+	help
+	  Enable process management for the IOMMU API. In systems that support
+	  it, device drivers can bind processes 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 b910aea813a1..a2832edbfaa2 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -1,6 +1,7 @@
 obj-$(CONFIG_IOMMU_API) += iommu.o
 obj-$(CONFIG_IOMMU_API) += iommu-traces.o
 obj-$(CONFIG_IOMMU_API) += iommu-sysfs.o
+obj-$(CONFIG_IOMMU_PROCESS) += iommu-process.o
 obj-$(CONFIG_IOMMU_DMA) += dma-iommu.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE) += io-pgtable.o
 obj-$(CONFIG_IOMMU_IO_PGTABLE_ARMV7S) += io-pgtable-arm-v7s.o
diff --git a/drivers/iommu/iommu-process.c b/drivers/iommu/iommu-process.c
new file mode 100644
index 000000000000..a7e5a1c94305
--- /dev/null
+++ b/drivers/iommu/iommu-process.c
@@ -0,0 +1,225 @@
+/*
+ * Track processes bound to devices
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * Copyright (C) 2017 ARM Ltd.
+ *
+ * Author: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
+ */
+
+#include <linux/idr.h>
+#include <linux/iommu.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+/* Link between a domain and a process */
+struct iommu_context {
+	struct iommu_process	*process;
+	struct iommu_domain	*domain;
+
+	struct list_head	process_head;
+	struct list_head	domain_head;
+
+	/* Number of devices that use this context */
+	refcount_t		ref;
+};
+
+/*
+ * Because we're using an IDR, PASIDs are limited to 31 bits (the sign bit is
+ * used for returning errors). In practice implementations will use at most 20
+ * bits, which is the PCI limit.
+ */
+static DEFINE_IDR(iommu_process_idr);
+
+/*
+ * For the moment this is an all-purpose lock. It serializes
+ * access/modifications to contexts (process-domain links), access/modifications
+ * to the PASID IDR, and changes to process refcount as well.
+ */
+static DEFINE_SPINLOCK(iommu_process_lock);
+
+/*
+ * Allocate a iommu_process structure for the given task.
+ *
+ * Ideally we shouldn't need the domain parameter, since iommu_process is
+ * system-wide, but we use it to retrieve the driver's allocation ops and a
+ * PASID range.
+ */
+static struct iommu_process *
+iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
+{
+	int err;
+	int pasid;
+	struct iommu_process *process;
+
+	if (WARN_ON(!domain->ops->process_alloc || !domain->ops->process_free))
+		return ERR_PTR(-ENODEV);
+
+	process = domain->ops->process_alloc(task);
+	if (IS_ERR(process))
+		return process;
+	if (!process)
+		return ERR_PTR(-ENOMEM);
+
+	process->pid		= get_task_pid(task, PIDTYPE_PID);
+	process->release	= domain->ops->process_free;
+	INIT_LIST_HEAD(&process->domains);
+	kref_init(&process->kref);
+
+	if (!process->pid) {
+		err = -EINVAL;
+		goto err_free_process;
+	}
+
+	idr_preload(GFP_KERNEL);
+	spin_lock(&iommu_process_lock);
+	pasid = idr_alloc_cyclic(&iommu_process_idr, process, domain->min_pasid,
+				 domain->max_pasid + 1, GFP_ATOMIC);
+	process->pasid = pasid;
+	spin_unlock(&iommu_process_lock);
+	idr_preload_end();
+
+	if (pasid < 0) {
+		err = pasid;
+		goto err_put_pid;
+	}
+
+	return process;
+
+err_put_pid:
+	put_pid(process->pid);
+
+err_free_process:
+	domain->ops->process_free(process);
+
+	return ERR_PTR(err);
+}
+
+static void iommu_process_release(struct kref *kref)
+{
+	struct iommu_process *process;
+	void (*release)(struct iommu_process *);
+
+	assert_spin_locked(&iommu_process_lock);
+
+	process = container_of(kref, struct iommu_process, kref);
+	release = process->release;
+
+	WARN_ON(!list_empty(&process->domains));
+
+	idr_remove(&iommu_process_idr, process->pasid);
+	put_pid(process->pid);
+	release(process);
+}
+
+/*
+ * Returns non-zero if a reference to the process was successfully taken.
+ * Returns zero if the process is being freed and should not be used.
+ */
+static int iommu_process_get_locked(struct iommu_process *process)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	if (process)
+		return kref_get_unless_zero(&process->kref);
+
+	return 0;
+}
+
+static void iommu_process_put_locked(struct iommu_process *process)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	kref_put(&process->kref, iommu_process_release);
+}
+
+static int iommu_process_attach(struct iommu_domain *domain, struct device *dev,
+				struct iommu_process *process)
+{
+	int err;
+	int pasid = process->pasid;
+	struct iommu_context *context;
+
+	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach))
+		return -ENODEV;
+
+	if (pasid > domain->max_pasid || pasid < domain->min_pasid)
+		return -ENOSPC;
+
+	context = kzalloc(sizeof(*context), GFP_KERNEL);
+	if (!context)
+		return -ENOMEM;
+
+	context->process	= process;
+	context->domain		= domain;
+	refcount_set(&context->ref, 1);
+
+	spin_lock(&iommu_process_lock);
+	err = domain->ops->process_attach(domain, dev, process, true);
+	if (err) {
+		kfree(context);
+		spin_unlock(&iommu_process_lock);
+		return err;
+	}
+
+	list_add(&context->process_head, &process->domains);
+	list_add(&context->domain_head, &domain->processes);
+	spin_unlock(&iommu_process_lock);
+
+	return 0;
+}
+
+static void iommu_context_free(struct iommu_context *context)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	if (WARN_ON(!context->process || !context->domain))
+		return;
+
+	list_del(&context->process_head);
+	list_del(&context->domain_head);
+	iommu_process_put_locked(context->process);
+
+	kfree(context);
+}
+
+/* Attach an existing context to the device */
+static int iommu_process_attach_locked(struct iommu_context *context,
+				       struct device *dev)
+{
+	assert_spin_locked(&iommu_process_lock);
+
+	refcount_inc(&context->ref);
+	return context->domain->ops->process_attach(context->domain, dev,
+						    context->process, false);
+}
+
+/* Detach device from context and release it if necessary */
+static void iommu_process_detach_locked(struct iommu_context *context,
+					struct device *dev)
+{
+	bool last = false;
+	struct iommu_domain *domain = context->domain;
+
+	assert_spin_locked(&iommu_process_lock);
+
+	if (refcount_dec_and_test(&context->ref))
+		last = true;
+
+	domain->ops->process_detach(domain, dev, context->process, last);
+
+	if (last)
+		iommu_context_free(context);
+}
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index 3de5c0bcb5cc..b2b34cf7c978 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1264,6 +1264,7 @@ static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
 	domain->type = type;
 	/* Assume all sizes by default; the driver may override this later */
 	domain->pgsize_bitmap  = bus->iommu_ops->pgsize_bitmap;
+	INIT_LIST_HEAD(&domain->processes);
 
 	return domain;
 }
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 41b8c5757859..3978dc094706 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -94,6 +94,19 @@ struct iommu_domain {
 	void *handler_token;
 	struct iommu_domain_geometry geometry;
 	void *iova_cookie;
+
+	unsigned int min_pasid, max_pasid;
+	struct list_head processes;
+};
+
+struct iommu_process {
+	struct pid		*pid;
+	int			pasid;
+	struct list_head	domains;
+	struct kref		kref;
+
+	/* Release callback for this process */
+	void (*release)(struct iommu_process *process);
 };
 
 enum iommu_cap {
@@ -164,6 +177,11 @@ struct iommu_resv_region {
  * @domain_free: free iommu domain
  * @attach_dev: attach device to an iommu domain
  * @detach_dev: detach device from an iommu domain
+ * @process_alloc: allocate iommu process
+ * @process_free: free iommu process
+ * @process_attach: attach iommu process to a domain
+ * @process_detach: detach iommu process from a domain. Remove PASID entry and
+ *                  flush associated TLB entries.
  * @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
@@ -197,6 +215,12 @@ struct iommu_ops {
 
 	int (*attach_dev)(struct iommu_domain *domain, struct device *dev);
 	void (*detach_dev)(struct iommu_domain *domain, struct device *dev);
+	struct iommu_process *(*process_alloc)(struct task_struct *task);
+	void (*process_free)(struct iommu_process *process);
+	int (*process_attach)(struct iommu_domain *domain, struct device *dev,
+			      struct iommu_process *process, bool first);
+	void (*process_detach)(struct iommu_domain *domain, struct device *dev,
+			       struct iommu_process *process, bool last);
 	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,
-- 
2.13.3

  parent reply	other threads:[~2017-10-06 13:31 UTC|newest]

Thread overview: 268+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-10-06 13:31 [RFCv2 PATCH 00/36] Process management for IOMMU + SVM for SMMUv3 Jean-Philippe Brucker
2017-10-06 13:31 ` Jean-Philippe Brucker
2017-10-06 13:31 ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 02/36] iommu: Add a process_exit callback for device drivers Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 03/36] iommu/process: Add public function to search for a process Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
     [not found] ` <20171006133203.22803-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-10-06 13:31   ` Jean-Philippe Brucker [this message]
2017-10-06 13:31     ` [RFCv2 PATCH 01/36] iommu: Keep track of processes and PASIDs Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-23 11:04     ` Liu, Yi L
2017-10-23 11:04       ` Liu, Yi L
2017-10-23 11:04       ` Liu, Yi L
2017-10-23 12:17       ` Jean-Philippe Brucker
2017-10-23 12:17         ` Jean-Philippe Brucker
2017-10-23 12:17         ` Jean-Philippe Brucker
     [not found]         ` <7aaf9851-9546-f34d-1496-cbeea404abbd-5wv7dgnIgG8@public.gmane.org>
2017-10-25 18:05           ` Raj, Ashok
2017-10-25 18:05             ` Raj, Ashok
2017-10-25 18:05             ` Raj, Ashok
2017-10-30 10:28             ` Jean-Philippe Brucker
2017-10-30 10:28               ` Jean-Philippe Brucker
2017-10-30 10:28               ` Jean-Philippe Brucker
     [not found]     ` <20171006133203.22803-2-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-10-20 23:32       ` Sinan Kaya
2017-10-20 23:32         ` Sinan Kaya
2017-10-20 23:32         ` Sinan Kaya
2017-11-02 16:20         ` Jean-Philippe Brucker
2017-11-02 16:20           ` Jean-Philippe Brucker
2017-11-02 16:20           ` Jean-Philippe Brucker
2017-11-08 17:50       ` Bharat Kumar Gogada
2017-11-08 17:50         ` Bharat Kumar Gogada
2017-11-08 17:50         ` Bharat Kumar Gogada
2017-11-09 12:13         ` Jean-Philippe Brucker
2017-11-09 12:13           ` Jean-Philippe Brucker
2017-11-09 12:13           ` Jean-Philippe Brucker
     [not found]         ` <BLUPR0201MB150538FDD455F6042803B54FA5560-hRBPhS1iNj/g9tdZWAsUFxrHTHEw16jenBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-11-09 12:16           ` Jean-Philippe Brucker
2017-11-09 12:16             ` Jean-Philippe Brucker
2017-11-09 12:16             ` Jean-Philippe Brucker
     [not found]             ` <16b6ba80-b15b-b278-0d06-350ae0201e82-5wv7dgnIgG8@public.gmane.org>
2017-11-13 11:06               ` Bharat Kumar Gogada
2017-11-13 11:06                 ` Bharat Kumar Gogada
2017-11-13 11:06                 ` Bharat Kumar Gogada
2017-11-22  3:15     ` Bob Liu
2017-11-22  3:15       ` Bob Liu
2017-11-22  3:15       ` Bob Liu
2017-11-22 13:04       ` Jean-Philippe Brucker
2017-11-22 13:04         ` Jean-Philippe Brucker
2017-11-22 13:04         ` Jean-Philippe Brucker
     [not found]         ` <42f815ee-2a9a-ac49-2392-5c03c1d4c809-5wv7dgnIgG8@public.gmane.org>
2017-11-23 10:33           ` Bob Liu
2017-11-23 10:33             ` Bob Liu
2017-11-23 10:33             ` Bob Liu
2017-10-06 13:31   ` [RFCv2 PATCH 04/36] iommu/process: Track process changes with an mmu_notifier Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 05/36] iommu/process: Bind and unbind process to and from devices Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-11 11:33     ` Joerg Roedel
2017-10-11 11:33       ` Joerg Roedel
2017-10-12 11:13       ` Jean-Philippe Brucker
2017-10-12 11:13         ` Jean-Philippe Brucker
2017-10-12 11:13         ` Jean-Philippe Brucker
     [not found]         ` <ee7f80e3-ca30-0ee7-53f3-3e57b2b58df6-5wv7dgnIgG8@public.gmane.org>
2017-10-12 12:47           ` Joerg Roedel
2017-10-12 12:47             ` Joerg Roedel
2017-10-12 12:47             ` Joerg Roedel
     [not found]     ` <20171006133203.22803-6-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-10-21 15:47       ` Sinan Kaya
2017-10-21 15:47         ` Sinan Kaya
2017-10-21 15:47         ` Sinan Kaya
     [not found]         ` <683a518d-0e22-c855-2416-2e097ec3291d-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2017-11-02 16:21           ` Jean-Philippe Brucker
2017-11-02 16:21             ` Jean-Philippe Brucker
2017-11-02 16:21             ` Jean-Philippe Brucker
2017-11-29  6:08     ` Yisheng Xie
2017-11-29  6:08       ` Yisheng Xie
2017-11-29  6:08       ` Yisheng Xie
2017-11-29 15:01       ` Jean-Philippe Brucker
2017-11-29 15:01         ` Jean-Philippe Brucker
2017-11-29 15:01         ` Jean-Philippe Brucker
2017-11-30  1:11         ` Yisheng Xie
2017-11-30  1:11           ` Yisheng Xie
2017-11-30  1:11           ` Yisheng Xie
2017-11-30 13:39           ` Jean-Philippe Brucker
2017-11-30 13:39             ` Jean-Philippe Brucker
2017-11-30 13:39             ` Jean-Philippe Brucker
2018-01-19  4:52     ` Sinan Kaya
2018-01-19  4:52       ` Sinan Kaya
2018-01-19  4:52       ` Sinan Kaya
     [not found]       ` <0772e71e-4861-1e7b-f248-88aaba8bf2fc-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2018-01-19 10:27         ` Jean-Philippe Brucker
2018-01-19 10:27           ` Jean-Philippe Brucker
2018-01-19 10:27           ` Jean-Philippe Brucker
2018-01-19 13:07           ` okaya
2018-01-19 13:07             ` okaya at codeaurora.org
2018-01-19 13:07             ` okaya
2017-10-06 13:31   ` [RFCv2 PATCH 06/36] iommu: Extend fault reporting Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 07/36] iommu: Add a fault handler Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 08/36] iommu/fault: Handle mm faults Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 13/36] iommu/of: Add stall and pasid properties to iommu_fwspec Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 19/36] arm64: mm: Pin down ASIDs for sharing contexts with devices Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 20/36] iommu/arm-smmu-v3: Track ASID state Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 21/36] iommu/arm-smmu-v3: Implement process operations Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-11-09  3:32     ` Yisheng Xie
2017-11-09  3:32       ` Yisheng Xie
2017-11-09  3:32       ` Yisheng Xie
2017-11-09 12:08       ` Jean-Philippe Brucker
2017-11-09 12:08         ` Jean-Philippe Brucker
2017-11-09 12:08         ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 23/36] iommu/arm-smmu-v3: Share process page tables Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 28/36] iommu/arm-smmu-v3: Maintain a SID->device structure Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 29/36] iommu/arm-smmu-v3: Add stall support for platform devices Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31   ` [RFCv2 PATCH 30/36] ACPI/IORT: Check ATS capability in root complex nodes Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:31     ` Jean-Philippe Brucker
2017-10-06 13:32   ` [RFCv2 PATCH 34/36] PCI: Make "PRG Response PASID Required" handling common Jean-Philippe Brucker
2017-10-06 13:32     ` Jean-Philippe Brucker
2017-10-06 13:32     ` Jean-Philippe Brucker
     [not found]     ` <20171006133203.22803-35-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-10-06 18:11       ` Bjorn Helgaas
2017-10-06 18:11         ` Bjorn Helgaas
2017-10-06 18:11         ` Bjorn Helgaas
2017-10-06 13:32   ` [RFCv2 PATCH 35/36] iommu/arm-smmu-v3: Add support for PRI Jean-Philippe Brucker
2017-10-06 13:32     ` Jean-Philippe Brucker
2017-10-06 13:32     ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 09/36] iommu/fault: Allow blocking fault handlers Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
     [not found]   ` <20171006133203.22803-10-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-11-29  6:15     ` Yisheng Xie
2017-11-29  6:15       ` Yisheng Xie
2017-11-29  6:15       ` Yisheng Xie
     [not found]       ` <7e1c8ea4-e568-1000-17de-62f8562c7169-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2017-11-29 15:01         ` Jean-Philippe Brucker
2017-11-29 15:01           ` Jean-Philippe Brucker
2017-11-29 15:01           ` Jean-Philippe Brucker
     [not found]           ` <74891e35-17d8-5831-1ebd-18e00ce00d74-5wv7dgnIgG8@public.gmane.org>
2017-11-30  2:45             ` Yisheng Xie
2017-11-30  2:45               ` Yisheng Xie
2017-11-30  2:45               ` Yisheng Xie
2017-10-06 13:31 ` [RFCv2 PATCH 10/36] vfio: Add support for Shared Virtual Memory Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-11-24  8:23   ` Bob Liu
2017-11-24  8:23     ` Bob Liu
2017-11-24  8:23     ` Bob Liu
2017-11-24 10:58     ` Jean-Philippe Brucker
2017-11-24 10:58       ` Jean-Philippe Brucker
2017-11-24 10:58       ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 11/36] iommu/arm-smmu-v3: Link domains and devices Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 12/36] dt-bindings: document stall and PASID properties for IOMMU masters Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
     [not found]   ` <20171006133203.22803-13-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
2017-10-13 19:10     ` Rob Herring
2017-10-13 19:10       ` Rob Herring
2017-10-13 19:10       ` Rob Herring
2017-10-16 10:23       ` Jean-Philippe Brucker
2017-10-16 10:23         ` Jean-Philippe Brucker
2017-10-16 10:23         ` Jean-Philippe Brucker
     [not found]         ` <e7288f51-1cfa-44ce-e3ce-e9f3daf91579-5wv7dgnIgG8@public.gmane.org>
2017-10-18  2:06           ` Rob Herring
2017-10-18  2:06             ` Rob Herring
2017-10-18  2:06             ` Rob Herring
2017-10-06 13:31 ` [RFCv2 PATCH 14/36] iommu/arm-smmu-v3: Add support for Substream IDs Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-11-02 12:49   ` Shameerali Kolothum Thodi
2017-11-02 12:49     ` Shameerali Kolothum Thodi
2017-11-02 12:49     ` Shameerali Kolothum Thodi
2017-11-02 15:51     ` Jean-Philippe Brucker
2017-11-02 15:51       ` Jean-Philippe Brucker
2017-11-02 15:51       ` Jean-Philippe Brucker
2017-11-02 17:02       ` Shameerali Kolothum Thodi
2017-11-02 17:02         ` Shameerali Kolothum Thodi
2017-11-02 17:02         ` Shameerali Kolothum Thodi
2017-11-03  5:45         ` Yisheng Xie
2017-11-03  5:45           ` Yisheng Xie
2017-11-03  5:45           ` Yisheng Xie
2017-11-03  9:37           ` Jean-Philippe Brucker
2017-11-03  9:37             ` Jean-Philippe Brucker
2017-11-03  9:37             ` Jean-Philippe Brucker
2017-11-03  9:39             ` Shameerali Kolothum Thodi
2017-11-03  9:39               ` Shameerali Kolothum Thodi
2017-11-03  9:39               ` Shameerali Kolothum Thodi
2017-11-06  0:50             ` Yisheng Xie
2017-11-06  0:50               ` Yisheng Xie
2017-11-06  0:50               ` Yisheng Xie
2017-10-06 13:31 ` [RFCv2 PATCH 15/36] iommu/arm-smmu-v3: Add second level of context descriptor table Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 16/36] iommu/arm-smmu-v3: Add support for VHE Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 17/36] iommu/arm-smmu-v3: Support broadcast TLB maintenance Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 18/36] iommu/arm-smmu-v3: Add SVM feature checking Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 22/36] iommu/io-pgtable-arm: Factor out ARM LPAE register defines Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 24/36] iommu/arm-smmu-v3: Steal private ASID from a domain Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 25/36] iommu/arm-smmu-v3: Use shared ASID set Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 26/36] iommu/arm-smmu-v3: Add support for Hardware Translation Table Update Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-12-06  6:51   ` Yisheng Xie
2017-12-06  6:51     ` Yisheng Xie
2017-12-06  6:51     ` Yisheng Xie
     [not found]     ` <d2ec2e61-f758-0394-41d2-555ae65feb0d-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
2017-12-06 11:06       ` Jean-Philippe Brucker
2017-12-06 11:06         ` Jean-Philippe Brucker
2017-12-06 11:06         ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 27/36] iommu/arm-smmu-v3: Register fault workqueue Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 31/36] iommu/arm-smmu-v3: Add support for PCI ATS Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-11-16 14:19   ` Bharat Kumar Gogada
2017-11-16 14:19     ` Bharat Kumar Gogada
2017-11-16 14:19     ` Bharat Kumar Gogada
     [not found]     ` <BLUPR0201MB150565029F9260A528739ACBA52E0-hRBPhS1iNj/g9tdZWAsUFxrHTHEw16jenBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-11-16 15:03       ` Jean-Philippe Brucker
2017-11-16 15:03         ` Jean-Philippe Brucker
2017-11-16 15:03         ` Jean-Philippe Brucker
     [not found]         ` <673fda01-2ae0-87e4-637e-fe27096b6be0-5wv7dgnIgG8@public.gmane.org>
2017-11-17  6:11           ` Bharat Kumar Gogada
2017-11-17  6:11             ` Bharat Kumar Gogada
2017-11-17  6:11             ` Bharat Kumar Gogada
     [not found]             ` <BLUPR0201MB1505BC86D3838D13F38665E7A52F0-hRBPhS1iNj/g9tdZWAsUFxrHTHEw16jenBOFsp37pqbUKgpGm//BTAC/G2K4zDHf@public.gmane.org>
2017-11-17 11:39               ` Jean-Philippe Brucker
2017-11-17 11:39                 ` Jean-Philippe Brucker
2017-11-17 11:39                 ` Jean-Philippe Brucker
2017-10-06 13:31 ` [RFCv2 PATCH 32/36] iommu/arm-smmu-v3: Hook ATC invalidation to process ops Jean-Philippe Brucker
2017-10-06 13:31   ` Jean-Philippe Brucker
2017-10-06 13:32 ` [RFCv2 PATCH 33/36] iommu/arm-smmu-v3: Disable tagged pointers Jean-Philippe Brucker
2017-10-06 13:32   ` Jean-Philippe Brucker
2017-10-06 13:32 ` [RFCv2 PATCH 36/36] iommu/arm-smmu-v3: Add support for PCI PASID Jean-Philippe Brucker
2017-10-06 13:32   ` Jean-Philippe Brucker
2017-10-09  9:49 ` [RFCv2 PATCH 00/36] Process management for IOMMU + SVM for SMMUv3 Yisheng Xie
2017-10-09  9:49   ` Yisheng Xie
2017-10-09  9:49   ` Yisheng Xie
2017-10-09 11:36   ` Jean-Philippe Brucker
2017-10-09 11:36     ` Jean-Philippe Brucker
2017-10-09 11:36     ` Jean-Philippe Brucker
     [not found]     ` <0fecd29e-eaf7-9503-b087-7bfbc251da88-5wv7dgnIgG8@public.gmane.org>
2017-10-12 12:05       ` Yisheng Xie
2017-10-12 12:05         ` Yisheng Xie
2017-10-12 12:05         ` Yisheng Xie
2017-10-12 12:55         ` Jean-Philippe Brucker
2017-10-12 12:55           ` Jean-Philippe Brucker
2017-10-12 12:55           ` Jean-Philippe Brucker
     [not found]           ` <8a1e090d-22e8-0295-a53f-bc3b5b7d7971-5wv7dgnIgG8@public.gmane.org>
2017-10-12 15:28             ` Jordan Crouse
2017-10-12 15:28               ` Jordan Crouse
2017-10-12 15:28               ` Jordan Crouse
     [not found]               ` <20171012152803.GA3027-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2017-10-23 13:00                 ` Jean-Philippe Brucker
2017-10-23 13:00                   ` Jean-Philippe Brucker
     [not found]                   ` <8539601d-ef7a-8dd0-2fc7-51240c292678-5wv7dgnIgG8@public.gmane.org>
2017-10-25 20:20                     ` Jordan Crouse
2017-10-25 20:20                       ` Jordan Crouse
     [not found]                       ` <20171025202015.GA6159-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2018-02-05 18:15                         ` Jordan Crouse
2018-02-05 18:15                           ` Jordan Crouse
     [not found]                           ` <20180205181513.GB878-9PYrDHPZ2Orvke4nUoYGnHL1okKdlPRT@public.gmane.org>
2018-02-05 18:43                             ` Jean-Philippe Brucker
2018-02-05 18:43                               ` Jean-Philippe Brucker
2017-11-08  1:21           ` Bob Liu
2017-11-08  1:21             ` Bob Liu
2017-11-08  1:21             ` Bob Liu
2017-11-08 10:50             ` Jean-Philippe Brucker
2017-11-08 10:50               ` Jean-Philippe Brucker
2017-11-08 10:50               ` Jean-Philippe Brucker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171006133203.22803-2-jean-philippe.brucker@arm.com \
    --to=jean-philippe.brucker-5wv7dgnigg8@public.gmane.org \
    --cc=bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
    --cc=catalin.marinas-5wv7dgnIgG8@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org \
    --cc=gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA@public.gmane.org \
    --cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
    --cc=lenb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=linux-acpi-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
    --cc=okaya-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org \
    --cc=rfranz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org \
    --cc=rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=sudeep.holla-5wv7dgnIgG8@public.gmane.org \
    --cc=will.deacon-5wv7dgnIgG8@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.