From: Frederic Weisbecker <fweisbec@gmail.com>
To: suravee.suthikulpanit@amd.com
Cc: mingo@kernel.org, mingo@redhat.com, jacob.w.shin@gmail.com,
oleg@redhat.com, a.p.zijlstra@chello.nl, acme@ghostprotocols.net,
hpa@zytor.com, tgl@domain.invalid, linux-kernel@vger.kernel.org,
sherry.hurwitz@amd.com
Subject: Re: [PATCH 1/3] perf/x86/amd: AMD support for bp_len > HW_BREAKPOINT_LEN_8
Date: Tue, 10 Dec 2013 16:23:44 +0100 [thread overview]
Message-ID: <20131210152342.GE10633@localhost.localdomain> (raw)
In-Reply-To: <1380730268-25807-2-git-send-email-suravee.suthikulpanit@amd.com>
On Wed, Oct 02, 2013 at 11:11:06AM -0500, suravee.suthikulpanit@amd.com wrote:
> From: Jacob Shin <jacob.w.shin@gmail.com>
>
> 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: Jacob Shin <jacob.w.shin@gmail.com>
> Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Thinking further about this, Oleg convinced me that we can keep the mask eventually.
It actually makes sense internally just for the use of bpext.
But I still have a few comments on this patchset:
> ---
> arch/x86/include/asm/cpufeature.h | 2 ++
> arch/x86/include/asm/debugreg.h | 5 ++++
> arch/x86/include/asm/hw_breakpoint.h | 1 +
> arch/x86/include/uapi/asm/msr-index.h | 4 +++
> arch/x86/kernel/cpu/amd.c | 19 ++++++++++++++
> arch/x86/kernel/hw_breakpoint.c | 47 ++++++++++++++---------------------
> 6 files changed, 49 insertions(+), 29 deletions(-)
>
> diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
> index d3f5c63..26609bb 100644
> --- a/arch/x86/include/asm/cpufeature.h
> +++ b/arch/x86/include/asm/cpufeature.h
> @@ -170,6 +170,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 */
Please comment that it's AMD specific.
> #define X86_FEATURE_PERFCTR_L2 (6*32+28) /* L2 performance counter extensions */
>
> /*
> @@ -332,6 +333,7 @@ extern const char * const x86_power_flags[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)
>
> #ifdef CONFIG_X86_64
>
> diff --git a/arch/x86/include/asm/debugreg.h b/arch/x86/include/asm/debugreg.h
> index 4b528a9..145b009 100644
> --- a/arch/x86/include/asm/debugreg.h
> +++ b/arch/x86/include/asm/debugreg.h
> @@ -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 */
> diff --git a/arch/x86/include/asm/hw_breakpoint.h b/arch/x86/include/asm/hw_breakpoint.h
> index ef1c4d2..6c98be8 100644
> --- a/arch/x86/include/asm/hw_breakpoint.h
> +++ b/arch/x86/include/asm/hw_breakpoint.h
> @@ -12,6 +12,7 @@
> */
> struct arch_hw_breakpoint {
> unsigned long address;
> + unsigned long mask;
> u8 len;
> u8 type;
> };
> diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h
> index bb04650..1f04f6c 100644
> --- a/arch/x86/include/uapi/asm/msr-index.h
> +++ b/arch/x86/include/uapi/asm/msr-index.h
> @@ -205,6 +205,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
> diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
> index 903a264..fffc9cb 100644
> --- a/arch/x86/kernel/cpu/amd.c
> +++ b/arch/x86/kernel/cpu/amd.c
> @@ -909,3 +909,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:
How about just:
if (dr <= 4 && dr >= 0)
wrmsr(MSR_F16H_DR1_ADDR_MASK + dr - 1, mask, 0)
> + break;
> + }
> +}
> diff --git a/arch/x86/kernel/hw_breakpoint.c b/arch/x86/kernel/hw_breakpoint.c
> index f66ff16..3cb1951 100644
> --- a/arch/x86/kernel/hw_breakpoint.c
> +++ b/arch/x86/kernel/hw_breakpoint.c
> @@ -128,6 +128,8 @@ int arch_install_hw_breakpoint(struct perf_event *bp)
> *dr7 |= encode_dr7(i, info->len, info->type);
>
> set_debugreg(*dr7, 7);
> + if (info->mask)
> + set_dr_addr_mask(info->mask, i);
>
> return 0;
> }
> @@ -163,29 +165,8 @@ void arch_uninstall_hw_breakpoint(struct perf_event *bp)
> *dr7 &= ~__encode_dr7(i, info->len, info->type);
>
> set_debugreg(*dr7, 7);
> -}
> -
> -static int get_hbp_len(u8 hbp_len)
> -{
> - unsigned int len_in_bytes = 0;
> -
> - switch (hbp_len) {
> - case X86_BREAKPOINT_LEN_1:
> - len_in_bytes = 1;
> - break;
> - case X86_BREAKPOINT_LEN_2:
> - len_in_bytes = 2;
> - break;
> - case X86_BREAKPOINT_LEN_4:
> - len_in_bytes = 4;
> - break;
> -#ifdef CONFIG_X86_64
> - case X86_BREAKPOINT_LEN_8:
> - len_in_bytes = 8;
> - break;
> -#endif
> - }
> - return len_in_bytes;
> + if (info->mask)
> + set_dr_addr_mask(0, i);
> }
>
> /*
> @@ -198,7 +179,7 @@ int arch_check_bp_in_kernelspace(struct perf_event *bp)
> struct arch_hw_breakpoint *info = counter_arch_bp(bp);
>
> va = info->address;
> - len = get_hbp_len(info->len);
> + len = bp->attr.bp_len;
So we can access the attr directly instead of get_hbp_len(). Good, that's a welcome
simplification but it's a change that is meaningful and tricky enough to deserve a seperate patch.
Could you send a seperate one for that?
>
> return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
> }
> @@ -279,7 +260,16 @@ static int arch_build_bp_info(struct perf_event *bp)
> }
>
> /* Len */
> + info->mask = 0;
> +
> switch (bp->attr.bp_len) {
> + default:
> + if (!is_power_of_2(bp->attr.bp_len))
> + return -EINVAL;
> + if (!cpu_has_bpext)
> + return -EOPNOTSUPP;
> + info->mask = bp->attr.bp_len - 1;
> + /* fall through */
So, that's perhaps just personal preference but having the default on
top of the switch makes things very confusing. Can't we put the above
in the end of the switch instead?
> case HW_BREAKPOINT_LEN_1:
> info->len = X86_BREAKPOINT_LEN_1;
> break;
> @@ -294,12 +284,11 @@ static int arch_build_bp_info(struct perf_event *bp)
> info->len = X86_BREAKPOINT_LEN_8;
> break;
> #endif
> - default:
> - return -EINVAL;
> }
>
> return 0;
> }
> +
> /*
> * Validate the arch-specific HW Breakpoint register settings
> */
> @@ -314,11 +303,11 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
> if (ret)
> return ret;
>
> - ret = -EINVAL;
> -
> switch (info->len) {
> case X86_BREAKPOINT_LEN_1:
> align = 0;
> + if (info->mask)
> + align = info->mask;
Confused, I thought mask is set only when length is above 8?
> break;
> case X86_BREAKPOINT_LEN_2:
> align = 1;
> @@ -332,7 +321,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
> break;
> #endif
> default:
> - return ret;
> + BUG();
Please use WARN_ON_ONCE() instead.
Thanks.
> }
>
> /*
> --
> 1.8.1.2
>
>
next prev parent reply other threads:[~2013-12-10 15:23 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-02 16:11 [PATCH V5 0/3] perf/x86/amd: AMD Family 16h Data Breakpoint Extensions suravee.suthikulpanit
2013-10-02 16:11 ` [PATCH 1/3] perf/x86/amd: AMD support for bp_len > HW_BREAKPOINT_LEN_8 suravee.suthikulpanit
2013-10-31 9:58 ` Frederic Weisbecker
2013-10-31 10:48 ` Borislav Petkov
2013-10-31 11:23 ` Frederic Weisbecker
2013-11-02 4:34 ` Borislav Petkov
2013-11-08 21:22 ` Suravee Suthikulpanit
2013-11-08 14:40 ` Borislav Petkov
2013-10-31 16:49 ` Oleg Nesterov
2013-11-08 19:41 ` Frederic Weisbecker
2013-11-09 15:11 ` Oleg Nesterov
2013-11-09 15:32 ` Frederic Weisbecker
2013-11-09 15:54 ` Oleg Nesterov
2013-11-11 15:44 ` Frederic Weisbecker
2013-11-11 17:51 ` Oleg Nesterov
2013-12-02 23:12 ` Frederic Weisbecker
2013-12-04 13:57 ` Oleg Nesterov
2013-12-10 14:43 ` Frederic Weisbecker
2013-12-10 14:52 ` Frederic Weisbecker
2013-12-10 15:23 ` Frederic Weisbecker [this message]
2013-12-10 16:19 ` Oleg Nesterov
2013-12-10 16:30 ` Frederic Weisbecker
2013-12-11 12:05 ` Suravee Suthikulanit
2013-10-02 16:11 ` [PATCH 2/3] perf tools: allow user to specify hardware breakpoint bp_len suravee.suthikulpanit
2013-12-10 15:25 ` Frederic Weisbecker
2013-12-10 16:22 ` Oleg Nesterov
2013-12-10 16:26 ` Frederic Weisbecker
2013-10-02 16:11 ` [PATCH 3/3] perf tools: add hardware breakpoint bp_len test cases suravee.suthikulpanit
2013-10-02 16:15 ` [PATCH V5 0/3] perf/x86/amd: AMD Family 16h Data Breakpoint Extensions Oleg Nesterov
2013-10-02 16:54 ` Suravee Suthikulpanit
2013-10-31 9:43 ` Frederic Weisbecker
-- strict thread matches above, loose matches on Subject: below --
2013-04-28 6:05 [PATCH V4 " Jacob Shin
2013-04-28 6:05 ` [PATCH 1/3] perf/x86/amd: AMD support for bp_len > HW_BREAKPOINT_LEN_8 Jacob Shin
2013-04-26 18:57 [PATCH 0/3] perf/x86/amd: AMD Family 16h Data Breakpoint Extensions Jacob Shin
2013-04-26 18:57 ` [PATCH 1/3] perf/x86/amd: AMD support for bp_len > HW_BREAKPOINT_LEN_8 Jacob Shin
2013-04-27 15:05 ` Oleg Nesterov
2013-04-27 15:14 ` Oleg Nesterov
2013-04-27 15:40 ` Jacob Shin
2013-04-27 16:10 ` Oleg Nesterov
2013-04-28 6:05 ` Jacob Shin
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=20131210152342.GE10633@localhost.localdomain \
--to=fweisbec@gmail.com \
--cc=a.p.zijlstra@chello.nl \
--cc=acme@ghostprotocols.net \
--cc=hpa@zytor.com \
--cc=jacob.w.shin@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=mingo@redhat.com \
--cc=oleg@redhat.com \
--cc=sherry.hurwitz@amd.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=tgl@domain.invalid \
/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.