[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1585158931-1825-6-git-send-email-jacob.jun.pan@linux.intel.com>
Date: Wed, 25 Mar 2020 10:55:26 -0700
From: Jacob Pan <jacob.jun.pan@...ux.intel.com>
To: Joerg Roedel <joro@...tes.org>,
Alex Williamson <alex.williamson@...hat.com>,
"Lu Baolu" <baolu.lu@...ux.intel.com>,
iommu@...ts.linux-foundation.org,
LKML <linux-kernel@...r.kernel.org>,
David Woodhouse <dwmw2@...radead.org>,
Jean-Philippe Brucker <jean-philippe@...aro.com>
Cc: "Yi Liu" <yi.l.liu@...el.com>,
"Tian, Kevin" <kevin.tian@...el.com>,
Raj Ashok <ashok.raj@...el.com>,
"Christoph Hellwig" <hch@...radead.org>,
Jonathan Cameron <jic23@...nel.org>,
Eric Auger <eric.auger@...hat.com>,
Jacob Pan <jacob.jun.pan@...ux.intel.com>
Subject: [PATCH 05/10] iommu/ioasid: Create an IOASID set for host SVA use
Bare metal SVA allocates IOASIDs for native process addresses. This
should be separated from VM allocated IOASIDs thus under its own set.
This patch creates a system IOASID set with its quota set to PID_MAX.
This is a reasonable default in that SVM capable devices can only bind
to limited user processes.
Signed-off-by: Jacob Pan <jacob.jun.pan@...ux.intel.com>
---
drivers/iommu/intel-iommu.c | 8 +++++++-
drivers/iommu/ioasid.c | 9 +++++++++
include/linux/ioasid.h | 9 +++++++++
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index ec3fc121744a..af7a1ef7b31e 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -3511,8 +3511,14 @@ static int __init init_dmars(void)
goto free_iommu;
/* PASID is needed for scalable mode irrespective to SVM */
- if (intel_iommu_sm)
+ if (intel_iommu_sm) {
ioasid_install_capacity(intel_pasid_max_id);
+ /* We should not run out of IOASIDs at boot */
+ if (ioasid_alloc_system_set(PID_MAX_DEFAULT)) {
+ pr_err("Failed to enable host PASID allocator\n");
+ intel_iommu_sm = 0;
+ }
+ }
/*
* for each drhd
diff --git a/drivers/iommu/ioasid.c b/drivers/iommu/ioasid.c
index 6265d2dbbced..9135af171a7c 100644
--- a/drivers/iommu/ioasid.c
+++ b/drivers/iommu/ioasid.c
@@ -39,6 +39,9 @@ struct ioasid_data {
static ioasid_t ioasid_capacity;
static ioasid_t ioasid_capacity_avail;
+int system_ioasid_sid;
+static DECLARE_IOASID_SET(system_ioasid);
+
/* System capacity can only be set once */
void ioasid_install_capacity(ioasid_t total)
{
@@ -51,6 +54,12 @@ void ioasid_install_capacity(ioasid_t total)
}
EXPORT_SYMBOL_GPL(ioasid_install_capacity);
+int ioasid_alloc_system_set(int quota)
+{
+ return ioasid_alloc_set(&system_ioasid, quota, &system_ioasid_sid);
+}
+EXPORT_SYMBOL_GPL(ioasid_alloc_system_set);
+
/*
* struct ioasid_allocator_data - Internal data structure to hold information
* about an allocator. There are two types of allocators:
diff --git a/include/linux/ioasid.h b/include/linux/ioasid.h
index 8c82d2625671..097b1cc043a3 100644
--- a/include/linux/ioasid.h
+++ b/include/linux/ioasid.h
@@ -29,6 +29,9 @@ struct ioasid_allocator_ops {
void *pdata;
};
+/* Shared IOASID set for reserved for host system use */
+extern int system_ioasid_sid;
+
#define DECLARE_IOASID_SET(name) struct ioasid_set name = { 0 }
#if IS_ENABLED(CONFIG_IOASID)
@@ -41,6 +44,7 @@ int ioasid_register_allocator(struct ioasid_allocator_ops *allocator);
void ioasid_unregister_allocator(struct ioasid_allocator_ops *allocator);
int ioasid_attach_data(ioasid_t ioasid, void *data);
void ioasid_install_capacity(ioasid_t total);
+int ioasid_alloc_system_set(int quota);
int ioasid_alloc_set(struct ioasid_set *token, ioasid_t quota, int *sid);
void ioasid_free_set(int sid, bool destroy_set);
int ioasid_find_sid(ioasid_t ioasid);
@@ -88,5 +92,10 @@ static inline void ioasid_install_capacity(ioasid_t total)
{
}
+static inline int ioasid_alloc_system_set(int quota)
+{
+ return -ENOTSUPP;
+}
+
#endif /* CONFIG_IOASID */
#endif /* __LINUX_IOASID_H */
--
2.7.4
Powered by blists - more mailing lists