Some architectures (for us, AMD Family 16h) allow for "don't care" bit mask to further qualify a hardware breakpoint address, in order to trap on range of addresses. Update perf uapi to add bp_addr_mask field and define HAVE_HW_BREAKPOINT_ADDR_MASK.
Signed-off-by: Jacob Shin <jacob.s...@amd.com> --- arch/Kconfig | 4 ++++ include/linux/hw_breakpoint.h | 6 ++++++ include/uapi/linux/perf_event.h | 5 ++++- kernel/events/hw_breakpoint.c | 3 +++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/arch/Kconfig b/arch/Kconfig index 7f8f281..9ca606c 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -221,6 +221,10 @@ config HAVE_HW_BREAKPOINT bool depends on PERF_EVENTS +config HAVE_HW_BREAKPOINT_ADDR_MASK + bool + depends on HAVE_HW_BREAKPOINT + config HAVE_MIXED_BREAKPOINTS_REGS bool depends on HAVE_HW_BREAKPOINT diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index 0464c85..9384201 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h @@ -84,6 +84,12 @@ static inline struct arch_hw_breakpoint *counter_arch_bp(struct perf_event *bp) return &bp->hw.info; } +#ifdef CONFIG_HAVE_HW_BREAKPOINT_ADDR_MASK +extern int arch_has_hw_breakpoint_addr_mask(void); +#else +static inline int arch_has_hw_breakpoint_addr_mask(void) { return 0; } +#endif /* CONFIG_HAVE_HW_BREAKPOINT_ADDR_MASK */ + #else /* !CONFIG_HAVE_HW_BREAKPOINT */ static inline int __init init_hw_breakpoint(void) { return 0; } diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h index 4f63c05..067d315 100644 --- a/include/uapi/linux/perf_event.h +++ b/include/uapi/linux/perf_event.h @@ -284,7 +284,10 @@ struct perf_event_attr { __u64 config1; /* extension of config */ }; union { - __u64 bp_len; + struct { + __u32 bp_len; + __u32 bp_addr_mask; + }; __u64 config2; /* extension of config1 */ }; __u64 branch_sample_type; /* enum perf_branch_sample_type */ diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index fe8a916..6f10baa 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c @@ -612,6 +612,9 @@ static int hw_breakpoint_add(struct perf_event *bp, int flags) if (!(flags & PERF_EF_START)) bp->hw.state = PERF_HES_STOPPED; + if (bp->attr.bp_addr_mask && !arch_has_hw_breakpoint_addr_mask()) + return -EOPNOTSUPP; + return arch_install_hw_breakpoint(bp); } -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/