Commit eded6754 authored by Quan Zhou's avatar Quan Zhou Committed by Anup Patel
Browse files

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: default avatarQuan Zhou <zhouquan@iscas.ac.cn>
Reviewed-by: default avatarAndrew Jones <ajones@ventanamicro.com>
Link: https://lore.kernel.org/r/00342d535311eb0629b9ba4f1e457a48e2abee33.1728957131.git.zhouquan@iscas.ac.cn


Signed-off-by: default avatarAnup Patel <anup@brainfault.org>
parent 5bb5ccb3
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -286,6 +286,16 @@ struct kvm_vcpu_arch {
	} sta;
};

/*
 * Returns true if a Performance Monitoring Interrupt (PMI), a.k.a. perf event,
 * arrived in guest context.  For riscv, any event that arrives while a vCPU is
 * loaded is considered to be "in guest".
 */
static inline bool kvm_arch_pmi_in_guest(struct kvm_vcpu *vcpu)
{
	return IS_ENABLED(CONFIG_GUEST_PERF_EVENTS) && !!vcpu;
}

static inline void kvm_arch_sync_events(struct kvm *kvm) {}

#define KVM_RISCV_GSTAGE_TLB_MIN_ORDER		12
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ config KVM
	select KVM_XFER_TO_GUEST_WORK
	select KVM_GENERIC_MMU_NOTIFIER
	select SCHED_INFO
	select GUEST_PERF_EVENTS if PERF_EVENTS
	help
	  Support hosting virtualized guest machines.

+10 −2
Original line number Diff line number Diff line
@@ -51,6 +51,12 @@ void kvm_arch_disable_virtualization_cpu(void)
	csr_write(CSR_HIDELEG, 0);
}

static void kvm_riscv_teardown(void)
{
	kvm_riscv_aia_exit();
	kvm_unregister_perf_callbacks();
}

static int __init riscv_kvm_init(void)
{
	int rc;
@@ -105,9 +111,11 @@ static int __init riscv_kvm_init(void)
		kvm_info("AIA available with %d guest external interrupts\n",
			 kvm_riscv_aia_nr_hgei);

	kvm_register_perf_callbacks(NULL);

	rc = kvm_init(sizeof(struct kvm_vcpu), 0, THIS_MODULE);
	if (rc) {
		kvm_riscv_aia_exit();
		kvm_riscv_teardown();
		return rc;
	}

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

static void __exit riscv_kvm_exit(void)
{
	kvm_riscv_aia_exit();
	kvm_riscv_teardown();

	kvm_exit();
}
+7 −0
Original line number Diff line number Diff line
@@ -226,6 +226,13 @@ bool kvm_arch_vcpu_in_kernel(struct kvm_vcpu *vcpu)
	return (vcpu->arch.guest_context.sstatus & SR_SPP) ? true : false;
}

#ifdef CONFIG_GUEST_PERF_EVENTS
unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
{
	return vcpu->arch.guest_context.sepc;
}
#endif

vm_fault_t kvm_arch_vcpu_fault(struct kvm_vcpu *vcpu, struct vm_fault *vmf)
{
	return VM_FAULT_SIGBUS;