From: Qingfang Deng <qingfang.deng@linux.dev>
To: Himanshu Chauhan <himanshu.chauhan@oss.qualcomm.com>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu,
alex@ghiti.fr, shuah@kernel.org
Subject: Re: [PATCH v4 1/2] riscv: Introduce support for hardware break/watchpoints
Date: Fri, 17 Jul 2026 15:19:00 +0800 [thread overview]
Message-ID: <765ac2fe-a0ff-4980-915c-b2546a85b86a@linux.dev> (raw)
In-Reply-To: <20260518065920.872131-2-himanshu.chauhan@oss.qualcomm.com>
Hi,
On 2026/5/18 14:59, Himanshu Chauhan wrote:
> diff --git a/arch/riscv/kernel/hw_breakpoint.c b/arch/riscv/kernel/hw_breakpoint.c
> new file mode 100644
> index 000000000000..34556a8f3c9b
> --- /dev/null
> +++ b/arch/riscv/kernel/hw_breakpoint.c
> @@ -0,0 +1,736 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 Qualcomm Technologies, Inc.
> + */
> +
To make your logs more informative, you may want to #define pr_fmt here.
For example: `#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt` will prefix
all your logs with "hw_breakpoint: ".
> +#include <linux/hw_breakpoint.h>
> +#include <linux/perf_event.h>
> +#include <linux/spinlock.h>
> +#include <linux/percpu.h>
> +#include <linux/kdebug.h>
> +#include <linux/bitops.h>
> +#include <linux/cpu.h>
> +#include <linux/cpuhotplug.h>
> +
> +#include <asm/sbi.h>
> +
> +/* Registered per-cpu bp/wp */
> +static DEFINE_PER_CPU(struct perf_event *, pcpu_hw_bp_events[RISCV_HW_BP_NUM_MAX]);
> +static DEFINE_PER_CPU(unsigned long, ecall_lock_flags);
> +static DEFINE_PER_CPU(raw_spinlock_t, ecall_lock);
> +
> +/* Per-cpu shared memory between S and M mode */
> +static union sbi_dbtr_shmem_entry __percpu *sbi_dbtr_shmem;
> +
> +/* number of debug triggers on this cpu . */
> +static int dbtr_total_num __ro_after_init;
> +static int dbtr_type __ro_after_init;
> +static int dbtr_init __ro_after_init;
> +
> +#if __riscv_xlen == 64
> +#define MEM_HI(_m) 0
> +#define MEM_LO(_m) ((u64)(_m))
> +#elif __riscv_xlen == 32
> +#define MEM_HI(_m) ((u64)(_m) >> 32)
> +#define MEM_LO(_m) ((u64)(_m) & 0xFFFFFFFFUL)
> +#else
> +#error "Unknown __riscv_xlen"
> +#endif
> +
> +static int arch_smp_setup_sbi_shmem(unsigned int cpu)
> +{
> + union sbi_dbtr_shmem_entry *dbtr_shmem;
> + unsigned long shmem_pa;
Nit: the type of a physical address should be "phys_addr_t".
> + struct sbiret ret;
> + int rc = 0;
> +
> + dbtr_shmem = per_cpu_ptr(sbi_dbtr_shmem, cpu);
> + if (!dbtr_shmem) {
> + pr_err("Invalid per-cpu shared memory for debug triggers\n");
> + return -ENODEV;
> + }
> +
> + shmem_pa = __pa(dbtr_shmem);
It's not safe to get the physical address of a percpu-allocated pointer
with __pa(), as it may be a vmalloc()'d pointer. Please use
per_cpu_ptr_to_phys() instead.
Also, even per_cpu_ptr_to_phys() will break if the allocation size is
larger than the page size, as it only returns the physical address of
the very first page.
> +
> + ret = sbi_ecall(SBI_EXT_DBTR, SBI_EXT_DBTR_SETUP_SHMEM,
> + MEM_LO(shmem_pa), MEM_HI(shmem_pa), 0, 0, 0, 0);
> +
> + if (ret.error) {
> + switch (ret.error) {
> + case SBI_ERR_DENIED:
> + pr_warn("Access denied for shared memory at %lx\n",
> + shmem_pa);
> + rc = -EPERM;
> + break;
> +
> + case SBI_ERR_INVALID_PARAM:
> + case SBI_ERR_INVALID_ADDRESS:
> + pr_warn("Invalid address parameter (%lu)\n",
> + ret.error);
> + rc = -EINVAL;
> + break;
> +
> + case SBI_ERR_ALREADY_AVAILABLE:
> + pr_warn("Shared memory is already set\n");
> + rc = -EADDRINUSE;
> + break;
> +
> + case SBI_ERR_FAILURE:
> + pr_err("Internal sdtrig state error\n");
> + rc = -ENXIO;
> + break;
> +
> + default:
> + pr_warn("Unknown error %lu\n", ret.error);
> + rc = -ENXIO;
> + break;
> + }
> + }
> +
> + pr_info("CPU %d: HW Breakpoint shared memory registered.\n", cpu);
This will be printed even if an error occurs. Please move it into the
`else` block of `if (ret.error)`.
> +
> + return rc;
> +}
> +
> +static int arch_smp_teardown_sbi_shmem(unsigned int cpu)
> +{
> + struct sbiret ret;
> +
> + /* Disable shared memory */
> + ret = sbi_ecall(SBI_EXT_DBTR, SBI_EXT_DBTR_SETUP_SHMEM,
> + -1UL, -1UL, 0, 0, 0, 0);
> +
> + if (ret.error) {
> + switch (ret.error) {
> + case SBI_ERR_DENIED:
> + pr_err("Access denied for shared memory.\n");
> + break;
> +
> + case SBI_ERR_INVALID_PARAM:
> + case SBI_ERR_INVALID_ADDRESS:
> + pr_err("Invalid address parameter (%lu)\n", ret.error);
> + break;
> +
> + case SBI_ERR_ALREADY_AVAILABLE:
> + pr_err("Shared memory is already set\n");
> + break;
> + case SBI_ERR_FAILURE:
> + pr_err("Internal sdtrig state error\n");
> + break;
> + default:
> + pr_err("Unknown error %lu\n", ret.error);
> + break;
> + }
> + }
> +
> + pr_warn("CPU %d: HW Breakpoint shared memory disabled.\n", cpu);
Ditto.
> +
> + return 0;
> +}
Best regards,
Qingfang
WARNING: multiple messages have this Message-ID (diff)
From: Qingfang Deng <qingfang.deng@linux.dev>
To: Himanshu Chauhan <himanshu.chauhan@oss.qualcomm.com>,
linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
pjw@kernel.org, palmer@dabbelt.com, aou@eecs.berkeley.edu,
alex@ghiti.fr, shuah@kernel.org
Subject: Re: [PATCH v4 1/2] riscv: Introduce support for hardware break/watchpoints
Date: Fri, 17 Jul 2026 15:19:00 +0800 [thread overview]
Message-ID: <765ac2fe-a0ff-4980-915c-b2546a85b86a@linux.dev> (raw)
In-Reply-To: <20260518065920.872131-2-himanshu.chauhan@oss.qualcomm.com>
Hi,
On 2026/5/18 14:59, Himanshu Chauhan wrote:
> diff --git a/arch/riscv/kernel/hw_breakpoint.c b/arch/riscv/kernel/hw_breakpoint.c
> new file mode 100644
> index 000000000000..34556a8f3c9b
> --- /dev/null
> +++ b/arch/riscv/kernel/hw_breakpoint.c
> @@ -0,0 +1,736 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (C) 2026 Qualcomm Technologies, Inc.
> + */
> +
To make your logs more informative, you may want to #define pr_fmt here.
For example: `#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt` will prefix
all your logs with "hw_breakpoint: ".
> +#include <linux/hw_breakpoint.h>
> +#include <linux/perf_event.h>
> +#include <linux/spinlock.h>
> +#include <linux/percpu.h>
> +#include <linux/kdebug.h>
> +#include <linux/bitops.h>
> +#include <linux/cpu.h>
> +#include <linux/cpuhotplug.h>
> +
> +#include <asm/sbi.h>
> +
> +/* Registered per-cpu bp/wp */
> +static DEFINE_PER_CPU(struct perf_event *, pcpu_hw_bp_events[RISCV_HW_BP_NUM_MAX]);
> +static DEFINE_PER_CPU(unsigned long, ecall_lock_flags);
> +static DEFINE_PER_CPU(raw_spinlock_t, ecall_lock);
> +
> +/* Per-cpu shared memory between S and M mode */
> +static union sbi_dbtr_shmem_entry __percpu *sbi_dbtr_shmem;
> +
> +/* number of debug triggers on this cpu . */
> +static int dbtr_total_num __ro_after_init;
> +static int dbtr_type __ro_after_init;
> +static int dbtr_init __ro_after_init;
> +
> +#if __riscv_xlen == 64
> +#define MEM_HI(_m) 0
> +#define MEM_LO(_m) ((u64)(_m))
> +#elif __riscv_xlen == 32
> +#define MEM_HI(_m) ((u64)(_m) >> 32)
> +#define MEM_LO(_m) ((u64)(_m) & 0xFFFFFFFFUL)
> +#else
> +#error "Unknown __riscv_xlen"
> +#endif
> +
> +static int arch_smp_setup_sbi_shmem(unsigned int cpu)
> +{
> + union sbi_dbtr_shmem_entry *dbtr_shmem;
> + unsigned long shmem_pa;
Nit: the type of a physical address should be "phys_addr_t".
> + struct sbiret ret;
> + int rc = 0;
> +
> + dbtr_shmem = per_cpu_ptr(sbi_dbtr_shmem, cpu);
> + if (!dbtr_shmem) {
> + pr_err("Invalid per-cpu shared memory for debug triggers\n");
> + return -ENODEV;
> + }
> +
> + shmem_pa = __pa(dbtr_shmem);
It's not safe to get the physical address of a percpu-allocated pointer
with __pa(), as it may be a vmalloc()'d pointer. Please use
per_cpu_ptr_to_phys() instead.
Also, even per_cpu_ptr_to_phys() will break if the allocation size is
larger than the page size, as it only returns the physical address of
the very first page.
> +
> + ret = sbi_ecall(SBI_EXT_DBTR, SBI_EXT_DBTR_SETUP_SHMEM,
> + MEM_LO(shmem_pa), MEM_HI(shmem_pa), 0, 0, 0, 0);
> +
> + if (ret.error) {
> + switch (ret.error) {
> + case SBI_ERR_DENIED:
> + pr_warn("Access denied for shared memory at %lx\n",
> + shmem_pa);
> + rc = -EPERM;
> + break;
> +
> + case SBI_ERR_INVALID_PARAM:
> + case SBI_ERR_INVALID_ADDRESS:
> + pr_warn("Invalid address parameter (%lu)\n",
> + ret.error);
> + rc = -EINVAL;
> + break;
> +
> + case SBI_ERR_ALREADY_AVAILABLE:
> + pr_warn("Shared memory is already set\n");
> + rc = -EADDRINUSE;
> + break;
> +
> + case SBI_ERR_FAILURE:
> + pr_err("Internal sdtrig state error\n");
> + rc = -ENXIO;
> + break;
> +
> + default:
> + pr_warn("Unknown error %lu\n", ret.error);
> + rc = -ENXIO;
> + break;
> + }
> + }
> +
> + pr_info("CPU %d: HW Breakpoint shared memory registered.\n", cpu);
This will be printed even if an error occurs. Please move it into the
`else` block of `if (ret.error)`.
> +
> + return rc;
> +}
> +
> +static int arch_smp_teardown_sbi_shmem(unsigned int cpu)
> +{
> + struct sbiret ret;
> +
> + /* Disable shared memory */
> + ret = sbi_ecall(SBI_EXT_DBTR, SBI_EXT_DBTR_SETUP_SHMEM,
> + -1UL, -1UL, 0, 0, 0, 0);
> +
> + if (ret.error) {
> + switch (ret.error) {
> + case SBI_ERR_DENIED:
> + pr_err("Access denied for shared memory.\n");
> + break;
> +
> + case SBI_ERR_INVALID_PARAM:
> + case SBI_ERR_INVALID_ADDRESS:
> + pr_err("Invalid address parameter (%lu)\n", ret.error);
> + break;
> +
> + case SBI_ERR_ALREADY_AVAILABLE:
> + pr_err("Shared memory is already set\n");
> + break;
> + case SBI_ERR_FAILURE:
> + pr_err("Internal sdtrig state error\n");
> + break;
> + default:
> + pr_err("Unknown error %lu\n", ret.error);
> + break;
> + }
> + }
> +
> + pr_warn("CPU %d: HW Breakpoint shared memory disabled.\n", cpu);
Ditto.
> +
> + return 0;
> +}
Best regards,
Qingfang
_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv
next prev parent reply other threads:[~2026-07-17 7:19 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-18 6:59 [PATCH v4 0/2] riscv: Introduce support for hardware break/watchpoints Himanshu Chauhan
2026-05-18 6:59 ` Himanshu Chauhan
2026-05-18 6:59 ` [PATCH v4 1/2] " Himanshu Chauhan
2026-05-18 6:59 ` Himanshu Chauhan
2026-07-17 7:19 ` Qingfang Deng [this message]
2026-07-17 7:19 ` Qingfang Deng
2026-05-18 6:59 ` [PATCH v4 2/2] riscv: Add breakpoint and watchpoint test for riscv Himanshu Chauhan
2026-05-18 6:59 ` Himanshu Chauhan
2026-07-15 16:21 ` [PATCH v4 0/2] riscv: Introduce support for hardware break/watchpoints Paul Walmsley
2026-07-15 16:21 ` Paul Walmsley
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=765ac2fe-a0ff-4980-915c-b2546a85b86a@linux.dev \
--to=qingfang.deng@linux.dev \
--cc=alex@ghiti.fr \
--cc=aou@eecs.berkeley.edu \
--cc=himanshu.chauhan@oss.qualcomm.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=palmer@dabbelt.com \
--cc=pjw@kernel.org \
--cc=shuah@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.