From nobody Sun Feb 8 04:13:26 2026 Received: from out30-131.freemail.mail.aliyun.com (out30-131.freemail.mail.aliyun.com [115.124.30.131]) (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 A31D630CDB0 for ; Thu, 22 Jan 2026 14:32:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.30.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769092365; cv=none; b=fSyJTzdUyZRiaw2BG8PUmeUjlNpjHLnAGAoBmKIX2zO+nf8XmUD4nsTp4/4lEm4HrR/kOCP31NYh+u1/yNvYIY+16qva+6EjRlk4J1yLp89yrLtKCLiGBlIkrRjcpOdqIk0HHpv9nulA0IzhZ41u3QOEvlLZCnDJsLQU6CrKQMk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1769092365; c=relaxed/simple; bh=JobbWyi35dBaTRlOiDrSW0ff78dEI0J9IcQnpnC8bXs=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=gU6siUrjtkWUdWotyvQ+WhiHJTnyG+nrlYAAXbsPRal92GqRu6C3whxnFlfElbKcfDm5AZHemeHRLdR7+1nBf2pCh6CyX7oycQmT10yibNx5y5LxYAVoHebeKCDuYxuFdIyfRBGG4aV3RORJRzuYq5I8OuxG5n+/8bnk4Hq1u1c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com; spf=pass smtp.mailfrom=linux.alibaba.com; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b=ERstbwQj; arc=none smtp.client-ip=115.124.30.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linux.alibaba.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linux.alibaba.com header.i=@linux.alibaba.com header.b="ERstbwQj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.alibaba.com; s=default; t=1769092353; h=From:To:Subject:Date:Message-Id:MIME-Version; bh=Z0T0NHnnLOBXCB1Q9RaOjVenK8UxFN8ICt7x482Hlzk=; b=ERstbwQjT371JxnzcM9dzqX983NwpGhkA+HcDWetoiR8aMVIL3Byx5AQhljhiv80LNimg4P/lV2cfNyOCj4D6iB7tkBOj/XR5GmPGRMeMTyw9tZ+cAtx8UREoAFe9ZK8zxVUTFdZSdvkkCmQH8eFISXF/lvg6fjf844Y2QHcnu0= Received: from localhost.localdomain(mailfrom:fangyu.yu@linux.alibaba.com fp:SMTPD_---0Wxcfz.h_1769092350 cluster:ay36) by smtp.aliyun-inc.com; Thu, 22 Jan 2026 22:32:32 +0800 From: fangyu.yu@linux.alibaba.com To: tjeznach@rivosinc.com, joro@8bytes.org, will@kernel.org, robin.murphy@arm.com, pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu, alex@ghiti.fr, baolu.lu@linux.intel.com, zong.li@sifive.com, andrew.jones@oss.qualcomm.com Cc: guoren@kernel.org, ajones@ventanamicro.com, iommu@lists.linux.dev, linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org, Fangyu Yu Subject: [PATCH v2] iommu/riscv: Add IOTINVAL after updating DDT/PDT entries Date: Thu, 22 Jan 2026 22:32:24 +0800 Message-Id: <20260122143224.25146-1-fangyu.yu@linux.alibaba.com> X-Mailer: git-send-email 2.39.3 (Apple Git-146) 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" From: Fangyu Yu Add riscv_iommu_iodir_iotinval() to perform required TLB and context cache invalidations after updating DDT or PDT entries, as mandated by the RISC-V IOMMU specification (Section 6.3.1 and 6.3.2). Fixes: 488ffbf18171 ("iommu/riscv: Paging domain support") Signed-off-by: Fangyu Yu Reviewed-by: Andrew Jones --- Changes in v2: - Reworked the patch formatting (per Drew). - Fixed the call site of riscv_iommu_iodir_iotinval() (per Drew). - Moved riscv_iommu_cmd_inval_vma() out of the conditional blocks to av= oid duplication (per Guoren). - Dropped the #if 0-guarded code (per Guoren). - Updated the Fixes: tag (per Drew). - Link to v1: https://lore.kernel.org/linux-riscv/20260108134855.91341-1-fangyu.yu@= linux.alibaba.com/ --- drivers/iommu/riscv/iommu.c | 70 +++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c index d9429097a2b5..c762b4f335d1 100644 --- a/drivers/iommu/riscv/iommu.c +++ b/drivers/iommu/riscv/iommu.c @@ -996,7 +996,67 @@ static void riscv_iommu_iotlb_inval(struct riscv_iommu= _domain *domain, } =20 #define RISCV_IOMMU_FSC_BARE 0 +/* + * This function sends IOTINVAL commands as required by the RISC-V + * IOMMU specification (Section 6.3.1 and 6.3.2 in 1.0 spec version) + * after modifying DDT or PDT entries + */ +static void riscv_iommu_iodir_iotinval(struct riscv_iommu_device *iommu, + bool inval_pdt, unsigned long iohgatp, + struct riscv_iommu_dc *dc, + struct riscv_iommu_pc *pc) +{ + struct riscv_iommu_command cmd; + + riscv_iommu_cmd_inval_vma(&cmd); =20 + if (FIELD_GET(RISCV_IOMMU_DC_IOHGATP_MODE, iohgatp) =3D=3D + RISCV_IOMMU_DC_IOHGATP_MODE_BARE) { + if (inval_pdt) { + /* + * IOTINVAL.VMA with GV=3DAV=3D0, and PSCV=3D1, and + * PSCID=3DPC.PSCID + */ + riscv_iommu_cmd_inval_set_pscid(&cmd, + FIELD_GET(RISCV_IOMMU_PC_TA_PSCID, pc->ta)); + } else { + if (!FIELD_GET(RISCV_IOMMU_DC_TC_PDTV, dc->tc) && + FIELD_GET(RISCV_IOMMU_DC_FSC_MODE, dc->fsc) !=3D + RISCV_IOMMU_DC_FSC_MODE_BARE) { + /* + * DC.tc.PDTV =3D=3D 0 && DC.fsc.MODE !=3D Bare + * IOTINVAL.VMA with GV=3DAV=3D0, and PSCV=3D1, and + * PSCID=3DDC.ta.PSCID + */ + riscv_iommu_cmd_inval_set_pscid(&cmd, + FIELD_GET(RISCV_IOMMU_DC_TA_PSCID, dc->ta)); + } + /* else: IOTINVAL.VMA with GV=3DAV=3DPSCV=3D0 */ + } + } else { + riscv_iommu_cmd_inval_set_gscid(&cmd, + FIELD_GET(RISCV_IOMMU_DC_IOHGATP_GSCID, iohgatp)); + + if (inval_pdt) { + /* + * IOTINVAL.VMA with GV=3D1, AV=3D0, and PSCV=3D1, and + * GSCID=3DDC.iohgatp.GSCID, PSCID=3DPC.PSCID + */ + riscv_iommu_cmd_inval_set_pscid(&cmd, + FIELD_GET(RISCV_IOMMU_PC_TA_PSCID, pc->ta)); + } + /* + * else: IOTINVAL.VMA with GV=3D1,AV=3DPSCV=3D0,and + * GSCID=3DDC.iohgatp.GSCID + * + * IOTINVAL.GVMA with GV=3D1,AV=3D0,and + * GSCID=3DDC.iohgatp.GSCID + * TODO: For now, the Second-Stage feature have not yet been merged, + * also issue IOTINVAL.GVMA once second-stage support is merged. + */ + } + riscv_iommu_cmd_send(iommu, &cmd); +} /* * Update IODIR for the device. * @@ -1031,6 +1091,11 @@ static void riscv_iommu_iodir_update(struct riscv_io= mmu_device *iommu, riscv_iommu_cmd_iodir_inval_ddt(&cmd); riscv_iommu_cmd_iodir_set_did(&cmd, fwspec->ids[i]); riscv_iommu_cmd_send(iommu, &cmd); + /* + * For now, the SVA and PASID features have not yet been merged, the + * default configuration is inval_pdt=3Dfalse and pc=3DNULL. + */ + riscv_iommu_iodir_iotinval(iommu, false, dc->iohgatp, dc, NULL); sync_required =3D true; } =20 @@ -1056,6 +1121,11 @@ static void riscv_iommu_iodir_update(struct riscv_io= mmu_device *iommu, riscv_iommu_cmd_iodir_inval_ddt(&cmd); riscv_iommu_cmd_iodir_set_did(&cmd, fwspec->ids[i]); riscv_iommu_cmd_send(iommu, &cmd); + /* + * For now, the SVA and PASID features have not yet been merged, the + * default configuration is inval_pdt=3Dfalse and pc=3DNULL. + */ + riscv_iommu_iodir_iotinval(iommu, false, dc->iohgatp, dc, NULL); } =20 riscv_iommu_cmd_sync(iommu, RISCV_IOMMU_IOTINVAL_TIMEOUT); --=20 2.50.1