Commit 4a934d284d for qemu.org

commit 4a934d284dfac9fa19b0f47874f12d9b3519c21c
Author: Peter Maydell <peter.maydell@linaro.org>
Date:   Fri Nov 14 15:53:04 2025 +0000

    hw/arm/armv7m: Disable reentrancy guard for v7m_sysreg_ns_ops MRs

    For M-profile cores which support TrustZone, there are some memory
    areas which are "NS aliases" -- a Secure access to these addresses
    really performs an NS access to a different part of the device.  We
    implement these using MemoryRegionOps read and write functions which
    pass the access on with adjusted attributes using
    memory_region_dispatch_read() and memory_region_dispatch_write().

    Since the MR we are dispatching to is owned by the same device that
    owns the NS-alias MR (the TYPE_ARMV7M container object), this trips
    the reentrancy-guard that is applied by access_with_adjusted_size().

    Mark the NS alias MemoryRegions as disable_reentrancy_guard; this is
    safe because v7m_sysreg_ns_read() and v7m_sysreg_ns_write() do not
    touch any of the device's state.  (Any further reentrancy attempts by
    the underlying MR will still be caught.)

    Without this fix, an attempt to read from an address like 0xe002e010,
    which is a register in the NS systick alias, will fail and provoke

     qemu-system-arm: warning: Blocked re-entrant IO on MemoryRegion: v7m_systick at addr: 0x0

    We didn't notice this earlier because almost all code accesses
    the registers and systick via the non-alias addresses; the NS
    aliases are only need for the rarer case of Secure code that needs
    to manage the NS timer or system state on behalf of NS code.

    Note that although the v7m_systick_ops read and write functions
    also call memory_region_dispatch_{read,write}, this MR does not
    need to have the reentrancy-guard disabled because the underlying
    MR that it forwards to is owned by a different device (the
    TYPE_SYSTICK timer device).

    Reported via a stackoverflow question:
    https://stackoverflow.com/questions/79808107/what-this-error-is-even-about-qemu-system-arm-warning-blocked-re-entrant-io

    Cc: qemu-stable@nongnu.org
    Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
    Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
    Message-id: 20251114155304.2662414-1-peter.maydell@linaro.org

diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index c4a9c3ac52..7fa1b37630 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -442,6 +442,12 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
                               &v7m_sysreg_ns_ops,
                               sysbus_mmio_get_region(sbd, 0),
                               "nvic_sysregs_ns", 0x1000);
+        /*
+         * This MR calls memory_region_dispatch_read/write to access the
+         * real region for the NVIC sysregs (which is also owned by this
+         * device), so reentrancy through here is expected and safe.
+         */
+        s->sysreg_ns_mem.disable_reentrancy_guard = true;
         memory_region_add_subregion(&s->container, 0xe002e000,
                                     &s->sysreg_ns_mem);
     }
@@ -499,6 +505,12 @@ static void armv7m_realize(DeviceState *dev, Error **errp)
         memory_region_init_io(&s->systick_ns_mem, OBJECT(s),
                               &v7m_sysreg_ns_ops, &s->systickmem,
                               "v7m_systick_ns", 0xe0);
+        /*
+         * This MR calls memory_region_dispatch_read/write to access the
+         * real region for the systick regs (which is also owned by this
+         * device), so reentrancy through here is expected and safe.
+         */
+        s->systick_ns_mem.disable_reentrancy_guard = true;
         memory_region_add_subregion_overlap(&s->container, 0xe002e010,
                                             &s->systick_ns_mem, 1);
     }