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: joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	mark.rutland-5wv7dgnIgG8@public.gmane.org,
	catalin.marinas-5wv7dgnIgG8@public.gmane.org,
	will.deacon-5wv7dgnIgG8@public.gmane.org,
	lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org,
	hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org,
	sudeep.holla-5wv7dgnIgG8@public.gmane.org,
	rjw-LthD3rsA81gm4RdzfppkhA@public.gmane.org,
	lenb-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org,
	robin.murphy-5wv7dgnIgG8@public.gmane.org,
	bhelgaas-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org,
	alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
	tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org,
	liubo95-hv44wF8Li93QT0dZR+AlfA@public.gmane.org,
	thunder.leizhen-hv44wF8Li93QT0dZR+AlfA@public.gmane.org,
	xieyisheng1-hv44wF8Li93QT0dZR+AlfA@public.gmane.org,
	gabriele.paoloni-hv44wF8Li93QT0dZR+AlfA@public.gmane.org,
	nwatters-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	okaya-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org,
	rfranz-YGCgFSpz5w/QT0dZR+AlfA@public.gmane.org,
	dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org,
	jacob.jun.pan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
	yi.l.liu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
	ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org,
	robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Subject: [RFCv2 PATCH 04/36] iommu/process: Track process changes with an mmu_notifier
Date: Fri,  6 Oct 2017 14:31:31 +0100	[thread overview]
Message-ID: <20171006133203.22803-5-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20171006133203.22803-1-jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>

When creating an iommu_process structure, register a notifier to be
informed of changes to the virtual address space and to know when the
process exits.

Two new operations are added to the IOMMU driver:

* process_invalidate when a range of addresses is unmapped, to let the
  IOMMU driver send TLB invalidations.

* process_exit when the mm is released. It's a bit more involved in this
  case, as the IOMMU driver has to tell all devices drivers to stop using
  this PASID, then clear the PASID table and invalidate TLBs.

Adding the notifier in the mix complicates process release. In one case
device drivers free the process explicitly by calling unbind (or detaching
the device). In the other case the process could crash before unbind, in
which case the release notifier has to do all the work.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker-5wv7dgnIgG8@public.gmane.org>
---
 drivers/iommu/iommu-process.c | 165 ++++++++++++++++++++++++++++++++++++++++--
 include/linux/iommu.h         |  12 +++
 2 files changed, 170 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu-process.c b/drivers/iommu/iommu-process.c
index 8f4c98632d58..1ef3f55b962b 100644
--- a/drivers/iommu/iommu-process.c
+++ b/drivers/iommu/iommu-process.c
@@ -21,9 +21,14 @@
 
 #include <linux/idr.h>
 #include <linux/iommu.h>
+#include <linux/mmu_notifier.h>
 #include <linux/slab.h>
+#include <linux/sched/mm.h>
 #include <linux/spinlock.h>
 
+/* FIXME: stub for the fault queue. Remove later. */
+#define iommu_fault_queue_flush(...)
+
 /* Link between a domain and a process */
 struct iommu_context {
 	struct iommu_process	*process;
@@ -50,6 +55,8 @@ static DEFINE_IDR(iommu_process_idr);
  */
 static DEFINE_SPINLOCK(iommu_process_lock);
 
+static struct mmu_notifier_ops iommu_process_mmu_notfier;
+
 /*
  * Allocate a iommu_process structure for the given task.
  *
@@ -74,15 +81,21 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 		return ERR_PTR(-ENOMEM);
 
 	process->pid		= get_task_pid(task, PIDTYPE_PID);
+	process->mm		= get_task_mm(task);
+	process->notifier.ops	= &iommu_process_mmu_notfier;
 	process->release	= domain->ops->process_free;
 	INIT_LIST_HEAD(&process->domains);
-	kref_init(&process->kref);
 
 	if (!process->pid) {
 		err = -EINVAL;
 		goto err_free_process;
 	}
 
+	if (!process->mm) {
+		err = -EINVAL;
+		goto err_put_pid;
+	}
+
 	idr_preload(GFP_KERNEL);
 	spin_lock(&iommu_process_lock);
 	pasid = idr_alloc_cyclic(&iommu_process_idr, process, domain->min_pasid,
@@ -93,11 +106,44 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 
 	if (pasid < 0) {
 		err = pasid;
-		goto err_put_pid;
+		goto err_put_mm;
 	}
 
+	err = mmu_notifier_register(&process->notifier, process->mm);
+	if (err)
+		goto err_free_pasid;
+
+	/*
+	 * Now that the MMU notifier is valid, we can allow users to grab this
+	 * process by setting a valid refcount. Before that it was accessible in
+	 * the IDR but invalid.
+	 *
+	 * Users of the process structure obtain it with inc_not_zero, which
+	 * provides a control dependency to ensure that they don't modify the
+	 * structure if they didn't acquire the ref. So I think we need a write
+	 * barrier here to pair with that control dependency (XXX probably
+	 * nonsense.)
+	 */
+	smp_wmb();
+	kref_init(&process->kref);
+
+	/* A mm_count reference is kept by the notifier */
+	mmput(process->mm);
+
 	return process;
 
+err_free_pasid:
+	/*
+	 * Even if the process is accessible from the IDR at this point, kref is
+	 * 0 so no user could get a reference to it. Free it manually.
+	 */
+	spin_lock(&iommu_process_lock);
+	idr_remove(&iommu_process_idr, process->pasid);
+	spin_unlock(&iommu_process_lock);
+
+err_put_mm:
+	mmput(process->mm);
+
 err_put_pid:
 	put_pid(process->pid);
 
@@ -107,21 +153,46 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 	return ERR_PTR(err);
 }
 
-static void iommu_process_release(struct kref *kref)
+static void iommu_process_free(struct rcu_head *rcu)
 {
 	struct iommu_process *process;
 	void (*release)(struct iommu_process *);
 
+	process = container_of(rcu, struct iommu_process, rcu);
+	release = process->release;
+
+	release(process);
+}
+
+static void iommu_process_release(struct kref *kref)
+{
+	struct iommu_process *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);
+
+	/*
+	 * If we're being released from process exit, the notifier callback
+	 * ->release has already been called. Otherwise we don't need to go
+	 * through there, the process isn't attached to anything anymore. Hence
+	 * no_release.
+	 */
+	mmu_notifier_unregister_no_release(&process->notifier, process->mm);
+
+	/*
+	 * We can't free the structure here, because ->release might be
+	 * attempting to grab it concurrently. And in the other case, if the
+	 * structure is being released from within ->release, then
+	 * __mmu_notifier_release expects to still have a valid mn when
+	 * returning. So free the structure when it's safe, after the RCU grace
+	 * period elapsed.
+	 */
+	mmu_notifier_call_srcu(&process->rcu, iommu_process_free);
 }
 
 /*
@@ -187,7 +258,8 @@ static int iommu_process_attach(struct iommu_domain *domain, struct device *dev,
 	int pasid = process->pasid;
 	struct iommu_context *context;
 
-	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach))
+	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach ||
+		    !domain->ops->process_exit || !domain->ops->process_invalidate))
 		return -ENODEV;
 
 	if (pasid > domain->max_pasid || pasid < domain->min_pasid)
@@ -259,6 +331,85 @@ static void iommu_process_detach_locked(struct iommu_context *context,
 		iommu_context_free(context);
 }
 
+/*
+ * Called when the process exits. Might race with unbind or any other function
+ * dropping the last reference to the process. As the mmu notifier doesn't hold
+ * any reference to the process when calling ->release, try to take a reference.
+ */
+static void iommu_notifier_release(struct mmu_notifier *mn, struct mm_struct *mm)
+{
+	struct iommu_context *context, *next;
+	struct iommu_process *process = container_of(mn, struct iommu_process, notifier);
+
+	/*
+	 * If the process is exiting then domains are still attached to the
+	 * process. A few things need to be done before it is safe to release
+	 *
+	 * 1) Tell the IOMMU driver to stop using this PASID (and forward the
+	 *    message to attached device drivers. It can then clear the PASID
+	 *    table and invalidate relevant TLBs.
+	 *
+	 * 2) Drop all references to this process, by freeing the contexts.
+	 */
+	spin_lock(&iommu_process_lock);
+	if (!iommu_process_get_locked(process)) {
+		/* Someone's already taking care of it. */
+		spin_unlock(&iommu_process_lock);
+		return;
+	}
+
+	list_for_each_entry_safe(context, next, &process->domains, process_head) {
+		context->domain->ops->process_exit(context->domain, process);
+		iommu_context_free(context);
+	}
+	spin_unlock(&iommu_process_lock);
+
+	iommu_fault_queue_flush(NULL);
+
+	/*
+	 * We're now reasonably certain that no more fault is being handled for
+	 * this process, since we just flushed them all out of the fault queue.
+	 * Release the last reference to free the process.
+	 */
+	iommu_process_put(process);
+}
+
+static void iommu_notifier_invalidate_range(struct mmu_notifier *mn, struct mm_struct *mm,
+					    unsigned long start, unsigned long end)
+{
+	struct iommu_context *context;
+	struct iommu_process *process = container_of(mn, struct iommu_process, notifier);
+
+	spin_lock(&iommu_process_lock);
+	list_for_each_entry(context, &process->domains, process_head) {
+		context->domain->ops->process_invalidate(context->domain,
+						 process, start, end - start);
+	}
+	spin_unlock(&iommu_process_lock);
+}
+
+static int iommu_notifier_clear_flush_young(struct mmu_notifier *mn,
+					    struct mm_struct *mm,
+					    unsigned long start,
+					    unsigned long end)
+{
+	iommu_notifier_invalidate_range(mn, mm, start, end);
+	return 0;
+}
+
+static void iommu_notifier_change_pte(struct mmu_notifier *mn, struct mm_struct *mm,
+				      unsigned long address, pte_t pte)
+{
+	iommu_notifier_invalidate_range(mn, mm, address, address + PAGE_SIZE);
+}
+
+static struct mmu_notifier_ops iommu_process_mmu_notfier = {
+	.release		= iommu_notifier_release,
+	.clear_flush_young	= iommu_notifier_clear_flush_young,
+	.change_pte		= iommu_notifier_change_pte,
+	.invalidate_range	= iommu_notifier_invalidate_range,
+};
+
 /**
  * iommu_set_process_exit_handler() - set a callback for stopping the use of
  * PASID in a device.
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index e9528fcacab1..42b818437fa1 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/of.h>
+#include <linux/mmu_notifier.h>
 
 #define IOMMU_READ	(1 << 0)
 #define IOMMU_WRITE	(1 << 1)
@@ -111,9 +112,13 @@ struct iommu_process {
 	int			pasid;
 	struct list_head	domains;
 	struct kref		kref;
+	struct mmu_notifier	notifier;
+	struct mm_struct	*mm;
 
 	/* Release callback for this process */
 	void (*release)(struct iommu_process *process);
+	/* For postponed release */
+	struct rcu_head		rcu;
 };
 
 enum iommu_cap {
@@ -189,6 +194,9 @@ struct iommu_resv_region {
  * @process_attach: attach iommu process to a domain
  * @process_detach: detach iommu process from a domain. Remove PASID entry and
  *                  flush associated TLB entries.
+ * @process_invalidate: Invalidate a range of mappings for a process.
+ * @process_exit: A process is exiting. Stop using the PASID, 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
@@ -228,6 +236,10 @@ struct iommu_ops {
 			      struct iommu_process *process, bool first);
 	void (*process_detach)(struct iommu_domain *domain, struct device *dev,
 			       struct iommu_process *process, bool last);
+	void (*process_invalidate)(struct iommu_domain *domain,
+				   struct iommu_process *process,
+				   unsigned long iova, size_t size);
+	void (*process_exit)(struct iommu_domain *domain, struct iommu_process *process);
 	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

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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 04/36] iommu/process: Track process changes with an mmu_notifier
Date: Fri,  6 Oct 2017 14:31:31 +0100	[thread overview]
Message-ID: <20171006133203.22803-5-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20171006133203.22803-1-jean-philippe.brucker@arm.com>

When creating an iommu_process structure, register a notifier to be
informed of changes to the virtual address space and to know when the
process exits.

Two new operations are added to the IOMMU driver:

* process_invalidate when a range of addresses is unmapped, to let the
  IOMMU driver send TLB invalidations.

* process_exit when the mm is released. It's a bit more involved in this
  case, as the IOMMU driver has to tell all devices drivers to stop using
  this PASID, then clear the PASID table and invalidate TLBs.

Adding the notifier in the mix complicates process release. In one case
device drivers free the process explicitly by calling unbind (or detaching
the device). In the other case the process could crash before unbind, in
which case the release notifier has to do all the work.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 drivers/iommu/iommu-process.c | 165 ++++++++++++++++++++++++++++++++++++++++--
 include/linux/iommu.h         |  12 +++
 2 files changed, 170 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu-process.c b/drivers/iommu/iommu-process.c
index 8f4c98632d58..1ef3f55b962b 100644
--- a/drivers/iommu/iommu-process.c
+++ b/drivers/iommu/iommu-process.c
@@ -21,9 +21,14 @@
 
 #include <linux/idr.h>
 #include <linux/iommu.h>
+#include <linux/mmu_notifier.h>
 #include <linux/slab.h>
+#include <linux/sched/mm.h>
 #include <linux/spinlock.h>
 
+/* FIXME: stub for the fault queue. Remove later. */
+#define iommu_fault_queue_flush(...)
+
 /* Link between a domain and a process */
 struct iommu_context {
 	struct iommu_process	*process;
@@ -50,6 +55,8 @@ static DEFINE_IDR(iommu_process_idr);
  */
 static DEFINE_SPINLOCK(iommu_process_lock);
 
+static struct mmu_notifier_ops iommu_process_mmu_notfier;
+
 /*
  * Allocate a iommu_process structure for the given task.
  *
@@ -74,15 +81,21 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 		return ERR_PTR(-ENOMEM);
 
 	process->pid		= get_task_pid(task, PIDTYPE_PID);
+	process->mm		= get_task_mm(task);
+	process->notifier.ops	= &iommu_process_mmu_notfier;
 	process->release	= domain->ops->process_free;
 	INIT_LIST_HEAD(&process->domains);
-	kref_init(&process->kref);
 
 	if (!process->pid) {
 		err = -EINVAL;
 		goto err_free_process;
 	}
 
+	if (!process->mm) {
+		err = -EINVAL;
+		goto err_put_pid;
+	}
+
 	idr_preload(GFP_KERNEL);
 	spin_lock(&iommu_process_lock);
 	pasid = idr_alloc_cyclic(&iommu_process_idr, process, domain->min_pasid,
@@ -93,11 +106,44 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 
 	if (pasid < 0) {
 		err = pasid;
-		goto err_put_pid;
+		goto err_put_mm;
 	}
 
+	err = mmu_notifier_register(&process->notifier, process->mm);
+	if (err)
+		goto err_free_pasid;
+
+	/*
+	 * Now that the MMU notifier is valid, we can allow users to grab this
+	 * process by setting a valid refcount. Before that it was accessible in
+	 * the IDR but invalid.
+	 *
+	 * Users of the process structure obtain it with inc_not_zero, which
+	 * provides a control dependency to ensure that they don't modify the
+	 * structure if they didn't acquire the ref. So I think we need a write
+	 * barrier here to pair with that control dependency (XXX probably
+	 * nonsense.)
+	 */
+	smp_wmb();
+	kref_init(&process->kref);
+
+	/* A mm_count reference is kept by the notifier */
+	mmput(process->mm);
+
 	return process;
 
+err_free_pasid:
+	/*
+	 * Even if the process is accessible from the IDR at this point, kref is
+	 * 0 so no user could get a reference to it. Free it manually.
+	 */
+	spin_lock(&iommu_process_lock);
+	idr_remove(&iommu_process_idr, process->pasid);
+	spin_unlock(&iommu_process_lock);
+
+err_put_mm:
+	mmput(process->mm);
+
 err_put_pid:
 	put_pid(process->pid);
 
@@ -107,21 +153,46 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 	return ERR_PTR(err);
 }
 
-static void iommu_process_release(struct kref *kref)
+static void iommu_process_free(struct rcu_head *rcu)
 {
 	struct iommu_process *process;
 	void (*release)(struct iommu_process *);
 
+	process = container_of(rcu, struct iommu_process, rcu);
+	release = process->release;
+
+	release(process);
+}
+
+static void iommu_process_release(struct kref *kref)
+{
+	struct iommu_process *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);
+
+	/*
+	 * If we're being released from process exit, the notifier callback
+	 * ->release has already been called. Otherwise we don't need to go
+	 * through there, the process isn't attached to anything anymore. Hence
+	 * no_release.
+	 */
+	mmu_notifier_unregister_no_release(&process->notifier, process->mm);
+
+	/*
+	 * We can't free the structure here, because ->release might be
+	 * attempting to grab it concurrently. And in the other case, if the
+	 * structure is being released from within ->release, then
+	 * __mmu_notifier_release expects to still have a valid mn when
+	 * returning. So free the structure when it's safe, after the RCU grace
+	 * period elapsed.
+	 */
+	mmu_notifier_call_srcu(&process->rcu, iommu_process_free);
 }
 
 /*
@@ -187,7 +258,8 @@ static int iommu_process_attach(struct iommu_domain *domain, struct device *dev,
 	int pasid = process->pasid;
 	struct iommu_context *context;
 
-	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach))
+	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach ||
+		    !domain->ops->process_exit || !domain->ops->process_invalidate))
 		return -ENODEV;
 
 	if (pasid > domain->max_pasid || pasid < domain->min_pasid)
@@ -259,6 +331,85 @@ static void iommu_process_detach_locked(struct iommu_context *context,
 		iommu_context_free(context);
 }
 
+/*
+ * Called when the process exits. Might race with unbind or any other function
+ * dropping the last reference to the process. As the mmu notifier doesn't hold
+ * any reference to the process when calling ->release, try to take a reference.
+ */
+static void iommu_notifier_release(struct mmu_notifier *mn, struct mm_struct *mm)
+{
+	struct iommu_context *context, *next;
+	struct iommu_process *process = container_of(mn, struct iommu_process, notifier);
+
+	/*
+	 * If the process is exiting then domains are still attached to the
+	 * process. A few things need to be done before it is safe to release
+	 *
+	 * 1) Tell the IOMMU driver to stop using this PASID (and forward the
+	 *    message to attached device drivers. It can then clear the PASID
+	 *    table and invalidate relevant TLBs.
+	 *
+	 * 2) Drop all references to this process, by freeing the contexts.
+	 */
+	spin_lock(&iommu_process_lock);
+	if (!iommu_process_get_locked(process)) {
+		/* Someone's already taking care of it. */
+		spin_unlock(&iommu_process_lock);
+		return;
+	}
+
+	list_for_each_entry_safe(context, next, &process->domains, process_head) {
+		context->domain->ops->process_exit(context->domain, process);
+		iommu_context_free(context);
+	}
+	spin_unlock(&iommu_process_lock);
+
+	iommu_fault_queue_flush(NULL);
+
+	/*
+	 * We're now reasonably certain that no more fault is being handled for
+	 * this process, since we just flushed them all out of the fault queue.
+	 * Release the last reference to free the process.
+	 */
+	iommu_process_put(process);
+}
+
+static void iommu_notifier_invalidate_range(struct mmu_notifier *mn, struct mm_struct *mm,
+					    unsigned long start, unsigned long end)
+{
+	struct iommu_context *context;
+	struct iommu_process *process = container_of(mn, struct iommu_process, notifier);
+
+	spin_lock(&iommu_process_lock);
+	list_for_each_entry(context, &process->domains, process_head) {
+		context->domain->ops->process_invalidate(context->domain,
+						 process, start, end - start);
+	}
+	spin_unlock(&iommu_process_lock);
+}
+
+static int iommu_notifier_clear_flush_young(struct mmu_notifier *mn,
+					    struct mm_struct *mm,
+					    unsigned long start,
+					    unsigned long end)
+{
+	iommu_notifier_invalidate_range(mn, mm, start, end);
+	return 0;
+}
+
+static void iommu_notifier_change_pte(struct mmu_notifier *mn, struct mm_struct *mm,
+				      unsigned long address, pte_t pte)
+{
+	iommu_notifier_invalidate_range(mn, mm, address, address + PAGE_SIZE);
+}
+
+static struct mmu_notifier_ops iommu_process_mmu_notfier = {
+	.release		= iommu_notifier_release,
+	.clear_flush_young	= iommu_notifier_clear_flush_young,
+	.change_pte		= iommu_notifier_change_pte,
+	.invalidate_range	= iommu_notifier_invalidate_range,
+};
+
 /**
  * iommu_set_process_exit_handler() - set a callback for stopping the use of
  * PASID in a device.
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index e9528fcacab1..42b818437fa1 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/of.h>
+#include <linux/mmu_notifier.h>
 
 #define IOMMU_READ	(1 << 0)
 #define IOMMU_WRITE	(1 << 1)
@@ -111,9 +112,13 @@ struct iommu_process {
 	int			pasid;
 	struct list_head	domains;
 	struct kref		kref;
+	struct mmu_notifier	notifier;
+	struct mm_struct	*mm;
 
 	/* Release callback for this process */
 	void (*release)(struct iommu_process *process);
+	/* For postponed release */
+	struct rcu_head		rcu;
 };
 
 enum iommu_cap {
@@ -189,6 +194,9 @@ struct iommu_resv_region {
  * @process_attach: attach iommu process to a domain
  * @process_detach: detach iommu process from a domain. Remove PASID entry and
  *                  flush associated TLB entries.
+ * @process_invalidate: Invalidate a range of mappings for a process.
+ * @process_exit: A process is exiting. Stop using the PASID, 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
@@ -228,6 +236,10 @@ struct iommu_ops {
 			      struct iommu_process *process, bool first);
 	void (*process_detach)(struct iommu_domain *domain, struct device *dev,
 			       struct iommu_process *process, bool last);
+	void (*process_invalidate)(struct iommu_domain *domain,
+				   struct iommu_process *process,
+				   unsigned long iova, size_t size);
+	void (*process_exit)(struct iommu_domain *domain, struct iommu_process *process);
 	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 04/36] iommu/process: Track process changes with an mmu_notifier
Date: Fri,  6 Oct 2017 14:31:31 +0100	[thread overview]
Message-ID: <20171006133203.22803-5-jean-philippe.brucker@arm.com> (raw)
In-Reply-To: <20171006133203.22803-1-jean-philippe.brucker@arm.com>

When creating an iommu_process structure, register a notifier to be
informed of changes to the virtual address space and to know when the
process exits.

Two new operations are added to the IOMMU driver:

* process_invalidate when a range of addresses is unmapped, to let the
  IOMMU driver send TLB invalidations.

* process_exit when the mm is released. It's a bit more involved in this
  case, as the IOMMU driver has to tell all devices drivers to stop using
  this PASID, then clear the PASID table and invalidate TLBs.

Adding the notifier in the mix complicates process release. In one case
device drivers free the process explicitly by calling unbind (or detaching
the device). In the other case the process could crash before unbind, in
which case the release notifier has to do all the work.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 drivers/iommu/iommu-process.c | 165 ++++++++++++++++++++++++++++++++++++++++--
 include/linux/iommu.h         |  12 +++
 2 files changed, 170 insertions(+), 7 deletions(-)

diff --git a/drivers/iommu/iommu-process.c b/drivers/iommu/iommu-process.c
index 8f4c98632d58..1ef3f55b962b 100644
--- a/drivers/iommu/iommu-process.c
+++ b/drivers/iommu/iommu-process.c
@@ -21,9 +21,14 @@
 
 #include <linux/idr.h>
 #include <linux/iommu.h>
+#include <linux/mmu_notifier.h>
 #include <linux/slab.h>
+#include <linux/sched/mm.h>
 #include <linux/spinlock.h>
 
+/* FIXME: stub for the fault queue. Remove later. */
+#define iommu_fault_queue_flush(...)
+
 /* Link between a domain and a process */
 struct iommu_context {
 	struct iommu_process	*process;
@@ -50,6 +55,8 @@ static DEFINE_IDR(iommu_process_idr);
  */
 static DEFINE_SPINLOCK(iommu_process_lock);
 
+static struct mmu_notifier_ops iommu_process_mmu_notfier;
+
 /*
  * Allocate a iommu_process structure for the given task.
  *
@@ -74,15 +81,21 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 		return ERR_PTR(-ENOMEM);
 
 	process->pid		= get_task_pid(task, PIDTYPE_PID);
+	process->mm		= get_task_mm(task);
+	process->notifier.ops	= &iommu_process_mmu_notfier;
 	process->release	= domain->ops->process_free;
 	INIT_LIST_HEAD(&process->domains);
-	kref_init(&process->kref);
 
 	if (!process->pid) {
 		err = -EINVAL;
 		goto err_free_process;
 	}
 
+	if (!process->mm) {
+		err = -EINVAL;
+		goto err_put_pid;
+	}
+
 	idr_preload(GFP_KERNEL);
 	spin_lock(&iommu_process_lock);
 	pasid = idr_alloc_cyclic(&iommu_process_idr, process, domain->min_pasid,
@@ -93,11 +106,44 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 
 	if (pasid < 0) {
 		err = pasid;
-		goto err_put_pid;
+		goto err_put_mm;
 	}
 
+	err = mmu_notifier_register(&process->notifier, process->mm);
+	if (err)
+		goto err_free_pasid;
+
+	/*
+	 * Now that the MMU notifier is valid, we can allow users to grab this
+	 * process by setting a valid refcount. Before that it was accessible in
+	 * the IDR but invalid.
+	 *
+	 * Users of the process structure obtain it with inc_not_zero, which
+	 * provides a control dependency to ensure that they don't modify the
+	 * structure if they didn't acquire the ref. So I think we need a write
+	 * barrier here to pair with that control dependency (XXX probably
+	 * nonsense.)
+	 */
+	smp_wmb();
+	kref_init(&process->kref);
+
+	/* A mm_count reference is kept by the notifier */
+	mmput(process->mm);
+
 	return process;
 
+err_free_pasid:
+	/*
+	 * Even if the process is accessible from the IDR at this point, kref is
+	 * 0 so no user could get a reference to it. Free it manually.
+	 */
+	spin_lock(&iommu_process_lock);
+	idr_remove(&iommu_process_idr, process->pasid);
+	spin_unlock(&iommu_process_lock);
+
+err_put_mm:
+	mmput(process->mm);
+
 err_put_pid:
 	put_pid(process->pid);
 
@@ -107,21 +153,46 @@ iommu_process_alloc(struct iommu_domain *domain, struct task_struct *task)
 	return ERR_PTR(err);
 }
 
-static void iommu_process_release(struct kref *kref)
+static void iommu_process_free(struct rcu_head *rcu)
 {
 	struct iommu_process *process;
 	void (*release)(struct iommu_process *);
 
+	process = container_of(rcu, struct iommu_process, rcu);
+	release = process->release;
+
+	release(process);
+}
+
+static void iommu_process_release(struct kref *kref)
+{
+	struct iommu_process *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);
+
+	/*
+	 * If we're being released from process exit, the notifier callback
+	 * ->release has already been called. Otherwise we don't need to go
+	 * through there, the process isn't attached to anything anymore. Hence
+	 * no_release.
+	 */
+	mmu_notifier_unregister_no_release(&process->notifier, process->mm);
+
+	/*
+	 * We can't free the structure here, because ->release might be
+	 * attempting to grab it concurrently. And in the other case, if the
+	 * structure is being released from within ->release, then
+	 * __mmu_notifier_release expects to still have a valid mn when
+	 * returning. So free the structure when it's safe, after the RCU grace
+	 * period elapsed.
+	 */
+	mmu_notifier_call_srcu(&process->rcu, iommu_process_free);
 }
 
 /*
@@ -187,7 +258,8 @@ static int iommu_process_attach(struct iommu_domain *domain, struct device *dev,
 	int pasid = process->pasid;
 	struct iommu_context *context;
 
-	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach))
+	if (WARN_ON(!domain->ops->process_attach || !domain->ops->process_detach ||
+		    !domain->ops->process_exit || !domain->ops->process_invalidate))
 		return -ENODEV;
 
 	if (pasid > domain->max_pasid || pasid < domain->min_pasid)
@@ -259,6 +331,85 @@ static void iommu_process_detach_locked(struct iommu_context *context,
 		iommu_context_free(context);
 }
 
+/*
+ * Called when the process exits. Might race with unbind or any other function
+ * dropping the last reference to the process. As the mmu notifier doesn't hold
+ * any reference to the process when calling ->release, try to take a reference.
+ */
+static void iommu_notifier_release(struct mmu_notifier *mn, struct mm_struct *mm)
+{
+	struct iommu_context *context, *next;
+	struct iommu_process *process = container_of(mn, struct iommu_process, notifier);
+
+	/*
+	 * If the process is exiting then domains are still attached to the
+	 * process. A few things need to be done before it is safe to release
+	 *
+	 * 1) Tell the IOMMU driver to stop using this PASID (and forward the
+	 *    message to attached device drivers. It can then clear the PASID
+	 *    table and invalidate relevant TLBs.
+	 *
+	 * 2) Drop all references to this process, by freeing the contexts.
+	 */
+	spin_lock(&iommu_process_lock);
+	if (!iommu_process_get_locked(process)) {
+		/* Someone's already taking care of it. */
+		spin_unlock(&iommu_process_lock);
+		return;
+	}
+
+	list_for_each_entry_safe(context, next, &process->domains, process_head) {
+		context->domain->ops->process_exit(context->domain, process);
+		iommu_context_free(context);
+	}
+	spin_unlock(&iommu_process_lock);
+
+	iommu_fault_queue_flush(NULL);
+
+	/*
+	 * We're now reasonably certain that no more fault is being handled for
+	 * this process, since we just flushed them all out of the fault queue.
+	 * Release the last reference to free the process.
+	 */
+	iommu_process_put(process);
+}
+
+static void iommu_notifier_invalidate_range(struct mmu_notifier *mn, struct mm_struct *mm,
+					    unsigned long start, unsigned long end)
+{
+	struct iommu_context *context;
+	struct iommu_process *process = container_of(mn, struct iommu_process, notifier);
+
+	spin_lock(&iommu_process_lock);
+	list_for_each_entry(context, &process->domains, process_head) {
+		context->domain->ops->process_invalidate(context->domain,
+						 process, start, end - start);
+	}
+	spin_unlock(&iommu_process_lock);
+}
+
+static int iommu_notifier_clear_flush_young(struct mmu_notifier *mn,
+					    struct mm_struct *mm,
+					    unsigned long start,
+					    unsigned long end)
+{
+	iommu_notifier_invalidate_range(mn, mm, start, end);
+	return 0;
+}
+
+static void iommu_notifier_change_pte(struct mmu_notifier *mn, struct mm_struct *mm,
+				      unsigned long address, pte_t pte)
+{
+	iommu_notifier_invalidate_range(mn, mm, address, address + PAGE_SIZE);
+}
+
+static struct mmu_notifier_ops iommu_process_mmu_notfier = {
+	.release		= iommu_notifier_release,
+	.clear_flush_young	= iommu_notifier_clear_flush_young,
+	.change_pte		= iommu_notifier_change_pte,
+	.invalidate_range	= iommu_notifier_invalidate_range,
+};
+
 /**
  * iommu_set_process_exit_handler() - set a callback for stopping the use of
  * PASID in a device.
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index e9528fcacab1..42b818437fa1 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -25,6 +25,7 @@
 #include <linux/errno.h>
 #include <linux/err.h>
 #include <linux/of.h>
+#include <linux/mmu_notifier.h>
 
 #define IOMMU_READ	(1 << 0)
 #define IOMMU_WRITE	(1 << 1)
@@ -111,9 +112,13 @@ struct iommu_process {
 	int			pasid;
 	struct list_head	domains;
 	struct kref		kref;
+	struct mmu_notifier	notifier;
+	struct mm_struct	*mm;
 
 	/* Release callback for this process */
 	void (*release)(struct iommu_process *process);
+	/* For postponed release */
+	struct rcu_head		rcu;
 };
 
 enum iommu_cap {
@@ -189,6 +194,9 @@ struct iommu_resv_region {
  * @process_attach: attach iommu process to a domain
  * @process_detach: detach iommu process from a domain. Remove PASID entry and
  *                  flush associated TLB entries.
+ * @process_invalidate: Invalidate a range of mappings for a process.
+ * @process_exit: A process is exiting. Stop using the PASID, 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
@@ -228,6 +236,10 @@ struct iommu_ops {
 			      struct iommu_process *process, bool first);
 	void (*process_detach)(struct iommu_domain *domain, struct device *dev,
 			       struct iommu_process *process, bool last);
+	void (*process_invalidate)(struct iommu_domain *domain,
+				   struct iommu_process *process,
+				   unsigned long iova, size_t size);
+	void (*process_exit)(struct iommu_domain *domain, struct iommu_process *process);
 	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   ` [RFCv2 PATCH 01/36] iommu: Keep track of processes and PASIDs Jean-Philippe Brucker
2017-10-06 13:31     ` 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   ` Jean-Philippe Brucker [this message]
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   ` [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-5-jean-philippe.brucker@arm.com \
    --to=jean-philippe.brucker-5wv7dgnigg8@public.gmane.org \
    --cc=alex.williamson-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
    --cc=ashok.raj-ral2JQCrhuEAvxtiuMwx3w@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=hanjun.guo-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
    --cc=jacob.jun.pan-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
    --cc=joro-zLv9SwRftAIdnm+yROfE0A@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=liubo95-hv44wF8Li93QT0dZR+AlfA@public.gmane.org \
    --cc=lorenzo.pieralisi-5wv7dgnIgG8@public.gmane.org \
    --cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
    --cc=nwatters-sgV2jX0FEOL9JmXXK+q4OQ@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=robdclark-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=robin.murphy-5wv7dgnIgG8@public.gmane.org \
    --cc=sudeep.holla-5wv7dgnIgG8@public.gmane.org \
    --cc=thunder.leizhen-hv44wF8Li93QT0dZR+AlfA@public.gmane.org \
    --cc=tn-nYOzD4b6Jr9Wk0Htik3J/w@public.gmane.org \
    --cc=will.deacon-5wv7dgnIgG8@public.gmane.org \
    --cc=xieyisheng1-hv44wF8Li93QT0dZR+AlfA@public.gmane.org \
    --cc=yi.l.liu-ral2JQCrhuEAvxtiuMwx3w@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.