diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2009-06-17 08:22:14 -0400 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-09-10 01:32:59 -0400 |
commit | 229456fc34b1c9031b04f7581e7b755d1cebfe9c (patch) | |
tree | 85fc0b54e9403d6ea059b8f7f78cea49594aaace /arch/x86/kvm/svm.c | |
parent | 219b65dcf6c0bad83d51bfa12e25891c02de2414 (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.c | 84 |
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 | ||
1289 | static int nmi_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1281 | static 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 | ||
1295 | static int intr_interception(struct vcpu_svm *svm, struct kvm_run *kvm_run) | 1286 | static 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) | |||
2185 | static int interrupt_window_interception(struct vcpu_svm *svm, | 2173 | static 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 | ||
2705 | static 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 | |||
2720 | static struct kvm_x86_ops svm_x86_ops = { | 2758 | static 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 | ||
2783 | static int __init svm_init(void) | 2823 | static int __init svm_init(void) |