From: Shyam Saini <shyamsaini@linux.microsoft.com>
To: iommu@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
devicetree@vger.kernel.org, virtualization@lists.linux.dev
Cc: jgg@ziepe.ca, will@kernel.org, jacob.pan@linux.microsoft.com,
eric.auger@redhat.com, code@tyhicks.com,
eahariha@linux.microsoft.com, vijayb@linux.microsoft.com
Subject: [PATCH v2 3/3] arm-smmu: select suitable MSI IOVA
Date: Thu, 10 Apr 2025 15:50:30 -0700 [thread overview]
Message-ID: <20250410225030.2528385-4-shyamsaini@linux.microsoft.com> (raw)
In-Reply-To: <20250410225030.2528385-1-shyamsaini@linux.microsoft.com>
Currently ARM SMMU drivers hardcode PCI MSI IOVA address.
Not all the platform have same memory mappings and some platform
could have this address already being mapped for something else.
This can lead to collision and as a consequence the MSI IOVA addr
range is never reserved.
Fix this by adding one more MSI_IOVA base address, so that if the
platforms can select suitable PCI MSI IOVA address if SMMU dts node
has "arm,smmu-faulty-msi-iova".
If this property is not found in the dtb for the given platform then
the driver falls back on the default MSI IOVA address.
Signed-off-by: Shyam Saini <shyamsaini@linux.microsoft.com>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 9 +++-
drivers/iommu/arm/arm-smmu/arm-smmu.c | 9 +++-
include/linux/iommu.h | 49 +++++++++++++++++++++
3 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 358072b4e293..d6ea82ed4530 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -33,6 +33,8 @@
#include "arm-smmu-v3.h"
#include "../../dma-iommu.h"
+u32 msi_iova_base;
+
static bool disable_msipolling;
module_param(disable_msipolling, bool, 0444);
MODULE_PARM_DESC(disable_msipolling,
@@ -3541,8 +3543,8 @@ static void arm_smmu_get_resv_regions(struct device *dev,
struct iommu_resv_region *region;
int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
- region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
- prot, IOMMU_RESV_SW_MSI, GFP_KERNEL);
+ region = iommu_alloc_resv_region(msi_iova_base, MSI_IOVA_LENGTH, prot,
+ IOMMU_RESV_SW_MSI, GFP_KERNEL);
if (!region)
return;
@@ -4570,6 +4572,9 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
struct device *dev = &pdev->dev;
u32 cells;
int ret = -EINVAL;
+ u32 msi_iova_ptr;
+
+ iommu_configure_msi_iova(dev, "arm,smmu-faulty-msi-iova", msi_iova_ptr);
if (of_property_read_u32(dev->of_node, "#iommu-cells", &cells))
dev_err(dev, "missing #iommu-cells property\n");
diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu.c b/drivers/iommu/arm/arm-smmu/arm-smmu.c
index a54dc4608c62..cd8bf2278057 100644
--- a/drivers/iommu/arm/arm-smmu/arm-smmu.c
+++ b/drivers/iommu/arm/arm-smmu/arm-smmu.c
@@ -50,6 +50,8 @@
*/
#define QCOM_DUMMY_VAL -1
+u32 msi_iova_base;
+
static int force_stage;
module_param(force_stage, int, S_IRUGO);
MODULE_PARM_DESC(force_stage,
@@ -1594,8 +1596,8 @@ static void arm_smmu_get_resv_regions(struct device *dev,
struct iommu_resv_region *region;
int prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO;
- region = iommu_alloc_resv_region(MSI_IOVA_BASE, MSI_IOVA_LENGTH,
- prot, IOMMU_RESV_SW_MSI, GFP_KERNEL);
+ region = iommu_alloc_resv_region(msi_iova_base, MSI_IOVA_LENGTH, prot,
+ IOMMU_RESV_SW_MSI, GFP_KERNEL);
if (!region)
return;
@@ -2030,6 +2032,9 @@ static int arm_smmu_device_dt_probe(struct arm_smmu_device *smmu,
const struct arm_smmu_match_data *data;
struct device *dev = smmu->dev;
bool legacy_binding;
+ u32 *msi_iova_ptr = &msi_iova_base;
+
+ iommu_configure_msi_iova(dev, "arm,smmu-faulty-msi-iova", msi_iova_ptr);
if (of_property_read_u32(dev->of_node, "#global-interrupts", global_irqs))
return dev_err_probe(dev, -ENODEV,
diff --git a/include/linux/iommu.h b/include/linux/iommu.h
index 8d38d85f23f1..cfd047fdf225 100644
--- a/include/linux/iommu.h
+++ b/include/linux/iommu.h
@@ -1531,10 +1531,59 @@ static inline void iommu_debugfs_setup(void) {}
#ifdef CONFIG_IOMMU_DMA
#define MSI_IOVA_BASE 0x8000000
+#define MSI_IOVA_BASE2 0xa0000000
#define MSI_IOVA_LENGTH 0x100000
+static inline u32 select_msi_iova_base(u32 erratic_iova_addr)
+{
+ phys_addr_t start, end, msi_iova_end;
+
+ if (!erratic_iova_addr)
+ return MSI_IOVA_BASE;
+
+ start = erratic_iova_addr;
+ end = start + MSI_IOVA_LENGTH - 1;
+ msi_iova_end = MSI_IOVA_BASE + MSI_IOVA_LENGTH - 1;
+
+ /* return non-overlapping address */
+ return (start > MSI_IOVA_BASE ||
+ end < msi_iova_end) ? MSI_IOVA_BASE : MSI_IOVA_BASE2;
+}
+
+static inline void iommu_configure_msi_iova(struct device *iommu_dev,
+ const char *faulty_msi_iova_prop,
+ u32 *msi_iova)
+{
+ static bool is_msi_iova_selected;
+ u32 faulty_msi_iova_from_dt;
+ int rc;
+
+ rc = of_property_read_u32(iommu_dev->of_node, faulty_msi_iova_prop,
+ &faulty_msi_iova_from_dt);
+ if (!is_msi_iova_selected) {
+ *msi_iova = select_msi_iova_base(rc ? 0 : faulty_msi_iova_from_dt);
+ dev_dbg(iommu_dev, "setting custom MSI IOVA base to 0x%x\n", *msi_iova);
+ is_msi_iova_selected = true;
+ return;
+ }
+
+ dev_dbg(iommu_dev, "custom MSI IOVA base already set to 0x%x\n", *msi_iova);
+}
+
int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base);
#else /* CONFIG_IOMMU_DMA */
+
+static inline u32 select_msi_iova_base(u32 erratic_iova_addr)
+{
+}
+
+static inline void iommu_configure_msi_iova(struct device *iommu_dev,
+ const char *faulty_msi_iova_prop,
+ u32 *msi_iova)
+{
+}
+
+
static inline int iommu_get_msi_cookie(struct iommu_domain *domain, dma_addr_t base)
{
return -ENODEV;
--
2.34.1
next prev parent reply other threads:[~2025-04-10 22:50 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-04-10 22:50 [PATCH v2 0/3] arm-smmu: select suitable IOVA Shyam Saini
2025-04-10 22:50 ` [PATCH v2 1/3] arm-smmu: move MSI_IOVA macro definitions Shyam Saini
2025-04-11 23:28 ` kernel test robot
2025-04-12 3:17 ` kernel test robot
2025-04-10 22:50 ` [PATCH v2 2/3] dt-bindings: iommu: add "arm,smmu-faulty-msi-iova" property Shyam Saini
2025-04-10 22:50 ` Shyam Saini [this message]
2025-04-11 23:40 ` [PATCH v2 3/3] arm-smmu: select suitable MSI IOVA kernel test robot
2025-04-10 23:00 ` [PATCH v2 0/3] arm-smmu: select suitable IOVA Jason Gunthorpe
2025-04-16 18:04 ` Jacob Pan
[not found] ` <67fff12d.650a0220.208c7c.d69dSMTPIN_ADDED_BROKEN@mx.google.com>
2025-04-16 18:17 ` Jason Gunthorpe
2025-04-16 21:34 ` Jacob Pan
2025-05-20 22:42 ` Shyam Saini
2025-05-25 19:07 ` Jason Gunthorpe
2025-05-27 20:54 ` Shyam Saini
2025-05-28 0:04 ` Jason Gunthorpe
2025-05-28 22:42 ` Jacob Pan
[not found] ` <68379171.170a0220.191ee0.8d6bSMTPIN_ADDED_BROKEN@mx.google.com>
2025-05-29 0:38 ` Jason Gunthorpe
2025-05-29 18:22 ` Shyam Saini
2025-05-29 18:38 ` Jason Gunthorpe
2025-05-29 22:08 ` Shyam Saini
2025-05-30 13:13 ` Jason Gunthorpe
2025-05-30 21:30 ` Shyam Saini
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=20250410225030.2528385-4-shyamsaini@linux.microsoft.com \
--to=shyamsaini@linux.microsoft.com \
--cc=code@tyhicks.com \
--cc=devicetree@vger.kernel.org \
--cc=eahariha@linux.microsoft.com \
--cc=eric.auger@redhat.com \
--cc=iommu@lists.linux.dev \
--cc=jacob.pan@linux.microsoft.com \
--cc=jgg@ziepe.ca \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=vijayb@linux.microsoft.com \
--cc=virtualization@lists.linux.dev \
--cc=will@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox