Skip to content

Commit c8e2fe1

Browse files
sean-jcPeter Zijlstra
authored andcommitted
x86/perf: Use RET0 as default for guest_get_msrs to handle "no PMU" case
Initialize x86_pmu.guest_get_msrs to return 0/NULL to handle the "nop" case. Patching in perf_guest_get_msrs_nop() during setup does not work if there is no PMU, as setup bails before updating the static calls, leaving x86_pmu.guest_get_msrs NULL and thus a complete nop. Ultimately, this causes VMX abort on VM-Exit due to KVM putting random garbage from the stack into the MSR load list. Add a comment in KVM to note that nr_msrs is valid if and only if the return value is non-NULL. Fixes: abd562d ("x86/perf: Use static_call for x86_pmu.guest_get_msrs") Reported-by: Dmitry Vyukov <[email protected]> Reported-by: [email protected] Suggested-by: Peter Zijlstra <[email protected]> Signed-off-by: Sean Christopherson <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Link: https://lkml.kernel.org/r/[email protected]
1 parent afbef30 commit c8e2fe1

File tree

2 files changed

+7
-10
lines changed

2 files changed

+7
-10
lines changed

arch/x86/events/core.c

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,11 @@ DEFINE_STATIC_CALL_NULL(x86_pmu_swap_task_ctx, *x86_pmu.swap_task_ctx);
8181
DEFINE_STATIC_CALL_NULL(x86_pmu_drain_pebs, *x86_pmu.drain_pebs);
8282
DEFINE_STATIC_CALL_NULL(x86_pmu_pebs_aliases, *x86_pmu.pebs_aliases);
8383

84-
DEFINE_STATIC_CALL_NULL(x86_pmu_guest_get_msrs, *x86_pmu.guest_get_msrs);
84+
/*
85+
* This one is magic, it will get called even when PMU init fails (because
86+
* there is no PMU), in which case it should simply return NULL.
87+
*/
88+
DEFINE_STATIC_CALL_RET0(x86_pmu_guest_get_msrs, *x86_pmu.guest_get_msrs);
8589

8690
u64 __read_mostly hw_cache_event_ids
8791
[PERF_COUNT_HW_CACHE_MAX]
@@ -1944,13 +1948,6 @@ static void _x86_pmu_read(struct perf_event *event)
19441948
x86_perf_event_update(event);
19451949
}
19461950

1947-
static inline struct perf_guest_switch_msr *
1948-
perf_guest_get_msrs_nop(int *nr)
1949-
{
1950-
*nr = 0;
1951-
return NULL;
1952-
}
1953-
19541951
static int __init init_hw_perf_events(void)
19551952
{
19561953
struct x86_pmu_quirk *quirk;
@@ -2025,7 +2022,7 @@ static int __init init_hw_perf_events(void)
20252022
x86_pmu.read = _x86_pmu_read;
20262023

20272024
if (!x86_pmu.guest_get_msrs)
2028-
x86_pmu.guest_get_msrs = perf_guest_get_msrs_nop;
2025+
x86_pmu.guest_get_msrs = (void *)&__static_call_return0;
20292026

20302027
x86_pmu_static_call_update();
20312028

arch/x86/kvm/vmx/vmx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6580,8 +6580,8 @@ static void atomic_switch_perf_msrs(struct vcpu_vmx *vmx)
65806580
int i, nr_msrs;
65816581
struct perf_guest_switch_msr *msrs;
65826582

6583+
/* Note, nr_msrs may be garbage if perf_guest_get_msrs() returns NULL. */
65836584
msrs = perf_guest_get_msrs(&nr_msrs);
6584-
65856585
if (!msrs)
65866586
return;
65876587

0 commit comments

Comments
 (0)