All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jinchao Wang <wangjinchao600@gmail.com>
To: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
	Dave Hansen <dave.hansen@linux.intel.com>,
	x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 1/2] x86/hw_breakpoint: Unify breakpoint install/uninstall
Date: Fri, 12 Sep 2025 09:05:15 +0800	[thread overview]
Message-ID: <aMNxyx3RADiosttf@mdev> (raw)
In-Reply-To: <20250911170345.80169f37b3964eb9c9475c41@kernel.org>

On Thu, Sep 11, 2025 at 05:03:45PM +0900, Masami Hiramatsu wrote:
> On Wed, 10 Sep 2025 17:39:34 +0800
> Jinchao Wang <wangjinchao600@gmail.com> wrote:
> 
> > Consolidate breakpoint management into a single helper function to
> > reduce code duplication. This introduces new static helpers for
> > slot management and debug register manipulation.
> > 
> > Also, add `<linux/types.h>` to the header file to fix a build
> > dependency.
> 
> Looks good to me. Just some nitpicks.
> 
> Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
> 
> > 
> > Signed-off-by: Jinchao Wang <wangjinchao600@gmail.com>
> > ---
> >  arch/x86/include/asm/hw_breakpoint.h |   7 +-
> >  arch/x86/kernel/hw_breakpoint.c      | 151 ++++++++++++++++-----------
> >  2 files changed, 96 insertions(+), 62 deletions(-)
> > 
> > diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h
> > index 0bc931cd0698..bd437a30dbf2 100644
> > --- a/arch/x86/include/asm/hw_breakpoint.h
> > +++ b/arch/x86/include/asm/hw_breakpoint.h
> > @@ -3,8 +3,8 @@
> >  #define	_I386_HW_BREAKPOINT_H
> >  
> >  #include <uapi/asm/hw_breakpoint.h>
> > -
> 
> nit: Why this line is removed?
sharp eye, will restore to its original state.
> 
> >  #define	__ARCH_HW_BREAKPOINT_H
> > +#include <linux/types.h>
> >  
> >  /*
> >   * The name should probably be something dealt in
> > @@ -18,6 +18,11 @@ struct arch_hw_breakpoint {
> >  	u8		type;
> >  };
> >  
> > +enum bp_slot_action {
> > +	BP_SLOT_ACTION_INSTALL,
> > +	BP_SLOT_ACTION_UNINSTALL,
> > +};
> > +
> >  #include <linux/kdebug.h>
> >  #include <linux/percpu.h>
> >  #include <linux/list.h>
> > diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
> > index b01644c949b2..1736063a82b7 100644
> > --- a/arch/x86/kernel/hw_breakpoint.c
> > +++ b/arch/x86/kernel/hw_breakpoint.c
> > @@ -48,7 +48,6 @@ static DEFINE_PER_CPU(unsigned long, cpu_debugreg[HBP_NUM]);
> >   */
> >  static DEFINE_PER_CPU(struct perf_event *, bp_per_reg[HBP_NUM]);
> >  
> > -
> 
> Ditto.
There were double-space lines, so delete one.
> 
> >  static inline unsigned long
> >  __encode_dr7(int drnum, unsigned int len, unsigned int type)
> >  {
> > @@ -84,54 +83,115 @@ int decode_dr7(unsigned long dr7, int bpnum, unsigned *len, unsigned *type)
> >  	return (dr7 >> (bpnum * DR_ENABLE_SIZE)) & 0x3;
> >  }
> >  
> > -/*
> > - * Install a perf counter breakpoint.
> > - *
> > - * We seek a free debug address register and use it for this
> > - * breakpoint. Eventually we enable it in the debug control register.
> > - *
> > - * Atomic: we hold the counter->ctx->lock and we only handle variables
> > - * and registers local to this cpu.
> > - */
> > -int arch_install_hw_breakpoint(struct perf_event *bp)
> > +static int manage_bp_slot(struct perf_event *bp, enum bp_slot_action action)
> >  {
> > -	struct arch_hw_breakpoint *info = counter_arch_bp(bp);
> > -	unsigned long *dr7;
> > -	int i;
> > +	struct perf_event *old_bp;
> > +	struct perf_event *new_bp;
> > +	int slot;
> > +
> > +	switch (action) {
> > +	case BP_SLOT_ACTION_INSTALL:
> > +		old_bp = NULL;
> > +		new_bp = bp;
> > +		break;
> > +	case BP_SLOT_ACTION_UNINSTALL:
> > +		old_bp = bp;
> > +		new_bp = NULL;
> > +		break;
> > +	default:
> > +		return -EINVAL;
> > +	}
> >  
> >  	lockdep_assert_irqs_disabled();
> >  
> > -	for (i = 0; i < HBP_NUM; i++) {
> > -		struct perf_event **slot = this_cpu_ptr(&bp_per_reg[i]);
> > +	for (slot = 0; slot < HBP_NUM; slot++) {
> > +		struct perf_event **curr = this_cpu_ptr(&bp_per_reg[slot]);
> >  
> > -		if (!*slot) {
> > -			*slot = bp;
> > -			break;
> > +		if (*curr == old_bp) {
> > +			*curr = new_bp;
> > +			return slot;
> >  		}
> >  	}
> >  
> > -	if (WARN_ONCE(i == HBP_NUM, "Can't find any breakpoint slot"))
> > -		return -EBUSY;
> > +	if (old_bp) {
> > +		WARN_ONCE(1, "Can't find matching breakpoint slot");
> > +		return -EINVAL;
> > +	}
> >  
> > -	set_debugreg(info->address, i);
> > -	__this_cpu_write(cpu_debugreg[i], info->address);
> > +	WARN_ONCE(1, "No free breakpoint slots");
> > +	return -EBUSY;
> > +}
> >  
> > -	dr7 = this_cpu_ptr(&cpu_dr7);
> > -	*dr7 |= encode_dr7(i, info->len, info->type);
> > +static void setup_hwbp(struct arch_hw_breakpoint *info, int slot, bool enable)
> > +{
> > +	unsigned long dr7;
> > +
> > +	set_debugreg(info->address, slot);
> > +	__this_cpu_write(cpu_debugreg[slot], info->address);
> > +
> > +	dr7 = this_cpu_read(cpu_dr7);
> > +	if (enable)
> > +		dr7 |= encode_dr7(slot, info->len, info->type);
> > +	else
> > +		dr7 &= ~__encode_dr7(slot, info->len, info->type);
> >  
> >  	/*
> > -	 * Ensure we first write cpu_dr7 before we set the DR7 register.
> > -	 * This ensures an NMI never see cpu_dr7 0 when DR7 is not.
> > +	 * Enabling:
> > +	 *   Ensure we first write cpu_dr7 before we set the DR7 register.
> > +	 *   This ensures an NMI never see cpu_dr7 0 when DR7 is not.
> >  	 */
> > +	if (enable)
> > +		this_cpu_write(cpu_dr7, dr7);
> > +
> >  	barrier();
> >  
> > -	set_debugreg(*dr7, 7);
> > +	set_debugreg(dr7, 7);
> > +
> >  	if (info->mask)
> > -		amd_set_dr_addr_mask(info->mask, i);
> > +		amd_set_dr_addr_mask(enable ? info->mask : 0, slot);
> > +
> > +	/*
> > +	 * Disabling:
> > +	 *   Ensure the write to cpu_dr7 is after we've set the DR7 register.
> > +	 *   This ensures an NMI never see cpu_dr7 0 when DR7 is not.
> > +	 */
> > +	if (!enable)
> > +		this_cpu_write(cpu_dr7, dr7);
> > +}
> > +
> > +static int arch_manage_bp(struct perf_event *bp, enum bp_slot_action action)
> > +{
> > +	struct arch_hw_breakpoint *info;
> > +	bool install = true;
> > +	int slot;
> > +
> > +	if (action == BP_SLOT_ACTION_UNINSTALL)
> > +		install = false;
> 
> This looks a bit unnecessary. 
> 
> > +
> > +	slot = manage_bp_slot(bp, action);
> > +	if (slot < 0)
> > +		return slot;
> > +
> > +	info = counter_arch_bp(bp);
> > +	setup_hwbp(info, slot, install);
> 
> since you can do
> 
> 	setup_hwbp(info, slot,
> 		   action != BP_SLOT_ACTION_UNINSTALL);
> 
> Thank you,
Thanks, I will follow your advice in the next patch.
> 
> 
> -- 
> Masami Hiramatsu (Google) <mhiramat@kernel.org>

-- 
Jinchao

      reply	other threads:[~2025-09-12  1:05 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-10  9:39 [PATCH 1/2] x86/hw_breakpoint: Unify breakpoint install/uninstall Jinchao Wang
2025-09-10  9:39 ` [PATCH 2/2] x86/hw_breakpoint: Add arch_reinstall_hw_breakpoint Jinchao Wang
2025-09-11 10:16   ` Masami Hiramatsu
2025-09-10 14:47 ` [PATCH 1/2] x86/hw_breakpoint: Unify breakpoint install/uninstall Dave Hansen
2025-09-10 14:56   ` H. Peter Anvin
2025-09-11  0:42     ` Jinchao Wang
2025-09-11  8:03 ` Masami Hiramatsu
2025-09-12  1:05   ` Jinchao Wang [this message]

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=aMNxyx3RADiosttf@mdev \
    --to=wangjinchao600@gmail.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=x86@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.