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).