On Tue, 9 Dec 2025 12:22:09 +0000 Mark Burton <[email protected]> wrote:
>
> Also turns out that we have a very similar issue (though not exactly the
> same, and unfortunately doesn’t get fixed by this patch)
>
> If an instruction is going to do multiple accesses to memory - (something
> that sets an area of memory to zero, or a DMA or….) typically we probe it, if
> that fails, go ahead and do the access using MMIO. If (by chance) we then get
> a Memory region added, lots of bad stuff happens.

FWIW, this exposed a bug downstream, for which the following workaround was
temporary applied:

diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index b09229dae8..90011e5671 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -2529,4 +2529,5 @@ static uint64_t int_st_mmio_leN(CPUState *cpu, 
CPUTLBEntryFull *full,
                                 MemoryRegion *mr, hwaddr mr_offset)
 {
+    vaddr orig_vaddr = addr;
     do {
         MemOp this_mop;
@@ -2570,5 +2571,6 @@ static uint64_t int_st_mmio_leN(CPUState *cpu, 
CPUTLBEntryFull *full,
         }
         if (this_size == 8) {
-            return 0;
+            val_le = 0;
+            break;
         }

@@ -2579,4 +2581,9 @@ static uint64_t int_st_mmio_leN(CPUState *cpu, 
CPUTLBEntryFull *full,
     } while (size);

+    if (!memory_region_get_iommu(mr)) {
+        tlb_set_page(cpu, orig_vaddr, cpu_get_phys_page_debug(cpu, orig_vaddr),
+                     PAGE_READ | PAGE_WRITE, mmu_idx, TARGET_PAGE_SIZE);
+    }
+
     return val_le;
 }
--- 8< ---

> One could expect many things  - there used to be a cache which hid this issue
> - you could also expect memory regions to be added only ‘outside’ of an
> instruction execution block - or you could expect that adding a memory region
> shouldn’t break the MMIO access, or …..

The cache Mark has mentioned here is `cpuas->memory_dispatch`, which was
removed at 2865bf1c57 (system/physmem: fix use-after-free with dispatch,
2025-07-24).

Reply via email to