From: Kyle Fox <kylefoxaustin.github@gmail.com>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: Kyle Fox <kylefoxaustin.github@gmail.com>,
qemu-arm@nongnu.org, qemu-devel@nongnu.org
Subject: [PATCH] target/arm: align down misaligned PMSAv7 MPU region base instead of dropping it
Date: Thu, 4 Jun 2026 22:47:29 -0500 [thread overview]
Message-ID: <20260605034729.2874861-1-kylefoxaustin.github@gmail.com> (raw)
When a PMSAv7 (ARMv7-M) MPU region's DRBAR base is not aligned to its
DRSR region size, get_phys_addr_pmsav7() logged a guest-error and
skipped the region entirely (continue). The architecture calls a
misaligned base UNPREDICTABLE, but real Cortex-M hardware does not
disable the region: RBAR.ADDR is only bits [31:log2(size)], so the
sub-size low bits are simply ignored and the region matches against the
aligned-down base.
NXP's i.MX95 Cortex-M7 firmware (and the MCUXpresso SDK demos) rely on
this. The M7 sets up a deny-all background region (region 0, whole
address space, AP=000) and then grants the peripheral space with a
512 MiB region programmed as DRBAR=0x4c800000 - misaligned, intended as
0x40000000. QEMU dropped that region, so a privileged access to e.g.
LPUART3 at 0x42570000 fell through to the deny-all region and took a
MemManage fault (CFSR.DACCVIOL), trapping the firmware in its default
fault handler before it could print anything.
Align the base down to the region size (base &= ~rmask) to match
silicon, and keep a (now-accurate) guest-error note. This only changes
the previously-UNPREDICTABLE misaligned case; correctly-aligned regions
are unaffected.
Signed-off-by: Kyle Fox <kylefoxaustin.github@gmail.com>
---
Found while bringing up the i.MX95 Cortex-M7 in an out-of-tree machine
model: the M7's MCUXpresso-SDK firmware programs the misaligned 512 MiB
peripheral region described above. With this change the firmware reaches
its FreeRTOS/UART banner; without it the region was dropped and the first
peripheral access took a MemManage DACCVIOL.
The new branch only executes in the previously-UNPREDICTABLE misaligned
case (base & rmask != 0), so correctly-aligned MPU regions are unchanged.
Tested on master: qemu-system-arm builds clean, and the ARMv7-M / MPS2
qtests pass with no regression -- boot-serial (incl. stm32vldiscovery,
Cortex-M3), the stm32l4x5 suite (Cortex-M4: exti/gpio/rcc/syscfg/usart),
microbit, sse-timer and cmsdk-apb-watchdog.
target/arm/ptw.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/target/arm/ptw.c b/target/arm/ptw.c
index 0a5201763a..3914d05449 100644
--- a/target/arm/ptw.c
+++ b/target/arm/ptw.c
@@ -2665,11 +2665,24 @@ static bool get_phys_addr_pmsav7(CPUARMState *env,
rmask = (1ull << rsize) - 1;
if (base & rmask) {
+ /*
+ * The region base is not aligned to the region size. The
+ * architecture calls this UNPREDICTABLE, but real Cortex-M
+ * hardware ignores the sub-size low bits of RBAR.ADDR (the
+ * field is only [31:log2(size)]) and matches against the
+ * aligned-down base rather than disabling the region. NXP's
+ * i.MX95 M7 firmware relies on this for its peripheral
+ * region (e.g. DRBAR 0x4c800000 with a 512MB size, intended
+ * as 0x40000000), so align down to match silicon instead of
+ * dropping the region (which would leave the access to fall
+ * through to a lower-priority deny-all background region).
+ */
qemu_log_mask(LOG_GUEST_ERROR,
- "DRBAR[%d]: 0x%" PRIx32 " misaligned "
- "to DRSR region size, mask = 0x%" PRIx32 "\n",
- n, base, rmask);
- continue;
+ "DRBAR[%d]: 0x%" PRIx32 " not aligned to DRSR "
+ "region size (mask 0x%" PRIx32 "); aligning down "
+ "to 0x%" PRIx32 " to match Cortex-M behaviour\n",
+ n, base, rmask, base & ~rmask);
+ base &= ~rmask;
}
if (address < base || address > base + rmask) {
--
2.34.1
reply other threads:[~2026-06-05 4:40 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260605034729.2874861-1-kylefoxaustin.github@gmail.com \
--to=kylefoxaustin.github@gmail.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.