From nobody Mon Oct 27 01:13:59 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1759462640; cv=none; d=zohomail.com; s=zohoarc; b=SNI85u0OHidGx2NOlTtXbFXPkAFKNGRXfnyigNkzLCqFI5kC/xLOWwpGs03VQvAmORNvkQiVCmCAmpCaR448xHQziAvsCj2ZkA3Im3eFu74qIViYWgyZBHbdAMgca0lmNIduzyT9GbgoYu7IyLttbFJfSJRfXaZVVf6Oli2TnvA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759462640; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ik1JHVLc+Pu/i5FRVMv/NQaG1gi/dWuXVteURjPkC2o=; b=nUEV8kLLqC4Jg6FtzuSfD5b3HWke1Q9EMG65F+WVpI2bLXDXerlZ4KX26HSlKg0XD1kvewelGiFJ/e3NiCS+g4itch5cZda2Hcd7wZHdLBnGZCpGbGXKPCNal5uB+PfpkZ2N8ebDy1Bj6OaZkVa7pOkKgFc5+f3Y5g6hi7nWYzQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759462640869612.239585963208; Thu, 2 Oct 2025 20:37:20 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v4WTp-0007SZ-Hl; Thu, 02 Oct 2025 23:29:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v4WTl-0007Rw-Rw for qemu-devel@nongnu.org; Thu, 02 Oct 2025 23:29:09 -0400 Received: from mail-pj1-x1034.google.com ([2607:f8b0:4864:20::1034]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1v4WTe-0001Qd-D4 for qemu-devel@nongnu.org; Thu, 02 Oct 2025 23:29:09 -0400 Received: by mail-pj1-x1034.google.com with SMTP id 98e67ed59e1d1-33274fcf5c1so1848118a91.1 for ; Thu, 02 Oct 2025 20:29:00 -0700 (PDT) Received: from toolbx.alistair23.me (2403-580b-97e8-0-82ce-f179-8a79-69f4.ip6.aussiebb.net. [2403:580b:97e8:0:82ce:f179:8a79:69f4]) by smtp.gmail.com with ESMTPSA id 41be03b00d2f7-b62ce55205csm844202a12.18.2025.10.02.20.28.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Oct 2025 20:28:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1759462138; x=1760066938; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ik1JHVLc+Pu/i5FRVMv/NQaG1gi/dWuXVteURjPkC2o=; b=IPLGQAaVkT8GVaby1kGvy5h9PpOjEYVoyr1OTlMGCUU31ECKt9SWZU1dESzoH9xHJW vEvjNA2G+A7sBGyeai1toBat0puA2iCUCphVT7sdpU9W8b/OaZM6Wj+mQ/Uc+kJyCnxe 9ivH8Ut9ZnmnFJTXkX3Zxcn41iCbAvYyEOlJuprEzeJYNDrcS78pOOfivwyeT0I/XyU+ GOYqS2RZKr14v5AROsPl6o35qYUOIvHarYc3orctAFhEHupVKYFf5pk6yKAYRz3ekogC s9o70B+0wXIbWXjAoAkKEUQWzeBDl8PMvqNLlyAz/TS4bNB4jxgmscMRX48e6uIsu4Be sfqQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759462138; x=1760066938; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ik1JHVLc+Pu/i5FRVMv/NQaG1gi/dWuXVteURjPkC2o=; b=IN9rbd4Bhal9JKaapHrUsGyCk9fEVnDD5PKq4dBL5arT6MhQK2p4h2YODY0tecGUvr 8F0IuIeSfAC4CsOnhvg/DEyM4r4WUo7eQRZ7d4fQUTPcrMaH2aOejzqGWSZFpianve/8 GOq6ItvYPL+rw33hndXTd4RwvYAlNsqnOD3/czI6JyBPacyLzy1b0jV6azUOJTHJ/mlI ot/3zPDAaZIbNvFW8fX+g6IjTt0D/2rNUwzoV3Kz5V1QA5NOooYftAIl4fEqNvw1LGwy IfSnSVvwepnvLGQzzwY/9+YY5r4M2+vXegeDFWAQEmRTfdkrgNhNo/ZQ06lUXhEJSNy3 WZog== X-Gm-Message-State: AOJu0YzkvYbRU7e1xJmEIeMV9RqtQWYIbeGKub5HLw76YtGBcSLsTo0V /Qg1Mpm/i1zUiPScciXjChg8W2bmRVRE0FXNyt1qn6MNPMi0/A1TPat+J9x4mg== X-Gm-Gg: ASbGncsBLFOhI3ue8PjhUptIylUPn/ffv9iFNUZJT4Q0HbYBTxZSJKvbkg9hNLzQ43n IgFGEbW3R077bjr5+DkYLp4MTgDsuDoASL/fUCe5NHazmPRLWq8KRYtERqDL0cBYY+lflpk9qNv GQylpfVwbaJa+7WiIjdTNYozUNNpAhPa16sDdVh4puSiauPwpca8XSeTmVuNJi4Q5arigblvRXF IdPAJhsziknIiXOCyliWZT8AV4QxqXl8zewb9FrGB92JDCajSpBMWZw+HXI/9am8oEXZevMtFoE Jd4Yr3er75bMM2n/awqKvnq+RRO0WLnienRQ7iXZBt+iLTyHEal9u1Wa3cZ5C1P9MZIwsrOJG/l LNX7Yvws4Tjfbg2Gt/V+BLKeOxRuX5sX8eyurQCKXh+6l7s/r5SMZQ8kMDk+wxeERpEwGp1eLVg wWlwcmIzOIkK6ufM5SXtH/gA2TcvbnBFMdP3t6wXH/vjDtKw2etN9Sw7CoMzAjNgU= X-Google-Smtp-Source: AGHT+IG7wVRiMbW1WM09nZNhYK5L4IOqVNVO7AohMlZdBTJMJhV8zwKyYgK49xKAiCtbXSi9JIbdTQ== X-Received: by 2002:a17:90b:1811:b0:329:f630:6c3 with SMTP id 98e67ed59e1d1-339c278a004mr2062931a91.20.1759462137573; Thu, 02 Oct 2025 20:28:57 -0700 (PDT) From: alistair23@gmail.com X-Google-Original-From: alistair.francis@wdc.com To: qemu-devel@nongnu.org Cc: alistair23@gmail.com, "Guo Ren (Alibaba DAMO Academy)" , qemu-stable@nongnu.org, Sebastien Boeuf , Tomasz Jeznach , Weiwei Li , Nutty Liu , Chen Pei , =?UTF-8?q?Fangyu=20Yu=C2=A0?= , Alistair Francis Subject: [PULL 24/26] hw/riscv/riscv-iommu: Fixup PDT Nested Walk Date: Fri, 3 Oct 2025 13:27:16 +1000 Message-ID: <20251003032718.1324734-25-alistair.francis@wdc.com> X-Mailer: git-send-email 2.51.0 In-Reply-To: <20251003032718.1324734-1-alistair.francis@wdc.com> References: <20251003032718.1324734-1-alistair.francis@wdc.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::1034; envelope-from=alistair23@gmail.com; helo=mail-pj1-x1034.google.com X-Spam_score_int: -17 X-Spam_score: -1.8 X-Spam_bar: - X-Spam_report: (-1.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_ENVFROM_END_DIGIT=0.25, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1759462642089116600 From: "Guo Ren (Alibaba DAMO Academy)" Current implementation is wrong when iohgatp !=3D bare. The RISC-V IOMMU specification has defined that the PDT is based on GPA, not SPA. So this patch fixes the problem, making PDT walk correctly when the G-stage table walk is enabled. Fixes: 0c54acb8243d ("hw/riscv: add RISC-V IOMMU base emulation") Cc: qemu-stable@nongnu.org Cc: Sebastien Boeuf Cc: Tomasz Jeznach Reviewed-by: Weiwei Li Reviewed-by: Nutty Liu Signed-off-by: Guo Ren (Alibaba DAMO Academy) Tested-by: Chen Pei Tested-by: Fangyu Yu=C2=A0 Message-ID: <20250913041233.972870-1-guoren@kernel.org> [ Changes by AF: - Add braces to if statements ] Signed-off-by: Alistair Francis --- hw/riscv/riscv-iommu.c | 143 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 141 insertions(+), 2 deletions(-) diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c index 155190d032..b33c7fe325 100644 --- a/hw/riscv/riscv-iommu.c +++ b/hw/riscv/riscv-iommu.c @@ -869,6 +869,145 @@ static bool riscv_iommu_validate_process_ctx(RISCVIOM= MUState *s, return true; } =20 +/** + * pdt_memory_read: PDT wrapper of dma_memory_read. + * + * @s: IOMMU Device State + * @ctx: Device Translation Context with devid and pasid set + * @addr: address within that address space + * @buf: buffer with the data transferred + * @len: length of the data transferred + * @attrs: memory transaction attributes + */ +static MemTxResult pdt_memory_read(RISCVIOMMUState *s, + RISCVIOMMUContext *ctx, + dma_addr_t addr, + void *buf, dma_addr_t len, + MemTxAttrs attrs) +{ + uint64_t gatp_mode, pte; + struct { + unsigned char step; + unsigned char levels; + unsigned char ptidxbits; + unsigned char ptesize; + } sc; + MemTxResult ret; + dma_addr_t base =3D addr; + + /* G stages translation mode */ + gatp_mode =3D get_field(ctx->gatp, RISCV_IOMMU_ATP_MODE_FIELD); + if (gatp_mode =3D=3D RISCV_IOMMU_DC_IOHGATP_MODE_BARE) { + goto out; + } + + /* G stages translation tables root pointer */ + base =3D PPN_PHYS(get_field(ctx->gatp, RISCV_IOMMU_ATP_PPN_FIELD)); + + /* Start at step 0 */ + sc.step =3D 0; + + if (s->fctl & RISCV_IOMMU_FCTL_GXL) { + /* 32bit mode for GXL =3D=3D 1 */ + switch (gatp_mode) { + case RISCV_IOMMU_DC_IOHGATP_MODE_SV32X4: + if (!(s->cap & RISCV_IOMMU_CAP_SV32X4)) { + return MEMTX_ACCESS_ERROR; + } + sc.levels =3D 2; + sc.ptidxbits =3D 10; + sc.ptesize =3D 4; + break; + default: + return MEMTX_ACCESS_ERROR; + } + } else { + /* 64bit mode for GXL =3D=3D 0 */ + switch (gatp_mode) { + case RISCV_IOMMU_DC_IOHGATP_MODE_SV39X4: + if (!(s->cap & RISCV_IOMMU_CAP_SV39X4)) { + return MEMTX_ACCESS_ERROR; + } + sc.levels =3D 3; + sc.ptidxbits =3D 9; + sc.ptesize =3D 8; + break; + case RISCV_IOMMU_DC_IOHGATP_MODE_SV48X4: + if (!(s->cap & RISCV_IOMMU_CAP_SV48X4)) { + return MEMTX_ACCESS_ERROR; + } + sc.levels =3D 4; + sc.ptidxbits =3D 9; + sc.ptesize =3D 8; + break; + case RISCV_IOMMU_DC_IOHGATP_MODE_SV57X4: + if (!(s->cap & RISCV_IOMMU_CAP_SV57X4)) { + return MEMTX_ACCESS_ERROR; + } + sc.levels =3D 5; + sc.ptidxbits =3D 9; + sc.ptesize =3D 8; + break; + default: + return MEMTX_ACCESS_ERROR; + } + } + + do { + const unsigned va_bits =3D (sc.step ? 0 : 2) + sc.ptidxbits; + const unsigned va_skip =3D TARGET_PAGE_BITS + sc.ptidxbits * + (sc.levels - 1 - sc.step); + const unsigned idx =3D (addr >> va_skip) & ((1 << va_bits) - 1); + const dma_addr_t pte_addr =3D base + idx * sc.ptesize; + + /* Address range check before first level lookup */ + if (!sc.step) { + const uint64_t va_mask =3D (1ULL << (va_skip + va_bits)) - 1; + if ((addr & va_mask) !=3D addr) { + return MEMTX_ACCESS_ERROR; + } + } + + /* Read page table entry */ + if (sc.ptesize =3D=3D 4) { + uint32_t pte32 =3D 0; + ret =3D ldl_le_dma(s->target_as, pte_addr, &pte32, attrs); + pte =3D pte32; + } else { + ret =3D ldq_le_dma(s->target_as, pte_addr, &pte, attrs); + } + if (ret !=3D MEMTX_OK) { + return ret; + } + + sc.step++; + hwaddr ppn =3D pte >> PTE_PPN_SHIFT; + + if (!(pte & PTE_V)) { + return MEMTX_ACCESS_ERROR; /* Invalid PTE */ + } else if (!(pte & (PTE_R | PTE_W | PTE_X))) { + base =3D PPN_PHYS(ppn); /* Inner PTE, continue walking */ + } else if ((pte & (PTE_R | PTE_W | PTE_X)) =3D=3D PTE_W) { + return MEMTX_ACCESS_ERROR; /* Reserved leaf PTE flags: PTE_W */ + } else if ((pte & (PTE_R | PTE_W | PTE_X)) =3D=3D (PTE_W | PTE_X))= { + return MEMTX_ACCESS_ERROR; /* Reserved leaf PTE flags: PTE_W += PTE_X */ + } else if (ppn & ((1ULL << (va_skip - TARGET_PAGE_BITS)) - 1)) { + return MEMTX_ACCESS_ERROR; /* Misaligned PPN */ + } else { + /* Leaf PTE, translation completed. */ + base =3D PPN_PHYS(ppn) | (addr & ((1ULL << va_skip) - 1)); + break; + } + + if (sc.step =3D=3D sc.levels) { + return MEMTX_ACCESS_ERROR; /* Can't find leaf PTE */ + } + } while (1); + +out: + return dma_memory_read(s->target_as, base, buf, len, attrs); +} + /* * RISC-V IOMMU Device Context Loopkup - Device Directory Tree Walk * @@ -1041,7 +1180,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, = RISCVIOMMUContext *ctx) */ const int split =3D depth * 9 + 8; addr |=3D ((ctx->process_id >> split) << 3) & ~TARGET_PAGE_MASK; - if (dma_memory_read(s->target_as, addr, &de, sizeof(de), + if (pdt_memory_read(s, ctx, addr, &de, sizeof(de), MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT; } @@ -1056,7 +1195,7 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, = RISCVIOMMUContext *ctx) =20 /* Leaf entry in PDT */ addr |=3D (ctx->process_id << 4) & ~TARGET_PAGE_MASK; - if (dma_memory_read(s->target_as, addr, &dc.ta, sizeof(uint64_t) * 2, + if (pdt_memory_read(s, ctx, addr, &dc.ta, sizeof(uint64_t) * 2, MEMTXATTRS_UNSPECIFIED) !=3D MEMTX_OK) { return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT; } --=20 2.51.0