linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification
@ 2022-01-31 10:34 Marco Elver
  2022-01-31 10:34 ` [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data Marco Elver
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Marco Elver @ 2022-01-31 10:34 UTC (permalink / raw)
  To: elver, Peter Zijlstra
  Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, Dmitry Vyukov,
	linux-perf-users, kasan-dev, linux-kernel

The intent has always been that perf_event_attr::sig_data should also be
modifiable along with PERF_EVENT_IOC_MODIFY_ATTRIBUTES, because it is
observable by user space if SIGTRAP on events is requested.

Currently only PERF_TYPE_BREAKPOINT is modifiable, and explicitly copies
relevant breakpoint-related attributes in hw_breakpoint_copy_attr().
This misses copying perf_event_attr::sig_data.

Since sig_data is not specific to PERF_TYPE_BREAKPOINT, introduce a
helper to copy generic event-type-independent attributes on
modification.

Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Marco Elver <elver@google.com>
---
 kernel/events/core.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index fc18664f49b0..db0d85a85f1b 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3197,6 +3197,15 @@ static int perf_event_modify_breakpoint(struct perf_event *bp,
 	return err;
 }
 
+/*
+ * Copy event-type-independent attributes that may be modified.
+ */
+static void perf_event_modify_copy_attr(struct perf_event_attr *to,
+					const struct perf_event_attr *from)
+{
+	to->sig_data = from->sig_data;
+}
+
 static int perf_event_modify_attr(struct perf_event *event,
 				  struct perf_event_attr *attr)
 {
@@ -3219,10 +3228,17 @@ static int perf_event_modify_attr(struct perf_event *event,
 	WARN_ON_ONCE(event->ctx->parent_ctx);
 
 	mutex_lock(&event->child_mutex);
+	/*
+	 * Event-type-independent attributes must be copied before event-type
+	 * modification, which will validate that final attributes match the
+	 * source attributes after all relevant attributes have been copied.
+	 */
+	perf_event_modify_copy_attr(&event->attr, attr);
 	err = func(event, attr);
 	if (err)
 		goto out;
 	list_for_each_entry(child, &event->child_list, child_list) {
+		perf_event_modify_copy_attr(&child->attr, attr);
 		err = func(child, attr);
 		if (err)
 			goto out;
-- 
2.35.0.rc2.247.g8bbb082509-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data
  2022-01-31 10:34 [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Marco Elver
@ 2022-01-31 10:34 ` Marco Elver
  2022-02-01  7:33   ` Dmitry Vyukov
  2022-02-03 14:33   ` [tip: perf/urgent] " tip-bot2 for Marco Elver
  2022-01-31 10:34 ` [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures Marco Elver
                   ` (2 subsequent siblings)
  3 siblings, 2 replies; 10+ messages in thread
From: Marco Elver @ 2022-01-31 10:34 UTC (permalink / raw)
  To: elver, Peter Zijlstra
  Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, Dmitry Vyukov,
	linux-perf-users, kasan-dev, linux-kernel

Test that PERF_EVENT_IOC_MODIFY_ATTRIBUTES correctly modifies
perf_event_attr::sig_data as well.

Signed-off-by: Marco Elver <elver@google.com>
---
 .../selftests/perf_events/sigtrap_threads.c     | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/perf_events/sigtrap_threads.c b/tools/testing/selftests/perf_events/sigtrap_threads.c
index 8e83cf91513a..6d849dc2bee0 100644
--- a/tools/testing/selftests/perf_events/sigtrap_threads.c
+++ b/tools/testing/selftests/perf_events/sigtrap_threads.c
@@ -44,9 +44,10 @@ static struct {
 } ctx;
 
 /* Unique value to check si_perf_data is correctly set from perf_event_attr::sig_data. */
-#define TEST_SIG_DATA(addr) (~(unsigned long)(addr))
+#define TEST_SIG_DATA(addr, id) (~(unsigned long)(addr) + id)
 
-static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
+static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr,
+					      unsigned long id)
 {
 	struct perf_event_attr attr = {
 		.type		= PERF_TYPE_BREAKPOINT,
@@ -60,7 +61,7 @@ static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
 		.inherit_thread = 1, /* ... but only cloned with CLONE_THREAD. */
 		.remove_on_exec = 1, /* Required by sigtrap. */
 		.sigtrap	= 1, /* Request synchronous SIGTRAP on event. */
-		.sig_data	= TEST_SIG_DATA(addr),
+		.sig_data	= TEST_SIG_DATA(addr, id),
 	};
 	return attr;
 }
@@ -110,7 +111,7 @@ FIXTURE(sigtrap_threads)
 
 FIXTURE_SETUP(sigtrap_threads)
 {
-	struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on);
+	struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on, 0);
 	struct sigaction action = {};
 	int i;
 
@@ -165,7 +166,7 @@ TEST_F(sigtrap_threads, enable_event)
 	EXPECT_EQ(ctx.tids_want_signal, 0);
 	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
 	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
-	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
+	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
 
 	/* Check enabled for parent. */
 	ctx.iterate_on = 0;
@@ -175,7 +176,7 @@ TEST_F(sigtrap_threads, enable_event)
 /* Test that modification propagates to all inherited events. */
 TEST_F(sigtrap_threads, modify_and_enable_event)
 {
-	struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on);
+	struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on, 42);
 
 	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &new_attr), 0);
 	run_test_threads(_metadata, self);
@@ -184,7 +185,7 @@ TEST_F(sigtrap_threads, modify_and_enable_event)
 	EXPECT_EQ(ctx.tids_want_signal, 0);
 	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
 	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
-	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
+	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 42));
 
 	/* Check enabled for parent. */
 	ctx.iterate_on = 0;
@@ -204,7 +205,7 @@ TEST_F(sigtrap_threads, signal_stress)
 	EXPECT_EQ(ctx.tids_want_signal, 0);
 	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
 	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
-	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
+	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
 }
 
 TEST_HARNESS_MAIN
-- 
2.35.0.rc2.247.g8bbb082509-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures
  2022-01-31 10:34 [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Marco Elver
  2022-01-31 10:34 ` [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data Marco Elver
@ 2022-01-31 10:34 ` Marco Elver
  2022-02-01  7:33   ` Dmitry Vyukov
  2022-02-03 14:33   ` [tip: perf/urgent] " tip-bot2 for Marco Elver
  2022-02-01  7:32 ` [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Dmitry Vyukov
  2022-02-03 14:33 ` [tip: perf/urgent] " tip-bot2 for Marco Elver
  3 siblings, 2 replies; 10+ messages in thread
From: Marco Elver @ 2022-01-31 10:34 UTC (permalink / raw)
  To: elver, Peter Zijlstra
  Cc: Ingo Molnar, Arnaldo Carvalho de Melo, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, Dmitry Vyukov,
	linux-perf-users, kasan-dev, linux-kernel

Due to the alignment requirements of siginfo_t, as described in
3ddb3fd8cdb0 ("signal, perf: Fix siginfo_t by avoiding u64 on 32-bit
architectures"), siginfo_t::si_perf_data is limited to an unsigned long.

However, perf_event_attr::sig_data is an u64, to avoid having to deal
with compat conversions. Due to being an u64, it may not immediately be
clear to users that sig_data is truncated on 32 bit architectures.

Add a comment to explicitly point this out, and hopefully help some
users save time by not having to deduce themselves what's happening.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Marco Elver <elver@google.com>
---
 include/uapi/linux/perf_event.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 1b65042ab1db..82858b697c05 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -465,6 +465,8 @@ struct perf_event_attr {
 	/*
 	 * User provided data if sigtrap=1, passed back to user via
 	 * siginfo_t::si_perf_data, e.g. to permit user to identify the event.
+	 * Note, siginfo_t::si_perf_data is long-sized, and sig_data will be
+	 * truncated accordingly on 32 bit architectures.
 	 */
 	__u64	sig_data;
 };
-- 
2.35.0.rc2.247.g8bbb082509-goog


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification
  2022-01-31 10:34 [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Marco Elver
  2022-01-31 10:34 ` [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data Marco Elver
  2022-01-31 10:34 ` [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures Marco Elver
@ 2022-02-01  7:32 ` Dmitry Vyukov
  2022-02-01 11:07   ` Peter Zijlstra
  2022-02-03 14:33 ` [tip: perf/urgent] " tip-bot2 for Marco Elver
  3 siblings, 1 reply; 10+ messages in thread
From: Dmitry Vyukov @ 2022-02-01  7:32 UTC (permalink / raw)
  To: Marco Elver
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	linux-perf-users, kasan-dev, linux-kernel

On Mon, 31 Jan 2022 at 11:34, Marco Elver <elver@google.com> wrote:
>
> The intent has always been that perf_event_attr::sig_data should also be
> modifiable along with PERF_EVENT_IOC_MODIFY_ATTRIBUTES, because it is
> observable by user space if SIGTRAP on events is requested.
>
> Currently only PERF_TYPE_BREAKPOINT is modifiable, and explicitly copies
> relevant breakpoint-related attributes in hw_breakpoint_copy_attr().
> This misses copying perf_event_attr::sig_data.
>
> Since sig_data is not specific to PERF_TYPE_BREAKPOINT, introduce a
> helper to copy generic event-type-independent attributes on
> modification.
>
> Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events")
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Marco Elver <elver@google.com>

Reviewed-by: Dmitry Vyukov <dvyukov@google.com>

Thanks for the quick fix.

> ---
>  kernel/events/core.c | 16 ++++++++++++++++
>  1 file changed, 16 insertions(+)
>
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index fc18664f49b0..db0d85a85f1b 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -3197,6 +3197,15 @@ static int perf_event_modify_breakpoint(struct perf_event *bp,
>         return err;
>  }
>
> +/*
> + * Copy event-type-independent attributes that may be modified.
> + */
> +static void perf_event_modify_copy_attr(struct perf_event_attr *to,
> +                                       const struct perf_event_attr *from)
> +{
> +       to->sig_data = from->sig_data;
> +}
> +
>  static int perf_event_modify_attr(struct perf_event *event,
>                                   struct perf_event_attr *attr)
>  {
> @@ -3219,10 +3228,17 @@ static int perf_event_modify_attr(struct perf_event *event,
>         WARN_ON_ONCE(event->ctx->parent_ctx);
>
>         mutex_lock(&event->child_mutex);
> +       /*
> +        * Event-type-independent attributes must be copied before event-type
> +        * modification, which will validate that final attributes match the
> +        * source attributes after all relevant attributes have been copied.
> +        */
> +       perf_event_modify_copy_attr(&event->attr, attr);
>         err = func(event, attr);
>         if (err)
>                 goto out;
>         list_for_each_entry(child, &event->child_list, child_list) {
> +               perf_event_modify_copy_attr(&child->attr, attr);
>                 err = func(child, attr);
>                 if (err)
>                         goto out;
> --
> 2.35.0.rc2.247.g8bbb082509-goog
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data
  2022-01-31 10:34 ` [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data Marco Elver
@ 2022-02-01  7:33   ` Dmitry Vyukov
  2022-02-03 14:33   ` [tip: perf/urgent] " tip-bot2 for Marco Elver
  1 sibling, 0 replies; 10+ messages in thread
From: Dmitry Vyukov @ 2022-02-01  7:33 UTC (permalink / raw)
  To: Marco Elver
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	linux-perf-users, kasan-dev, linux-kernel

On Mon, 31 Jan 2022 at 11:34, Marco Elver <elver@google.com> wrote:
>
> Test that PERF_EVENT_IOC_MODIFY_ATTRIBUTES correctly modifies
> perf_event_attr::sig_data as well.
>
> Signed-off-by: Marco Elver <elver@google.com>

Reviewed-by: Dmitry Vyukov <dvyukov@google.com>


> ---
>  .../selftests/perf_events/sigtrap_threads.c     | 17 +++++++++--------
>  1 file changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/tools/testing/selftests/perf_events/sigtrap_threads.c b/tools/testing/selftests/perf_events/sigtrap_threads.c
> index 8e83cf91513a..6d849dc2bee0 100644
> --- a/tools/testing/selftests/perf_events/sigtrap_threads.c
> +++ b/tools/testing/selftests/perf_events/sigtrap_threads.c
> @@ -44,9 +44,10 @@ static struct {
>  } ctx;
>
>  /* Unique value to check si_perf_data is correctly set from perf_event_attr::sig_data. */
> -#define TEST_SIG_DATA(addr) (~(unsigned long)(addr))
> +#define TEST_SIG_DATA(addr, id) (~(unsigned long)(addr) + id)
>
> -static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
> +static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr,
> +                                             unsigned long id)
>  {
>         struct perf_event_attr attr = {
>                 .type           = PERF_TYPE_BREAKPOINT,
> @@ -60,7 +61,7 @@ static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
>                 .inherit_thread = 1, /* ... but only cloned with CLONE_THREAD. */
>                 .remove_on_exec = 1, /* Required by sigtrap. */
>                 .sigtrap        = 1, /* Request synchronous SIGTRAP on event. */
> -               .sig_data       = TEST_SIG_DATA(addr),
> +               .sig_data       = TEST_SIG_DATA(addr, id),
>         };
>         return attr;
>  }
> @@ -110,7 +111,7 @@ FIXTURE(sigtrap_threads)
>
>  FIXTURE_SETUP(sigtrap_threads)
>  {
> -       struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on);
> +       struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on, 0);
>         struct sigaction action = {};
>         int i;
>
> @@ -165,7 +166,7 @@ TEST_F(sigtrap_threads, enable_event)
>         EXPECT_EQ(ctx.tids_want_signal, 0);
>         EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
>         EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
> -       EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
> +       EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
>
>         /* Check enabled for parent. */
>         ctx.iterate_on = 0;
> @@ -175,7 +176,7 @@ TEST_F(sigtrap_threads, enable_event)
>  /* Test that modification propagates to all inherited events. */
>  TEST_F(sigtrap_threads, modify_and_enable_event)
>  {
> -       struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on);
> +       struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on, 42);
>
>         EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &new_attr), 0);
>         run_test_threads(_metadata, self);
> @@ -184,7 +185,7 @@ TEST_F(sigtrap_threads, modify_and_enable_event)
>         EXPECT_EQ(ctx.tids_want_signal, 0);
>         EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
>         EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
> -       EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
> +       EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 42));
>
>         /* Check enabled for parent. */
>         ctx.iterate_on = 0;
> @@ -204,7 +205,7 @@ TEST_F(sigtrap_threads, signal_stress)
>         EXPECT_EQ(ctx.tids_want_signal, 0);
>         EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
>         EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
> -       EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
> +       EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
>  }
>
>  TEST_HARNESS_MAIN
> --
> 2.35.0.rc2.247.g8bbb082509-goog
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures
  2022-01-31 10:34 ` [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures Marco Elver
@ 2022-02-01  7:33   ` Dmitry Vyukov
  2022-02-03 14:33   ` [tip: perf/urgent] " tip-bot2 for Marco Elver
  1 sibling, 0 replies; 10+ messages in thread
From: Dmitry Vyukov @ 2022-02-01  7:33 UTC (permalink / raw)
  To: Marco Elver
  Cc: Peter Zijlstra, Ingo Molnar, Arnaldo Carvalho de Melo,
	Mark Rutland, Alexander Shishkin, Jiri Olsa, Namhyung Kim,
	linux-perf-users, kasan-dev, linux-kernel

On Mon, 31 Jan 2022 at 11:34, Marco Elver <elver@google.com> wrote:
>
> Due to the alignment requirements of siginfo_t, as described in
> 3ddb3fd8cdb0 ("signal, perf: Fix siginfo_t by avoiding u64 on 32-bit
> architectures"), siginfo_t::si_perf_data is limited to an unsigned long.
>
> However, perf_event_attr::sig_data is an u64, to avoid having to deal
> with compat conversions. Due to being an u64, it may not immediately be
> clear to users that sig_data is truncated on 32 bit architectures.
>
> Add a comment to explicitly point this out, and hopefully help some
> users save time by not having to deduce themselves what's happening.
>
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Marco Elver <elver@google.com>

Reviewed-by: Dmitry Vyukov <dvyukov@google.com>


> ---
>  include/uapi/linux/perf_event.h | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
> index 1b65042ab1db..82858b697c05 100644
> --- a/include/uapi/linux/perf_event.h
> +++ b/include/uapi/linux/perf_event.h
> @@ -465,6 +465,8 @@ struct perf_event_attr {
>         /*
>          * User provided data if sigtrap=1, passed back to user via
>          * siginfo_t::si_perf_data, e.g. to permit user to identify the event.
> +        * Note, siginfo_t::si_perf_data is long-sized, and sig_data will be
> +        * truncated accordingly on 32 bit architectures.
>          */
>         __u64   sig_data;
>  };
> --
> 2.35.0.rc2.247.g8bbb082509-goog
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification
  2022-02-01  7:32 ` [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Dmitry Vyukov
@ 2022-02-01 11:07   ` Peter Zijlstra
  0 siblings, 0 replies; 10+ messages in thread
From: Peter Zijlstra @ 2022-02-01 11:07 UTC (permalink / raw)
  To: Dmitry Vyukov
  Cc: Marco Elver, Ingo Molnar, Arnaldo Carvalho de Melo, Mark Rutland,
	Alexander Shishkin, Jiri Olsa, Namhyung Kim, linux-perf-users,
	kasan-dev, linux-kernel

On Tue, Feb 01, 2022 at 08:32:45AM +0100, Dmitry Vyukov wrote:
> On Mon, 31 Jan 2022 at 11:34, Marco Elver <elver@google.com> wrote:
> >
> > The intent has always been that perf_event_attr::sig_data should also be
> > modifiable along with PERF_EVENT_IOC_MODIFY_ATTRIBUTES, because it is
> > observable by user space if SIGTRAP on events is requested.
> >
> > Currently only PERF_TYPE_BREAKPOINT is modifiable, and explicitly copies
> > relevant breakpoint-related attributes in hw_breakpoint_copy_attr().
> > This misses copying perf_event_attr::sig_data.
> >
> > Since sig_data is not specific to PERF_TYPE_BREAKPOINT, introduce a
> > helper to copy generic event-type-independent attributes on
> > modification.
> >
> > Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events")
> > Reported-by: Dmitry Vyukov <dvyukov@google.com>
> > Signed-off-by: Marco Elver <elver@google.com>
> 
> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>

Thanks guys! Queued for perf/urgent

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [tip: perf/urgent] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures
  2022-01-31 10:34 ` [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures Marco Elver
  2022-02-01  7:33   ` Dmitry Vyukov
@ 2022-02-03 14:33   ` tip-bot2 for Marco Elver
  1 sibling, 0 replies; 10+ messages in thread
From: tip-bot2 for Marco Elver @ 2022-02-03 14:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Dmitry Vyukov, Marco Elver, Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID:     ddecd22878601a606d160680fa85802b75d92eb6
Gitweb:        https://git.kernel.org/tip/ddecd22878601a606d160680fa85802b75d92eb6
Author:        Marco Elver <elver@google.com>
AuthorDate:    Mon, 31 Jan 2022 11:34:07 +01:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 02 Feb 2022 13:11:40 +01:00

perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures

Due to the alignment requirements of siginfo_t, as described in
3ddb3fd8cdb0 ("signal, perf: Fix siginfo_t by avoiding u64 on 32-bit
architectures"), siginfo_t::si_perf_data is limited to an unsigned long.

However, perf_event_attr::sig_data is an u64, to avoid having to deal
with compat conversions. Due to being an u64, it may not immediately be
clear to users that sig_data is truncated on 32 bit architectures.

Add a comment to explicitly point this out, and hopefully help some
users save time by not having to deduce themselves what's happening.

Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Link: https://lore.kernel.org/r/20220131103407.1971678-3-elver@google.com
---
 include/uapi/linux/perf_event.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/uapi/linux/perf_event.h b/include/uapi/linux/perf_event.h
index 1b65042..82858b6 100644
--- a/include/uapi/linux/perf_event.h
+++ b/include/uapi/linux/perf_event.h
@@ -465,6 +465,8 @@ struct perf_event_attr {
 	/*
 	 * User provided data if sigtrap=1, passed back to user via
 	 * siginfo_t::si_perf_data, e.g. to permit user to identify the event.
+	 * Note, siginfo_t::si_perf_data is long-sized, and sig_data will be
+	 * truncated accordingly on 32 bit architectures.
 	 */
 	__u64	sig_data;
 };

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [tip: perf/urgent] selftests/perf_events: Test modification of perf_event_attr::sig_data
  2022-01-31 10:34 ` [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data Marco Elver
  2022-02-01  7:33   ` Dmitry Vyukov
@ 2022-02-03 14:33   ` tip-bot2 for Marco Elver
  1 sibling, 0 replies; 10+ messages in thread
From: tip-bot2 for Marco Elver @ 2022-02-03 14:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Marco Elver, Peter Zijlstra (Intel), Dmitry Vyukov, x86, linux-kernel

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID:     95d29fa104523b1756323f7003294b1711c27808
Gitweb:        https://git.kernel.org/tip/95d29fa104523b1756323f7003294b1711c27808
Author:        Marco Elver <elver@google.com>
AuthorDate:    Mon, 31 Jan 2022 11:34:06 +01:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 02 Feb 2022 13:11:40 +01:00

selftests/perf_events: Test modification of perf_event_attr::sig_data

Test that PERF_EVENT_IOC_MODIFY_ATTRIBUTES correctly modifies
perf_event_attr::sig_data as well.

Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Link: https://lore.kernel.org/r/20220131103407.1971678-2-elver@google.com
---
 tools/testing/selftests/perf_events/sigtrap_threads.c | 17 +++++-----
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/tools/testing/selftests/perf_events/sigtrap_threads.c b/tools/testing/selftests/perf_events/sigtrap_threads.c
index 8e83cf9..6d849dc 100644
--- a/tools/testing/selftests/perf_events/sigtrap_threads.c
+++ b/tools/testing/selftests/perf_events/sigtrap_threads.c
@@ -44,9 +44,10 @@ static struct {
 } ctx;
 
 /* Unique value to check si_perf_data is correctly set from perf_event_attr::sig_data. */
-#define TEST_SIG_DATA(addr) (~(unsigned long)(addr))
+#define TEST_SIG_DATA(addr, id) (~(unsigned long)(addr) + id)
 
-static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
+static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr,
+					      unsigned long id)
 {
 	struct perf_event_attr attr = {
 		.type		= PERF_TYPE_BREAKPOINT,
@@ -60,7 +61,7 @@ static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
 		.inherit_thread = 1, /* ... but only cloned with CLONE_THREAD. */
 		.remove_on_exec = 1, /* Required by sigtrap. */
 		.sigtrap	= 1, /* Request synchronous SIGTRAP on event. */
-		.sig_data	= TEST_SIG_DATA(addr),
+		.sig_data	= TEST_SIG_DATA(addr, id),
 	};
 	return attr;
 }
@@ -110,7 +111,7 @@ FIXTURE(sigtrap_threads)
 
 FIXTURE_SETUP(sigtrap_threads)
 {
-	struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on);
+	struct perf_event_attr attr = make_event_attr(false, &ctx.iterate_on, 0);
 	struct sigaction action = {};
 	int i;
 
@@ -165,7 +166,7 @@ TEST_F(sigtrap_threads, enable_event)
 	EXPECT_EQ(ctx.tids_want_signal, 0);
 	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
 	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
-	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
+	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
 
 	/* Check enabled for parent. */
 	ctx.iterate_on = 0;
@@ -175,7 +176,7 @@ TEST_F(sigtrap_threads, enable_event)
 /* Test that modification propagates to all inherited events. */
 TEST_F(sigtrap_threads, modify_and_enable_event)
 {
-	struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on);
+	struct perf_event_attr new_attr = make_event_attr(true, &ctx.iterate_on, 42);
 
 	EXPECT_EQ(ioctl(self->fd, PERF_EVENT_IOC_MODIFY_ATTRIBUTES, &new_attr), 0);
 	run_test_threads(_metadata, self);
@@ -184,7 +185,7 @@ TEST_F(sigtrap_threads, modify_and_enable_event)
 	EXPECT_EQ(ctx.tids_want_signal, 0);
 	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
 	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
-	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
+	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 42));
 
 	/* Check enabled for parent. */
 	ctx.iterate_on = 0;
@@ -204,7 +205,7 @@ TEST_F(sigtrap_threads, signal_stress)
 	EXPECT_EQ(ctx.tids_want_signal, 0);
 	EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
 	EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
-	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
+	EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on, 0));
 }
 
 TEST_HARNESS_MAIN

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [tip: perf/urgent] perf: Copy perf_event_attr::sig_data on modification
  2022-01-31 10:34 [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Marco Elver
                   ` (2 preceding siblings ...)
  2022-02-01  7:32 ` [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Dmitry Vyukov
@ 2022-02-03 14:33 ` tip-bot2 for Marco Elver
  3 siblings, 0 replies; 10+ messages in thread
From: tip-bot2 for Marco Elver @ 2022-02-03 14:33 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: Dmitry Vyukov, Marco Elver, Peter Zijlstra (Intel), x86, linux-kernel

The following commit has been merged into the perf/urgent branch of tip:

Commit-ID:     3c25fc97f5590060464cabfa25710970ecddbc96
Gitweb:        https://git.kernel.org/tip/3c25fc97f5590060464cabfa25710970ecddbc96
Author:        Marco Elver <elver@google.com>
AuthorDate:    Mon, 31 Jan 2022 11:34:05 +01:00
Committer:     Peter Zijlstra <peterz@infradead.org>
CommitterDate: Wed, 02 Feb 2022 13:11:40 +01:00

perf: Copy perf_event_attr::sig_data on modification

The intent has always been that perf_event_attr::sig_data should also be
modifiable along with PERF_EVENT_IOC_MODIFY_ATTRIBUTES, because it is
observable by user space if SIGTRAP on events is requested.

Currently only PERF_TYPE_BREAKPOINT is modifiable, and explicitly copies
relevant breakpoint-related attributes in hw_breakpoint_copy_attr().
This misses copying perf_event_attr::sig_data.

Since sig_data is not specific to PERF_TYPE_BREAKPOINT, introduce a
helper to copy generic event-type-independent attributes on
modification.

Fixes: 97ba62b27867 ("perf: Add support for SIGTRAP on perf events")
Reported-by: Dmitry Vyukov <dvyukov@google.com>
Signed-off-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
Link: https://lore.kernel.org/r/20220131103407.1971678-1-elver@google.com
---
 kernel/events/core.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/kernel/events/core.c b/kernel/events/core.c
index 76c754e..57c7197 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3238,6 +3238,15 @@ static int perf_event_modify_breakpoint(struct perf_event *bp,
 	return err;
 }
 
+/*
+ * Copy event-type-independent attributes that may be modified.
+ */
+static void perf_event_modify_copy_attr(struct perf_event_attr *to,
+					const struct perf_event_attr *from)
+{
+	to->sig_data = from->sig_data;
+}
+
 static int perf_event_modify_attr(struct perf_event *event,
 				  struct perf_event_attr *attr)
 {
@@ -3260,10 +3269,17 @@ static int perf_event_modify_attr(struct perf_event *event,
 	WARN_ON_ONCE(event->ctx->parent_ctx);
 
 	mutex_lock(&event->child_mutex);
+	/*
+	 * Event-type-independent attributes must be copied before event-type
+	 * modification, which will validate that final attributes match the
+	 * source attributes after all relevant attributes have been copied.
+	 */
+	perf_event_modify_copy_attr(&event->attr, attr);
 	err = func(event, attr);
 	if (err)
 		goto out;
 	list_for_each_entry(child, &event->child_list, child_list) {
+		perf_event_modify_copy_attr(&child->attr, attr);
 		err = func(child, attr);
 		if (err)
 			goto out;

^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2022-02-03 14:35 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-31 10:34 [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Marco Elver
2022-01-31 10:34 ` [PATCH 2/3] selftests/perf_events: Test modification of perf_event_attr::sig_data Marco Elver
2022-02-01  7:33   ` Dmitry Vyukov
2022-02-03 14:33   ` [tip: perf/urgent] " tip-bot2 for Marco Elver
2022-01-31 10:34 ` [PATCH 3/3] perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures Marco Elver
2022-02-01  7:33   ` Dmitry Vyukov
2022-02-03 14:33   ` [tip: perf/urgent] " tip-bot2 for Marco Elver
2022-02-01  7:32 ` [PATCH 1/3] perf: Copy perf_event_attr::sig_data on modification Dmitry Vyukov
2022-02-01 11:07   ` Peter Zijlstra
2022-02-03 14:33 ` [tip: perf/urgent] " tip-bot2 for Marco Elver

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).