diff options
-rw-r--r-- | arch/x86/kvm/vmx.c | 35 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 26 | ||||
-rw-r--r-- | include/asm-x86/kvm.h | 20 | ||||
-rw-r--r-- | include/asm-x86/kvm_host.h | 19 | ||||
-rw-r--r-- | include/linux/kvm.h | 49 |
5 files changed, 147 insertions, 2 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 6249810b2155..8e5d6645b90d 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1843,6 +1843,8 @@ static void vmx_inject_irq(struct kvm_vcpu *vcpu, int irq) | |||
1843 | { | 1843 | { |
1844 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 1844 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
1845 | 1845 | ||
1846 | KVMTRACE_1D(INJ_VIRQ, vcpu, (u32)irq, handler); | ||
1847 | |||
1846 | if (vcpu->arch.rmode.active) { | 1848 | if (vcpu->arch.rmode.active) { |
1847 | vmx->rmode.irq.pending = true; | 1849 | vmx->rmode.irq.pending = true; |
1848 | vmx->rmode.irq.vector = irq; | 1850 | vmx->rmode.irq.vector = irq; |
@@ -1993,6 +1995,8 @@ static int handle_exception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
1993 | error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE); | 1995 | error_code = vmcs_read32(VM_EXIT_INTR_ERROR_CODE); |
1994 | if (is_page_fault(intr_info)) { | 1996 | if (is_page_fault(intr_info)) { |
1995 | cr2 = vmcs_readl(EXIT_QUALIFICATION); | 1997 | cr2 = vmcs_readl(EXIT_QUALIFICATION); |
1998 | KVMTRACE_3D(PAGE_FAULT, vcpu, error_code, (u32)cr2, | ||
1999 | (u32)((u64)cr2 >> 32), handler); | ||
1996 | return kvm_mmu_page_fault(vcpu, cr2, error_code); | 2000 | return kvm_mmu_page_fault(vcpu, cr2, error_code); |
1997 | } | 2001 | } |
1998 | 2002 | ||
@@ -2021,6 +2025,7 @@ static int handle_external_interrupt(struct kvm_vcpu *vcpu, | |||
2021 | struct kvm_run *kvm_run) | 2025 | struct kvm_run *kvm_run) |
2022 | { | 2026 | { |
2023 | ++vcpu->stat.irq_exits; | 2027 | ++vcpu->stat.irq_exits; |
2028 | KVMTRACE_1D(INTR, vcpu, vmcs_read32(VM_EXIT_INTR_INFO), handler); | ||
2024 | return 1; | 2029 | return 1; |
2025 | } | 2030 | } |
2026 | 2031 | ||
@@ -2078,6 +2083,8 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2078 | reg = (exit_qualification >> 8) & 15; | 2083 | reg = (exit_qualification >> 8) & 15; |
2079 | switch ((exit_qualification >> 4) & 3) { | 2084 | switch ((exit_qualification >> 4) & 3) { |
2080 | case 0: /* mov to cr */ | 2085 | case 0: /* mov to cr */ |
2086 | KVMTRACE_3D(CR_WRITE, vcpu, (u32)cr, (u32)vcpu->arch.regs[reg], | ||
2087 | (u32)((u64)vcpu->arch.regs[reg] >> 32), handler); | ||
2081 | switch (cr) { | 2088 | switch (cr) { |
2082 | case 0: | 2089 | case 0: |
2083 | vcpu_load_rsp_rip(vcpu); | 2090 | vcpu_load_rsp_rip(vcpu); |
@@ -2110,6 +2117,7 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2110 | vcpu->arch.cr0 &= ~X86_CR0_TS; | 2117 | vcpu->arch.cr0 &= ~X86_CR0_TS; |
2111 | vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0); | 2118 | vmcs_writel(CR0_READ_SHADOW, vcpu->arch.cr0); |
2112 | vmx_fpu_activate(vcpu); | 2119 | vmx_fpu_activate(vcpu); |
2120 | KVMTRACE_0D(CLTS, vcpu, handler); | ||
2113 | skip_emulated_instruction(vcpu); | 2121 | skip_emulated_instruction(vcpu); |
2114 | return 1; | 2122 | return 1; |
2115 | case 1: /*mov from cr*/ | 2123 | case 1: /*mov from cr*/ |
@@ -2118,12 +2126,18 @@ static int handle_cr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2118 | vcpu_load_rsp_rip(vcpu); | 2126 | vcpu_load_rsp_rip(vcpu); |
2119 | vcpu->arch.regs[reg] = vcpu->arch.cr3; | 2127 | vcpu->arch.regs[reg] = vcpu->arch.cr3; |
2120 | vcpu_put_rsp_rip(vcpu); | 2128 | vcpu_put_rsp_rip(vcpu); |
2129 | KVMTRACE_3D(CR_READ, vcpu, (u32)cr, | ||
2130 | (u32)vcpu->arch.regs[reg], | ||
2131 | (u32)((u64)vcpu->arch.regs[reg] >> 32), | ||
2132 | handler); | ||
2121 | skip_emulated_instruction(vcpu); | 2133 | skip_emulated_instruction(vcpu); |
2122 | return 1; | 2134 | return 1; |
2123 | case 8: | 2135 | case 8: |
2124 | vcpu_load_rsp_rip(vcpu); | 2136 | vcpu_load_rsp_rip(vcpu); |
2125 | vcpu->arch.regs[reg] = kvm_get_cr8(vcpu); | 2137 | vcpu->arch.regs[reg] = kvm_get_cr8(vcpu); |
2126 | vcpu_put_rsp_rip(vcpu); | 2138 | vcpu_put_rsp_rip(vcpu); |
2139 | KVMTRACE_2D(CR_READ, vcpu, (u32)cr, | ||
2140 | (u32)vcpu->arch.regs[reg], handler); | ||
2127 | skip_emulated_instruction(vcpu); | 2141 | skip_emulated_instruction(vcpu); |
2128 | return 1; | 2142 | return 1; |
2129 | } | 2143 | } |
@@ -2169,6 +2183,7 @@ static int handle_dr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2169 | val = 0; | 2183 | val = 0; |
2170 | } | 2184 | } |
2171 | vcpu->arch.regs[reg] = val; | 2185 | vcpu->arch.regs[reg] = val; |
2186 | KVMTRACE_2D(DR_READ, vcpu, (u32)dr, (u32)val, handler); | ||
2172 | } else { | 2187 | } else { |
2173 | /* mov to dr */ | 2188 | /* mov to dr */ |
2174 | } | 2189 | } |
@@ -2193,6 +2208,9 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2193 | return 1; | 2208 | return 1; |
2194 | } | 2209 | } |
2195 | 2210 | ||
2211 | KVMTRACE_3D(MSR_READ, vcpu, ecx, (u32)data, (u32)(data >> 32), | ||
2212 | handler); | ||
2213 | |||
2196 | /* FIXME: handling of bits 32:63 of rax, rdx */ | 2214 | /* FIXME: handling of bits 32:63 of rax, rdx */ |
2197 | vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u; | 2215 | vcpu->arch.regs[VCPU_REGS_RAX] = data & -1u; |
2198 | vcpu->arch.regs[VCPU_REGS_RDX] = (data >> 32) & -1u; | 2216 | vcpu->arch.regs[VCPU_REGS_RDX] = (data >> 32) & -1u; |
@@ -2206,6 +2224,9 @@ static int handle_wrmsr(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2206 | u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) | 2224 | u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) |
2207 | | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); | 2225 | | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); |
2208 | 2226 | ||
2227 | KVMTRACE_3D(MSR_WRITE, vcpu, ecx, (u32)data, (u32)(data >> 32), | ||
2228 | handler); | ||
2229 | |||
2209 | if (vmx_set_msr(vcpu, ecx, data) != 0) { | 2230 | if (vmx_set_msr(vcpu, ecx, data) != 0) { |
2210 | kvm_inject_gp(vcpu, 0); | 2231 | kvm_inject_gp(vcpu, 0); |
2211 | return 1; | 2232 | return 1; |
@@ -2230,6 +2251,9 @@ static int handle_interrupt_window(struct kvm_vcpu *vcpu, | |||
2230 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); | 2251 | cpu_based_vm_exec_control = vmcs_read32(CPU_BASED_VM_EXEC_CONTROL); |
2231 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; | 2252 | cpu_based_vm_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; |
2232 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); | 2253 | vmcs_write32(CPU_BASED_VM_EXEC_CONTROL, cpu_based_vm_exec_control); |
2254 | |||
2255 | KVMTRACE_0D(PEND_INTR, vcpu, handler); | ||
2256 | |||
2233 | /* | 2257 | /* |
2234 | * If the user space waits to inject interrupts, exit as soon as | 2258 | * If the user space waits to inject interrupts, exit as soon as |
2235 | * possible | 2259 | * possible |
@@ -2272,6 +2296,8 @@ static int handle_apic_access(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2272 | exit_qualification = vmcs_read64(EXIT_QUALIFICATION); | 2296 | exit_qualification = vmcs_read64(EXIT_QUALIFICATION); |
2273 | offset = exit_qualification & 0xffful; | 2297 | offset = exit_qualification & 0xffful; |
2274 | 2298 | ||
2299 | KVMTRACE_1D(APIC_ACCESS, vcpu, (u32)offset, handler); | ||
2300 | |||
2275 | er = emulate_instruction(vcpu, kvm_run, 0, 0, 0); | 2301 | er = emulate_instruction(vcpu, kvm_run, 0, 0, 0); |
2276 | 2302 | ||
2277 | if (er != EMULATE_DONE) { | 2303 | if (er != EMULATE_DONE) { |
@@ -2335,6 +2361,9 @@ static int kvm_handle_exit(struct kvm_run *kvm_run, struct kvm_vcpu *vcpu) | |||
2335 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 2361 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
2336 | u32 vectoring_info = vmx->idt_vectoring_info; | 2362 | u32 vectoring_info = vmx->idt_vectoring_info; |
2337 | 2363 | ||
2364 | KVMTRACE_3D(VMEXIT, vcpu, exit_reason, (u32)vmcs_readl(GUEST_RIP), | ||
2365 | (u32)((u64)vmcs_readl(GUEST_RIP) >> 32), entryexit); | ||
2366 | |||
2338 | if (unlikely(vmx->fail)) { | 2367 | if (unlikely(vmx->fail)) { |
2339 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; | 2368 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; |
2340 | kvm_run->fail_entry.hardware_entry_failure_reason | 2369 | kvm_run->fail_entry.hardware_entry_failure_reason |
@@ -2416,6 +2445,8 @@ static void vmx_intr_assist(struct kvm_vcpu *vcpu) | |||
2416 | return; | 2445 | return; |
2417 | } | 2446 | } |
2418 | 2447 | ||
2448 | KVMTRACE_1D(REDELIVER_EVT, vcpu, idtv_info_field, handler); | ||
2449 | |||
2419 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field); | 2450 | vmcs_write32(VM_ENTRY_INTR_INFO_FIELD, idtv_info_field); |
2420 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, | 2451 | vmcs_write32(VM_ENTRY_INSTRUCTION_LEN, |
2421 | vmcs_read32(VM_EXIT_INSTRUCTION_LEN)); | 2452 | vmcs_read32(VM_EXIT_INSTRUCTION_LEN)); |
@@ -2601,8 +2632,10 @@ static void vmx_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
2601 | intr_info = vmcs_read32(VM_EXIT_INTR_INFO); | 2632 | intr_info = vmcs_read32(VM_EXIT_INTR_INFO); |
2602 | 2633 | ||
2603 | /* We need to handle NMIs before interrupts are enabled */ | 2634 | /* We need to handle NMIs before interrupts are enabled */ |
2604 | if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) /* nmi */ | 2635 | if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == 0x200) { /* nmi */ |
2636 | KVMTRACE_0D(NMI, vcpu, handler); | ||
2605 | asm("int $2"); | 2637 | asm("int $2"); |
2638 | } | ||
2606 | } | 2639 | } |
2607 | 2640 | ||
2608 | static void vmx_free_vmcs(struct kvm_vcpu *vcpu) | 2641 | static void vmx_free_vmcs(struct kvm_vcpu *vcpu) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index c7ad2352227a..f070f0a9adee 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -303,6 +303,9 @@ EXPORT_SYMBOL_GPL(kvm_set_cr0); | |||
303 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) | 303 | void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw) |
304 | { | 304 | { |
305 | kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)); | 305 | kvm_set_cr0(vcpu, (vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)); |
306 | KVMTRACE_1D(LMSW, vcpu, | ||
307 | (u32)((vcpu->arch.cr0 & ~0x0ful) | (msw & 0x0f)), | ||
308 | handler); | ||
306 | } | 309 | } |
307 | EXPORT_SYMBOL_GPL(kvm_lmsw); | 310 | EXPORT_SYMBOL_GPL(kvm_lmsw); |
308 | 311 | ||
@@ -2269,6 +2272,13 @@ int kvm_emulate_pio(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
2269 | vcpu->arch.pio.guest_page_offset = 0; | 2272 | vcpu->arch.pio.guest_page_offset = 0; |
2270 | vcpu->arch.pio.rep = 0; | 2273 | vcpu->arch.pio.rep = 0; |
2271 | 2274 | ||
2275 | if (vcpu->run->io.direction == KVM_EXIT_IO_IN) | ||
2276 | KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size, | ||
2277 | handler); | ||
2278 | else | ||
2279 | KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size, | ||
2280 | handler); | ||
2281 | |||
2272 | kvm_x86_ops->cache_regs(vcpu); | 2282 | kvm_x86_ops->cache_regs(vcpu); |
2273 | memcpy(vcpu->arch.pio_data, &vcpu->arch.regs[VCPU_REGS_RAX], 4); | 2283 | memcpy(vcpu->arch.pio_data, &vcpu->arch.regs[VCPU_REGS_RAX], 4); |
2274 | kvm_x86_ops->decache_regs(vcpu); | 2284 | kvm_x86_ops->decache_regs(vcpu); |
@@ -2307,6 +2317,13 @@ int kvm_emulate_pio_string(struct kvm_vcpu *vcpu, struct kvm_run *run, int in, | |||
2307 | vcpu->arch.pio.guest_page_offset = offset_in_page(address); | 2317 | vcpu->arch.pio.guest_page_offset = offset_in_page(address); |
2308 | vcpu->arch.pio.rep = rep; | 2318 | vcpu->arch.pio.rep = rep; |
2309 | 2319 | ||
2320 | if (vcpu->run->io.direction == KVM_EXIT_IO_IN) | ||
2321 | KVMTRACE_2D(IO_READ, vcpu, vcpu->run->io.port, (u32)size, | ||
2322 | handler); | ||
2323 | else | ||
2324 | KVMTRACE_2D(IO_WRITE, vcpu, vcpu->run->io.port, (u32)size, | ||
2325 | handler); | ||
2326 | |||
2310 | if (!count) { | 2327 | if (!count) { |
2311 | kvm_x86_ops->skip_emulated_instruction(vcpu); | 2328 | kvm_x86_ops->skip_emulated_instruction(vcpu); |
2312 | return 1; | 2329 | return 1; |
@@ -2414,6 +2431,7 @@ void kvm_arch_exit(void) | |||
2414 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) | 2431 | int kvm_emulate_halt(struct kvm_vcpu *vcpu) |
2415 | { | 2432 | { |
2416 | ++vcpu->stat.halt_exits; | 2433 | ++vcpu->stat.halt_exits; |
2434 | KVMTRACE_0D(HLT, vcpu, handler); | ||
2417 | if (irqchip_in_kernel(vcpu->kvm)) { | 2435 | if (irqchip_in_kernel(vcpu->kvm)) { |
2418 | vcpu->arch.mp_state = VCPU_MP_STATE_HALTED; | 2436 | vcpu->arch.mp_state = VCPU_MP_STATE_HALTED; |
2419 | up_read(&vcpu->kvm->slots_lock); | 2437 | up_read(&vcpu->kvm->slots_lock); |
@@ -2451,6 +2469,8 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu) | |||
2451 | a2 = vcpu->arch.regs[VCPU_REGS_RDX]; | 2469 | a2 = vcpu->arch.regs[VCPU_REGS_RDX]; |
2452 | a3 = vcpu->arch.regs[VCPU_REGS_RSI]; | 2470 | a3 = vcpu->arch.regs[VCPU_REGS_RSI]; |
2453 | 2471 | ||
2472 | KVMTRACE_1D(VMMCALL, vcpu, (u32)nr, handler); | ||
2473 | |||
2454 | if (!is_long_mode(vcpu)) { | 2474 | if (!is_long_mode(vcpu)) { |
2455 | nr &= 0xFFFFFFFF; | 2475 | nr &= 0xFFFFFFFF; |
2456 | a0 &= 0xFFFFFFFF; | 2476 | a0 &= 0xFFFFFFFF; |
@@ -2639,6 +2659,11 @@ void kvm_emulate_cpuid(struct kvm_vcpu *vcpu) | |||
2639 | } | 2659 | } |
2640 | kvm_x86_ops->decache_regs(vcpu); | 2660 | kvm_x86_ops->decache_regs(vcpu); |
2641 | kvm_x86_ops->skip_emulated_instruction(vcpu); | 2661 | kvm_x86_ops->skip_emulated_instruction(vcpu); |
2662 | KVMTRACE_5D(CPUID, vcpu, function, | ||
2663 | (u32)vcpu->arch.regs[VCPU_REGS_RAX], | ||
2664 | (u32)vcpu->arch.regs[VCPU_REGS_RBX], | ||
2665 | (u32)vcpu->arch.regs[VCPU_REGS_RCX], | ||
2666 | (u32)vcpu->arch.regs[VCPU_REGS_RDX], handler); | ||
2642 | } | 2667 | } |
2643 | EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); | 2668 | EXPORT_SYMBOL_GPL(kvm_emulate_cpuid); |
2644 | 2669 | ||
@@ -2794,6 +2819,7 @@ again: | |||
2794 | if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) | 2819 | if (test_and_clear_bit(KVM_REQ_TLB_FLUSH, &vcpu->requests)) |
2795 | kvm_x86_ops->tlb_flush(vcpu); | 2820 | kvm_x86_ops->tlb_flush(vcpu); |
2796 | 2821 | ||
2822 | KVMTRACE_0D(VMENTRY, vcpu, entryexit); | ||
2797 | kvm_x86_ops->run(vcpu, kvm_run); | 2823 | kvm_x86_ops->run(vcpu, kvm_run); |
2798 | 2824 | ||
2799 | vcpu->guest_mode = 0; | 2825 | vcpu->guest_mode = 0; |
diff --git a/include/asm-x86/kvm.h b/include/asm-x86/kvm.h index 12b4b25371d5..80eefef2cc76 100644 --- a/include/asm-x86/kvm.h +++ b/include/asm-x86/kvm.h | |||
@@ -209,4 +209,24 @@ struct kvm_pit_state { | |||
209 | struct kvm_pit_channel_state channels[3]; | 209 | struct kvm_pit_channel_state channels[3]; |
210 | }; | 210 | }; |
211 | 211 | ||
212 | #define KVM_TRC_INJ_VIRQ (KVM_TRC_HANDLER + 0x02) | ||
213 | #define KVM_TRC_REDELIVER_EVT (KVM_TRC_HANDLER + 0x03) | ||
214 | #define KVM_TRC_PEND_INTR (KVM_TRC_HANDLER + 0x04) | ||
215 | #define KVM_TRC_IO_READ (KVM_TRC_HANDLER + 0x05) | ||
216 | #define KVM_TRC_IO_WRITE (KVM_TRC_HANDLER + 0x06) | ||
217 | #define KVM_TRC_CR_READ (KVM_TRC_HANDLER + 0x07) | ||
218 | #define KVM_TRC_CR_WRITE (KVM_TRC_HANDLER + 0x08) | ||
219 | #define KVM_TRC_DR_READ (KVM_TRC_HANDLER + 0x09) | ||
220 | #define KVM_TRC_DR_WRITE (KVM_TRC_HANDLER + 0x0A) | ||
221 | #define KVM_TRC_MSR_READ (KVM_TRC_HANDLER + 0x0B) | ||
222 | #define KVM_TRC_MSR_WRITE (KVM_TRC_HANDLER + 0x0C) | ||
223 | #define KVM_TRC_CPUID (KVM_TRC_HANDLER + 0x0D) | ||
224 | #define KVM_TRC_INTR (KVM_TRC_HANDLER + 0x0E) | ||
225 | #define KVM_TRC_NMI (KVM_TRC_HANDLER + 0x0F) | ||
226 | #define KVM_TRC_VMMCALL (KVM_TRC_HANDLER + 0x10) | ||
227 | #define KVM_TRC_HLT (KVM_TRC_HANDLER + 0x11) | ||
228 | #define KVM_TRC_CLTS (KVM_TRC_HANDLER + 0x12) | ||
229 | #define KVM_TRC_LMSW (KVM_TRC_HANDLER + 0x13) | ||
230 | #define KVM_TRC_APIC_ACCESS (KVM_TRC_HANDLER + 0x14) | ||
231 | |||
212 | #endif | 232 | #endif |
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h index 286117878ce2..15169cb71c83 100644 --- a/include/asm-x86/kvm_host.h +++ b/include/asm-x86/kvm_host.h | |||
@@ -667,4 +667,23 @@ enum { | |||
667 | TASK_SWITCH_GATE = 3, | 667 | TASK_SWITCH_GATE = 3, |
668 | }; | 668 | }; |
669 | 669 | ||
670 | #define KVMTRACE_5D(evt, vcpu, d1, d2, d3, d4, d5, name) \ | ||
671 | trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ | ||
672 | vcpu, 5, d1, d2, d3, d4, d5) | ||
673 | #define KVMTRACE_4D(evt, vcpu, d1, d2, d3, d4, name) \ | ||
674 | trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ | ||
675 | vcpu, 4, d1, d2, d3, d4, 0) | ||
676 | #define KVMTRACE_3D(evt, vcpu, d1, d2, d3, name) \ | ||
677 | trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ | ||
678 | vcpu, 3, d1, d2, d3, 0, 0) | ||
679 | #define KVMTRACE_2D(evt, vcpu, d1, d2, name) \ | ||
680 | trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ | ||
681 | vcpu, 2, d1, d2, 0, 0, 0) | ||
682 | #define KVMTRACE_1D(evt, vcpu, d1, name) \ | ||
683 | trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ | ||
684 | vcpu, 1, d1, 0, 0, 0, 0) | ||
685 | #define KVMTRACE_0D(evt, vcpu, name) \ | ||
686 | trace_mark(kvm_trace_##name, "%u %p %u %u %u %u %u %u", KVM_TRC_##evt, \ | ||
687 | vcpu, 0, 0, 0, 0, 0, 0) | ||
688 | |||
670 | #endif | 689 | #endif |
diff --git a/include/linux/kvm.h b/include/linux/kvm.h index f04bb426618f..d302d63517e4 100644 --- a/include/linux/kvm.h +++ b/include/linux/kvm.h | |||
@@ -14,6 +14,12 @@ | |||
14 | 14 | ||
15 | #define KVM_API_VERSION 12 | 15 | #define KVM_API_VERSION 12 |
16 | 16 | ||
17 | /* for KVM_TRACE_ENABLE */ | ||
18 | struct kvm_user_trace_setup { | ||
19 | __u32 buf_size; /* sub_buffer size of each per-cpu */ | ||
20 | __u32 buf_nr; /* the number of sub_buffers of each per-cpu */ | ||
21 | }; | ||
22 | |||
17 | /* for KVM_CREATE_MEMORY_REGION */ | 23 | /* for KVM_CREATE_MEMORY_REGION */ |
18 | struct kvm_memory_region { | 24 | struct kvm_memory_region { |
19 | __u32 slot; | 25 | __u32 slot; |
@@ -242,6 +248,42 @@ struct kvm_s390_interrupt { | |||
242 | __u64 parm64; | 248 | __u64 parm64; |
243 | }; | 249 | }; |
244 | 250 | ||
251 | #define KVM_TRC_SHIFT 16 | ||
252 | /* | ||
253 | * kvm trace categories | ||
254 | */ | ||
255 | #define KVM_TRC_ENTRYEXIT (1 << KVM_TRC_SHIFT) | ||
256 | #define KVM_TRC_HANDLER (1 << (KVM_TRC_SHIFT + 1)) /* only 12 bits */ | ||
257 | |||
258 | /* | ||
259 | * kvm trace action | ||
260 | */ | ||
261 | #define KVM_TRC_VMENTRY (KVM_TRC_ENTRYEXIT + 0x01) | ||
262 | #define KVM_TRC_VMEXIT (KVM_TRC_ENTRYEXIT + 0x02) | ||
263 | #define KVM_TRC_PAGE_FAULT (KVM_TRC_HANDLER + 0x01) | ||
264 | |||
265 | #define KVM_TRC_HEAD_SIZE 12 | ||
266 | #define KVM_TRC_CYCLE_SIZE 8 | ||
267 | #define KVM_TRC_EXTRA_MAX 7 | ||
268 | |||
269 | /* This structure represents a single trace buffer record. */ | ||
270 | struct kvm_trace_rec { | ||
271 | __u32 event:28; | ||
272 | __u32 extra_u32:3; | ||
273 | __u32 cycle_in:1; | ||
274 | __u32 pid; | ||
275 | __u32 vcpu_id; | ||
276 | union { | ||
277 | struct { | ||
278 | __u32 cycle_lo, cycle_hi; | ||
279 | __u32 extra_u32[KVM_TRC_EXTRA_MAX]; | ||
280 | } cycle; | ||
281 | struct { | ||
282 | __u32 extra_u32[KVM_TRC_EXTRA_MAX]; | ||
283 | } nocycle; | ||
284 | } u; | ||
285 | }; | ||
286 | |||
245 | #define KVMIO 0xAE | 287 | #define KVMIO 0xAE |
246 | 288 | ||
247 | /* | 289 | /* |
@@ -262,7 +304,12 @@ struct kvm_s390_interrupt { | |||
262 | */ | 304 | */ |
263 | #define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */ | 305 | #define KVM_GET_VCPU_MMAP_SIZE _IO(KVMIO, 0x04) /* in bytes */ |
264 | #define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2) | 306 | #define KVM_GET_SUPPORTED_CPUID _IOWR(KVMIO, 0x05, struct kvm_cpuid2) |
265 | 307 | /* | |
308 | * ioctls for kvm trace | ||
309 | */ | ||
310 | #define KVM_TRACE_ENABLE _IOW(KVMIO, 0x06, struct kvm_user_trace_setup) | ||
311 | #define KVM_TRACE_PAUSE _IO(KVMIO, 0x07) | ||
312 | #define KVM_TRACE_DISABLE _IO(KVMIO, 0x08) | ||
266 | /* | 313 | /* |
267 | * Extension capability list. | 314 | * Extension capability list. |
268 | */ | 315 | */ |