From: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx> Similar to VMX/SVM, add necessary information to support kvm_exit() tracepoint. Suggested-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx> Signed-off-by: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx> Signed-off-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx> --- arch/x86/kvm/pvm/pvm.c | 41 +++++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/pvm/pvm.h | 35 +++++++++++++++++++++++++++++++++++ arch/x86/kvm/trace.h | 7 ++++++- 3 files changed, 82 insertions(+), 1 deletion(-) diff --git a/arch/x86/kvm/pvm/pvm.c b/arch/x86/kvm/pvm/pvm.c index e68052f33186..6ac599587567 100644 --- a/arch/x86/kvm/pvm/pvm.c +++ b/arch/x86/kvm/pvm/pvm.c @@ -1996,6 +1996,43 @@ static int pvm_handle_exit(struct kvm_vcpu *vcpu, fastpath_t exit_fastpath) return 0; } +static u32 pvm_get_syscall_exit_reason(struct kvm_vcpu *vcpu) +{ + struct vcpu_pvm *pvm = to_pvm(vcpu); + unsigned long rip = kvm_rip_read(vcpu); + + if (is_smod(pvm)) { + if (rip == pvm->msr_retu_rip_plus2) + return PVM_EXIT_REASONS_ERETU; + else if (rip == pvm->msr_rets_rip_plus2) + return PVM_EXIT_REASONS_ERETS; + else + return PVM_EXIT_REASONS_HYPERCALL; + } + + return PVM_EXIT_REASONS_SYSCALL; +} + +static void pvm_get_exit_info(struct kvm_vcpu *vcpu, u32 *reason, u64 *info1, u64 *info2, + u32 *intr_info, u32 *error_code) +{ + struct vcpu_pvm *pvm = to_pvm(vcpu); + + if (pvm->exit_vector == PVM_SYSCALL_VECTOR) + *reason = pvm_get_syscall_exit_reason(vcpu); + else if (pvm->exit_vector == IA32_SYSCALL_VECTOR) + *reason = PVM_EXIT_REASONS_INT80; + else if (pvm->exit_vector >= FIRST_EXTERNAL_VECTOR && + pvm->exit_vector < NR_VECTORS) + *reason = PVM_EXIT_REASONS_INTERRUPT; + else + *reason = pvm->exit_vector; + *info1 = pvm->exit_vector; + *info2 = pvm->exit_error_code; + *intr_info = pvm->exit_vector; + *error_code = pvm->exit_error_code; +} + static void pvm_handle_exit_irqoff(struct kvm_vcpu *vcpu) { struct vcpu_pvm *pvm = to_pvm(vcpu); @@ -2298,6 +2335,8 @@ static fastpath_t pvm_vcpu_run(struct kvm_vcpu *vcpu) mark_page_dirty_in_slot(vcpu->kvm, pvm->pvcs_gpc.memslot, pvm->pvcs_gpc.gpa >> PAGE_SHIFT); + trace_kvm_exit(vcpu, KVM_ISA_PVM); + return EXIT_FASTPATH_NONE; } @@ -2627,6 +2666,8 @@ static struct kvm_x86_ops pvm_x86_ops __initdata = { .refresh_apicv_exec_ctrl = pvm_refresh_apicv_exec_ctrl, .deliver_interrupt = pvm_deliver_interrupt, + .get_exit_info = pvm_get_exit_info, + .vcpu_after_set_cpuid = pvm_vcpu_after_set_cpuid, .check_intercept = pvm_check_intercept, diff --git a/arch/x86/kvm/pvm/pvm.h b/arch/x86/kvm/pvm/pvm.h index f28ab0b48f40..2f8fdb0ae3df 100644 --- a/arch/x86/kvm/pvm/pvm.h +++ b/arch/x86/kvm/pvm/pvm.h @@ -10,6 +10,41 @@ #define PVM_SYSCALL_VECTOR SWITCH_EXIT_REASONS_SYSCALL #define PVM_FAILED_VMENTRY_VECTOR SWITCH_EXIT_REASONS_FAILED_VMETNRY +#define PVM_EXIT_REASONS_SHIFT 16 +#define PVM_EXIT_REASONS_SYSCALL (1UL << PVM_EXIT_REASONS_SHIFT) +#define PVM_EXIT_REASONS_HYPERCALL (2UL << PVM_EXIT_REASONS_SHIFT) +#define PVM_EXIT_REASONS_ERETU (3UL << PVM_EXIT_REASONS_SHIFT) +#define PVM_EXIT_REASONS_ERETS (4UL << PVM_EXIT_REASONS_SHIFT) +#define PVM_EXIT_REASONS_INTERRUPT (5UL << PVM_EXIT_REASONS_SHIFT) +#define PVM_EXIT_REASONS_INT80 (6UL << PVM_EXIT_REASONS_SHIFT) + +#define PVM_EXIT_REASONS \ + { DE_VECTOR, "DE excp" }, \ + { DB_VECTOR, "DB excp" }, \ + { NMI_VECTOR, "NMI excp" }, \ + { BP_VECTOR, "BP excp" }, \ + { OF_VECTOR, "OF excp" }, \ + { BR_VECTOR, "BR excp" }, \ + { UD_VECTOR, "UD excp" }, \ + { NM_VECTOR, "NM excp" }, \ + { DF_VECTOR, "DF excp" }, \ + { TS_VECTOR, "TS excp" }, \ + { SS_VECTOR, "SS excp" }, \ + { GP_VECTOR, "GP excp" }, \ + { PF_VECTOR, "PF excp" }, \ + { MF_VECTOR, "MF excp" }, \ + { AC_VECTOR, "AC excp" }, \ + { MC_VECTOR, "MC excp" }, \ + { XM_VECTOR, "XM excp" }, \ + { VE_VECTOR, "VE excp" }, \ + { PVM_EXIT_REASONS_SYSCALL, "SYSCALL" }, \ + { PVM_EXIT_REASONS_HYPERCALL, "HYPERCALL" }, \ + { PVM_EXIT_REASONS_ERETU, "ERETU" }, \ + { PVM_EXIT_REASONS_ERETS, "ERETS" }, \ + { PVM_EXIT_REASONS_INTERRUPT, "INTERRUPT" }, \ + { PVM_EXIT_REASONS_INT80, "INT80" }, \ + { PVM_FAILED_VMENTRY_VECTOR, "FAILED_VMENTRY" } + #define PT_L4_SHIFT 39 #define PT_L4_SIZE (1UL << PT_L4_SHIFT) #define DEFAULT_RANGE_L4_SIZE (32 * PT_L4_SIZE) diff --git a/arch/x86/kvm/trace.h b/arch/x86/kvm/trace.h index 83843379813e..3d6549679e98 100644 --- a/arch/x86/kvm/trace.h +++ b/arch/x86/kvm/trace.h @@ -8,6 +8,8 @@ #include <asm/clocksource.h> #include <asm/pvclock-abi.h> +#include "pvm/pvm.h" + #undef TRACE_SYSTEM #define TRACE_SYSTEM kvm @@ -282,11 +284,14 @@ TRACE_EVENT(kvm_apic, #define KVM_ISA_VMX 1 #define KVM_ISA_SVM 2 +#define KVM_ISA_PVM 3 #define kvm_print_exit_reason(exit_reason, isa) \ (isa == KVM_ISA_VMX) ? \ __print_symbolic(exit_reason & 0xffff, VMX_EXIT_REASONS) : \ - __print_symbolic(exit_reason, SVM_EXIT_REASONS), \ + ((isa == KVM_ISA_SVM) ? \ + __print_symbolic(exit_reason, SVM_EXIT_REASONS) : \ + __print_symbolic(exit_reason, PVM_EXIT_REASONS)), \ (isa == KVM_ISA_VMX && exit_reason & ~0xffff) ? " " : "", \ (isa == KVM_ISA_VMX) ? \ __print_flags(exit_reason & ~0xffff, " ", VMX_EXIT_REASON_FLAGS) : "" -- 2.19.1.6.gb485710b