Re: [RFC][PATCH 07/11] perf: Provide PERF_SAMPLE_REGS

From: Stephane Eranian
Date: Wed Mar 03 2010 - 12:30:44 EST


This assumes struct pt_regs is somehow exported to userland.
Is that the case?

I would clearly spell out that the REGS are the interrupted REGS,
not the overflow REGS. Maybe PERF_SAMPLE_IREGS.

On Wed, Mar 3, 2010 at 8:39 AM, Peter Zijlstra <a.p.zijlstra@xxxxxxxxx> wrote:
> Simply copy out the provided pt_regs in a u64 aligned fashion.
>
> XXX: do task_pt_regs() and get_irq_regs() always clear everything or
> Â Â are we now leaking data?
>
> Signed-off-by: Peter Zijlstra <a.p.zijlstra@xxxxxxxxx>
> ---
> Âinclude/linux/perf_event.h | Â Â5 ++++-
> Âkernel/perf_event.c    Â|  17 +++++++++++++++++
> Â2 files changed, 21 insertions(+), 1 deletion(-)
>
> Index: linux-2.6/include/linux/perf_event.h
> ===================================================================
> --- linux-2.6.orig/include/linux/perf_event.h
> +++ linux-2.6/include/linux/perf_event.h
> @@ -125,8 +125,9 @@ enum perf_event_sample_format {
> Â Â Â ÂPERF_SAMPLE_PERIOD Â Â Â Â Â Â Â Â Â Â Â= 1U << 8,
> Â Â Â ÂPERF_SAMPLE_STREAM_ID Â Â Â Â Â Â Â Â Â = 1U << 9,
> Â Â Â ÂPERF_SAMPLE_RAW Â Â Â Â Â Â Â Â Â Â Â Â = 1U << 10,
> + Â Â Â PERF_SAMPLE_REGS Â Â Â Â Â Â Â Â Â Â Â Â= 1U << 11,
>
> - Â Â Â PERF_SAMPLE_MAX = 1U << 11, Â Â Â Â Â Â /* non-ABI */
> + Â Â Â PERF_SAMPLE_MAX = 1U << 12, Â Â Â Â Â Â /* non-ABI */
> Â};
>
> Â/*
> @@ -392,6 +393,7 @@ enum perf_event_type {
> Â Â Â Â * Â Â Â{ u64 Â Â Â Â Â Â Â Â Â period; Â } && PERF_SAMPLE_PERIOD
> Â Â Â Â *
>     *   Â{ struct read_format  Âvalues;  } && PERF_SAMPLE_READ
> +    Â*   Â{ struct pt_regs    Âregs;   } && PERF_SAMPLE_REGS
> Â Â Â Â *
> Â Â Â Â * Â Â Â{ u64 Â Â Â Â Â Â Â Â Â nr,
> Â Â Â Â * Â Â Â Âu64 Â Â Â Â Â Â Â Â Â ips[nr]; Â} && PERF_SAMPLE_CALLCHAIN
> @@ -800,6 +802,7 @@ struct perf_sample_data {
> Â Â Â Âu64 Â Â Â Â Â Â Â Â Â Â Â Â Â Â period;
>    Âstruct perf_callchain_entry   *callchain;
>    Âstruct perf_raw_record     Â*raw;
> +    struct pt_regs         Â*regs;
> Â};
>
> Âstatic inline
> Index: linux-2.6/kernel/perf_event.c
> ===================================================================
> --- linux-2.6.orig/kernel/perf_event.c
> +++ linux-2.6/kernel/perf_event.c
> @@ -3176,6 +3176,17 @@ void perf_output_sample(struct perf_outp
> Â Â Â Âif (sample_type & PERF_SAMPLE_READ)
> Â Â Â Â Â Â Â Âperf_output_read(handle, event);
>
> + Â Â Â if (sample_type & PERF_SAMPLE_REGS) {
> + Â Â Â Â Â Â Â int size = DIV_ROUND_UP(sizeof(struct pt_regs), sizeof(u64)) -
> + Â Â Â Â Â Â Â Â Â Â Â Â Âsizeof(struct pt_regs);
> +
> + Â Â Â Â Â Â Â perf_output_put(handle, *data->regs);
> + Â Â Â Â Â Â Â if (size) {
> + Â Â Â Â Â Â Â Â Â Â Â u64 zero = 0;
> + Â Â Â Â Â Â Â Â Â Â Â perf_output_copy(handle, &zero, size);
> + Â Â Â Â Â Â Â }
> + Â Â Â }
> +
> Â Â Â Âif (sample_type & PERF_SAMPLE_CALLCHAIN) {
> Â Â Â Â Â Â Â Âif (data->callchain) {
> Â Â Â Â Â Â Â Â Â Â Â Âint size = 1;
> @@ -3273,6 +3284,12 @@ void perf_prepare_sample(struct perf_eve
> Â Â Â Âif (sample_type & PERF_SAMPLE_READ)
> Â Â Â Â Â Â Â Âheader->size += perf_event_read_size(event);
>
> + Â Â Â if (sample_type & PERF_SAMPLE_REGS) {
> + Â Â Â Â Â Â Â data->regs = regs;
> + Â Â Â Â Â Â Â header->size += DIV_ROUND_UP(sizeof(struct pt_regs),
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Â Âsizeof(u64));
> + Â Â Â }
> +
> Â Â Â Âif (sample_type & PERF_SAMPLE_CALLCHAIN) {
> Â Â Â Â Â Â Â Âint size = 1;
>
>
> --
>
>



--
Stephane Eranian | EMEA Software Engineering
Google France | 38 avenue de l'OpÃra | 75002 Paris
Tel : +33 (0) 1 42 68 53 00
This email may be confidential or privileged. If you received this
communication by mistake, please
don't forward it to anyone else, please erase all copies and
attachments, and please let me know that
it went to the wrong person. Thanks
èº{.nÇ+‰·Ÿ®‰­†+%ŠËlzwm…ébëæìr¸›zX§»®w¥Š{ayºÊÚë,j­¢f£¢·hš‹àz¹®w¥¢¸ ¢·¦j:+v‰¨ŠwèjØm¶Ÿÿ¾«‘êçzZ+ƒùšŽŠÝj"ú!¶iO•æ¬z·švØ^¶m§ÿðà nÆàþY&—