Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 586f9607 authored by Avi Kivity's avatar Avi Kivity
Browse files

KVM: Add instruction-set-specific exit qualifications to kvm_exit trace



The exit reason alone is insufficient to understand exactly why an exit
occured; add ISA-specific trace parameters for additional information.

Because fetching these parameters is expensive on vmx, and because these
parameters are fetched even if tracing is disabled, we fetch the
parameters via a callback instead of as traditional trace arguments.

Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
parent aa17911e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -594,6 +594,7 @@ struct kvm_x86_ops {

	void (*write_tsc_offset)(struct kvm_vcpu *vcpu, u64 offset);

	void (*get_exit_info)(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2);
	const struct trace_print_flags *exit_reasons_str;
};

+10 −0
Original line number Diff line number Diff line
@@ -2974,6 +2974,14 @@ void dump_vmcb(struct kvm_vcpu *vcpu)

}

static void svm_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
{
	struct vmcb_control_area *control = &to_svm(vcpu)->vmcb->control;

	*info1 = control->exit_info_1;
	*info2 = control->exit_info_2;
}

static int handle_exit(struct kvm_vcpu *vcpu)
{
	struct vcpu_svm *svm = to_svm(vcpu);
@@ -3684,7 +3692,9 @@ static struct kvm_x86_ops svm_x86_ops = {
	.get_tdp_level = get_npt_level,
	.get_mt_mask = svm_get_mt_mask,

	.get_exit_info = svm_get_exit_info,
	.exit_reasons_str = svm_exit_reasons_str,

	.get_lpage_level = svm_get_lpage_level,

	.cpuid_update = svm_cpuid_update,
+6 −2
Original line number Diff line number Diff line
@@ -192,18 +192,22 @@ TRACE_EVENT(kvm_exit,
		__field(	unsigned int,	exit_reason	)
		__field(	unsigned long,	guest_rip	)
		__field(	u32,	        isa             )
		__field(	u64,	        info1           )
		__field(	u64,	        info2           )
	),

	TP_fast_assign(
		__entry->exit_reason	= exit_reason;
		__entry->guest_rip	= kvm_rip_read(vcpu);
		__entry->isa            = isa;
		kvm_x86_ops->get_exit_info(vcpu, &__entry->info1,
					   &__entry->info2);
	),

	TP_printk("reason %s rip 0x%lx",
	TP_printk("reason %s rip 0x%lx info %llx %llx",
		 ftrace_print_symbols_seq(p, __entry->exit_reason,
					  kvm_x86_ops->exit_reasons_str),
		 __entry->guest_rip)
		 __entry->guest_rip, __entry->info1, __entry->info2)
);

/*
+8 −0
Original line number Diff line number Diff line
@@ -3690,6 +3690,12 @@ static int (*kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = {
static const int kvm_vmx_max_exit_handlers =
	ARRAY_SIZE(kvm_vmx_exit_handlers);

static void vmx_get_exit_info(struct kvm_vcpu *vcpu, u64 *info1, u64 *info2)
{
	*info1 = vmcs_readl(EXIT_QUALIFICATION);
	*info2 = vmcs_read32(VM_EXIT_INTR_INFO);
}

/*
 * The guest has exited.  See if we can fix it or if we need userspace
 * assistance.
@@ -4334,7 +4340,9 @@ static struct kvm_x86_ops vmx_x86_ops = {
	.get_tdp_level = get_ept_level,
	.get_mt_mask = vmx_get_mt_mask,

	.get_exit_info = vmx_get_exit_info,
	.exit_reasons_str = vmx_exit_reasons_str,

	.get_lpage_level = vmx_get_lpage_level,

	.cpuid_update = vmx_cpuid_update,