forked from Minki/linux
perf/urgent contains 3 fixups:
- Intel/PT: filters could crash the kernel - Intel: default disable the PMU for SMM, some new-ish EFI firmware has started using CPL3 and the PMU CPL filters don't discriminate against SMM, meaning that CPL3 (userspace only) events now also count EFI/SMM cycles. - Fixup for perf_event_attr::sig_data (Peter Zijlstra) -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEzv7L6UO9uDPlPSfHEsHwGGHeVUoFAmH/vpgACgkQEsHwGGHe VUqIGw/9EWg7Ek89BG9ZZui8EEDAzx3x0s/tyxiz0z18YfvtTnex5I87uJUYpw2s hFhxxmGN+rwhcMGQDc0sDLLLxp170Yg0383N6OBBBMWPtNyxMWihBOHQgz8hQzbW KtwoiBewmvAycHw0aoOtDMqFZTn5RToONnG9h7yV9rUIGKq75XNh72MBy9sCSE2F w8lA3WWVTrv91YTPSMbsrm/tMC6eQCRiJGRMHTapxrWxkVu/H8O42pxJgS6dlo+h vw025hXcf0KGBLzwVSHYdZg8jMn7uD2oSMh+wQ+Jy15XjKVWDfF1m3sA5S+zSJsS THHtmqni5mF5xn0H7eOK9nYmRXR013zx6weo9miK4SN1pcoJq+PTNdSZOIwBm3Nh eUXR/bXFYL0GGuPOk0QHA9AjqbCBPrkiw1nfppbJem2rrZ0uKHyKa8REVcVg/Xzy e/nDy8I2y2bnwU9Ugk9BNWBRmn54Q2kb4/egmtLME6oYiqOXumQ4ZB/CmwRaSwxG bB99/tBKblrWSA6wcgATkqYFSg4ZJniDxKipnrEYX8ePkGODKHoIQS4EUyjxuPW/ fO2G4Oe8aO/qYS/yei8XcubyEFaSPyUo+th+ZiPODCt15JKzQCAxeOYxqnEI4I4s 5afDBmAo47bs9Eem7GRjZOgrDOP88+lISZ1rZidp5paDwWAmL2E= =0tH5 -----END PGP SIGNATURE----- Merge tag 'perf_urgent_for_v5.17_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip Pull perf fixes from Borislav Petkov: - Intel/PT: filters could crash the kernel - Intel: default disable the PMU for SMM, some new-ish EFI firmware has started using CPL3 and the PMU CPL filters don't discriminate against SMM, meaning that CPL3 (userspace only) events now also count EFI/SMM cycles. - Fixup for perf_event_attr::sig_data * tag 'perf_urgent_for_v5.17_rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/x86/intel/pt: Fix crash with stop filters in single-range mode perf: uapi: Document perf_event_attr::sig_data truncation on 32 bit architectures selftests/perf_events: Test modification of perf_event_attr::sig_data perf: Copy perf_event_attr::sig_data on modification x86/perf: Default set FREEZE_ON_SMI for all
This commit is contained in:
commit
c3bf8a1440
@ -4703,6 +4703,19 @@ static __initconst const struct x86_pmu intel_pmu = {
|
||||
.lbr_read = intel_pmu_lbr_read_64,
|
||||
.lbr_save = intel_pmu_lbr_save,
|
||||
.lbr_restore = intel_pmu_lbr_restore,
|
||||
|
||||
/*
|
||||
* SMM has access to all 4 rings and while traditionally SMM code only
|
||||
* ran in CPL0, 2021-era firmware is starting to make use of CPL3 in SMM.
|
||||
*
|
||||
* Since the EVENTSEL.{USR,OS} CPL filtering makes no distinction
|
||||
* between SMM or not, this results in what should be pure userspace
|
||||
* counters including SMM data.
|
||||
*
|
||||
* This is a clear privilege issue, therefore globally disable
|
||||
* counting SMM by default.
|
||||
*/
|
||||
.attr_freeze_on_smi = 1,
|
||||
};
|
||||
|
||||
static __init void intel_clovertown_quirk(void)
|
||||
|
@ -897,8 +897,9 @@ static void pt_handle_status(struct pt *pt)
|
||||
* means we are already losing data; need to let the decoder
|
||||
* know.
|
||||
*/
|
||||
if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) ||
|
||||
buf->output_off == pt_buffer_region_size(buf)) {
|
||||
if (!buf->single &&
|
||||
(!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) ||
|
||||
buf->output_off == pt_buffer_region_size(buf))) {
|
||||
perf_aux_output_flag(&pt->handle,
|
||||
PERF_AUX_FLAG_TRUNCATED);
|
||||
advance++;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user