From: Mark Rutland <mark.rutland@arm.com>
To: Rob Herring <robh@kernel.org>
Cc: Anshuman Khandual <anshuman.khandual@arm.com>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Jonathan Corbet <corbet@lwn.net>,
Marc Zyngier <maz@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>, Mark Brown <broonie@kernel.org>,
kvmarm@lists.linux.dev
Subject: Re: [PATCH V3 7/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9
Date: Thu, 2 Apr 2026 11:37:37 +0100 [thread overview]
Message-ID: <ac5G8e4zWTdicDBs@J2N7QTR9R3> (raw)
In-Reply-To: <20260331225800.GA2082670-robh@kernel.org>
On Tue, Mar 31, 2026 at 05:58:00PM -0500, Rob Herring wrote:
> On Mon, Dec 16, 2024 at 10:58:29AM +0000, Mark Rutland wrote:
> > On Mon, Dec 16, 2024 at 09:38:31AM +0530, Anshuman Khandual wrote:
> > > Currently there can be maximum 16 breakpoints, and 16 watchpoints available
> > > on a given platform - as detected from ID_AA64DFR0_EL1.[BRPs|WRPs] register
> > > fields. But these breakpoint, and watchpoints can be extended further up to
> > > 64 via a new arch feature FEAT_Debugv8p9.
> > >
> > > This first enables banked access for the breakpoint and watchpoint register
> > > set via MDSELR_EL1, extended exceptions via MDSCR_EL1.EMBWE and determining
> > > available breakpoints and watchpoints in the platform from ID_AA64DFR1_EL1,
> > > when FEAT_Debugv8p9 is enabled.
> >
> > [...]
>
> Well, this series has landed on my plate...
Sorry about that; thanks for taking a look!
> > > +static u64 read_wb_reg(int reg, int n)
> > > +{
> > > + unsigned long flags;
> > > + u64 val;
> > > +
> > > + if (!is_debug_v8p9_enabled())
> > > + return __read_wb_reg(reg, n);
> > > +
> > > + /*
> > > + * Bank selection in MDSELR_EL1, followed by an indexed read from
> > > + * breakpoint (or watchpoint) registers cannot be interrupted, as
> > > + * that might cause misread from the wrong targets instead. Hence
> > > + * this requires mutual exclusion.
> > > + */
> > > + local_irq_save(flags);
> > > + write_sysreg_s(SYS_FIELD_PREP(MDSELR_EL1, BANK, n / MAX_PER_BANK), SYS_MDSELR_EL1);
> > > + isb();
> > > + val = __read_wb_reg(reg, n % MAX_PER_BANK);
> > > + local_irq_restore(flags);
> > > + return val;
> > > +}
> > > NOKPROBE_SYMBOL(read_wb_reg);
> >
> > I don't believe that disabling interrupts here is sufficient. On the
> > last version I asked about the case of racing with a watchpoint handler:
> >
> > | For example, what prevents watchpoint_handler() from firing in the
> > | middle of arch_install_hw_breakpoint() or
> > | arch_uninstall_hw_breakpoint()?
> >
> > ... and disabling interrupts cannot prevent that, because
> > local_irq_{save,restore}() do not affect the behaviour of watchpoints or
> > breakpoints.
>
> I think the answer is we just need NOKPROBE_SYMBOL() annotation on
> hw_breakpoint_control() (what arch_install_hw_breakpoint() and
> arch_uninstall_hw_breakpoint() wrap).
Ok. I couldn'y spot where we prevent placing HW breakpoints on
NOKPROBE_SYMBOL() functions, but if we do enforce that, something like
that sounds ok.
I suspect we'd need to make that noinstr to also prevent ftrace
instrumentation, unless ftrace also inhibits itself for
NOKPROBE_SYMBOL() functions.
> We also need that on __read_wb_reg
> and __read_wb_reg though I would think those are folded into the calling
> functions by the compiler. Interestly, the x86 code doesn't use the
> annotation at all.
IIUC, it looks like they *can* take debug NMIs during
arch_install_hw_breakpoint() and arch_uninstall_hw_breakpoint(), which
is why they have ordering constraints for modifying the percpu 'cpu_dr7'
variable, and their actual DR7 register (which IIUC has the enable
controls for each HW breakpoint).
That said, the use of 'bp_per_reg' looks suspect given their
arch_install_hw_breakpoint() and arch_uninstall_hw_breakpoint() modify
that non-atomically.
We could consider allowing breakpoints on those functions, but I'm not
sure whether that's possible for us, and (as noted below) it might be
better to transiently disable breakpoints/watchpoints.
IIRC on x86, breakpoint exceptions are taken *after* execution of the
instruction that triggered them, so the handler doesn't have to
manipulate single-step, and can safely ignore a breakpoint exception
without the risk of getting stuck taking the breakpoint repeatedly.
> I initially thought the IRQ disabling is also still needed as IRQ
> handlers can trigger breakpoints. However, the x86 version of
> arch_install_hw_breakpoint() contains a lockdep_assert_irqs_disabled(),
> so it seems for that case interrupts are already disabled. And in debug
> exceptions, we disable interrupts. So I think the interrupt disabling
> can be dropped.
I'd expect that the core perf code disables interrupts before calling
arch_install_hw_breakpoint() or arch_uninstall_hw_breakpoint(), and this
would be necessary for perf to serialise against IPIs that manipulate
the perf_event_context.
I agree that when we actually take the breakpoint, we'll mask all
exceptions, and so it's not necessary to mask IRQs there.
So a first step is probably to add that lockdep assert.
> > Please can you try to answer the questions I asked last time, i.e.
> >
> > | What prevents a race with an exception handler? e.g.
> > |
> > | * Does the structure of the code prevent that somehow?
>
> If you can't set a breakpoint/watchpoint in NOKPROBE_SYMBOL() annotated
> code, you can't race.
As above, I agree (with caveats), but I couldn't spot where this is
enforced.
> However, there's no such annotation for data. It looks like the kernel
> policy is "don't do that" or disable all breakpoints/watchpoints.
If we have to transiently disable watchpoints/breakpoints when
manipulating the relevant HW registers, that sounds fine to me.
> > |
> > | * What context(s) does this code execute in?
> > | - Are debug exceptions always masked?
>
> No.
>
> > | - Do we disable breakpoints/watchpoints around (some) manipulation of
> > | the relevant registers?
>
> Yes, with NOKPROBE_SYMBOL().
Thanks for digging into this; much appreciated!
Mark.
next prev parent reply other threads:[~2026-04-02 10:37 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-12-16 4:08 [PATCH V3 0/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9 Anshuman Khandual
2024-12-16 4:08 ` [PATCH V3 1/7] arm64/sysreg: Update register fields for ID_AA64MMFR0_EL1 Anshuman Khandual
2024-12-16 4:08 ` [PATCH V3 2/7] arm64/sysreg: Add register fields for MDSELR_EL1 Anshuman Khandual
2024-12-16 4:08 ` [PATCH V3 3/7] arm64/sysreg: Add register fields for HDFGRTR2_EL2 Anshuman Khandual
2024-12-16 4:08 ` [PATCH V3 4/7] arm64/sysreg: Add register fields for HDFGWTR2_EL2 Anshuman Khandual
2024-12-16 4:08 ` [PATCH V3 5/7] arm64/cpufeature: Add field details for ID_AA64DFR1_EL1 register Anshuman Khandual
2024-12-16 4:08 ` [PATCH V3 6/7] arm64/boot: Enable EL2 requirements for FEAT_Debugv8p9 Anshuman Khandual
2024-12-16 23:42 ` Rob Herring
2024-12-17 8:48 ` Anshuman Khandual
2024-12-17 17:53 ` Rob Herring
2024-12-18 5:25 ` Anshuman Khandual
2024-12-18 9:10 ` Marc Zyngier
2024-12-18 13:15 ` Mark Brown
2024-12-16 4:08 ` [PATCH V3 7/7] arm64/hw_breakpoint: Enable FEAT_Debugv8p9 Anshuman Khandual
2024-12-16 10:58 ` Mark Rutland
2026-03-31 22:58 ` Rob Herring
2026-04-02 10:37 ` Mark Rutland [this message]
2026-04-02 17:46 ` Rob Herring
2026-03-31 23:02 ` Rob Herring
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=ac5G8e4zWTdicDBs@J2N7QTR9R3 \
--to=mark.rutland@arm.com \
--cc=anshuman.khandual@arm.com \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=corbet@lwn.net \
--cc=james.morse@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=maz@kernel.org \
--cc=oliver.upton@linux.dev \
--cc=robh@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.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