arch/arm64/kernel/hw_breakpoint.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
Some tools (e.g. perf) incorrectly assume that breakpoints should be
sizeof(long), but this is wrong for AArch64 where breakpoints must be
4 bytes. Add a warning when we silently fix up the parameter so tool
developers can get notified.
This addresses the FIXME comment by adding diagnostic output rather
than breaking existing tools by returning -EINVAL.
Signed-off-by: Osama Abdelkader <osama.abdelkader@gmail.com>
---
arch/arm64/kernel/hw_breakpoint.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c
index ab76b36dce82..4d31842e5d91 100644
--- a/arch/arm64/kernel/hw_breakpoint.c
+++ b/arch/arm64/kernel/hw_breakpoint.c
@@ -475,11 +475,13 @@ static int arch_build_bp_info(struct perf_event *bp,
return -EINVAL;
} else if (hw->ctrl.len != ARM_BREAKPOINT_LEN_4) {
/*
- * FIXME: Some tools (I'm looking at you perf) assume
- * that breakpoints should be sizeof(long). This
- * is nonsense. For now, we fix up the parameter
- * but we should probably return -EINVAL instead.
+ * Some tools (e.g. perf) incorrectly assume that
+ * breakpoints should be sizeof(long). This is wrong
+ * for AArch64 where breakpoints must be 4 bytes.
+ * Warn the user and fix up the parameter.
*/
+ pr_warn_once("hw_breakpoint: invalid AArch64 breakpoint length %d,
+ fixing to 4 bytes\n", hw->ctrl.len);
hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
}
}
--
2.43.0
Hi Osama,
kernel test robot noticed the following build errors:
[auto build test ERROR on arm64/for-next/core]
[also build test ERROR on arm-perf/for-next/perf linus/master v6.18 next-20251212]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Osama-Abdelkader/arm64-hw_breakpoint-warn-on-invalid-breakpoint-length/20251213-045501
base: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git for-next/core
patch link: https://lore.kernel.org/r/20251212205230.84606-1-osama.abdelkader%40gmail.com
patch subject: [PATCH] arm64: hw_breakpoint: warn on invalid breakpoint length
config: arm64-allmodconfig (https://download.01.org/0day-ci/archive/20251213/202512131730.89TvJc2D-lkp@intel.com/config)
compiler: clang version 19.1.7 (https://github.com/llvm/llvm-project cd708029e0b2869e80abe31ddb175f7c35361f90)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20251213/202512131730.89TvJc2D-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202512131730.89TvJc2D-lkp@intel.com/
All errors (new ones prefixed by >>):
arch/arm64/kernel/hw_breakpoint.c:483:17: warning: missing terminating '"' character [-Winvalid-pp-token]
483 | pr_warn_once("hw_breakpoint: invalid AArch64 breakpoint length %d,
| ^
arch/arm64/kernel/hw_breakpoint.c:484:24: warning: missing terminating '"' character [-Winvalid-pp-token]
484 | fixing to 4 bytes\n", hw->ctrl.len);
| ^
>> arch/arm64/kernel/hw_breakpoint.c:483:4: error: unterminated function-like macro invocation
483 | pr_warn_once("hw_breakpoint: invalid AArch64 breakpoint length %d,
| ^
include/linux/printk.h:669:9: note: macro 'pr_warn_once' defined here
669 | #define pr_warn_once(fmt, ...) \
| ^
>> arch/arm64/kernel/hw_breakpoint.c:1014:2: error: expected '}'
1014 | }
| ^
arch/arm64/kernel/hw_breakpoint.c:476:52: note: to match this '{'
476 | } else if (hw->ctrl.len != ARM_BREAKPOINT_LEN_4) {
| ^
>> arch/arm64/kernel/hw_breakpoint.c:1014:2: error: expected '}'
1014 | }
| ^
arch/arm64/kernel/hw_breakpoint.c:471:47: note: to match this '{'
471 | if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
| ^
>> arch/arm64/kernel/hw_breakpoint.c:1014:2: error: expected '}'
1014 | }
| ^
arch/arm64/kernel/hw_breakpoint.c:417:1: note: to match this '{'
417 | {
| ^
2 warnings and 4 errors generated.
vim +483 arch/arm64/kernel/hw_breakpoint.c
410
411 /*
412 * Construct an arch_hw_breakpoint from a perf_event.
413 */
414 static int arch_build_bp_info(struct perf_event *bp,
415 const struct perf_event_attr *attr,
416 struct arch_hw_breakpoint *hw)
417 {
418 /* Type */
419 switch (attr->bp_type) {
420 case HW_BREAKPOINT_X:
421 hw->ctrl.type = ARM_BREAKPOINT_EXECUTE;
422 break;
423 case HW_BREAKPOINT_R:
424 hw->ctrl.type = ARM_BREAKPOINT_LOAD;
425 break;
426 case HW_BREAKPOINT_W:
427 hw->ctrl.type = ARM_BREAKPOINT_STORE;
428 break;
429 case HW_BREAKPOINT_RW:
430 hw->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
431 break;
432 default:
433 return -EINVAL;
434 }
435
436 /* Len */
437 switch (attr->bp_len) {
438 case HW_BREAKPOINT_LEN_1:
439 hw->ctrl.len = ARM_BREAKPOINT_LEN_1;
440 break;
441 case HW_BREAKPOINT_LEN_2:
442 hw->ctrl.len = ARM_BREAKPOINT_LEN_2;
443 break;
444 case HW_BREAKPOINT_LEN_3:
445 hw->ctrl.len = ARM_BREAKPOINT_LEN_3;
446 break;
447 case HW_BREAKPOINT_LEN_4:
448 hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
449 break;
450 case HW_BREAKPOINT_LEN_5:
451 hw->ctrl.len = ARM_BREAKPOINT_LEN_5;
452 break;
453 case HW_BREAKPOINT_LEN_6:
454 hw->ctrl.len = ARM_BREAKPOINT_LEN_6;
455 break;
456 case HW_BREAKPOINT_LEN_7:
457 hw->ctrl.len = ARM_BREAKPOINT_LEN_7;
458 break;
459 case HW_BREAKPOINT_LEN_8:
460 hw->ctrl.len = ARM_BREAKPOINT_LEN_8;
461 break;
462 default:
463 return -EINVAL;
464 }
465
466 /*
467 * On AArch64, we only permit breakpoints of length 4, whereas
468 * AArch32 also requires breakpoints of length 2 for Thumb.
469 * Watchpoints can be of length 1, 2, 4 or 8 bytes.
470 */
471 if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE) {
472 if (is_compat_bp(bp)) {
473 if (hw->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
474 hw->ctrl.len != ARM_BREAKPOINT_LEN_4)
475 return -EINVAL;
476 } else if (hw->ctrl.len != ARM_BREAKPOINT_LEN_4) {
477 /*
478 * Some tools (e.g. perf) incorrectly assume that
479 * breakpoints should be sizeof(long). This is wrong
480 * for AArch64 where breakpoints must be 4 bytes.
481 * Warn the user and fix up the parameter.
482 */
> 483 pr_warn_once("hw_breakpoint: invalid AArch64 breakpoint length %d,
> 484 fixing to 4 bytes\n", hw->ctrl.len);
485 hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
486 }
487 }
488
489 /* Address */
490 hw->address = attr->bp_addr;
491
492 /*
493 * Privilege
494 * Note that we disallow combined EL0/EL1 breakpoints because
495 * that would complicate the stepping code.
496 */
497 if (arch_check_bp_in_kernelspace(hw))
498 hw->ctrl.privilege = AARCH64_BREAKPOINT_EL1;
499 else
500 hw->ctrl.privilege = AARCH64_BREAKPOINT_EL0;
501
502 /* Enabled? */
503 hw->ctrl.enabled = !attr->disabled;
504
505 return 0;
506 }
507
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
© 2016 - 2025 Red Hat, Inc.