Skip to content

Commit

Permalink
x86: events: Do not return bogus capabilities if PMU is broken
Browse files Browse the repository at this point in the history
If the PMU is broken due to firmware issues, check_hw_exists() will return
false but perf_get_x86_pmu_capability() will still return data from x86_pmu.
Likewise if some of the hotplug callbacks cannot be installed the contents
of x86_pmu will not be reverted.

Handle the failure in both cases by clearing x86_pmu if init_hw_perf_events()
or reverts to software events only.

Co-developed-by: Like Xu <likexu@tencent.com>
Signed-off-by: Like Xu <likexu@tencent.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
  • Loading branch information
Paolo Bonzini committed Jun 8, 2022
1 parent 92d8017 commit 916e3a4
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions arch/x86/events/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -2103,14 +2103,15 @@ static int __init init_hw_perf_events(void)
}
if (err != 0) {
pr_cont("no PMU driver, software events only.\n");
return 0;
err = 0;
goto out_bad_pmu;
}

pmu_check_apic();

/* sanity check that the hardware exists or is emulated */
if (!check_hw_exists(&pmu, x86_pmu.num_counters, x86_pmu.num_counters_fixed))
return 0;
goto out_bad_pmu;

pr_cont("%s PMU driver.\n", x86_pmu.name);

Expand Down Expand Up @@ -2219,6 +2220,8 @@ static int __init init_hw_perf_events(void)
cpuhp_remove_state(CPUHP_AP_PERF_X86_STARTING);
out:
cpuhp_remove_state(CPUHP_PERF_X86_PREPARE);
out_bad_pmu:
memset(&x86_pmu, 0, sizeof(x86_pmu));
return err;
}
early_initcall(init_hw_perf_events);
Expand Down Expand Up @@ -2990,6 +2993,11 @@ unsigned long perf_misc_flags(struct pt_regs *regs)

void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap)
{
if (!x86_pmu_initialized()) {
memset(cap, 0, sizeof(*cap));
return;
}

cap->version = x86_pmu.version;
/*
* KVM doesn't support the hybrid PMU yet.
Expand Down

0 comments on commit 916e3a4

Please sign in to comment.