diff options
author | Bryan Cantrill <bryan@joyent.com> | 2011-11-29 06:23:47 +0000 |
---|---|---|
committer | Bryan Cantrill <bryan@joyent.com> | 2011-11-29 06:23:47 +0000 |
commit | 3b2aaad2c0647aa661548ee3add64f1aa590100c (patch) | |
tree | f496dae87ac9db7c36d9aaf7d897297340d50d93 | |
parent | a131c2d183ff020f325c894f2d5d20a8c93ea3d9 (diff) | |
download | illumos-kvm-3b2aaad2c0647aa661548ee3add64f1aa590100c.tar.gz |
HVM-701 need static instrumentation in kvm_ctx_save()/kvm_ctx_restore()
-rw-r--r-- | kvm.c | 17 | ||||
-rw-r--r-- | kvm_host.h | 25 | ||||
-rw-r--r-- | kvm_vmx.c | 9 |
3 files changed, 50 insertions, 1 deletions
@@ -421,6 +421,19 @@ kvm_fire_urn(struct kvm_vcpu *vcpu) vcpu->urn->on_user_return(vcpu, vcpu->urn); } +void +kvm_ringbuf_record(kvm_ringbuf_t *ringbuf, uint32_t tag, uint64_t payload) +{ + kvm_ringbuf_entry_t *ent = &ringbuf->kvmr_buf[ringbuf->kvmr_ent++ & + (KVM_RINGBUF_NENTRIES - 1)]; + + ent->kvmre_tag = tag; + ent->kvmre_cpuid = curthread->t_cpu->cpu_id; + ent->kvmre_thread = (uintptr_t)curthread; + ent->kvmre_tsc = gethrtime_unscaled(); + ent->kvmre_payload = payload; +} + /* * Called when we've been asked to save our context. i.e. we're being swapped * out. @@ -429,6 +442,8 @@ void kvm_ctx_save(void *arg) { struct kvm_vcpu *vcpu = arg; + kvm_ringbuf_record(&vcpu->kvcpu_ringbuf, + KVM_RINGBUF_TAG_CTXSAVE, vcpu->cpu); kvm_arch_vcpu_put(vcpu); kvm_fire_urn(vcpu); } @@ -444,6 +459,8 @@ kvm_ctx_restore(void *arg) cpu = CPU->cpu_seqid; struct kvm_vcpu *vcpu = arg; + kvm_ringbuf_record(&vcpu->kvcpu_ringbuf, + KVM_RINGBUF_TAG_CTXRESTORE, vcpu->cpu); kvm_arch_vcpu_load(vcpu, cpu); } @@ -100,6 +100,29 @@ extern int kvm_io_bus_unregister_dev(struct kvm *, enum kvm_bus, #define KVM_MAX_IRQ_ROUTES 1024 +#define KVM_RINGBUF_NENTRIES 512 + +#define KVM_RINGBUF_TAG_CTXSAVE 1 +#define KVM_RINGBUF_TAG_CTXRESTORE 2 +#define KVM_RINGBUF_TAG_VMPTRLD 3 +#define KVM_RINGBUF_TAG_VCPUMIGRATE 4 +#define KVM_RINGBUF_TAG_VCPUCLEAR 5 + +typedef struct kvm_ringbuf_entry { + uint32_t kvmre_tag; /* tag for this entry */ + uint32_t kvmre_cpuid; /* CPU of entry */ + uint64_t kvmre_thread; /* thread for entry */ + uint64_t kvmre_tsc; /* TSC at time of entry */ + uint64_t kvmre_payload; /* payload for this entry */ +} kvm_ringbuf_entry_t; + +typedef struct kvm_ringbuf { + kvm_ringbuf_entry_t kvmr_buf[KVM_RINGBUF_NENTRIES]; /* ring buffer */ + uint32_t kvmr_ent; /* current entry */ +} kvm_ringbuf_t; + +extern void kvm_ringbuf_record(kvm_ringbuf_t *, uint32_t, uint64_t); + typedef struct kvm_vcpu { struct kvm *kvm; int vcpu_id; @@ -117,7 +140,7 @@ typedef struct kvm_vcpu { kcondvar_t kvcpu_kick_cv; kvm_vcpu_stats_t kvcpu_stats; kstat_t *kvcpu_kstat; - + kvm_ringbuf_t kvcpu_ringbuf; int sigset_active; sigset_t sigset; int mmio_needed; @@ -497,6 +497,9 @@ __vcpu_clear(void *arg) vmx->vmcs->revision_id = vmcs_config.revision_id; + kvm_ringbuf_record(&vmx->vcpu.kvcpu_ringbuf, + KVM_RINGBUF_TAG_VCPUCLEAR, vmx->vcpu.cpu); + if (vmx->vcpu.cpu == cpu) vmcs_clear(vmx->vmcs_pa); @@ -840,6 +843,9 @@ vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) if (current_vmcs[cpu] != vmx->vmcs) { uint8_t error; + kvm_ringbuf_record(&vcpu->kvcpu_ringbuf, + KVM_RINGBUF_TAG_VMPTRLD, (uint64_t)current_vmcs[cpu]); + current_vmcs[cpu] = vmx->vmcs; KVM_TRACE1(vmx__vmptrld, uint64_t, phys_addr); @@ -854,6 +860,9 @@ vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu) struct descriptor_table dt; unsigned long sysenter_esp; + kvm_ringbuf_record(&vcpu->kvcpu_ringbuf, + KVM_RINGBUF_TAG_VCPUMIGRATE, vcpu->cpu); + vcpu->cpu = cpu; /* |