From a6a082c35673019483cbe172cc417bdc501641e9 Mon Sep 17 00:00:00 2001 From: Mostafa Saleh Date: Wed, 29 Jan 2025 16:30:45 +0000 Subject: [PATCH] ANDROID: iommu/io-pgtable-arm: Don't return on invalid ptes The walker can be called for a range that contains invalid PTEs, For example, with a table that has some already unmapped pages, It's valid to unmap the whole table at once or even overwrite it with a block, that will trigger flush_walk() operation for the full table range which is not all valid. So, the flush_walk() will walk the whole range and decrement the refcount of the valid ptes which can be scattered. Bug: 357781595 Bug: 384432312 Change-Id: If32bd389f29bbe5f6fedf1537cafc3f2badecc63 Signed-off-by: Mostafa Saleh --- drivers/iommu/io-pgtable-arm-common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/io-pgtable-arm-common.c b/drivers/iommu/io-pgtable-arm-common.c index a8d803167fc2..a7d9604b102f 100644 --- a/drivers/iommu/io-pgtable-arm-common.c +++ b/drivers/iommu/io-pgtable-arm-common.c @@ -551,7 +551,7 @@ static phys_addr_t arm_lpae_iova_to_phys(struct io_pgtable_ops *ops, int ret; ret = __arm_lpae_iopte_walk(data, &walk_data, data->pgd, data->start_level); - if (ret) + if (ret || !iopte_valid(d.pte)) return 0; iova &= (ARM_LPAE_BLOCK_SIZE(d.lvl, data) - 1); @@ -614,8 +614,11 @@ static int io_pgtable_visit(struct arm_lpae_io_pgtable *data, return 0; } - if (!is_table) - return -EINVAL; + /* Don't fail the walk if one entry is invalid, just skip over it */ + if (!is_table) { + walk_data->addr += size; + return 0; + } ptep = iopte_deref(pte, data);