public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jacob Pan <jacob.jun.pan@linux.intel.com>
To: iommu@lists.linux-foundation.org,
	LKML <linux-kernel@vger.kernel.org>,
	Joerg Roedel <joro@8bytes.org>,
	David Woodhouse <dwmw2@infradead.org>,
	Eric Auger <eric.auger@redhat.com>,
	Alex Williamson <alex.williamson@redhat.com>,
	Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
Cc: "Yi Liu" <yi.l.liu@intel.com>,
	"Tian, Kevin" <kevin.tian@intel.com>,
	Raj Ashok <ashok.raj@intel.com>,
	"Christoph Hellwig" <hch@infradead.org>,
	"Lu Baolu" <baolu.lu@linux.intel.com>,
	Andriy Shevchenko <andriy.shevchenko@linux.intel.com>
Subject: [PATCH v2 06/19] drivers core: Add I/O ASID allocator
Date: Tue, 23 Apr 2019 16:31:06 -0700	[thread overview]
Message-ID: <1556062279-64135-7-git-send-email-jacob.jun.pan@linux.intel.com> (raw)
In-Reply-To: <1556062279-64135-1-git-send-email-jacob.jun.pan@linux.intel.com>

From: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>

Some devices might support multiple DMA address spaces, in particular
those that have the PCI PASID feature. PASID (Process Address Space ID)
allows to share process address spaces with devices (SVA), partition a
device into VM-assignable entities (VFIO mdev) or simply provide
multiple DMA address space to kernel drivers. Add a global PASID
allocator usable by different drivers at the same time. Name it I/O ASID
to avoid confusion with ASIDs allocated by arch code, which are usually
a separate ID space.

The IOASID space is global. Each device can have its own PASID space,
but by convention the IOMMU ended up having a global PASID space, so
that with SVA, each mm_struct is associated to a single PASID.

The allocator doesn't really belong in drivers/iommu because some
drivers would like to allocate PASIDs for devices that aren't managed by
an IOMMU, using the same ID space as IOMMU. It doesn't really belong in
drivers/pci either since platform device also support PASID. Add the
allocator in drivers/base.

Signed-off-by: Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
---
 drivers/base/Kconfig   |   6 +++
 drivers/base/Makefile  |   1 +
 drivers/base/ioasid.c  | 106 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/ioasid.h |  40 +++++++++++++++++++
 4 files changed, 153 insertions(+)
 create mode 100644 drivers/base/ioasid.c
 create mode 100644 include/linux/ioasid.h

diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 059700e..47c1348 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -182,6 +182,12 @@ config DMA_SHARED_BUFFER
 	  APIs extension; the file's descriptor can then be passed on to other
 	  driver.
 
+config IOASID
+	bool
+	help
+	  Enable the I/O Address Space ID allocator. A single ID space shared
+	  between different users.
+
 config DMA_FENCE_TRACE
 	bool "Enable verbose DMA_FENCE_TRACE messages"
 	depends on DMA_SHARED_BUFFER
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index 1574520..aafa2ac 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o
 obj-$(CONFIG_DEV_COREDUMP) += devcoredump.o
 obj-$(CONFIG_GENERIC_MSI_IRQ_DOMAIN) += platform-msi.o
 obj-$(CONFIG_GENERIC_ARCH_TOPOLOGY) += arch_topology.o
+obj-$(CONFIG_IOASID) += ioasid.o
 
 obj-y			+= test/
 
diff --git a/drivers/base/ioasid.c b/drivers/base/ioasid.c
new file mode 100644
index 0000000..cf122b2
--- /dev/null
+++ b/drivers/base/ioasid.c
@@ -0,0 +1,106 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * I/O Address Space ID allocator. There is one global IOASID space, split into
+ * subsets. Users create a subset with DECLARE_IOASID_SET, then allocate and
+ * free IOASIDs with ioasid_alloc and ioasid_free.
+ */
+#include <linux/idr.h>
+#include <linux/ioasid.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+struct ioasid_data {
+	ioasid_t id;
+	struct ioasid_set *set;
+	void *private;
+	struct rcu_head rcu;
+};
+
+static DEFINE_IDR(ioasid_idr);
+
+/**
+ * ioasid_alloc - Allocate an IOASID
+ * @set: the IOASID set
+ * @min: the minimum ID (inclusive)
+ * @max: the maximum ID (exclusive)
+ * @private: data private to the caller
+ *
+ * Allocate an ID between @min and @max (or %0 and %INT_MAX). Return the
+ * allocated ID on success, or INVALID_IOASID on failure. The @private pointer
+ * is stored internally and can be retrieved with ioasid_find().
+ */
+ioasid_t ioasid_alloc(struct ioasid_set *set, ioasid_t min, ioasid_t max,
+		      void *private)
+{
+	int id = -1;
+	struct ioasid_data *data;
+
+	data = kzalloc(sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return INVALID_IOASID;
+
+	data->set = set;
+	data->private = private;
+
+	idr_preload(GFP_KERNEL);
+	idr_lock(&ioasid_idr);
+	data->id = id = idr_alloc(&ioasid_idr, data, min, max, GFP_ATOMIC);
+	idr_unlock(&ioasid_idr);
+	idr_preload_end();
+
+	if (id < 0) {
+		kfree(data);
+		return INVALID_IOASID;
+	}
+	return id;
+}
+EXPORT_SYMBOL_GPL(ioasid_alloc);
+
+/**
+ * ioasid_free - Free an IOASID
+ * @ioasid: the ID to remove
+ */
+void ioasid_free(ioasid_t ioasid)
+{
+	struct ioasid_data *ioasid_data;
+
+	idr_lock(&ioasid_idr);
+	ioasid_data = idr_remove(&ioasid_idr, ioasid);
+	idr_unlock(&ioasid_idr);
+
+	if (ioasid_data)
+		kfree_rcu(ioasid_data, rcu);
+}
+EXPORT_SYMBOL_GPL(ioasid_free);
+
+/**
+ * ioasid_find - Find IOASID data
+ * @set: the IOASID set
+ * @ioasid: the IOASID to find
+ * @getter: function to call on the found object
+ *
+ * The optional getter function allows to take a reference to the found object
+ * under the rcu lock. The function can also check if the object is still valid:
+ * if @getter returns false, then the object is invalid and NULL is returned.
+ *
+ * If the IOASID has been allocated for this set, return the private pointer
+ * passed to ioasid_alloc. Otherwise return NULL.
+ */
+void *ioasid_find(struct ioasid_set *set, ioasid_t ioasid,
+		  bool (*getter)(void *))
+{
+	void *priv = NULL;
+	struct ioasid_data *ioasid_data;
+
+	rcu_read_lock();
+	ioasid_data = idr_find(&ioasid_idr, ioasid);
+	if (ioasid_data && ioasid_data->set == set) {
+		priv = ioasid_data->private;
+		if (getter && !getter(priv))
+			priv = NULL;
+	}
+	rcu_read_unlock();
+
+	return priv;
+}
+EXPORT_SYMBOL_GPL(ioasid_find);
diff --git a/include/linux/ioasid.h b/include/linux/ioasid.h
new file mode 100644
index 0000000..6f3655a
--- /dev/null
+++ b/include/linux/ioasid.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_IOASID_H
+#define __LINUX_IOASID_H
+
+#define INVALID_IOASID ((ioasid_t)-1)
+typedef unsigned int ioasid_t;
+typedef int (*ioasid_iter_t)(ioasid_t ioasid, void *private, void *data);
+
+struct ioasid_set {
+	int dummy;
+};
+
+#define DECLARE_IOASID_SET(name) struct ioasid_set name = { 0 }
+
+#ifdef CONFIG_IOASID
+ioasid_t ioasid_alloc(struct ioasid_set *set, ioasid_t min, ioasid_t max,
+		      void *private);
+void ioasid_free(ioasid_t ioasid);
+
+void *ioasid_find(struct ioasid_set *set, ioasid_t ioasid,
+		  bool (*getter)(void *));
+
+#else /* !CONFIG_IOASID */
+static inline ioasid_t ioasid_alloc(struct ioasid_set *set, ioasid_t min,
+				    ioasid_t max, void *private)
+{
+	return INVALID_IOASID;
+}
+
+static inline void ioasid_free(ioasid_t ioasid)
+{
+}
+
+static inline void *ioasid_find(struct ioasid_set *set, ioasid_t ioasid,
+				bool (*getter)(void *))
+{
+	return NULL;
+}
+#endif /* CONFIG_IOASID */
+#endif /* __LINUX_IOASID_H */
-- 
2.7.4


  parent reply	other threads:[~2019-04-23 23:29 UTC|newest]

Thread overview: 74+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-04-23 23:31 [PATCH v2 00/19] Shared virtual address IOMMU and VT-d support Jacob Pan
2019-04-23 23:31 ` [PATCH v2 01/19] driver core: add per device iommu param Jacob Pan
2019-04-23 23:31 ` [PATCH v2 02/19] iommu: introduce device fault data Jacob Pan
2019-04-25 12:46   ` Jean-Philippe Brucker
2019-04-25 13:21     ` Auger Eric
2019-04-25 14:33       ` Jean-Philippe Brucker
2019-04-25 18:07         ` Jacob Pan
2019-04-23 23:31 ` [PATCH v2 03/19] iommu: introduce device fault report API Jacob Pan
2019-04-23 23:31 ` [PATCH v2 04/19] iommu: Introduce attach/detach_pasid_table API Jacob Pan
2019-04-23 23:31 ` [PATCH v2 05/19] iommu: Introduce cache_invalidate API Jacob Pan
2019-04-23 23:31 ` Jacob Pan [this message]
2019-04-24  6:19   ` [PATCH v2 06/19] drivers core: Add I/O ASID allocator Christoph Hellwig
2019-04-25 18:19     ` Jacob Pan
2019-04-26 11:47       ` Jean-Philippe Brucker
2019-04-26 12:21         ` Christoph Hellwig
2019-04-26 16:58           ` Jacob Pan
2019-04-25 10:17   ` Auger Eric
2019-04-25 10:41     ` Jean-Philippe Brucker
2019-04-30 20:24       ` Jacob Pan
2019-05-01 17:40         ` Jean-Philippe Brucker
2019-04-23 23:31 ` [PATCH v2 07/19] ioasid: Convert ioasid_idr to XArray Jacob Pan
2019-04-23 23:31 ` [PATCH v2 08/19] ioasid: Add custom IOASID allocator Jacob Pan
2019-04-25 10:03   ` Auger Eric
2019-04-25 21:29     ` Jacob Pan
2019-04-26  9:06       ` Auger Eric
2019-04-26 15:19         ` Jacob Pan
2019-05-06 17:59           ` Jacob Pan
2019-04-23 23:31 ` [PATCH v2 09/19] iommu/vt-d: Enlightened PASID allocation Jacob Pan
2019-04-24 17:27   ` Auger Eric
2019-04-25  7:12     ` Liu, Yi L
2019-04-25  7:40       ` Auger Eric
2019-04-25 23:01         ` Jacob Pan
2019-04-25 23:40     ` Jacob Pan
2019-04-26  7:24       ` Auger Eric
2019-04-26 15:05         ` Jacob Pan
2019-04-23 23:31 ` [PATCH v2 10/19] iommu/vt-d: Add custom allocator for IOASID Jacob Pan
2019-04-24 17:27   ` Auger Eric
2019-04-26 20:11     ` Jacob Pan
2019-04-23 23:31 ` [PATCH v2 11/19] iommu/vt-d: Replace Intel specific PASID allocator with IOASID Jacob Pan
2019-04-25 10:04   ` Auger Eric
     [not found]     ` <20190426140133.6d445315@jacob-builder>
2019-04-27  8:38       ` Auger Eric
2019-04-29 10:00         ` Jean-Philippe Brucker
2019-04-23 23:31 ` [PATCH v2 12/19] iommu/vt-d: Move domain helper to header Jacob Pan
2019-04-24 17:27   ` Auger Eric
2019-04-23 23:31 ` [PATCH v2 13/19] iommu/vt-d: Add nested translation support Jacob Pan
2019-04-26 15:42   ` Auger Eric
2019-04-26 21:57     ` Jacob Pan
2019-04-23 23:31 ` [PATCH v2 14/19] iommu: Add guest PASID bind function Jacob Pan
2019-04-26 15:53   ` Auger Eric
2019-04-26 22:11     ` Jacob Pan
2019-04-27  8:37       ` Auger Eric
2019-04-23 23:31 ` [PATCH v2 15/19] iommu/vt-d: Add bind guest PASID support Jacob Pan
2019-04-26 16:15   ` Auger Eric
2019-04-29 15:25     ` Jacob Pan
2019-04-30  7:05       ` Auger Eric
2019-04-30 17:49         ` Jacob Pan
2019-04-23 23:31 ` [PATCH v2 16/19] iommu/vtd: Clean up for SVM device list Jacob Pan
2019-04-26 16:19   ` Auger Eric
2019-04-23 23:31 ` [PATCH v2 17/19] iommu: Add max num of cache and granu types Jacob Pan
2019-04-26 16:22   ` Auger Eric
2019-04-29 16:17     ` Jacob Pan
2019-04-30  5:15       ` Auger Eric
2019-04-23 23:31 ` [PATCH v2 18/19] iommu/vt-d: Support flushing more translation cache types Jacob Pan
2019-04-27  9:04   ` Auger Eric
2019-04-29 21:29     ` Jacob Pan
2019-04-30  4:41       ` Auger Eric
2019-04-30 17:15         ` Jacob Pan
2019-04-30 17:41           ` Auger Eric
2019-04-23 23:31 ` [PATCH v2 19/19] iommu/vt-d: Add svm/sva invalidate function Jacob Pan
2019-04-26 17:23   ` Auger Eric
2019-04-29 22:41     ` Jacob Pan
2019-04-30  6:57       ` Auger Eric
2019-04-30 17:22         ` Jacob Pan
2019-04-30 17:36           ` Auger Eric

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=1556062279-64135-7-git-send-email-jacob.jun.pan@linux.intel.com \
    --to=jacob.jun.pan@linux.intel.com \
    --cc=alex.williamson@redhat.com \
    --cc=andriy.shevchenko@linux.intel.com \
    --cc=ashok.raj@intel.com \
    --cc=baolu.lu@linux.intel.com \
    --cc=dwmw2@infradead.org \
    --cc=eric.auger@redhat.com \
    --cc=hch@infradead.org \
    --cc=iommu@lists.linux-foundation.org \
    --cc=jean-philippe.brucker@arm.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=yi.l.liu@intel.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox