public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <ajones@ventanamicro.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: jgg@nvidia.com, zong.li@sifive.com, tjeznach@rivosinc.com,
	joro@8bytes.org, will@kernel.org, robin.murphy@arm.com,
	anup@brainfault.org, atish.patra@linux.dev, tglx@linutronix.de,
	alex.williamson@redhat.com, paul.walmsley@sifive.com,
	palmer@dabbelt.com, alex@ghiti.fr
Subject: [RFC PATCH v2 11/18] iommu/riscv: Maintain each irq msitbl index with chip data
Date: Sat, 20 Sep 2025 15:39:01 -0500	[thread overview]
Message-ID: <20250920203851.2205115-31-ajones@ventanamicro.com> (raw)
In-Reply-To: <20250920203851.2205115-20-ajones@ventanamicro.com>

Track each IRQ's MSI table index in the IRQ's chip data of the IR
irqdomain along with a generation number. This will be necessary
when support for irq-set-vcpu-affinity is added as the msitbl
configuration will change to match the guest. When a configuration
changes then it may no longer be possible to compute the index from
the target address, hence the need to stash it. Also, if an allocated
IRQ is not mapped with irq-set-vcpu-affinity after a configuration
change (which will unmap everything), then we need to avoid
attempting to unmap it at free-irqs time.

Signed-off-by: Andrew Jones <ajones@ventanamicro.com>
---
 drivers/iommu/riscv/iommu-ir.c | 75 +++++++++++++++++++++++++++++-----
 drivers/iommu/riscv/iommu.h    |  1 +
 2 files changed, 65 insertions(+), 11 deletions(-)

diff --git a/drivers/iommu/riscv/iommu-ir.c b/drivers/iommu/riscv/iommu-ir.c
index b97768cac4be..059671f18267 100644
--- a/drivers/iommu/riscv/iommu-ir.c
+++ b/drivers/iommu/riscv/iommu-ir.c
@@ -164,11 +164,42 @@ static void riscv_iommu_ir_msitbl_inval(struct riscv_iommu_domain *domain,
 	rcu_read_unlock();
 }
 
-static void riscv_iommu_ir_msitbl_map(struct riscv_iommu_domain *domain, size_t idx,
-				      phys_addr_t addr)
+struct riscv_iommu_ir_chip_data {
+	size_t idx;
+	u32 config;
+};
+
+static size_t riscv_iommu_ir_irq_msitbl_idx(struct irq_data *data)
+{
+	struct riscv_iommu_ir_chip_data *chip_data = irq_data_get_irq_chip_data(data);
+
+	return chip_data->idx;
+}
+
+static u32 riscv_iommu_ir_irq_msitbl_config(struct irq_data *data)
+{
+	struct riscv_iommu_ir_chip_data *chip_data = irq_data_get_irq_chip_data(data);
+
+	return chip_data->config;
+}
+
+static void riscv_iommu_ir_irq_set_msitbl_info(struct irq_data *data,
+					       size_t idx, u32 config)
+{
+	struct riscv_iommu_ir_chip_data *chip_data = irq_data_get_irq_chip_data(data);
+
+	chip_data->idx = idx;
+	chip_data->config = config;
+}
+
+static void riscv_iommu_ir_msitbl_map(struct riscv_iommu_domain *domain,
+				      struct irq_data *data,
+				      size_t idx, phys_addr_t addr)
 {
 	struct riscv_iommu_msipte *pte;
 
+	riscv_iommu_ir_irq_set_msitbl_info(data, idx, domain->msitbl_config);
+
 	if (!domain->msi_root)
 		return;
 
@@ -186,9 +217,17 @@ static void riscv_iommu_ir_msitbl_map(struct riscv_iommu_domain *domain, size_t
 	}
 }
 
-static void riscv_iommu_ir_msitbl_unmap(struct riscv_iommu_domain *domain, size_t idx)
+static void riscv_iommu_ir_msitbl_unmap(struct riscv_iommu_domain *domain,
+					struct irq_data *data, size_t idx)
 {
 	struct riscv_iommu_msipte *pte;
+	u32 config;
+
+	config = riscv_iommu_ir_irq_msitbl_config(data);
+	riscv_iommu_ir_irq_set_msitbl_info(data, -1, -1);
+
+	if (WARN_ON_ONCE(config != domain->msitbl_config))
+		return;
 
 	if (!domain->msi_root)
 		return;
@@ -219,11 +258,11 @@ static int riscv_iommu_ir_irq_set_affinity(struct irq_data *data,
 {
 	struct riscv_iommu_info *info = data->domain->host_data;
 	struct riscv_iommu_domain *domain = info->domain;
-	phys_addr_t old_addr, new_addr;
 	size_t old_idx, new_idx;
+	phys_addr_t new_addr;
 	int ret;
 
-	old_idx = riscv_iommu_ir_get_msipte_idx_from_target(domain, data, &old_addr);
+	old_idx = riscv_iommu_ir_irq_msitbl_idx(data);
 
 	ret = irq_chip_set_affinity_parent(data, dest, force);
 	if (ret < 0)
@@ -234,8 +273,8 @@ static int riscv_iommu_ir_irq_set_affinity(struct irq_data *data,
 	if (new_idx == old_idx)
 		return ret;
 
-	riscv_iommu_ir_msitbl_unmap(domain, old_idx);
-	riscv_iommu_ir_msitbl_map(domain, new_idx, new_addr);
+	riscv_iommu_ir_msitbl_unmap(domain, data, old_idx);
+	riscv_iommu_ir_msitbl_map(domain, data, new_idx, new_addr);
 
 	return ret;
 }
@@ -254,11 +293,16 @@ static int riscv_iommu_ir_irq_domain_alloc_irqs(struct irq_domain *irqdomain,
 {
 	struct riscv_iommu_info *info = irqdomain->host_data;
 	struct riscv_iommu_domain *domain = info->domain;
+	struct riscv_iommu_ir_chip_data *chip_data;
 	struct irq_data *data;
 	phys_addr_t addr;
 	size_t idx;
 	int i, ret;
 
+	chip_data = kzalloc(sizeof(*chip_data), GFP_KERNEL_ACCOUNT);
+	if (!chip_data)
+		return -ENOMEM;
+
 	ret = irq_domain_alloc_irqs_parent(irqdomain, irq_base, nr_irqs, arg);
 	if (ret)
 		return ret;
@@ -266,8 +310,9 @@ static int riscv_iommu_ir_irq_domain_alloc_irqs(struct irq_domain *irqdomain,
 	for (i = 0; i < nr_irqs; i++) {
 		data = irq_domain_get_irq_data(irqdomain, irq_base + i);
 		data->chip = &riscv_iommu_ir_irq_chip;
+		data->chip_data = chip_data;
 		idx = riscv_iommu_ir_get_msipte_idx_from_target(domain, data, &addr);
-		riscv_iommu_ir_msitbl_map(domain, idx, addr);
+		riscv_iommu_ir_msitbl_map(domain, data, idx, addr);
 	}
 
 	return 0;
@@ -280,14 +325,22 @@ static void riscv_iommu_ir_irq_domain_free_irqs(struct irq_domain *irqdomain,
 	struct riscv_iommu_info *info = irqdomain->host_data;
 	struct riscv_iommu_domain *domain = info->domain;
 	struct irq_data *data;
-	phys_addr_t addr;
+	u32 config;
 	size_t idx;
 	int i;
 
 	for (i = 0; i < nr_irqs; i++) {
 		data = irq_domain_get_irq_data(irqdomain, irq_base + i);
-		idx = riscv_iommu_ir_get_msipte_idx_from_target(domain, data, &addr);
-		riscv_iommu_ir_msitbl_unmap(domain, idx);
+		config = riscv_iommu_ir_irq_msitbl_config(data);
+		/*
+		 * Only irqs with matching config versions need to be unmapped here
+		 * since config changes will unmap everything.
+		 */
+		if (config == domain->msitbl_config) {
+			idx = riscv_iommu_ir_irq_msitbl_idx(data);
+			riscv_iommu_ir_msitbl_unmap(domain, data, idx);
+		}
+		kfree(data->chip_data);
 	}
 
 	irq_domain_free_irqs_parent(irqdomain, irq_base, nr_irqs);
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index aeb5642f003c..130f82e8392a 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -36,6 +36,7 @@ struct riscv_iommu_domain {
 	struct riscv_iommu_msipte *msi_root;
 	refcount_t *msi_pte_counts;
 	raw_spinlock_t msi_lock;
+	u32 msitbl_config;
 	u64 msi_addr_mask;
 	u64 msi_addr_pattern;
 	u32 group_index_bits;
-- 
2.49.0


  parent reply	other threads:[~2025-09-20 20:39 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-20 20:38 [RFC PATCH v2 00/18] iommu/riscv: Add irqbypass support Andrew Jones
2025-09-20 20:38 ` [RFC PATCH v2 01/18] genirq/msi: Provide DOMAIN_BUS_MSI_REMAP Andrew Jones
2025-09-30  8:25   ` Nutty.Liu
2025-09-20 20:38 ` [RFC PATCH v2 02/18] iommu/riscv: Move struct riscv_iommu_domain and info to iommu.h Andrew Jones
2025-09-30  8:26   ` Nutty.Liu
2025-09-20 20:38 ` [RFC PATCH v2 03/18] iommu/riscv: Use data structure instead of individual values Andrew Jones
2025-09-24  3:25   ` Nutty.Liu
2025-09-24 13:31     ` Andrew Jones
2025-09-20 20:38 ` [RFC PATCH v2 04/18] iommu/riscv: Add IRQ domain for interrupt remapping Andrew Jones
2025-09-28  9:30   ` Nutty.Liu
2025-09-29 15:50     ` Andrew Jones
2025-09-20 20:38 ` [RFC PATCH v2 05/18] iommu/riscv: Prepare to use MSI table Andrew Jones
2025-10-05  8:30   ` Nutty.Liu
2025-09-20 20:38 ` [RFC PATCH v2 06/18] iommu/riscv: Implement MSI table management functions Andrew Jones
2025-10-05  8:28   ` Nutty.Liu
2025-09-20 20:38 ` [RFC PATCH v2 07/18] iommu/riscv: Export phys_to_ppn and ppn_to_phys Andrew Jones
2025-10-05  8:39   ` Nutty.Liu
2025-09-20 20:38 ` [RFC PATCH v2 08/18] iommu/riscv: Use MSI table to enable IMSIC access Andrew Jones
2025-09-22 18:43   ` Jason Gunthorpe
2025-09-22 21:20     ` Andrew Jones
2025-09-22 23:56       ` Jason Gunthorpe
2025-09-23 10:12         ` Thomas Gleixner
2025-09-23 14:06           ` Jason Gunthorpe
2025-09-23 15:12             ` Andrew Jones
2025-09-23 15:27               ` Jason Gunthorpe
2025-09-23 15:50                 ` Andrew Jones
2025-09-23 16:23                   ` Jason Gunthorpe
2025-09-23 16:33                     ` Andrew Jones
2026-03-24  9:12                       ` Vincent Chen
2026-03-26 17:31                         ` Andrew Jones
2025-09-23 14:37           ` Andrew Jones
2025-09-23 14:52             ` Jason Gunthorpe
2025-09-23 15:37               ` Andrew Jones
2025-10-23 13:47         ` Jinvas
2025-09-20 20:38 ` [RFC PATCH v2 09/18] iommu/dma: enable IOMMU_DMA for RISC-V Andrew Jones
2025-10-05  8:40   ` Nutty.Liu
2025-09-20 20:39 ` [RFC PATCH v2 10/18] RISC-V: Define irqbypass vcpu_info Andrew Jones
2025-10-05  8:41   ` Nutty.Liu
2025-09-20 20:39 ` Andrew Jones [this message]
2025-09-20 20:39 ` [RFC PATCH v2 12/18] iommu/riscv: Add guest file irqbypass support Andrew Jones
2025-09-20 20:39 ` [RFC PATCH v2 13/18] iommu/riscv: report iommu capabilities Andrew Jones
2025-10-05  8:43   ` Nutty.Liu
2025-09-20 20:39 ` [RFC PATCH v2 14/18] RISC-V: KVM: Enable KVM_VFIO interfaces on RISC-V arch Andrew Jones
2025-10-05  8:44   ` Nutty.Liu
2025-09-20 20:39 ` [RFC PATCH v2 15/18] RISC-V: KVM: Add guest file irqbypass support Andrew Jones
2025-09-20 20:39 ` [RFC PATCH v2 16/18] vfio: enable IOMMU_TYPE1 for RISC-V Andrew Jones
2025-10-05  8:44   ` Nutty.Liu
2025-09-20 20:39 ` [RFC PATCH v2 17/18] RISC-V: defconfig: Add VFIO modules Andrew Jones
2025-10-05  8:47   ` Nutty.Liu
2025-09-20 20:39 ` [RFC PATCH v2 18/18] DO NOT UPSTREAM: RISC-V: KVM: Workaround kvm_riscv_gstage_ioremap() bug Andrew Jones
2025-10-20 13:12   ` fangyu.yu
2025-10-20 19:47     ` Daniel Henrique Barboza
2025-10-21  1:10   ` fangyu.yu

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=20250920203851.2205115-31-ajones@ventanamicro.com \
    --to=ajones@ventanamicro.com \
    --cc=alex.williamson@redhat.com \
    --cc=alex@ghiti.fr \
    --cc=anup@brainfault.org \
    --cc=atish.patra@linux.dev \
    --cc=iommu@lists.linux.dev \
    --cc=jgg@nvidia.com \
    --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=paul.walmsley@sifive.com \
    --cc=robin.murphy@arm.com \
    --cc=tglx@linutronix.de \
    --cc=tjeznach@rivosinc.com \
    --cc=will@kernel.org \
    --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