[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v4 01/10] qemu-kvm: Add KVM_CAP_X86_ROBUST_SINGLESTE
From: |
Jan Kiszka |
Subject: |
[Qemu-devel] [PATCH v4 01/10] qemu-kvm: Add KVM_CAP_X86_ROBUST_SINGLESTEP-awareness |
Date: |
Mon, 1 Mar 2010 18:17:20 +0100 |
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 <address@hidden>
---
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(-)
diff --git a/kvm-all.c b/kvm-all.c
index d1542e3..06708a5 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -65,6 +65,7 @@ struct KVMState
int 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;
@@ -933,6 +940,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()) {
diff --git a/kvm.h b/kvm.h
index 1b498d7..888dfcb 100644
--- a/kvm.h
+++ b/kvm.h
@@ -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);
diff --git a/qemu-kvm-x86.c b/qemu-kvm-x86.c
index 5af9ce1..5db95f8 100644
--- a/qemu-kvm-x86.c
+++ b/qemu-kvm-x86.c
@@ -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)
diff --git a/qemu-kvm.h b/qemu-kvm.h
index ecb52c1..ed00665 100644
--- a/qemu-kvm.h
+++ b/qemu-kvm.h
@@ -1012,6 +1012,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
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 4e1358c..dd636f1 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -861,6 +861,37 @@ int kvm_get_vcpu_events(CPUState *env)
return 0;
}
+static int kvm_guest_debug_workarounds(CPUState *env)
+{
+ int ret = 0;
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+ unsigned long reinject_trap = 0;
+
+ if (!kvm_has_vcpu_events()) {
+ 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;
+ }
+
+ /*
+ * Kernels before KVM_CAP_X86_ROBUST_SINGLESTEP 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 (reinject_trap ||
+ (!kvm_has_robust_singlestep() && env->singlestep_enabled)) {
+ ret = kvm_update_guest_debug(env, reinject_trap);
+ }
+#endif /* KVM_CAP_SET_GUEST_DEBUG */
+ return ret;
+}
+
#ifdef KVM_UPSTREAM
int kvm_arch_put_registers(CPUState *env)
{
@@ -890,31 +921,10 @@ int kvm_arch_put_registers(CPUState *env)
if (ret < 0)
return ret;
- /*
- * 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;
-
- ret = kvm_update_guest_debug(env, reinject_trap);
- if (ret < 0) {
- return ret;
- }
- }
+ /* must be last */
+ ret = kvm_guest_debug_workarounds(env);
+ if (ret < 0)
+ return ret;
return 0;
}
--
1.6.0.2
- [Qemu-devel] [PATCH v4 00/10] qemu-kvm: Hook cleanups and yet more use of upstream code, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 09/10] qemu-kvm: Move kvm_set_boot_cpu_id, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 05/10] KVM: x86: Restrict writeback of VCPU state, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 04/10] qemu-kvm: Clean up mpstate synchronization, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 08/10] qemu-kvm: Clean up KVM's APIC hooks, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 02/10] qemu-kvm: Rework VCPU state writeback API, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 06/10] qemu-kvm: Use VCPU event state for reset and vmsave/load, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 01/10] qemu-kvm: Add KVM_CAP_X86_ROBUST_SINGLESTEP-awareness,
Jan Kiszka <=
- [Qemu-devel] [PATCH v4 07/10] qemu-kvm: Cleanup/fix TSC and PV clock writeback, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 10/10] qemu-kvm: Bring qemu_init_vcpu back home, Jan Kiszka, 2010/03/01
- [Qemu-devel] [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Jan Kiszka, 2010/03/01
- [Qemu-devel] Re: [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Gleb Natapov, 2010/03/03
- [Qemu-devel] Re: [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Jan Kiszka, 2010/03/03
- [Qemu-devel] Re: [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Gleb Natapov, 2010/03/04
- [Qemu-devel] Re: [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Jan Kiszka, 2010/03/04
- [Qemu-devel] Re: [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Gleb Natapov, 2010/03/04
- [Qemu-devel] Re: [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Jan Kiszka, 2010/03/04
- [Qemu-devel] Re: [PATCH v4 03/10] x86: Extend validity of cpu_is_bsp, Gleb Natapov, 2010/03/04