riscv_iommu_translate() allocates an IOATC entry before passing it to riscv_iommu_iot_update(). The update helper normally transfers ownership to the hash table.
When ioatc-limit is zero, however, the helper returns without inserting or freeing the entry. Every cacheable non-identity translation therefore leaks one RISCVIOMMUEntry. Avoid this by disabling caching at the caller when ioatc-limit is zero, so riscv_iommu_translate() does not allocate an IOATC entry in the first place. This avoids special-casing entry freeing in riscv_iommu_iot_update() and keeps the ownership semantics simpler. Suggested-by: Daniel Henrique Barboza <[email protected]> Fixes: 9d085a1c3cb2 ("hw/riscv/riscv-iommu: add Address Translation Cache (IOATC)") Cc: [email protected] Signed-off-by: Tan Chi <[email protected]> --- v2: - Disable caching when ioatc-limit is zero instead of freeing the allocated entry in riscv_iommu_iot_update(). hw/riscv/riscv-iommu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c index 323a041b4a..866f49cc39 100644 --- a/hw/riscv/riscv-iommu.c +++ b/hw/riscv/riscv-iommu.c @@ -2919,7 +2919,8 @@ static IOMMUTLBEntry riscv_iommu_memory_region_translate( /* Translation disabled or invalid. */ iotlb.addr_mask = 0; iotlb.perm = IOMMU_NONE; - } else if (riscv_iommu_translate(as->iommu, ctx, &iotlb, true)) { + } else if (riscv_iommu_translate(as->iommu, ctx, &iotlb, + as->iommu->iot_limit > 0)) { /* Translation disabled or fault reported. */ iotlb.addr_mask = 0; iotlb.perm = IOMMU_NONE; -- 2.53.0
