From: David Woodhouse <dwmw2@infradead.org>
To: iommu@lists.linux-foundation.org,
intel-gfx@lists.freedesktop.org, jesse.barnes@intel.com
Subject: [PATCH 2/7] iommu/vt-d: Add initial support for PASID tables
Date: Fri, 09 Oct 2015 00:52:35 +0100 [thread overview]
Message-ID: <1444348355.92154.30.camel@infradead.org> (raw)
In-Reply-To: <1444348223.92154.22.camel@infradead.org>
[-- Attachment #1.1: Type: text/plain, Size: 6591 bytes --]
Add CONFIG_INTEL_IOMMU_SVM, and allocate PASID tables on supported hardware.
Signed-off-by: David Woodhouse <David.Woodhouse@intel.com>
---
drivers/iommu/Kconfig | 8 ++++++
drivers/iommu/Makefile | 1 +
drivers/iommu/intel-iommu.c | 14 ++++++++++
drivers/iommu/intel-svm.c | 65 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/intel-iommu.h | 15 +++++++++++
5 files changed, 103 insertions(+)
create mode 100644 drivers/iommu/intel-svm.c
diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
index d9da766..e3b2c2e 100644
--- a/drivers/iommu/Kconfig
+++ b/drivers/iommu/Kconfig
@@ -135,6 +135,14 @@ config INTEL_IOMMU
and include PCI device scope covered by these DMA
remapping devices.
+config INTEL_IOMMU_SVM
+ bool "Support for Shared Virtual Memory with Intel IOMMU"
+ depends on INTEL_IOMMU && X86
+ help
+ Shared Virtual Memory (SVM) provides a facility for devices
+ to access DMA resources through process address space by
+ means of a Process Address Space ID (PASID).
+
config INTEL_IOMMU_DEFAULT_ON
def_bool y
prompt "Enable Intel DMA Remapping Devices by default"
diff --git a/drivers/iommu/Makefile b/drivers/iommu/Makefile
index c6dcc51..dc6f511 100644
--- a/drivers/iommu/Makefile
+++ b/drivers/iommu/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
obj-$(CONFIG_DMAR_TABLE) += dmar.o
obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o
+obj-$(CONFIG_INTEL_IOMMU_SVM) += intel-svm.o
obj-$(CONFIG_IPMMU_VMSA) += ipmmu-vmsa.o
obj-$(CONFIG_IRQ_REMAP) += intel_irq_remapping.o irq_remapping.o
obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index a1514a5..1f89064 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -1680,6 +1680,11 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
/* free context mapping */
free_context_table(iommu);
+
+#ifdef CONFIG_INTEL_IOMMU_SVM
+ if (pasid_enabled(iommu))
+ intel_svm_free_pasid_tables(iommu);
+#endif
}
static struct dmar_domain *alloc_domain(int flags)
@@ -3103,6 +3108,10 @@ static int __init init_dmars(void)
if (!ecap_pass_through(iommu->ecap))
hw_pass_through = 0;
+#ifdef CONFIG_INTEL_IOMMU_SVM
+ if (pasid_enabled(iommu))
+ intel_svm_alloc_pasid_tables(iommu);
+#endif
}
if (iommu_pass_through)
@@ -4118,6 +4127,11 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
if (ret)
goto out;
+#ifdef CONFIG_INTEL_IOMMU_SVM
+ if (pasid_enabled(iommu))
+ intel_svm_alloc_pasid_tables(iommu);
+#endif
+
if (dmaru->ignored) {
/*
* we always have to disable PMRs or DMA may fail on this device
diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
new file mode 100644
index 0000000..9b40ad6
--- /dev/null
+++ b/drivers/iommu/intel-svm.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright © 2015 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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.
+ *
+ * Authors: David Woodhouse <dwmw2@infradead.org>
+ */
+
+#include <linux/intel-iommu.h>
+
+int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
+{
+ struct page *pages;
+ int order;
+
+ order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+ if (order < 0)
+ order = 0;
+
+ pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+ if (!pages) {
+ pr_warn("IOMMU: %s: Failed to allocate PASID table\n",
+ iommu->name);
+ return -ENOMEM;
+ }
+ iommu->pasid_table = page_address(pages);
+ pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+ if (!pages) {
+ pr_warn("IOMMU: %s: Failed to allocate PASID state table\n",
+ iommu->name);
+ free_pages((unsigned long)iommu->pasid_table, order);
+ iommu->pasid_table = NULL;
+ return -ENOMEM;
+ }
+ iommu->pasid_state_table = page_address(pages);
+ pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order);
+
+ return 0;
+}
+
+int intel_svm_free_pasid_tables(struct intel_iommu *iommu)
+{
+ int order;
+
+ order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+ if (order < 0)
+ order = 0;
+
+ if (iommu->pasid_table) {
+ free_pages((unsigned long)iommu->pasid_table, order);
+ iommu->pasid_table = NULL;
+ }
+ if (iommu->pasid_state_table) {
+ free_pages((unsigned long)iommu->pasid_state_table, order);
+ iommu->pasid_state_table = NULL;
+ }
+ return 0;
+}
diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
index c03316d..47844cb 100644
--- a/include/linux/intel-iommu.h
+++ b/include/linux/intel-iommu.h
@@ -327,6 +327,9 @@ enum {
#define VTD_FLAG_TRANS_PRE_ENABLED (1 << 0)
#define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1)
+struct pasid_entry;
+struct pasid_state_entry;
+
struct intel_iommu {
void __iomem *reg; /* Pointer to hardware regs, virtual addr */
u64 reg_phys; /* physical address of hw register set */
@@ -350,6 +353,15 @@ struct intel_iommu {
struct iommu_flush flush;
#endif
+#ifdef CONFIG_INTEL_IOMMU_SVM
+ /* These are large and need to be contiguous, so we allocate just
+ * one for now. We'll maybe want to rethink that if we truly give
+ * devices away to userspace processes (e.g. for DPDK) and don't
+ * want to trust that userspace will use *only* the PASID it was
+ * told to. But while it's all driver-arbitrated, we're fine. */
+ struct pasid_entry *pasid_table;
+ struct pasid_state_entry *pasid_state_table;
+#endif
struct q_inval *qi; /* Queued invalidation info */
u32 *iommu_state; /* Store iommu states between suspend and resume.*/
@@ -389,6 +401,9 @@ extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
extern int dmar_ir_support(void);
+extern int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu);
+extern int intel_svm_free_pasid_tables(struct intel_iommu *iommu);
+
extern const struct attribute_group *intel_iommu_groups[];
#endif
--
2.4.3
--
David Woodhouse Open Source Technology Centre
David.Woodhouse@intel.com Intel Corporation
[-- Attachment #1.2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 5691 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx
next prev parent reply other threads:[~2015-10-08 23:52 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-08 23:50 [PATCH 0/7] Enable SVM for Intel VT-d David Woodhouse
2015-10-08 23:52 ` David Woodhouse [this message]
2015-10-08 23:52 ` [PATCH 3/7] iommu/vt-d: Add intel_svm_{un, }bind_mm() functions David Woodhouse
2015-10-08 23:53 ` [PATCH 4/7] iommu/vt-d: Generalise DMAR MSI setup to allow for page request events David Woodhouse
[not found] ` <1444348223.92154.22.camel-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2015-10-08 23:52 ` [PATCH 1/7] iommu/vt-d: Introduce intel_iommu=pasid28, and pasid_enabled() macro David Woodhouse
2015-10-08 23:53 ` [PATCH 5/7] iommu/vt-d: Assume BIOS lies about ATSR for integrated gfx David Woodhouse
2015-10-08 23:53 ` [PATCH 6/7] iommu/vt-d: Enable page request interrupt David Woodhouse
2015-10-08 23:54 ` [PATCH 7/7] iommu/vt-d: Implement page request handling David Woodhouse
2015-10-10 16:54 ` Chris Wilson
2015-10-10 13:17 ` [PATCH 0/7] Enable SVM for Intel VT-d David Woodhouse
[not found] ` <1444483075.92154.98.camel-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>
2015-10-11 13:48 ` Oded Gabbay
2015-10-13 12:06 ` Daniel Vetter
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=1444348355.92154.30.camel@infradead.org \
--to=dwmw2@infradead.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=iommu@lists.linux-foundation.org \
--cc=jesse.barnes@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