Commit e57ad36701 for qemu.org

commit e57ad36701886404baaf5216bacfa9a21f98fd6e
Author: Matthew Rosato <mjrosato@linux.ibm.com>
Date:   Tue Sep 29 11:30:10 2026 -0400

    s390x/pci: Fix frame stepping in rpcit_service_call()

    When walking the guest IO address table, an invalid segment or region
    entry causes table_translate() to return entry.len equal to the frame
    size for that table level (1 MiB for ST, 2 GiB for RT).  Adding
    entry.len directly to start only advances to the correct next frame
    boundary if start is already frame-aligned at that level -- which is
    true for a well-behaved Linux guest but not a general requirement.

    Add logic to advance start to the next frame boundary rather than
    simply adding entry.len.  For a frame-aligned start (the typical,
    well-behaved case) the result is identical.

    Fixes: 0125861eacc3 ("s390x/pci: fixup the code walking IOMMU tables")
    Cc: qemu-stable@nongnu.org
    Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
    Reviewed-by: Eric Farman <farman@linux.ibm.com>
    Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
    Link: https://lore.kernel.org/qemu-devel/20260929153012.774530-2-mjrosato@linux.ibm.com
    Signed-off-by: Eric Farman <farman@linux.ibm.com>

diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 652e1712ec..bac813fb6a 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -808,7 +808,8 @@ int rpcit_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2, uintptr_t ra)
             coalesce = 0;
         }

-        start += entry.len;
+        /* Advance to next frame boundary if start was not frame-aligned */
+        start = QEMU_ALIGN_UP(start + 1, entry.len);
         while (entry.iova < start && entry.iova < end) {
             if (dma_avail > 0 || entry.perm == IOMMU_NONE) {
                 dma_avail = s390_pci_update_iotlb(iommu, &entry);