viommu_add_resv_mem() walks vdev->resv_regions to find the insertion point. When every element has a smaller start address, the list_for_each_entry() iterator ends up one past the last entry, and &next->list then aliases the list head, so the following list_add_tail() still appends at the tail. The result is correct, but using the iterator after the loop is undefined per the list_for_each_entry() contract.
The loop only needs a list_head as the insertion point, so iterate with list_for_each() and keep the typed list_entry() dereference inside the loop body. No functional change. Suggested-by: Robin Murphy <[email protected]> Signed-off-by: Maoyi Xie <[email protected]> --- drivers/iommu/virtio-iommu.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/iommu/virtio-iommu.c b/drivers/iommu/virtio-iommu.c index 587fc13197f1..1d58d6b626a5 100644 --- a/drivers/iommu/virtio-iommu.c +++ b/drivers/iommu/virtio-iommu.c @@ -486,7 +486,8 @@ static int viommu_add_resv_mem(struct viommu_endpoint *vdev, size_t size; u64 start64, end64; phys_addr_t start, end; - struct iommu_resv_region *region = NULL, *next; + struct iommu_resv_region *region = NULL; + struct list_head *pos; unsigned long prot = IOMMU_WRITE | IOMMU_NOEXEC | IOMMU_MMIO; start = start64 = le64_to_cpu(mem->start); @@ -520,11 +521,14 @@ static int viommu_add_resv_mem(struct viommu_endpoint *vdev, return -ENOMEM; /* Keep the list sorted */ - list_for_each_entry(next, &vdev->resv_regions, list) { + list_for_each(pos, &vdev->resv_regions) { + struct iommu_resv_region *next = + list_entry(pos, struct iommu_resv_region, list); + if (next->start > region->start) break; } - list_add_tail(®ion->list, &next->list); + list_add_tail(®ion->list, pos); return 0; } -- 2.34.1

