hw/riscv/riscv-iommu: Fix process directory table walk

The PPN field in a non-leaf PDT entry is positioned differently from that
in a leaf PDT entry. The original implementation incorrectly used the leaf
entry's PPN mask to extract the PPN from a non-leaf entry, leading to an
erroneous page table walk.

This commit introduces new macros to properly define the fields for
non-leaf PDT entries and corrects the page table walk.

Signed-off-by: Jason Chien <jason.chien@sifive.com>
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Message-ID: <20250301173751.9446-1-jason.chien@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Jason Chien 2025-03-02 01:37:51 +08:00 committed by Alistair Francis
parent d2c5759c8d
commit 3ea8fb521d
2 changed files with 7 additions and 3 deletions

View file

@ -415,12 +415,16 @@ enum riscv_iommu_fq_causes {
#define RISCV_IOMMU_DC_MSIPTP_MODE_OFF 0 #define RISCV_IOMMU_DC_MSIPTP_MODE_OFF 0
#define RISCV_IOMMU_DC_MSIPTP_MODE_FLAT 1 #define RISCV_IOMMU_DC_MSIPTP_MODE_FLAT 1
/* 2.2 Process Directory Table */
#define RISCV_IOMMU_PDTE_VALID BIT_ULL(0)
#define RISCV_IOMMU_PDTE_PPN RISCV_IOMMU_PPN_FIELD
/* Translation attributes fields */ /* Translation attributes fields */
#define RISCV_IOMMU_PC_TA_V BIT_ULL(0) #define RISCV_IOMMU_PC_TA_V BIT_ULL(0)
#define RISCV_IOMMU_PC_TA_RESERVED GENMASK_ULL(63, 32) #define RISCV_IOMMU_PC_TA_RESERVED GENMASK_ULL(63, 32)
/* First stage context fields */ /* First stage context fields */
#define RISCV_IOMMU_PC_FSC_PPN GENMASK_ULL(43, 0) #define RISCV_IOMMU_PC_FSC_PPN RISCV_IOMMU_ATP_PPN_FIELD
#define RISCV_IOMMU_PC_FSC_RESERVED GENMASK_ULL(59, 44) #define RISCV_IOMMU_PC_FSC_RESERVED GENMASK_ULL(59, 44)
enum riscv_iommu_fq_ttypes { enum riscv_iommu_fq_ttypes {

View file

@ -1042,10 +1042,10 @@ static int riscv_iommu_ctx_fetch(RISCVIOMMUState *s, RISCVIOMMUContext *ctx)
return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT; return RISCV_IOMMU_FQ_CAUSE_PDT_LOAD_FAULT;
} }
le64_to_cpus(&de); le64_to_cpus(&de);
if (!(de & RISCV_IOMMU_PC_TA_V)) { if (!(de & RISCV_IOMMU_PDTE_VALID)) {
return RISCV_IOMMU_FQ_CAUSE_PDT_INVALID; return RISCV_IOMMU_FQ_CAUSE_PDT_INVALID;
} }
addr = PPN_PHYS(get_field(de, RISCV_IOMMU_PC_FSC_PPN)); addr = PPN_PHYS(get_field(de, RISCV_IOMMU_PDTE_PPN));
} }
riscv_iommu_hpm_incr_ctr(s, ctx, RISCV_IOMMU_HPMEVENT_PD_WALK); riscv_iommu_hpm_incr_ctr(s, ctx, RISCV_IOMMU_HPMEVENT_PD_WALK);