QEMU-Arm Archive on lore.kernel.org
 help / color / mirror / Atom feed
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: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-05  3:47 Kyle Fox [this message]
2026-06-08  9:37 ` [PATCH] target/arm: align down misaligned PMSAv7 MPU region base instead of dropping it Peter Maydell
2026-06-13  5:22   ` kylefoxaustin
2026-06-16  8:45     ` Peter Maydell

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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox