# ARM STM instruction: page fault problem with MMIO

The ARM STM instruction is described here in the ARM manual. This instruction writes all or a subset of registers at memory locations starting from a base memory address. The manual does not impose any restriction on the start address. So, can the start address be such that some/all of the writes end up in MMIO address? If so, there can be a problematic scenario where a page fault happens in the execution of the STM instruction: Suppose the base memory address is b and 10 registers are to be written. The range b to b+5 belongs one page and the range b+6 - b+9 belongs to the next page. Suppose the virtual first page (where b belongs) is mapped to a physical page that corresponds to MMIO. Suppose the next virtual page is mapped to DRAM. Suppose that whe the STM execution tries to do the 7th write, to the address b+6, a page fault happens because the DRAM page is swapped out. The page fault handler loads that DRAM page and restarts the STM instruction. The first 6 writes (b to b+5) will be done again. Because these writes go to MMIO which can be mapped to devices, this operation may not be idempotent, e.g. it can launch some missiles twice!. The first 6 writes should not be repeated. How do page handlers handle this problem, if they handle it at all?

The STM instruction is just an example. The same problem happens with any instruction that does multiple writes that span different virtual pages.

What if the STM instruction were executed speculatively, and an instruction ahead of it faults? Or it's behind a mispredicted branch?

I can't speak for all ARM variants (things have probably changed over time), but the semantics of any instruction must be that if the instruction causes a fault, it's as if the instruction didn't happen.

What modern ARM cores probably do is use the store buffer. All stores (apart from TCM, which is by definition not MMIO) go through the store buffer. The only difference is in how the store buffer is flushed.

Presumably the store buffer has enough entries to satisfy a STM instruction. If the instruction (or an instruction ahead of it) faults, the relevant entries in the store buffer are purged. When the instruction retires (i.e. when it reaches the head of the reorder buffer), the stores are released for writing.