archive mirror
 help / color / mirror / Atom feed
Cc:, Kan Liang <>
Subject: [PATCH] perf/x86: Reset the counter to prevent the leak for a RDPMC task
Date: Thu, 30 Jul 2020 05:38:15 -0700	[thread overview]
Message-ID: <> (raw)

From: Kan Liang <>

The counter value of a perf task may leak to another RDPMC task.
For example, a perf stat task as below is running on CPU 0.

    perf stat -e 'branches,cycles' -- taskset -c 0 ./workload

In the meantime, an RDPMC task, which is also running on CPU 0, may read
the GP counters periodically. (The RDPMC task creates a fixed event,
but read four GP counters.)

    $ taskset -c 0 ./rdpmc_read_all_counters
    index 0x0 value 0x8001e5970f99
    index 0x1 value 0x8005d750edb6
    index 0x2 value 0x0
    index 0x3 value 0x0

    index 0x0 value 0x8002358e48a5
    index 0x1 value 0x8006bd1e3bc9
    index 0x2 value 0x0
    index 0x3 value 0x0

The counter value of the perf stat task leaks to the RDPMC task because
perf never clears the counter when it's stopped.

A counter/event stops for the following cases:
- Schedule the monitored task, e.g., context switch or task exit;
- Adjust the event period, e.g., Throttle, in frequency mode;
- Update the event's address range filters.

For the first case, following tasks may reuse the counter. To
prevent the leak, the counter has to be reset, when the event is
scheduled out. The del() is eventually invoked for the schedule out.
The counter should be reset in x86_pmu_del().

For the rest of the cases, the counter/event is temporarily stopped and
will be restarted soon. Other tasks don't have a chance to reuse the
counter. Reset the counter is not necessary.

The RDPMC instruction is only available for the X86 platform. Only apply
the fix for the X86 platform.

After applying the patch,

    $ taskset -c 0 ./rdpmc_read_all_counters
    index 0x0 value 0x0
    index 0x1 value 0x0
    index 0x2 value 0x0
    index 0x3 value 0x0

    index 0x0 value 0x0
    index 0x1 value 0x0
    index 0x2 value 0x0
    index 0x3 value 0x0

Signed-off-by: Kan Liang <>
 arch/x86/events/core.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
index 01ba5fec5765..72b2c7e1bb20 100644
--- a/arch/x86/events/core.c
+++ b/arch/x86/events/core.c
@@ -1499,6 +1499,13 @@ static void x86_pmu_del(struct perf_event *event, int flags)
 	x86_pmu_stop(event, PERF_EF_UPDATE);
+	/*
+	 * The counter value may leak to an RDPMC task.
+	 * Clear the counter if the userspace RDPMC usage is enabled.
+	 */
+	if (READ_ONCE(x86_pmu.attr_rdpmc))
+		wrmsrl(event->hw.event_base, 0);
 	for (i = 0; i < cpuc->n_events; i++) {
 		if (event == cpuc->event_list[i])

             reply	other threads:[~2020-07-30 12:38 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-30 12:38 kan.liang [this message]
2020-07-30 12:58 ` [PATCH] perf/x86: Reset the counter to prevent the leak for a RDPMC task peterz
2020-07-30 15:54   ` Liang, Kan
2020-07-30 16:44     ` peterz
2020-07-30 16:50       ` peterz
2020-07-31 18:08       ` Liang, Kan

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:

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \ \ \ \ \ \ \ \

* 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 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).