From: Andrew Jones <andrew.jones@oss.qualcomm.com>
To: iommu@lists.linux.dev, kvm-riscv@lists.infradead.org,
kvm@vger.kernel.org, linux-riscv@lists.infradead.org,
linux-kernel@vger.kernel.org
Cc: tomasz.jeznach@linux.dev, jgg@ziepe.ca, jgg@nvidia.com,
joro@8bytes.org, will@kernel.org, robin.murphy@arm.com,
pjw@kernel.org, palmer@dabbelt.com, tglx@kernel.org,
anup@brainfault.org, atish.patra@linux.dev,
fangyu.yu@linux.alibaba.com, zhangzhanpeng.jasper@bytedance.com,
zong.li@sifive.com
Subject: [RFC PATCH v3 07/14] iommu/riscv: Prepare MSI table updates for interrupt remapping
Date: Mon, 28 Sep 2026 16:31:06 +0200 [thread overview]
Message-ID: <20260928143113.49838-8-andrew.jones@oss.qualcomm.com> (raw)
In-Reply-To: <20260928143113.49838-1-andrew.jones@oss.qualcomm.com>
Guest interrupt-file mappings require interrupt-remapping code to
install or remove the MSI page-table pointer and address extraction
fields in every device context attached to a domain. Devices joining an
active MSI domain also need their device contexts initialized, so check
for an active MSI domain at attach time.
Add helpers to publish those fields to bonded devices and to invalidate
one or all MSI PTE translations. These helpers will be used by the IRQ
bypass implementation.
The per-device nr_forwarded_irqs counter is insufficient to detect
active MSI tables for the domain, so we introduce another counter which
is domain-wide. Like info->nr_forwarded_irqs, later patches which
introduce interrupt remapping support will manage the newly introduced
nr_forwarded_irqs counter.
Signed-off-by: Andrew Jones <andrew.jones@oss.qualcomm.com>
---
drivers/iommu/riscv/iommu.c | 65 +++++++++++++++++++++++++++++++++++++
drivers/iommu/riscv/iommu.h | 5 +++
2 files changed, 70 insertions(+)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 86d5795a12dd..db4539fbcb95 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -1189,6 +1189,28 @@ static void riscv_iommu_iotlb_inval(struct riscv_iommu_domain *domain,
rcu_read_unlock();
}
+void riscv_iommu_msi_table_inval(struct riscv_iommu_msi_table *msi_table, unsigned long addr)
+{
+ struct iommu_iotlb_gather gather = {
+ .start = addr,
+ .end = addr + SZ_4K - 1,
+ .pt.leaf_levels_bitmap = 1,
+ };
+ struct riscv_iommu_domain *domain;
+
+ domain = container_of(msi_table, struct riscv_iommu_domain, msi_table);
+ riscv_iommu_iotlb_inval(domain, &gather);
+}
+
+void riscv_iommu_msi_table_inval_all(struct riscv_iommu_msi_table *msi_table)
+{
+ struct iommu_iotlb_gather gather = { 0 };
+ struct riscv_iommu_domain *domain;
+
+ domain = container_of(msi_table, struct riscv_iommu_domain, msi_table);
+ riscv_iommu_iotlb_inval(domain, &gather);
+}
+
#define RISCV_IOMMU_FSC_BARE 0
/*
* This function sends IOTINVAL commands as required by the RISC-V
@@ -1311,6 +1333,11 @@ static void riscv_iommu_iodir_update(struct device *dev, struct riscv_iommu_dc *
WRITE_ONCE(dc->fsc, new_dc->fsc);
WRITE_ONCE(dc->ta, new_dc->ta & RISCV_IOMMU_PC_TA_PSCID);
WRITE_ONCE(dc->iohgatp, new_dc->iohgatp);
+ if (iommu->caps & RISCV_IOMMU_CAPABILITIES_MSI_FLAT) {
+ WRITE_ONCE(dc->msiptp, new_dc->msiptp);
+ WRITE_ONCE(dc->msi_addr_mask, new_dc->msi_addr_mask);
+ WRITE_ONCE(dc->msi_addr_pattern, new_dc->msi_addr_pattern);
+ }
/* Update device context, write TC.V as the last step. */
dma_wmb();
WRITE_ONCE(dc->tc, tc);
@@ -1329,6 +1356,40 @@ static void riscv_iommu_iodir_update(struct device *dev, struct riscv_iommu_dc *
riscv_iommu_cmd_sync(iommu, RISCV_IOMMU_IOTINVAL_TIMEOUT);
}
+static void riscv_iommu_msi_table_set_dc(struct riscv_iommu_msi_table *msi_table,
+ struct riscv_iommu_dc *dc, bool activate)
+{
+ if (activate) {
+ dc->msiptp = virt_to_pfn(msi_table->root) |
+ FIELD_PREP(RISCV_IOMMU_DC_MSIPTP_MODE,
+ RISCV_IOMMU_DC_MSIPTP_MODE_FLAT);
+ dc->msi_addr_mask = msi_table->msi_addr_mask;
+ dc->msi_addr_pattern = msi_table->msi_addr_pattern;
+ } else {
+ dc->msiptp = 0;
+ dc->msi_addr_mask = 0;
+ dc->msi_addr_pattern = 0;
+ }
+}
+
+void riscv_iommu_msi_table_update(struct riscv_iommu_msi_table *msi_table, bool activate)
+{
+ struct riscv_iommu_domain *domain;
+ struct riscv_iommu_bond *bond;
+
+ /* The MSI table lock excludes bond updates for this domain. */
+ lockdep_assert_held(&msi_table->lock);
+
+ domain = container_of(msi_table, struct riscv_iommu_domain, msi_table);
+
+ list_for_each_entry(bond, &domain->bonds, list) {
+ struct riscv_iommu_info *info = dev_iommu_priv_get(bond->dev);
+
+ riscv_iommu_msi_table_set_dc(msi_table, &info->dc, activate);
+ riscv_iommu_iodir_update(bond->dev, &info->dc);
+ }
+}
+
/*
* IOVA page translation tree management.
*/
@@ -1514,6 +1575,10 @@ static int riscv_iommu_attach_paging_domain(struct iommu_domain *iommu_domain,
kfree(bond);
return -EBUSY;
}
+
+ if (domain->msi_table.nr_forwarded_irqs)
+ riscv_iommu_msi_table_set_dc(&domain->msi_table, &dc, true);
+
info->dc = dc;
riscv_iommu_bond_link(domain, bond);
riscv_iommu_iodir_update(dev, &info->dc);
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index 2876703a6698..deb57b6a6c4b 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -71,6 +71,7 @@ struct riscv_iommu_device {
struct riscv_iommu_msi_table {
/* Protects attachment, interrupt forwarding state, and MSI PTE updates. */
raw_spinlock_t lock;
+ unsigned int nr_forwarded_irqs;
unsigned int nr_ptes;
struct riscv_iommu_msipte *root;
u64 msi_addr_mask;
@@ -81,6 +82,10 @@ int riscv_iommu_init(struct riscv_iommu_device *iommu);
void riscv_iommu_remove(struct riscv_iommu_device *iommu);
void riscv_iommu_disable(struct riscv_iommu_device *iommu);
+void riscv_iommu_msi_table_inval(struct riscv_iommu_msi_table *msi_table, unsigned long addr);
+void riscv_iommu_msi_table_inval_all(struct riscv_iommu_msi_table *msi_table);
+void riscv_iommu_msi_table_update(struct riscv_iommu_msi_table *msi_table, bool activate);
+
#define riscv_iommu_readl(iommu, addr) \
readl_relaxed((iommu)->reg + (addr))
--
2.43.0
next prev parent reply other threads:[~2026-09-28 14:32 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 14:30 [RFC PATCH v3 00/14] iommu/riscv: Add irqbypass support Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 01/14] iommu/riscv: Allocate MSI tables for second-stage domains Andrew Jones
2026-10-05 13:25 ` Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 02/14] iommu/riscv: Prepare domain bonds for outer locking Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 03/14] iommu/riscv: Serialize MSI table publication with domain attachment Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 04/14] iommu/riscv: Reject live S2 replacement with forwarded IRQs Andrew Jones
2026-10-09 9:05 ` Gong Shuai
2026-09-28 14:31 ` [RFC PATCH v3 05/14] iommu/riscv: Derive the IOMMU from the device in IODIR updates Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 06/14] iommu/riscv: Cache the programmed device context Andrew Jones
2026-09-28 14:31 ` Andrew Jones [this message]
2026-09-28 14:31 ` [RFC PATCH v3 08/14] irqchip/riscv-imsic: Define IOMMU IRQ bypass protocol Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 09/14] genirq/msi: Provide DOMAIN_BUS_MSI_REMAP Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 10/14] iommu/riscv: Add IRQ domain for interrupt remapping Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 11/14] iommu/riscv: Prepare info->domain for concurrent RCU access Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 12/14] iommu/riscv: Prepare interrupt remapping for IRQ bypass Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 13/14] iommu/riscv: Validate IRQ forwarding requests Andrew Jones
2026-09-28 14:31 ` [RFC PATCH v3 14/14] iommu/riscv: Implement IRQ forwarding Andrew Jones
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=20260928143113.49838-8-andrew.jones@oss.qualcomm.com \
--to=andrew.jones@oss.qualcomm.com \
--cc=anup@brainfault.org \
--cc=atish.patra@linux.dev \
--cc=fangyu.yu@linux.alibaba.com \
--cc=iommu@lists.linux.dev \
--cc=jgg@nvidia.com \
--cc=jgg@ziepe.ca \
--cc=joro@8bytes.org \
--cc=kvm-riscv@lists.infradead.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=robin.murphy@arm.com \
--cc=tglx@kernel.org \
--cc=tomasz.jeznach@linux.dev \
--cc=will@kernel.org \
--cc=zhangzhanpeng.jasper@bytedance.com \
--cc=zong.li@sifive.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