[PATCH v6 2/3] KVM: x86: tracemmio begin and complete
From: Dong Hao <hidden>
Date: 2012-08-10 03:20:08
Also in:
lkml
Subsystem:
kernel virtual machine (kvm), kernel virtual machine for x86 (kvm/x86), the rest, tracing, x86 architecture (32-bit and 64-bit) · Maintainers:
Paolo Bonzini, Sean Christopherson, Linus Torvalds, Steven Rostedt, Masami Hiramatsu, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
From: Xiao Guangrong <redacted> 'perf kvm stat record/report' will use kvm_exit and kvm_mmio(read...) to calculate mmio read emulated time for the old kernel, in order to trace mmio read event more exactly, we add kvm_mmio_begin to trace the time when mmio read begins, also, add kvm_io_done to trace the time when mmio/pio is completed [ Dong Hao [off-list ref]: rebase it on current kvm tree ] Signed-off-by: Xiao Guangrong <redacted> Signed-off-by: Dong Hao <redacted> --- arch/x86/kvm/x86.c | 32 ++++++++++++++++++++------------ include/trace/events/kvm.h | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 12 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8ebf65c..164ed9d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c@@ -3807,9 +3807,12 @@ mmio: /* * Is this MMIO handled locally? */ + trace_kvm_mmio_begin(vcpu->vcpu_id, write, gpa); handled = ops->read_write_mmio(vcpu, gpa, bytes, val); - if (handled == bytes) + if (handled == bytes) { + trace_kvm_io_done(vcpu->vcpu_id); return X86EMUL_CONTINUE; + } gpa += handled; bytes -= handled;
@@ -4002,6 +4005,7 @@ static int emulator_pio_in_out(struct kvm_vcpu *vcpu, int size, vcpu->arch.pio.size = size; if (!kernel_pio(vcpu, vcpu->arch.pio_data)) { + trace_kvm_io_done(vcpu->vcpu_id); vcpu->arch.pio.count = 0; return 1; }
@@ -4602,9 +4606,7 @@ restart: inject_emulated_exception(vcpu); r = EMULATE_DONE; } else if (vcpu->arch.pio.count) { - if (!vcpu->arch.pio.in) - vcpu->arch.pio.count = 0; - else + if (vcpu->arch.pio.in) writeback = false; r = EMULATE_DO_MMIO; } else if (vcpu->mmio_needed) {
@@ -4635,8 +4637,6 @@ int kvm_fast_pio_out(struct kvm_vcpu *vcpu, int size, unsigned short port) unsigned long val = kvm_register_read(vcpu, VCPU_REGS_RAX); int ret = emulator_pio_out_emulated(&vcpu->arch.emulate_ctxt, size, port, &val, 1); - /* do not return to emulator after return from userspace */ - vcpu->arch.pio.count = 0; return ret; } EXPORT_SYMBOL_GPL(kvm_fast_pio_out);
@@ -5487,11 +5487,16 @@ static int complete_mmio(struct kvm_vcpu *vcpu) { struct kvm_run *run = vcpu->run; struct kvm_mmio_fragment *frag; - int r; + int r = 1; if (!(vcpu->arch.pio.count || vcpu->mmio_needed)) return 1; + if (vcpu->arch.pio.count && !vcpu->arch.pio.in) { + vcpu->arch.pio.count = 0; + goto exit; + } + if (vcpu->mmio_needed) { /* Complete previous fragment */ frag = &vcpu->mmio_fragments[vcpu->mmio_cur_fragment++];
@@ -5499,8 +5504,10 @@ static int complete_mmio(struct kvm_vcpu *vcpu) memcpy(frag->data, run->mmio.data, frag->len); if (vcpu->mmio_cur_fragment == vcpu->mmio_nr_fragments) { vcpu->mmio_needed = 0; + if (vcpu->mmio_is_write) - return 1; + goto exit; + vcpu->mmio_read_completed = 1; goto done; }
@@ -5517,11 +5524,12 @@ static int complete_mmio(struct kvm_vcpu *vcpu) } done: vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu); - r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE); + r = emulate_instruction(vcpu, EMULTYPE_NO_DECODE) == EMULATE_DONE; srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx); - if (r != EMULATE_DONE) - return 0; - return 1; + +exit: + trace_kvm_io_done(vcpu->vcpu_id); + return r; } int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index 7ef9e75..5be5ad3 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h@@ -177,6 +177,43 @@ TRACE_EVENT(kvm_mmio, __entry->len, __entry->gpa, __entry->val) ); +TRACE_EVENT(kvm_mmio_begin, + TP_PROTO(unsigned int vcpu_id, bool rw, u64 gpa), + TP_ARGS(vcpu_id, rw, gpa), + + TP_STRUCT__entry( + __field(unsigned int, vcpu_id) + __field(int, type) + __field(u64, gpa) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + __entry->type = rw ? KVM_TRACE_MMIO_WRITE : + KVM_TRACE_MMIO_READ; + __entry->gpa = gpa; + ), + + TP_printk("vcpu %u mmio %s gpa 0x%llx", __entry->vcpu_id, + __print_symbolic(__entry->type, kvm_trace_symbol_mmio), + __entry->gpa) +); + +TRACE_EVENT(kvm_io_done, + TP_PROTO(unsigned int vcpu_id), + TP_ARGS(vcpu_id), + + TP_STRUCT__entry( + __field( unsigned int, vcpu_id ) + ), + + TP_fast_assign( + __entry->vcpu_id = vcpu_id; + ), + + TP_printk("vcpu %u", __entry->vcpu_id) +); + #define kvm_fpu_load_symbol \ {0, "unload"}, \ {1, "load"}
--
1.7.2.5