aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/svm.c
diff options
context:
space:
mode:
authorMarcelo Tosatti <mtosatti@redhat.com>2009-06-17 08:22:14 -0400
committerAvi Kivity <avi@redhat.com>2009-09-10 01:32:59 -0400
commit229456fc34b1c9031b04f7581e7b755d1cebfe9c (patch)
tree85fc0b54e9403d6ea059b8f7f78cea49594aaace /arch/x86/kvm/svm.c
parent219b65dcf6c0bad83d51bfa12e25891c02de2414 (diff)
KVM: convert custom marker based tracing to event traces
This allows use of the powerful ftrace infrastructure. See Documentation/trace/ for usage information. [avi, stephen: various build fixes] [sheng: fix control register breakage] Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com> Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au> Signed-off-by: Sheng Yang <sheng@linux.intel.com> Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r--arch/x86/kvm/svm.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 456666183770..b1c446208867 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -25,10 +25,12 @@
25#include <linux/vmalloc.h> 25#include <linux/vmalloc.h>
26#include <linux/highmem.h> 26#include <linux/highmem.h>
27#include <linux/sched.h> 27#include <linux/sched.h>
28#include <linux/ftrace_event.h>
28 29
29#include <asm/desc.h> 30#include <asm/desc.h>
30 31
31#include <asm/virtext.h> 32#include <asm/virtext.h>
33#include "trace.h"
32 34
33#define __ex(x) __kvm_handle_fault_on_reboot(x) 35#define __ex(x) __kvm_handle_fault_on_reboot(x)
34 36
@@ -1096,7 +1098,6 @@ static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr)
1096 val = 0; 1098 val = 0;
1097 } 1099 }
1098 1100
1099 KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler);
1100 return val; 1101 return val;
1101} 1102}
1102 1103
@@ -1105,8 +1106,6 @@ static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value,
1105{ 1106{
1106 struct vcpu_svm *svm = to_svm(vcpu); 1107 struct vcpu_svm *svm = to_svm(vcpu);
1107 1108
1108 KVMTRACE_2D(DR_WRITE, vcpu, (u32)dr, (u32)value, handler);
1109
1110 *exception = 0; 1109 *exception = 0;
1111 1110
1112 switch (dr) { 1111 switch (dr) {
@@ -1154,14 +1153,7 @@ static int pf_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1154 fault_address = svm->vmcb->control.exit_info_2; 1153 fault_address = svm->vmcb->control.exit_info_2;
1155 error_code = svm->vmcb->control.exit_info_1; 1154 error_code = svm->vmcb->control.exit_info_1;
1156 1155
1157 if (!npt_enabled) 1156 trace_kvm_page_fault(fault_address, error_code);
1158 KVMTRACE_3D(PAGE_FAULT, &svm->vcpu, error_code,
1159 (u32)fault_address, (u32)(fault_address >> 32),
1160 handler);
1161 else
1162 KVMTRACE_3D(TDP_FAULT, &svm->vcpu, error_code,
1163 (u32)fault_address, (u32)(fault_address >> 32),
1164 handler);
1165 /* 1157 /*
1166 * FIXME: Tis shouldn't be necessary here, but there is a flush 1158 * FIXME: Tis shouldn't be necessary here, but there is a flush
1167 * missing in the MMU code. Until we find this bug, flush the 1159 * missing in the MMU code. Until we find this bug, flush the
@@ -1288,14 +1280,12 @@ static int io_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1288 1280
1289static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1281static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1290{ 1282{
1291 KVMTRACE_0D(NMI, &svm->vcpu, handler);
1292 return 1; 1283 return 1;
1293} 1284}
1294 1285
1295static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) 1286static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
1296{ 1287{
1297 ++svm->vcpu.stat.irq_exits; 1288 ++svm->vcpu.stat.irq_exits;
1298 KVMTRACE_0D(INTR, &svm->vcpu, handler);
1299 return 1; 1289 return 1;
1300} 1290}
1301 1291
@@ -2077,8 +2067,7 @@ static int rdmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
2077 if (svm_get_msr(&svm->vcpu, ecx, &data)) 2067 if (svm_get_msr(&svm->vcpu, ecx, &data))
2078 kvm_inject_gp(&svm->vcpu, 0); 2068 kvm_inject_gp(&svm->vcpu, 0);
2079 else { 2069 else {
2080 KVMTRACE_3D(MSR_READ, &svm->vcpu, ecx, (u32)data, 2070 trace_kvm_msr_read(ecx, data);
2081 (u32)(data >> 32), handler);
2082 2071
2083 svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; 2072 svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff;
2084 svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32; 2073 svm->vcpu.arch.regs[VCPU_REGS_RDX] = data >> 32;
@@ -2163,8 +2152,7 @@ static int wrmsr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
2163 u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) 2152 u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
2164 | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); 2153 | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
2165 2154
2166 KVMTRACE_3D(MSR_WRITE, &svm->vcpu, ecx, (u32)data, (u32)(data >> 32), 2155 trace_kvm_msr_write(ecx, data);
2167 handler);
2168 2156
2169 svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; 2157 svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
2170 if (svm_set_msr(&svm->vcpu, ecx, data)) 2158 if (svm_set_msr(&svm->vcpu, ecx, data))
@@ -2185,8 +2173,6 @@ static int msr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run)
2185static int interrupt_window_interception(struct vcpu_svm *svm, 2173static int interrupt_window_interception(struct vcpu_svm *svm,
2186 struct kvm_run *kvm_run) 2174 struct kvm_run *kvm_run)
2187{ 2175{
2188 KVMTRACE_0D(PEND_INTR, &svm->vcpu, handler);
2189
2190 svm_clear_vintr(svm); 2176 svm_clear_vintr(svm);
2191 svm->vmcb->control.int_ctl &= ~V_IRQ_MASK; 2177 svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
2192 /* 2178 /*
@@ -2265,8 +2251,7 @@ static int handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu)
2265 struct vcpu_svm *svm = to_svm(vcpu); 2251 struct vcpu_svm *svm = to_svm(vcpu);
2266 u32 exit_code = svm->vmcb->control.exit_code; 2252 u32 exit_code = svm->vmcb->control.exit_code;
2267 2253
2268 KVMTRACE_3D(VMEXIT, vcpu, exit_code, (u32)svm->vmcb->save.rip, 2254 trace_kvm_exit(exit_code, svm->vmcb->save.rip);
2269 (u32)((u64)svm->vmcb->save.rip >> 32), entryexit);
2270 2255
2271 if (is_nested(svm)) { 2256 if (is_nested(svm)) {
2272 nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n", 2257 nsvm_printk("nested handle_exit: 0x%x | 0x%lx | 0x%lx | 0x%lx\n",
@@ -2354,7 +2339,7 @@ static inline void svm_inject_irq(struct vcpu_svm *svm, int irq)
2354{ 2339{
2355 struct vmcb_control_area *control; 2340 struct vmcb_control_area *control;
2356 2341
2357 KVMTRACE_1D(INJ_VIRQ, &svm->vcpu, (u32)irq, handler); 2342 trace_kvm_inj_virq(irq);
2358 2343
2359 ++svm->vcpu.stat.irq_injections; 2344 ++svm->vcpu.stat.irq_injections;
2360 control = &svm->vmcb->control; 2345 control = &svm->vmcb->control;
@@ -2717,6 +2702,59 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
2717 return 0; 2702 return 0;
2718} 2703}
2719 2704
2705static const struct trace_print_flags svm_exit_reasons_str[] = {
2706 { SVM_EXIT_READ_CR0, "read_cr0" },
2707 { SVM_EXIT_READ_CR3, "read_cr3" },
2708 { SVM_EXIT_READ_CR4, "read_cr4" },
2709 { SVM_EXIT_READ_CR8, "read_cr8" },
2710 { SVM_EXIT_WRITE_CR0, "write_cr0" },
2711 { SVM_EXIT_WRITE_CR3, "write_cr3" },
2712 { SVM_EXIT_WRITE_CR4, "write_cr4" },
2713 { SVM_EXIT_WRITE_CR8, "write_cr8" },
2714 { SVM_EXIT_READ_DR0, "read_dr0" },
2715 { SVM_EXIT_READ_DR1, "read_dr1" },
2716 { SVM_EXIT_READ_DR2, "read_dr2" },
2717 { SVM_EXIT_READ_DR3, "read_dr3" },
2718 { SVM_EXIT_WRITE_DR0, "write_dr0" },
2719 { SVM_EXIT_WRITE_DR1, "write_dr1" },
2720 { SVM_EXIT_WRITE_DR2, "write_dr2" },
2721 { SVM_EXIT_WRITE_DR3, "write_dr3" },
2722 { SVM_EXIT_WRITE_DR5, "write_dr5" },
2723 { SVM_EXIT_WRITE_DR7, "write_dr7" },
2724 { SVM_EXIT_EXCP_BASE + DB_VECTOR, "DB excp" },
2725 { SVM_EXIT_EXCP_BASE + BP_VECTOR, "BP excp" },
2726 { SVM_EXIT_EXCP_BASE + UD_VECTOR, "UD excp" },
2727 { SVM_EXIT_EXCP_BASE + PF_VECTOR, "PF excp" },
2728 { SVM_EXIT_EXCP_BASE + NM_VECTOR, "NM excp" },
2729 { SVM_EXIT_EXCP_BASE + MC_VECTOR, "MC excp" },
2730 { SVM_EXIT_INTR, "interrupt" },
2731 { SVM_EXIT_NMI, "nmi" },
2732 { SVM_EXIT_SMI, "smi" },
2733 { SVM_EXIT_INIT, "init" },
2734 { SVM_EXIT_VINTR, "vintr" },
2735 { SVM_EXIT_CPUID, "cpuid" },
2736 { SVM_EXIT_INVD, "invd" },
2737 { SVM_EXIT_HLT, "hlt" },
2738 { SVM_EXIT_INVLPG, "invlpg" },
2739 { SVM_EXIT_INVLPGA, "invlpga" },
2740 { SVM_EXIT_IOIO, "io" },
2741 { SVM_EXIT_MSR, "msr" },
2742 { SVM_EXIT_TASK_SWITCH, "task_switch" },
2743 { SVM_EXIT_SHUTDOWN, "shutdown" },
2744 { SVM_EXIT_VMRUN, "vmrun" },
2745 { SVM_EXIT_VMMCALL, "hypercall" },
2746 { SVM_EXIT_VMLOAD, "vmload" },
2747 { SVM_EXIT_VMSAVE, "vmsave" },
2748 { SVM_EXIT_STGI, "stgi" },
2749 { SVM_EXIT_CLGI, "clgi" },
2750 { SVM_EXIT_SKINIT, "skinit" },
2751 { SVM_EXIT_WBINVD, "wbinvd" },
2752 { SVM_EXIT_MONITOR, "monitor" },
2753 { SVM_EXIT_MWAIT, "mwait" },
2754 { SVM_EXIT_NPF, "npf" },
2755 { -1, NULL }
2756};
2757
2720static struct kvm_x86_ops svm_x86_ops = { 2758static struct kvm_x86_ops svm_x86_ops = {
2721 .cpu_has_kvm_support = has_svm, 2759 .cpu_has_kvm_support = has_svm,
2722 .disabled_by_bios = is_disabled, 2760 .disabled_by_bios = is_disabled,
@@ -2778,6 +2816,8 @@ static struct kvm_x86_ops svm_x86_ops = {
2778 .set_tss_addr = svm_set_tss_addr, 2816 .set_tss_addr = svm_set_tss_addr,
2779 .get_tdp_level = get_npt_level, 2817 .get_tdp_level = get_npt_level,
2780 .get_mt_mask = svm_get_mt_mask, 2818 .get_mt_mask = svm_get_mt_mask,
2819
2820 .exit_reasons_str = svm_exit_reasons_str,
2781}; 2821};
2782 2822
2783static int __init svm_init(void) 2823static int __init svm_init(void)