* [PATCH] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults @ 2026-06-05 3:50 Kyle Fox 2026-06-08 11:23 ` Peter Maydell 2026-06-15 0:08 ` [PATCH v2] " Kyle Fox 0 siblings, 2 replies; 5+ messages in thread From: Kyle Fox @ 2026-06-05 3:50 UTC (permalink / raw) To: Peter Maydell; +Cc: Kyle Fox, qemu-arm, qemu-devel M-profile CCR.BFHFNMIGN lets software executing at a negative execution priority (in HardFault/NMI, or with FAULTMASK set) suppress precise data BusFaults caused by load/store instructions: the access completes returning UNKNOWN data, the fault status is recorded in BFSR/BFAR, but no BusFault exception is taken. Software uses this to probe for the presence of a device. QEMU stored CCR.BFHFNMIGN but never consumed it: arm_cpu_do_transaction_ failed() always raised the external abort, which arm_v7m_cpu_do_interrupt() pended as a BusFault and then escalated to a HardFault it could not take at priority -1, aborting the VM with "Lockup: can't escalate 3 to HardFault". Honour the bit in arm_cpu_do_transaction_failed(): when the access is a data access from M-profile code at negative priority with BFHFNMIGN set, record PRECISERR/BFARVALID and BFAR and return without raising, so the faulting instruction completes instead of re-faulting forever. Instruction fetches are unaffected, since BFHFNMIGN applies only to data accesses. This surfaced running the real NXP i.MX 95 System Manager firmware on the emulated Cortex-M33: its SystemMemoryProbe() (set BFHFNMIGN + FAULTMASK, do the access, test CFSR.BFARVALID) locked up the VM. With this change the SM's debug-monitor memory-probe commands run and recover correctly. Signed-off-by: Kyle Fox <kylefoxaustin.github@gmail.com> --- Found while bringing up an out-of-tree i.MX 95 machine running the real NXP System Manager firmware on the emulated Cortex-M33; the change is generic to any ARMv7-M guest that probes for devices via BusFault suppression. It is independent of (and posted alongside) a separate PMSAv7 MPU align-down fix from the same bring-up. The new path only runs for an M-profile data access at negative priority with CCR.BFHFNMIGN set - the previously-broken case that aborted the VM. Normal BusFaults (no BFHFNMIGN, or at non-negative priority) and instruction fetches 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/tcg/tlb_helper.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index f90765cb59..cbef9cb03e 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -10,6 +10,7 @@ #include "helper.h" #include "internals.h" #include "cpu-features.h" +#include "hw/intc/armv7m_nvic.h" /* * Returns true if the stage 1 translation regime is using LPAE format page @@ -318,8 +319,31 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, MemTxResult response, uintptr_t retaddr) { ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; ARMMMUFaultInfo fi = {}; + /* + * For M-profile, CCR.BFHFNMIGN lets software executing at a negative + * priority (in HardFault/NMI, or with FAULTMASK set) suppress precise + * data BusFaults from load/store instructions: the access completes + * returning UNKNOWN data (the store is dropped), the fault status is + * recorded in BFSR/BFAR, but no BusFault exception is taken. This is + * the mechanism software uses to probe for the presence of a device + * (e.g. the NXP System Manager's SystemMemoryProbe). Honour it by + * recording the status and returning without raising, so the faulting + * instruction completes rather than re-faulting forever. BFHFNMIGN + * applies only to data accesses, so instruction fetches are unaffected. + */ + if (arm_feature(env, ARM_FEATURE_M) && + access_type != MMU_INST_FETCH && + (env->v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK) && + armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) { + env->v7m.cfsr[M_REG_NS] |= + (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK); + env->v7m.bfar = addr; + return; + } + /* now we have a real cpu fault */ cpu_restore_state(cs, retaddr); -- 2.34.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults 2026-06-05 3:50 [PATCH] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults Kyle Fox @ 2026-06-08 11:23 ` Peter Maydell 2026-06-13 5:17 ` kylefoxaustin 2026-06-15 0:08 ` [PATCH v2] " Kyle Fox 1 sibling, 1 reply; 5+ messages in thread From: Peter Maydell @ 2026-06-08 11:23 UTC (permalink / raw) To: Kyle Fox; +Cc: qemu-arm, qemu-devel On Fri, 5 Jun 2026 at 04:50, Kyle Fox <kylefoxaustin.github@gmail.com> wrote: > > M-profile CCR.BFHFNMIGN lets software executing at a negative execution > priority (in HardFault/NMI, or with FAULTMASK set) suppress precise data > BusFaults caused by load/store instructions: the access completes > returning UNKNOWN data, the fault status is recorded in BFSR/BFAR, but no > BusFault exception is taken. Software uses this to probe for the presence > of a device. > > QEMU stored CCR.BFHFNMIGN but never consumed it: arm_cpu_do_transaction_ > failed() always raised the external abort, which arm_v7m_cpu_do_interrupt() > pended as a BusFault and then escalated to a HardFault it could not take at > priority -1, aborting the VM with "Lockup: can't escalate 3 to HardFault". > > Honour the bit in arm_cpu_do_transaction_failed(): when the access is a > data access from M-profile code at negative priority with BFHFNMIGN set, > record PRECISERR/BFARVALID and BFAR and return without raising, so the > faulting instruction completes instead of re-faulting forever. Instruction > fetches are unaffected, since BFHFNMIGN applies only to data accesses. > > This surfaced running the real NXP i.MX 95 System Manager firmware on the > emulated Cortex-M33: its SystemMemoryProbe() (set BFHFNMIGN + FAULTMASK, > do the access, test CFSR.BFARVALID) locked up the VM. With this change the > SM's debug-monitor memory-probe commands run and recover correctly. > > Signed-off-by: Kyle Fox <kylefoxaustin.github@gmail.com> > --- > Found while bringing up an out-of-tree i.MX 95 machine running the real NXP > System Manager firmware on the emulated Cortex-M33; the change is generic to > any ARMv7-M guest that probes for devices via BusFault suppression. It is > independent of (and posted alongside) a separate PMSAv7 MPU align-down fix > from the same bring-up. > > The new path only runs for an M-profile data access at negative priority with > CCR.BFHFNMIGN set - the previously-broken case that aborted the VM. Normal > BusFaults (no BFHFNMIGN, or at non-negative priority) and instruction fetches > 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/tcg/tlb_helper.c | 24 ++++++++++++++++++++++++ > 1 file changed, 24 insertions(+) > > diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c > index f90765cb59..cbef9cb03e 100644 > --- a/target/arm/tcg/tlb_helper.c > +++ b/target/arm/tcg/tlb_helper.c > @@ -10,6 +10,7 @@ > #include "helper.h" > #include "internals.h" > #include "cpu-features.h" > +#include "hw/intc/armv7m_nvic.h" > > /* > * Returns true if the stage 1 translation regime is using LPAE format page > @@ -318,8 +319,31 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, > MemTxResult response, uintptr_t retaddr) > { > ARMCPU *cpu = ARM_CPU(cs); > + CPUARMState *env = &cpu->env; > ARMMMUFaultInfo fi = {}; > > + /* > + * For M-profile, CCR.BFHFNMIGN lets software executing at a negative > + * priority (in HardFault/NMI, or with FAULTMASK set) suppress precise > + * data BusFaults from load/store instructions: the access completes > + * returning UNKNOWN data (the store is dropped), the fault status is > + * recorded in BFSR/BFAR, but no BusFault exception is taken. This is > + * the mechanism software uses to probe for the presence of a device > + * (e.g. the NXP System Manager's SystemMemoryProbe). Honour it by > + * recording the status and returning without raising, so the faulting > + * instruction completes rather than re-faulting forever. BFHFNMIGN > + * applies only to data accesses, so instruction fetches are unaffected. > + */ > + if (arm_feature(env, ARM_FEATURE_M) && > + access_type != MMU_INST_FETCH && > + (env->v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK) && > + armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) { > + env->v7m.cfsr[M_REG_NS] |= > + (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK); > + env->v7m.bfar = addr; > + return; > + } Thanks for this patch. This looks good, but it misses a very obscure corner case, which is the load of the word from the stack performed by the SG instruction. In the pseudocode that is an AccType_NORMAL access, so it should honour BFHFNMIGN. In QEMU we (for complicated reasons) implement that load manually in v7m_read_sg_stack_word(), so it doesn't go through the TCG TLB and this transaction_failed hook. So v7m_read_sg_stack_word() should check BFHFNMIGN to see if it should pend the ARMV7M_EXCP_BUS. The other places where we manually pend EXCP_BUS are all ones which should not or are not required to honour BFHFNMIGN (vector table loads, stacking and unstacking, which are AccType_VECTABLE, AccType_STACK, AccType_UNSTACK). thanks -- PMM ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults 2026-06-08 11:23 ` Peter Maydell @ 2026-06-13 5:17 ` kylefoxaustin 2026-06-14 15:56 ` Peter Maydell 0 siblings, 1 reply; 5+ messages in thread From: kylefoxaustin @ 2026-06-13 5:17 UTC (permalink / raw) To: Peter Maydell; +Cc: qemu-arm, qemu-devel [-- Attachment #1: Type: text/plain, Size: 6533 bytes --] Hi Peter! Thanks, great catch. You're right that the SG stack-word load is an AccType_NORMAL access and should honour BFHFNMIGN. I'm working on v2 to incorporate. Basically v2 adds the check in v7m_read_sg_stack_word(): on the BusFault path it records BFSR/BFAR as before but, when BFHFNMIGN is set at negative execution priority, it completes the access returning UNKNOWN data and returns true, instead of pending ARMV7M_EXCP_BUS. I left the vector-table, stacking and unstacking EXCP_BUS sites untouched, per your note that those are AccType_VECTABLE/STACK/UNSTACK and are not required to honour it. One question on the register bank: I kept ccr[M_REG_NS] in the new check to match the expression in the transaction_failed hook from v1, but the nearby STKOFHFNMIGN code in this file uses ccr[is_secure]. Happy to switch both sites to [secure] if you think that's more correct here. v2 follows soon for review. again many thanks! -- Kyle On Mon, Jun 8, 2026 at 6:24 AM Peter Maydell <peter.maydell@linaro.org> wrote: > On Fri, 5 Jun 2026 at 04:50, Kyle Fox <kylefoxaustin.github@gmail.com> > wrote: > > > > M-profile CCR.BFHFNMIGN lets software executing at a negative execution > > priority (in HardFault/NMI, or with FAULTMASK set) suppress precise data > > BusFaults caused by load/store instructions: the access completes > > returning UNKNOWN data, the fault status is recorded in BFSR/BFAR, but no > > BusFault exception is taken. Software uses this to probe for the presence > > of a device. > > > > QEMU stored CCR.BFHFNMIGN but never consumed it: arm_cpu_do_transaction_ > > failed() always raised the external abort, which > arm_v7m_cpu_do_interrupt() > > pended as a BusFault and then escalated to a HardFault it could not take > at > > priority -1, aborting the VM with "Lockup: can't escalate 3 to > HardFault". > > > > Honour the bit in arm_cpu_do_transaction_failed(): when the access is a > > data access from M-profile code at negative priority with BFHFNMIGN set, > > record PRECISERR/BFARVALID and BFAR and return without raising, so the > > faulting instruction completes instead of re-faulting forever. > Instruction > > fetches are unaffected, since BFHFNMIGN applies only to data accesses. > > > > This surfaced running the real NXP i.MX 95 System Manager firmware on the > > emulated Cortex-M33: its SystemMemoryProbe() (set BFHFNMIGN + FAULTMASK, > > do the access, test CFSR.BFARVALID) locked up the VM. With this change > the > > SM's debug-monitor memory-probe commands run and recover correctly. > > > > Signed-off-by: Kyle Fox <kylefoxaustin.github@gmail.com> > > --- > > Found while bringing up an out-of-tree i.MX 95 machine running the real > NXP > > System Manager firmware on the emulated Cortex-M33; the change is > generic to > > any ARMv7-M guest that probes for devices via BusFault suppression. It is > > independent of (and posted alongside) a separate PMSAv7 MPU align-down > fix > > from the same bring-up. > > > > The new path only runs for an M-profile data access at negative priority > with > > CCR.BFHFNMIGN set - the previously-broken case that aborted the VM. > Normal > > BusFaults (no BFHFNMIGN, or at non-negative priority) and instruction > fetches > > 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/tcg/tlb_helper.c | 24 ++++++++++++++++++++++++ > > 1 file changed, 24 insertions(+) > > > > diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c > > index f90765cb59..cbef9cb03e 100644 > > --- a/target/arm/tcg/tlb_helper.c > > +++ b/target/arm/tcg/tlb_helper.c > > @@ -10,6 +10,7 @@ > > #include "helper.h" > > #include "internals.h" > > #include "cpu-features.h" > > +#include "hw/intc/armv7m_nvic.h" > > > > /* > > * Returns true if the stage 1 translation regime is using LPAE format > page > > @@ -318,8 +319,31 @@ void arm_cpu_do_transaction_failed(CPUState *cs, > hwaddr physaddr, > > MemTxResult response, uintptr_t > retaddr) > > { > > ARMCPU *cpu = ARM_CPU(cs); > > + CPUARMState *env = &cpu->env; > > ARMMMUFaultInfo fi = {}; > > > > + /* > > + * For M-profile, CCR.BFHFNMIGN lets software executing at a > negative > > + * priority (in HardFault/NMI, or with FAULTMASK set) suppress > precise > > + * data BusFaults from load/store instructions: the access completes > > + * returning UNKNOWN data (the store is dropped), the fault status > is > > + * recorded in BFSR/BFAR, but no BusFault exception is taken. This > is > > + * the mechanism software uses to probe for the presence of a device > > + * (e.g. the NXP System Manager's SystemMemoryProbe). Honour it by > > + * recording the status and returning without raising, so the > faulting > > + * instruction completes rather than re-faulting forever. BFHFNMIGN > > + * applies only to data accesses, so instruction fetches are > unaffected. > > + */ > > + if (arm_feature(env, ARM_FEATURE_M) && > > + access_type != MMU_INST_FETCH && > > + (env->v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK) && > > + armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) { > > + env->v7m.cfsr[M_REG_NS] |= > > + (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK); > > + env->v7m.bfar = addr; > > + return; > > + } > > Thanks for this patch. This looks good, but it misses a very > obscure corner case, which is the load of the word from the stack > performed by the SG instruction. In the pseudocode that is an > AccType_NORMAL access, so it should honour BFHFNMIGN. In QEMU > we (for complicated reasons) implement that load manually in > v7m_read_sg_stack_word(), so it doesn't go through the TCG TLB > and this transaction_failed hook. So v7m_read_sg_stack_word() > should check BFHFNMIGN to see if it should pend the ARMV7M_EXCP_BUS. > > The other places where we manually pend EXCP_BUS are all ones > which should not or are not required to honour BFHFNMIGN > (vector table loads, stacking and unstacking, which are > AccType_VECTABLE, AccType_STACK, AccType_UNSTACK). > > thanks > -- PMM > [-- Attachment #2: Type: text/html, Size: 7746 bytes --] ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults 2026-06-13 5:17 ` kylefoxaustin @ 2026-06-14 15:56 ` Peter Maydell 0 siblings, 0 replies; 5+ messages in thread From: Peter Maydell @ 2026-06-14 15:56 UTC (permalink / raw) To: kylefoxaustin; +Cc: qemu-arm, qemu-devel On Sat, 13 Jun 2026 at 06:17, kylefoxaustin <kylefoxaustin.github@gmail.com> wrote: > > Hi Peter! > Thanks, great catch. You're right that the SG stack-word load is an > AccType_NORMAL access and should honour BFHFNMIGN. > > I'm working on v2 to incorporate. Basically v2 adds the check in v7m_read_sg_stack_word(): > on the BusFault path it records BFSR/BFAR as before but, when BFHFNMIGN is set at negative > execution priority, it completes the access returning UNKNOWN data and > returns true, instead of pending ARMV7M_EXCP_BUS. I left the vector-table, > stacking and unstacking EXCP_BUS sites untouched, per your note that those > are AccType_VECTABLE/STACK/UNSTACK and are not required to honour it. > > One question on the register bank: I kept ccr[M_REG_NS] in the new check to > match the expression in the transaction_failed hook from v1, but the nearby > STKOFHFNMIGN code in this file uses ccr[is_secure]. Happy to switch both > sites to [secure] if you think that's more correct here. The CCR register has some bits which are banked (so have S and NS copies) but some bits which are not banked (so S and NS see the same thing). The way we implement that is that for the non-banked bits we store them in one of the two entries in the v7m.ccr[] array, and code that uses the bit has to check that one. BFHFNMIGN is one of the non-banked bits, and we keep it in the NS array entry, and check ccr[M_REG_NS]. STKOFHFNMIGN is banked, so we check ccr[is_secure] to get the banked bit corresponding to the right securite state. thanks -- PMM ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v2] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults 2026-06-05 3:50 [PATCH] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults Kyle Fox 2026-06-08 11:23 ` Peter Maydell @ 2026-06-15 0:08 ` Kyle Fox 1 sibling, 0 replies; 5+ messages in thread From: Kyle Fox @ 2026-06-15 0:08 UTC (permalink / raw) To: Peter Maydell; +Cc: qemu-arm, qemu-devel, Kyle Fox M-profile CCR.BFHFNMIGN lets software executing at a negative execution priority (in HardFault/NMI, or with FAULTMASK set) suppress precise data BusFaults caused by load/store instructions: the access completes returning UNKNOWN data, the fault status is recorded in BFSR/BFAR, but no BusFault exception is taken. Software uses this to probe for the presence of a device. QEMU stored CCR.BFHFNMIGN but never consumed it: arm_cpu_do_transaction_ failed() always raised the external abort, which arm_v7m_cpu_do_interrupt() pended as a BusFault and then escalated to a HardFault it could not take at priority -1, aborting the VM with "Lockup: can't escalate 3 to HardFault". Honour the bit in arm_cpu_do_transaction_failed(): when the access is a data access from M-profile code at negative priority with BFHFNMIGN set, record PRECISERR/BFARVALID and BFAR and return without raising, so the faulting instruction completes instead of re-faulting forever. Instruction fetches are unaffected, since BFHFNMIGN applies only to data accesses. The SG instruction's stack-word load is also an AccType_NORMAL data access that must honour BFHFNMIGN, but QEMU performs it manually in v7m_read_sg_stack_word() (outside the TCG TLB, so it never reaches arm_cpu_do_transaction_failed()). Apply the same suppression there: on a BusFault, record the status and, when BFHFNMIGN is set at negative priority, return the UNKNOWN data instead of pending ARMV7M_EXCP_BUS. The remaining manual EXCP_BUS sites (vector-table loads, stacking, unstacking) are AccType_VECTABLE/STACK/UNSTACK and are not required to honour the bit, so they are left unchanged. This surfaced running the real NXP i.MX 95 System Manager firmware on the emulated Cortex-M33: its SystemMemoryProbe() (set BFHFNMIGN + FAULTMASK, do the access, test CFSR.BFARVALID) locked up the VM. With this change the SM's debug-monitor memory-probe commands run and recover correctly. Signed-off-by: Kyle Fox <kylefoxaustin.github@gmail.com> --- v2: - Also honour BFHFNMIGN for the SG instruction's stack-word load in v7m_read_sg_stack_word() (an AccType_NORMAL access performed manually, outside the TCG TLB), per review. The vector-table/stacking/unstacking EXCP_BUS sites are left unchanged (AccType_VECTABLE/STACK/UNSTACK). target/arm/tcg/m_helper.c | 12 ++++++++++++ target/arm/tcg/tlb_helper.c | 24 ++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/target/arm/tcg/m_helper.c b/target/arm/tcg/m_helper.c index f2059ed8b03..ba101ecb953 100644 --- a/target/arm/tcg/m_helper.c +++ b/target/arm/tcg/m_helper.c @@ -2086,6 +2086,18 @@ static bool v7m_read_sg_stack_word(ARMCPU *cpu, ARMMMUIdx mmu_idx, env->v7m.cfsr[M_REG_NS] |= (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK); env->v7m.bfar = addr; + /* + * The SG instruction's stack-word load is an AccType_NORMAL data + * access, so CCR.BFHFNMIGN applies: at negative execution priority + * with BFHFNMIGN set, the BusFault is suppressed -- the access + * completes returning UNKNOWN data (status recorded above), with no + * BusFault exception pended. + */ + if ((env->v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK) && + armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) { + *spdata = value; + return true; + } armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_BUS, false); return false; } diff --git a/target/arm/tcg/tlb_helper.c b/target/arm/tcg/tlb_helper.c index bbe1e70bc43..452688010f5 100644 --- a/target/arm/tcg/tlb_helper.c +++ b/target/arm/tcg/tlb_helper.c @@ -10,6 +10,7 @@ #include "helper.h" #include "internals.h" #include "cpu-features.h" +#include "hw/intc/armv7m_nvic.h" /* * Returns true if the stage 1 translation regime is using LPAE format page @@ -318,8 +319,31 @@ void arm_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr, MemTxResult response, uintptr_t retaddr) { ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; ARMMMUFaultInfo fi = {}; + /* + * For M-profile, CCR.BFHFNMIGN lets software executing at a negative + * priority (in HardFault/NMI, or with FAULTMASK set) suppress precise + * data BusFaults from load/store instructions: the access completes + * returning UNKNOWN data (the store is dropped), the fault status is + * recorded in BFSR/BFAR, but no BusFault exception is taken. This is + * the mechanism software uses to probe for the presence of a device + * (e.g. the NXP System Manager's SystemMemoryProbe). Honour it by + * recording the status and returning without raising, so the faulting + * instruction completes rather than re-faulting forever. BFHFNMIGN + * applies only to data accesses, so instruction fetches are unaffected. + */ + if (arm_feature(env, ARM_FEATURE_M) && + access_type != MMU_INST_FETCH && + (env->v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK) && + armv7m_nvic_neg_prio_requested(env->nvic, env->v7m.secure)) { + env->v7m.cfsr[M_REG_NS] |= + (R_V7M_CFSR_PRECISERR_MASK | R_V7M_CFSR_BFARVALID_MASK); + env->v7m.bfar = addr; + return; + } + /* now we have a real cpu fault */ cpu_restore_state(cs, retaddr); -- 2.34.1 ^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-15 0:09 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-05 3:50 [PATCH] target/arm: honour CCR.BFHFNMIGN for probed data BusFaults Kyle Fox 2026-06-08 11:23 ` Peter Maydell 2026-06-13 5:17 ` kylefoxaustin 2026-06-14 15:56 ` Peter Maydell 2026-06-15 0:08 ` [PATCH v2] " Kyle Fox
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.