Commit d6d55f0b authored by Jacob Shin's avatar Jacob Shin Committed by Frederic Weisbecker
Browse files

perf/x86/amd: AMD support for bp_len > HW_BREAKPOINT_LEN_8



Implement hardware breakpoint address mask for AMD Family 16h and
above processors. CPUID feature bit indicates hardware support for
DRn_ADDR_MASK MSRs. These masks further qualify DRn/DR7 hardware
breakpoint addresses to allow matching of larger addresses ranges.

Valuable advice and pseudo code from Oleg Nesterov <oleg@redhat.com>

Signed-off-by: default avatarJacob Shin <jacob.w.shin@gmail.com>
Signed-off-by: default avatarSuravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
Reviewed-by: default avatarOleg Nesterov <oleg@redhat.com>
Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: xiakaixu <xiakaixu@huawei.com>
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
parent 4e6e311e
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -174,6 +174,7 @@
#define X86_FEATURE_TOPOEXT	( 6*32+22) /* topology extensions CPUID leafs */
#define X86_FEATURE_PERFCTR_CORE ( 6*32+23) /* core performance counter extensions */
#define X86_FEATURE_PERFCTR_NB  ( 6*32+24) /* NB performance counter extensions */
#define X86_FEATURE_BPEXT	(6*32+26) /* data breakpoint extension */
#define X86_FEATURE_PERFCTR_L2	( 6*32+28) /* L2 performance counter extensions */

/*
@@ -383,6 +384,7 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
#define cpu_has_cx16		boot_cpu_has(X86_FEATURE_CX16)
#define cpu_has_eager_fpu	boot_cpu_has(X86_FEATURE_EAGER_FPU)
#define cpu_has_topoext		boot_cpu_has(X86_FEATURE_TOPOEXT)
#define cpu_has_bpext		boot_cpu_has(X86_FEATURE_BPEXT)

#if __GNUC__ >= 4
extern void warn_pre_alternatives(void);
+5 −0
Original line number Diff line number Diff line
@@ -114,5 +114,10 @@ static inline void debug_stack_usage_inc(void) { }
static inline void debug_stack_usage_dec(void) { }
#endif /* X86_64 */

#ifdef CONFIG_CPU_SUP_AMD
extern void set_dr_addr_mask(unsigned long mask, int dr);
#else
static inline void set_dr_addr_mask(unsigned long mask, int dr) { }
#endif

#endif /* _ASM_X86_DEBUGREG_H */
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
 */
struct arch_hw_breakpoint {
	unsigned long	address;
	unsigned long	mask;
	u8		len;
	u8		type;
};
+4 −0
Original line number Diff line number Diff line
@@ -212,6 +212,10 @@
/* Fam 16h MSRs */
#define MSR_F16H_L2I_PERF_CTL		0xc0010230
#define MSR_F16H_L2I_PERF_CTR		0xc0010231
#define MSR_F16H_DR1_ADDR_MASK		0xc0011019
#define MSR_F16H_DR2_ADDR_MASK		0xc001101a
#define MSR_F16H_DR3_ADDR_MASK		0xc001101b
#define MSR_F16H_DR0_ADDR_MASK		0xc0011027

/* Fam 15h MSRs */
#define MSR_F15H_PERF_CTL		0xc0010200
+19 −0
Original line number Diff line number Diff line
@@ -870,3 +870,22 @@ static bool cpu_has_amd_erratum(struct cpuinfo_x86 *cpu, const int *erratum)

	return false;
}

void set_dr_addr_mask(unsigned long mask, int dr)
{
	if (!cpu_has_bpext)
		return;

	switch (dr) {
	case 0:
		wrmsr(MSR_F16H_DR0_ADDR_MASK, mask, 0);
		break;
	case 1:
	case 2:
	case 3:
		wrmsr(MSR_F16H_DR1_ADDR_MASK - 1 + dr, mask, 0);
		break;
	default:
		break;
	}
}
Loading