Am 28.09.26 um 22:23 schrieb Matthew Rosato:
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: [email protected]
Signed-off-by: Matthew Rosato <[email protected]>
Looks good to me.
Acked-by: Christian Borntraeger <[email protected]>
---
hw/s390x/s390-pci-inst.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index 652e1712ec..a51543df44 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 = (start & ~(entry.len - 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);