From nobody Thu Apr 2 18:47:54 2026 Received: from out198-29.us.a.mail.aliyun.com (out198-29.us.a.mail.aliyun.com [47.90.198.29]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA5172F2905 for ; Thu, 12 Feb 2026 13:54:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=47.90.198.29 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770904459; cv=none; b=mWF/9wb9zVeqY//Y88dKgQnNYDxNzcK1Z8Ss/D9olTqCGcSPTXkHyyJ5GKYpbYj8babrU9MJhBJM84dwA2XBnuOB43HtFuUrRTC8JSgMaNv1L51Ds/j/LeBQ2moFXuw9CLzuevldd/AeKeZzZ7/0t9WZP6QPlMr+VQy/7ZkMpRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770904459; c=relaxed/simple; bh=KV4i8L7Sx46BFtSHDtsI7cyhZn06zatHHjtAOKqorcY=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=gWAnDawWGDZqgeBNkAvTjvBqRPRHvWA4DV/BdyluQHBtqnxjvhCr2aW6OlBpIQsIEfDpvPQ/98x2IQjvnopvRzEPwNNS9I4ATvAuckX4NCFcaWuGLlQ29zRFUknm3Y+SGlgUDiJvlUMX+BGFBEpMBYT4+4lMW0w+2jtxHCNh1dY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bosc.ac.cn; spf=pass smtp.mailfrom=bosc.ac.cn; arc=none smtp.client-ip=47.90.198.29 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=bosc.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bosc.ac.cn Received: from guoyaxing.localdomain(mailfrom:guoyaxing@bosc.ac.cn fp:SMTPD_---.gVs67R6_1770904420 cluster:ay29) by smtp.aliyun-inc.com; Thu, 12 Feb 2026 21:53:58 +0800 From: Yaxing Guo To: tglx@linutronix.de, anup@brainfault.org, pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu, alex@ghiti.fr Cc: linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, guoyaxing@bosc.ac.cn Subject: [PATCH v1] riscv/imsic: add support for IRQ_MSI_IOMMU and map MSI pages through IOMMU Date: Thu, 12 Feb 2026 21:53:37 +0800 Message-Id: <20260212135337.18308-1-guoyaxing@bosc.ac.cn> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch adds support for CONFIG_IRQ_MSI_IOMMU in the RISC-V IMSIC driver by calling iommu_dma_prepare_msi(), which allocates an IOVA and maps the physical IMSIC MSI address into the device domain. The MSI message address is then written to use the IOVA, ensuring IOMMU translation succeeds on MSI writes. With this change, PCIe or platform devices using IMSIC-based MSI can operate correctly under IOMMU isolation. Signed-off-by: Yaxing Guo --- drivers/irqchip/Kconfig | 1 + drivers/irqchip/irq-riscv-imsic-platform.c | 32 ++++++++++++++++------ 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 936d27c318e8..b778621ad252 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig @@ -633,6 +633,7 @@ config RISCV_IMSIC select GENERIC_IRQ_MATRIX_ALLOCATOR select GENERIC_MSI_IRQ select IRQ_MSI_LIB + select IRQ_MSI_IOMMU =20 config RISCV_RPMI_SYSMSI bool diff --git a/drivers/irqchip/irq-riscv-imsic-platform.c b/drivers/irqchip/i= rq-riscv-imsic-platform.c index 643c8e459611..7eeb2dc59d82 100644 --- a/drivers/irqchip/irq-riscv-imsic-platform.c +++ b/drivers/irqchip/irq-riscv-imsic-platform.c @@ -19,6 +19,7 @@ #include #include #include +#include =20 #include #include "irq-riscv-imsic-state.h" @@ -69,7 +70,8 @@ static void imsic_irq_ack(struct irq_data *d) irq_move_irq(d); } =20 -static void imsic_irq_compose_vector_msg(struct imsic_vector *vec, struct = msi_msg *msg) +static void imsic_irq_compose_vector_msg(struct irq_data *d, struct imsic_= vector *vec, + struct msi_msg *msg) { phys_addr_t msi_addr; =20 @@ -79,14 +81,13 @@ static void imsic_irq_compose_vector_msg(struct imsic_v= ector *vec, struct msi_ms if (WARN_ON(!imsic_cpu_page_phys(vec->cpu, 0, &msi_addr))) return; =20 - msg->address_hi =3D upper_32_bits(msi_addr); - msg->address_lo =3D lower_32_bits(msi_addr); msg->data =3D vec->local_id; + msi_msg_set_addr(irq_data_get_msi_desc(d), msg, msi_addr); } =20 static void imsic_irq_compose_msg(struct irq_data *d, struct msi_msg *msg) { - imsic_irq_compose_vector_msg(irq_data_get_irq_chip_data(d), msg); + imsic_irq_compose_vector_msg(d, irq_data_get_irq_chip_data(d), msg); } =20 #ifdef CONFIG_SMP @@ -94,13 +95,15 @@ static void imsic_msi_update_msg(struct irq_data *d, st= ruct imsic_vector *vec) { struct msi_msg msg =3D { }; =20 - imsic_irq_compose_vector_msg(vec, &msg); + imsic_irq_compose_vector_msg(d, vec, &msg); irq_data_get_irq_chip(d)->irq_write_msi_msg(d, &msg); } =20 static int imsic_irq_set_affinity(struct irq_data *d, const struct cpumask= *mask_val, bool force) { + int err; + phys_addr_t msi_pa; struct imsic_vector *old_vec, *new_vec; struct imsic_vector tmp_vec; =20 @@ -135,6 +138,11 @@ static int imsic_irq_set_affinity(struct irq_data *d, = const struct cpumask *mask if (!new_vec) return -ENOSPC; =20 + imsic_cpu_page_phys(new_vec->cpu, 0, &msi_pa); + err =3D iommu_dma_prepare_msi(irq_data_get_msi_desc(d), msi_pa); + if (err) + return err; + /* * Device having non-atomic MSI update might see an intermediate * state when changing target IMSIC vector from one CPU to another. @@ -161,12 +169,12 @@ static int imsic_irq_set_affinity(struct irq_data *d,= const struct cpumask *mask imsic_msi_update_msg(irq_get_irq_data(d->irq), &tmp_vec); } =20 - /* Point device to the new vector */ - imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec); - /* Update irq descriptors with the new vector */ d->chip_data =3D new_vec; =20 + /* Point device to the new vector */ + imsic_msi_update_msg(irq_get_irq_data(d->irq), new_vec); + /* Update effective affinity */ irq_data_update_effective_affinity(d, cpumask_of(new_vec->cpu)); =20 @@ -225,6 +233,9 @@ static struct irq_chip imsic_irq_base_chip =3D { static int imsic_irq_domain_alloc(struct irq_domain *domain, unsigned int = virq, unsigned int nr_irqs, void *args) { + int err; + msi_alloc_info_t *info =3D args; + phys_addr_t msi_pa; struct imsic_vector *vec; =20 /* Multi-MSI is not supported yet. */ @@ -235,6 +246,11 @@ static int imsic_irq_domain_alloc(struct irq_domain *d= omain, unsigned int virq, if (!vec) return -ENOSPC; =20 + imsic_cpu_page_phys(vec->cpu, 0, &msi_pa); + err =3D iommu_dma_prepare_msi(info->desc, msi_pa); + if (err) + return err; + irq_domain_set_info(domain, virq, virq, &imsic_irq_base_chip, vec, handle_edge_irq, NULL, NULL); irq_set_noprobe(virq); --=20 2.34.1