Skip to content

Commit 8e5b0ad

Browse files
committed
Merge tag 'perf_core_for_v5.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf updates from Borislav Petkov: "Cleanup of the perf/kvm interaction." * tag 'perf_core_for_v5.17_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf: Drop guest callback (un)register stubs KVM: arm64: Drop perf.c and fold its tiny bits of code into arm.c KVM: arm64: Hide kvm_arm_pmu_available behind CONFIG_HW_PERF_EVENTS=y KVM: arm64: Convert to the generic perf callbacks KVM: x86: Move Intel Processor Trace interrupt handler to vmx.c KVM: Move x86's perf guest info callbacks to generic KVM KVM: x86: More precisely identify NMI from guest when handling PMI KVM: x86: Drop current_vcpu for kvm_running_vcpu + kvm_arch_vcpu variable perf/core: Use static_call to optimize perf_guest_info_callbacks perf: Force architectures to opt-in to guest callbacks perf: Add wrappers for invoking guest callbacks perf/core: Rework guest callbacks to prepare for static_call support perf: Drop dead and useless guest "support" from arm, csky, nds32 and riscv perf: Stop pretending that perf can handle multiple guest callbacks KVM: x86: Register Processor Trace interrupt hook iff PT enabled in guest KVM: x86: Register perf callbacks after calling vendor's hardware_setup() perf: Protect perf_guest_cbs with RCU
2 parents 13eaa5b + a9f4a6e commit 8e5b0ad

File tree

29 files changed

+248
-256
lines changed

29 files changed

+248
-256
lines changed

arch/arm/kernel/perf_callchain.c

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
6464
{
6565
struct frame_tail __user *tail;
6666

67-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
68-
/* We don't support guest os callchain now */
69-
return;
70-
}
71-
7267
perf_callchain_store(entry, regs->ARM_pc);
7368

7469
if (!current->mm)
@@ -100,38 +95,23 @@ perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *re
10095
{
10196
struct stackframe fr;
10297

103-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
104-
/* We don't support guest os callchain now */
105-
return;
106-
}
107-
10898
arm_get_current_stackframe(regs, &fr);
10999
walk_stackframe(&fr, callchain_trace, entry);
110100
}
111101

112102
unsigned long perf_instruction_pointer(struct pt_regs *regs)
113103
{
114-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
115-
return perf_guest_cbs->get_guest_ip();
116-
117104
return instruction_pointer(regs);
118105
}
119106

120107
unsigned long perf_misc_flags(struct pt_regs *regs)
121108
{
122109
int misc = 0;
123110

124-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
125-
if (perf_guest_cbs->is_user_mode())
126-
misc |= PERF_RECORD_MISC_GUEST_USER;
127-
else
128-
misc |= PERF_RECORD_MISC_GUEST_KERNEL;
129-
} else {
130-
if (user_mode(regs))
131-
misc |= PERF_RECORD_MISC_USER;
132-
else
133-
misc |= PERF_RECORD_MISC_KERNEL;
134-
}
111+
if (user_mode(regs))
112+
misc |= PERF_RECORD_MISC_USER;
113+
else
114+
misc |= PERF_RECORD_MISC_KERNEL;
135115

136116
return misc;
137117
}

arch/arm64/include/asm/kvm_host.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -675,8 +675,15 @@ unsigned long kvm_mmio_read_buf(const void *buf, unsigned int len);
675675
int kvm_handle_mmio_return(struct kvm_vcpu *vcpu);
676676
int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa);
677677

678-
int kvm_perf_init(void);
679-
int kvm_perf_teardown(void);
678+
/*
679+
* Returns true if a Performance Monitoring Interrupt (PMI), a.k.a. perf event,
680+
* arrived in guest context. For arm64, any event that arrives while a vCPU is
681+
* loaded is considered to be "in guest".
682+
*/
683+
static inline bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
684+
{
685+
return IS_ENABLED(CONFIG_GUEST_PERF_EVENTS) && !!vcpu;
686+
}
680687

681688
long kvm_hypercall_pv_features(struct kvm_vcpu *vcpu);
682689
gpa_t kvm_init_stolen_time(struct kvm_vcpu *vcpu);

arch/arm64/kernel/image-vars.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ KVM_NVHE_ALIAS(__stop___kvm_ex_table);
102102
KVM_NVHE_ALIAS(kvm_arm_hyp_percpu_base);
103103

104104
/* PMU available static key */
105+
#ifdef CONFIG_HW_PERF_EVENTS
105106
KVM_NVHE_ALIAS(kvm_arm_pmu_available);
107+
#endif
106108

107109
/* Position-independent library routines */
108110
KVM_NVHE_ALIAS_HYP(clear_page, __pi_clear_page);

arch/arm64/kernel/perf_callchain.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ compat_user_backtrace(struct compat_frame_tail __user *tail,
102102
void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
103103
struct pt_regs *regs)
104104
{
105-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
105+
if (perf_guest_state()) {
106106
/* We don't support guest os callchain now */
107107
return;
108108
}
@@ -141,7 +141,7 @@ static bool callchain_trace(void *data, unsigned long pc)
141141
void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
142142
struct pt_regs *regs)
143143
{
144-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
144+
if (perf_guest_state()) {
145145
/* We don't support guest os callchain now */
146146
return;
147147
}
@@ -151,18 +151,19 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
151151

152152
unsigned long perf_instruction_pointer(struct pt_regs *regs)
153153
{
154-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
155-
return perf_guest_cbs->get_guest_ip();
154+
if (perf_guest_state())
155+
return perf_guest_get_ip();
156156

157157
return instruction_pointer(regs);
158158
}
159159

160160
unsigned long perf_misc_flags(struct pt_regs *regs)
161161
{
162+
unsigned int guest_state = perf_guest_state();
162163
int misc = 0;
163164

164-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
165-
if (perf_guest_cbs->is_user_mode())
165+
if (guest_state) {
166+
if (guest_state & PERF_GUEST_USER)
166167
misc |= PERF_RECORD_MISC_GUEST_USER;
167168
else
168169
misc |= PERF_RECORD_MISC_GUEST_KERNEL;

arch/arm64/kvm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ menuconfig KVM
3939
select HAVE_KVM_IRQ_BYPASS
4040
select HAVE_KVM_VCPU_RUN_PID_CHANGE
4141
select SCHED_INFO
42+
select GUEST_PERF_EVENTS if PERF_EVENTS
4243
help
4344
Support hosting virtualized guest machines.
4445

arch/arm64/kvm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ obj-$(CONFIG_KVM) += hyp/
1212

1313
kvm-y := $(KVM)/kvm_main.o $(KVM)/coalesced_mmio.o $(KVM)/eventfd.o \
1414
$(KVM)/vfio.o $(KVM)/irqchip.o $(KVM)/binary_stats.o \
15-
arm.o mmu.o mmio.o psci.o perf.o hypercalls.o pvtime.o \
15+
arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
1616
inject_fault.o va_layout.o handle_exit.o \
1717
guest.o debug.o reset.o sys_regs.o \
1818
vgic-sys-reg-v3.o fpsimd.o pmu.o \

arch/arm64/kvm/arm.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,13 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
503503
return vcpu_mode_priv(vcpu);
504504
}
505505

506+
#ifdef CONFIG_GUEST_PERF_EVENTS
507+
unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
508+
{
509+
return *vcpu_pc(vcpu);
510+
}
511+
#endif
512+
506513
/* Just ensure a guest exit from a particular CPU */
507514
static void exit_vm_noop(void *info)
508515
{
@@ -1775,7 +1782,8 @@ static int init_subsystems(void)
17751782
if (err)
17761783
goto out;
17771784

1778-
kvm_perf_init();
1785+
kvm_register_perf_callbacks(NULL);
1786+
17791787
kvm_sys_reg_table_init();
17801788

17811789
out:
@@ -2163,7 +2171,7 @@ int kvm_arch_init(void *opaque)
21632171
/* NOP: Compiling as a module not supported */
21642172
void kvm_arch_exit(void)
21652173
{
2166-
kvm_perf_teardown();
2174+
kvm_unregister_perf_callbacks();
21672175
}
21682176

21692177
static int __init early_kvm_mode_cfg(char *arg)

arch/arm64/kvm/perf.c

Lines changed: 0 additions & 59 deletions
This file was deleted.

arch/arm64/kvm/pmu-emul.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
#include <kvm/arm_pmu.h>
1515
#include <kvm/arm_vgic.h>
1616

17+
DEFINE_STATIC_KEY_FALSE(kvm_arm_pmu_available);
18+
1719
static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx);
1820
static void kvm_pmu_update_pmc_chained(struct kvm_vcpu *vcpu, u64 select_idx);
1921
static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc);

arch/csky/kernel/perf_callchain.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,6 @@ void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
8888
{
8989
unsigned long fp = 0;
9090

91-
/* C-SKY does not support virtualization. */
92-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest())
93-
return;
94-
9591
fp = regs->regs[4];
9692
perf_callchain_store(entry, regs->pc);
9793

@@ -112,12 +108,6 @@ void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
112108
{
113109
struct stackframe fr;
114110

115-
/* C-SKY does not support virtualization. */
116-
if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
117-
pr_warn("C-SKY does not support perf in guest mode!");
118-
return;
119-
}
120-
121111
fr.fp = regs->regs[4];
122112
fr.lr = regs->lr;
123113
walk_stackframe(&fr, entry);

0 commit comments

Comments
 (0)