All of lore.kernel.org
 help / color / mirror / Atom feed
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.

  reply	other threads:[~2026-04-02 10:37 UTC|newest]

Thread overview: 22+ 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-04-09 10:52           ` Mark Rutland
2026-04-10 19:55             ` Rob Herring
2026-04-13  8:48               ` Mark Rutland
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 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.