[PATCH v1 0/6] LoongArch: Fix perf hardware breakpoints

Tiezhu Yang posted 6 patches 1 month ago
There is a newer version of this series
arch/loongarch/include/asm/hw_breakpoint.h |  4 +-
arch/loongarch/include/asm/loongarch.h     |  7 +++-
arch/loongarch/kernel/hw_breakpoint.c      | 43 ++++++++++++++++------
arch/loongarch/kernel/traps.c              | 12 +++---
4 files changed, 46 insertions(+), 20 deletions(-)
[PATCH v1 0/6] LoongArch: Fix perf hardware breakpoints
Posted by Tiezhu Yang 1 month ago
This series addresses severe functional degradations in standard
perf_event usage, including initialization failures and one-shot
triggering limitations.

All fixes have been verified with user-space reproducers on real
hardware and align with the LoongArch Reference Manual.

Here is a user-space reproducer demonstrating that standard perf
hardware breakpoints can now reliably monitor 10,000 hits without
a single event leakage or subsystem lockup.

(1) Test program (perf-hw-breakpoint.c):

  #include <stdint.h>
  #include <stdio.h>
  #include <sys/ioctl.h>
  #include <sys/syscall.h>
  #include <unistd.h>
  #include <linux/hw_breakpoint.h>
  #include <linux/perf_event.h>

  #ifndef noinline
  #define noinline __attribute__((noinline))
  #endif

  static noinline void test_function(const uint8_t *data)
  {
	asm volatile("" :: "r"(data[0]) : "memory");
  }

  int main(void)
  {
	int fd, ret, i;
	size_t count;
	uint8_t data[] = "TEST DATA";
	struct perf_event_attr attr = {0};

	attr.type = PERF_TYPE_BREAKPOINT;
	attr.size = sizeof(struct perf_event_attr);
	attr.bp_type = HW_BREAKPOINT_RW;
	attr.bp_addr = (uintptr_t)data;
	attr.bp_len  = HW_BREAKPOINT_LEN_1;
	attr.exclude_kernel = 1;
	attr.exclude_hv = 1;
	attr.disabled = 1;

	fd = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0);
	ioctl(fd, PERF_EVENT_IOC_RESET, 0);
	ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);

	for (i = 0; i < 10000; i++)
		test_function(data);

	ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
	read(fd, &count, sizeof(size_t));

	printf("perf count = %zu\n", count);

	close(fd);
	return 0;
  }

(2) Test steps:

  $ gcc perf-hw-breakpoint.c -o perf-hw-breakpoint
  $ ./perf-hw-breakpoint

(3) Test results:

Without this series:

  perf count = 0

With this series:

  perf count = 10000

Tiezhu Yang (6):
  LoongArch: Fix bitmask corruption in update_bp_registers()
  LoongArch: Remove redundant call in update_bp_registers()
  LoongArch: Fix architectural naming typo for CSR_FWPS_SKIP
  LoongArch: Only send SIGTRAP signal if necessary in do_watch()
  LoongArch: Fix perf hardware breakpoint failure via installation
  LoongArch: Fix one-shot limitation for perf hardware breakpoints

 arch/loongarch/include/asm/hw_breakpoint.h |  4 +-
 arch/loongarch/include/asm/loongarch.h     |  7 +++-
 arch/loongarch/kernel/hw_breakpoint.c      | 43 ++++++++++++++++------
 arch/loongarch/kernel/traps.c              | 12 +++---
 4 files changed, 46 insertions(+), 20 deletions(-)

-- 
2.42.0