qemu-kvm: Add KVM_CAP_X86_ROBUST_SINGLESTEP-awareness
PATCH 1/1 qemu-kvm: Add KVM_CAP_X86_ROBUST_SINGLESTEP-awareness
This add-on patch to recent guest debugging refactorings adds the requested awareness for KVM_CAP_X86_ROBUST_SINGLESTEP to both the upstream as well as qemu-kvm's own code. Fortunately, code sharing increased once again.
Signed-off-by Jan Kiszka <[email protected]>
---
Note: Due to missing VCPU events synchronization during runtime in qemu-kvm, exception re-injection is unfortunately now broken (I missed a circular dependency in my series). However, the remaining VCPU state refactoring bits will be posted soon, and they will fix it again. Upstream code is not affected.
kvm-all.c | 12 +++++++++++ kvm.h | 1 + qemu-kvm-x86.c | 27 ++---------------------- qemu-kvm.h | 1 + target-i386/kvm.c | 60 +++++++++++++++++++++++++++++++---------------------- 5 files changed, 51 insertions(+), 50 deletions(-)
kvm-all.c +12 -0
@@ -65,6 +65,7 @@ struct KVMStateint broken_set_mem_region;int migration_log;int vcpu_events; +int robust_singlestep;#ifdef KVM_CAP_SET_GUEST_DEBUG struct kvm_sw_breakpoint_head kvm_sw_breakpoints;#endif
@@ -673,6 +674,12 @@ int kvm_init(int smp_cpus) s->vcpu_events =kvm_check_extension (s,KVM_CAP_VCPU_EVENTS );#endif + s->robust_singlestep =0 ; +#ifdef KVM_CAP_X86_ROBUST_SINGLESTEP + s->robust_singlestep = +kvm_check_extension (s,KVM_CAP_X86_ROBUST_SINGLESTEP ); +#endif + ret =kvm_arch_init (s, smp_cpus);if (ret <0 ) goto err;
@@ -932,6 +939,11 @@ int kvm_has_vcpu_events(void)return kvm_state->vcpu_events; } +int kvm_has_robust_singlestep (void ) +{ +return kvm_state->robust_singlestep; +} +void kvm_setup_guest_memory (void *start,size_t size) {if (!kvm_has_sync_mmu ()) {
kvm.h +1 -0
@@ -43,6 +43,7 @@ int kvm_log_stop(target_phys_addr_t phys_addr, ram_addr_t size);int kvm_has_sync_mmu (void );int kvm_has_vcpu_events (void ); +int kvm_has_robust_singlestep (void );int kvm_put_vcpu_events (CPUState *env);int kvm_get_vcpu_events (CPUState *env);
qemu-kvm-x86.c +2 -25
@@ -922,31 +922,8 @@ void kvm_arch_load_regs(CPUState *env)if (rc ==-1 )perror ("kvm_set_msrs FAILED" ); -/* -* Kernels before 2.6.33 (which correlates with !kvm_has_vcpu_events()) -* overwrote flags.TF injected via SET_GUEST_DEBUG while updating GP regs. -* Work around this by updating the debug state once again if -* single-stepping is on. -* Another reason to call kvm_update_guest_debug here is a pending debug -* trap raise by the guest. On kernels without SET_VCPU_EVENTS we have to -* reinject them via SET_GUEST_DEBUG. -*/ -if (!kvm_has_vcpu_events () && - (env->exception_injected !=-1 || env->singlestep_enabled)) { -unsigned long reinject_trap =0 ; - -if (env->exception_injected ==1 ) { - reinject_trap =KVM_GUESTDBG_INJECT_DB ; - }else if (env->exception_injected ==3 ) { - reinject_trap =KVM_GUESTDBG_INJECT_BP ; - } - env->exception_injected =-1 ; - - rc =kvm_update_guest_debug (env, reinject_trap); -if (rc <0 ) { -perror ("kvm_update_guest_debug FAILED" ); - } - } +/* must be last */ +kvm_guest_debug_workarounds (env); }void kvm_load_tsc (CPUState *env)
qemu-kvm.h +1 -0
@@ -1027,6 +1027,7 @@ struct KVMState {int broken_set_mem_region;int migration_log;int vcpu_events; +int robust_singlestep;#ifdef KVM_CAP_SET_GUEST_DEBUG QTAILQ_HEAD(, kvm_sw_breakpoint) kvm_sw_breakpoints;#endif
target-i386/kvm.c +35 -25
72 lines not on this page · raw message