lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221118020016.1571100-1-yamada.masahiko@fujitsu.com>
Date:   Fri, 18 Nov 2022 11:00:15 +0900
From:   "Masahiko, Yamada" <yamada.masahiko@...itsu.com>
To:     peterz@...radead.org, mingo@...hat.com, acme@...nel.org,
        mark.rutland@....com, alexander.shishkin@...ux.intel.com,
        jolsa@...nel.org, namhyung@...nel.org
Cc:     linux-perf-users@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH 0/1] perf: fix reset interface potential failure

There is a potential bug where PERF_EVENT_IOC_RESET
does not work when accessing PMU registers directly
from userspace in the perf_event interface.

In the x86 environment, the kernel(perf_event reset handling) has a
potential failure, but it works with the papi library side workaround.
The PMU register direct access feature from user space was implemented in
the perf_event facility from linux-5.18 version in the arm64 environment,
but it does not work with the workaround on the papi library side in the
arm64 environment.
The workaround worked in the x86 environment and not in the arm64
environment because in the arm64 environment, only CPU_CYCLES was
a 64 bit counter and the rest were 32 bit counters, so the workaround
cleared the upper 32 bits of the value measured by CPU_CYCLES.

For this reason, we have created a patch on the kernel
that fixes a potential perf_event reset failure.

The motivation for the fix is to initialize pc->offset.
The perf_mmap__read_self function in tools/lib/perf/mmap.c is set by:.
cnt = READ_ONCE(pc->offset);
The pc->offset value is set in the following process
in the perf_event_update_userpage function:.
userpg->offset -= local64_read(&event->hw.prev_count);
hw->prev_count is set in the armpmu_event_set_period function
in drivers/perf/arm_pmu.c and in the x86_perf_event_set_period function
in arch/x86/events/core.c as follows:.
local64_set(&hwc->prev_count, (u64)-left);

Therefore, this patch was created to initialize hwc->prev_count
during reset processing.

We used
https://github.com/deater/perf_event_tests/blob/master/tests/rdpmc/\
rdpmc_reset.c for verification testing.

The mmap_read_ self function in
https://github.com/deater/perf_event_tests/blob/master/tests/rdpmc/\
rdpmc_lib.c comes with a fix (lines 158 to 159) similar to
the workaround in the papi library.

The mmap_read_self function implements the equivalent of
the perf_mmap__read_self function.

The following is a workaround for the mmap_read_self function.

-----SNIP-----
    158                 count<<=(64-width);
    159                 count>>=(64-width);
-----SNIP-----

If you do not apply the kernel patch to fix a potential perf_event
failure, removing the workaround from perf_event_tests will cause
both the x86/arm64 versions to fail.

$ ./rdpmc_reset
This test checks if userspace rdpmc() style reads work.

total start/read/stop latency: 71772447 cycles
 Event 0 -- Raw count: 100069445 enabled: 6636 running: 6636
 Event 0 -- Raw count: -281474876643918 enabled: 16399496 running: 16399496
 Event 1 -- Raw count: 100069412 enabled: 2071 running: 2071
 Event 1 -- Raw count: -281474876645181 enabled: 16394819 running: 16394819

 Expected: 100000000
 High: -281474876643918 Low: -281474876643918 Average: -281474876643918
 ( note, a small value above 100000000 may be expected due
   to overhead and interrupt noise, among other reasons)
 Average Error = -281474976.64%
Error out of range!
Testing if resetting while using rdpmc works...            FAILED

In the environment with the kernel patch to fix a potential perf_event
failure, removing the workaround from perf_event_tests still works with
the x86/arm64 version.

$ ./rdpmc_reset
This test checks if userspace rdpmc() style reads work.

total start/read/stop latency: 71863055 cycles
 Event 0 -- Raw count: 100081688 enabled: 10353 running: 10353
 Event 0 -- Raw count: 100078316 enabled: 16493263 running: 16493263
 Event 1 -- Raw count: 100081789 enabled: 4186 running: 4186
 Event 1 -- Raw count: 100076770 enabled: 16486696 running: 16486696

 Expected: 100000000
 High: 100078316   Low:  100078316   Average:  100078316
 ( note, a small value above 100000000 may be expected due
   to overhead and interrupt noise, among other reasons)
 Average Error = 0.08%
Testing if resetting while using rdpmc works...            PASSED

Masahiko, Yamada (1):
  perf: fix reset interface potential failure

 kernel/events/core.c | 5 +++++
 1 file changed, 5 insertions(+)

-- 
2.27.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ