diff options
| -rw-r--r-- | hw/riscv/riscv-iommu.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c index 96a7fbdefc..155190d032 100644 --- a/hw/riscv/riscv-iommu.c +++ b/hw/riscv/riscv-iommu.c @@ -558,6 +558,7 @@ static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState *s, MemTxResult res; dma_addr_t addr; uint64_t intn; + size_t offset; uint32_t n190; uint64_t pte[2]; int fault_type = RISCV_IOMMU_FQ_TTYPE_UADDR_WR; @@ -565,16 +566,18 @@ static MemTxResult riscv_iommu_msi_write(RISCVIOMMUState *s, /* Interrupt File Number */ intn = riscv_iommu_pext_u64(PPN_DOWN(gpa), ctx->msi_addr_mask); - if (intn >= 256) { + offset = intn * sizeof(pte); + + /* fetch MSI PTE */ + addr = PPN_PHYS(get_field(ctx->msiptp, RISCV_IOMMU_DC_MSIPTP_PPN)); + if (addr & offset) { /* Interrupt file number out of range */ res = MEMTX_ACCESS_ERROR; cause = RISCV_IOMMU_FQ_CAUSE_MSI_LOAD_FAULT; goto err; } - /* fetch MSI PTE */ - addr = PPN_PHYS(get_field(ctx->msiptp, RISCV_IOMMU_DC_MSIPTP_PPN)); - addr = addr | (intn * sizeof(pte)); + addr |= offset; res = dma_memory_read(s->target_as, addr, &pte, sizeof(pte), MEMTXATTRS_UNSPECIFIED); if (res != MEMTX_OK) { |