Skip to content

Commit eded675

Browse files
zcxGGmuavpatel
authored andcommitted
riscv: KVM: add basic support for host vs guest profiling
For the information collected on the host side, we need to identify which data originates from the guest and record these events separately, this can be achieved by having KVM register perf callbacks. Signed-off-by: Quan Zhou <zhouquan@iscas.ac.cn> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Link: https://lore.kernel.org/r/00342d535311eb0629b9ba4f1e457a48e2abee33.1728957131.git.zhouquan@iscas.ac.cn Signed-off-by: Anup Patel <anup@brainfault.org>
1 parent 5bb5ccb commit eded675

File tree

4 files changed

+28
-2
lines changed

4 files changed

+28
-2
lines changed

arch/riscv/include/asm/kvm_host.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,16 @@ struct kvm_vcpu_arch {
286286
} sta;
287287
};
288288

289+
/*
290+
* Returns true if a Performance Monitoring Interrupt (PMI), a.k.a. perf event,
291+
* arrived in guest context. For riscv, any event that arrives while a vCPU is
292+
* loaded is considered to be "in guest".
293+
*/
294+
static inline bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
295+
{
296+
return IS_ENABLED(CONFIG_GUEST_PERF_EVENTS) && !!vcpu;
297+
}
298+
289299
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
290300

291301
#define KVM_RISCV_GSTAGE_TLB_MIN_ORDER 12

arch/riscv/kvm/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ config KVM
3232
select KVM_XFER_TO_GUEST_WORK
3333
select KVM_GENERIC_MMU_NOTIFIER
3434
select SCHED_INFO
35+
select GUEST_PERF_EVENTS if PERF_EVENTS
3536
help
3637
Support hosting virtualized guest machines.
3738

arch/riscv/kvm/main.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ void kvm_arch_disable_virtualization_cpu(void)
5151
csr_write(CSR_HIDELEG, 0);
5252
}
5353

54+
static void kvm_riscv_teardown(void)
55+
{
56+
kvm_riscv_aia_exit();
57+
kvm_unregister_perf_callbacks();
58+
}
59+
5460
static int __init riscv_kvm_init(void)
5561
{
5662
int rc;
@@ -105,9 +111,11 @@ static int __init riscv_kvm_init(void)
105111
kvm_info("AIA available with %d guest external interrupts\n",
106112
kvm_riscv_aia_nr_hgei);
107113

114+
kvm_register_perf_callbacks(NULL);
115+
108116
rc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
109117
if (rc) {
110-
kvm_riscv_aia_exit();
118+
kvm_riscv_teardown();
111119
return rc;
112120
}
113121

@@ -117,7 +125,7 @@ module_init(riscv_kvm_init);
117125

118126
static void __exit riscv_kvm_exit(void)
119127
{
120-
kvm_riscv_aia_exit();
128+
kvm_riscv_teardown();
121129

122130
kvm_exit();
123131
}

arch/riscv/kvm/vcpu.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,13 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
226226
return (vcpu->arch.guest_context.sstatus & SR_SPP) ? true : false;
227227
}
228228

229+
#ifdef CONFIG_GUEST_PERF_EVENTS
230+
unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
231+
{
232+
return vcpu->arch.guest_context.sepc;
233+
}
234+
#endif
235+
229236
vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
230237
{
231238
return VM_FAULT_SIGBUS;

0 commit comments

Comments
 (0)