@@ -1481,7 +1481,7 @@ int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info)
break;
}
}
- } else if (kvm_find_sw_breakpoint(arch_info->pc))
+ } else if (kvm_find_sw_breakpoint(cpu_single_env, arch_info->pc))
handle = 1;
if (!handle)
@@ -1504,7 +1504,7 @@ void kvm_arch_update_guest_debug(CPUState *env, struct kvm_guest_debug *dbg)
};
int n;
- if (!TAILQ_EMPTY(&kvm_sw_breakpoints))
+ if (kvm_sw_breakpoints_active(env))
dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
if (nb_hw_breakpoint > 0) {
@@ -459,6 +459,10 @@ int kvm_init(int smp_cpus)
kvm_context->no_irqchip_creation = 0;
kvm_context->no_pit_creation = 0;
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+ TAILQ_INIT(&kvm_state->kvm_sw_breakpoints);
+#endif
+
gsi_count = kvm_get_gsi_count(kvm_context);
if (gsi_count > 0) {
int gsi_bits, i;
@@ -2419,14 +2423,13 @@ int kvm_qemu_init_env(CPUState *cenv)
}
#ifdef KVM_CAP_SET_GUEST_DEBUG
-struct kvm_sw_breakpoint_head kvm_sw_breakpoints =
- TAILQ_HEAD_INITIALIZER(kvm_sw_breakpoints);
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(target_ulong pc)
+struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env,
+ target_ulong pc)
{
struct kvm_sw_breakpoint *bp;
- TAILQ_FOREACH(bp, &kvm_sw_breakpoints, entry) {
+ TAILQ_FOREACH(bp, &env->kvm_state->kvm_sw_breakpoints, entry) {
if (bp->pc == pc)
return bp;
}
@@ -2461,6 +2464,11 @@ int kvm_update_guest_debug(CPUState *env, unsigned long reinject_trap)
return data.err;
}
+int kvm_sw_breakpoints_active(CPUState *env)
+{
+ return !TAILQ_EMPTY(&env->kvm_state->kvm_sw_breakpoints);
+}
+
int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
target_ulong len, int type)
{
@@ -2469,7 +2477,7 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
int err;
if (type == GDB_BREAKPOINT_SW) {
- bp = kvm_find_sw_breakpoint(addr);
+ bp = kvm_find_sw_breakpoint(current_env, addr);
if (bp) {
bp->use_count++;
return 0;
@@ -2487,7 +2495,8 @@ int kvm_insert_breakpoint(CPUState *current_env, target_ulong addr,
return err;
}
- TAILQ_INSERT_HEAD(&kvm_sw_breakpoints, bp, entry);
+ TAILQ_INSERT_HEAD(¤t_env->kvm_state->kvm_sw_breakpoints,
+ bp, entry);
} else {
err = kvm_arch_insert_hw_breakpoint(addr, len, type);
if (err)
@@ -2510,7 +2519,7 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
int err;
if (type == GDB_BREAKPOINT_SW) {
- bp = kvm_find_sw_breakpoint(addr);
+ bp = kvm_find_sw_breakpoint(current_env, addr);
if (!bp)
return -ENOENT;
@@ -2523,7 +2532,7 @@ int kvm_remove_breakpoint(CPUState *current_env, target_ulong addr,
if (err)
return err;
- TAILQ_REMOVE(&kvm_sw_breakpoints, bp, entry);
+ TAILQ_REMOVE(¤t_env->kvm_state->kvm_sw_breakpoints, bp, entry);
qemu_free(bp);
} else {
err = kvm_arch_remove_hw_breakpoint(addr, len, type);
@@ -2544,7 +2553,7 @@ void kvm_remove_all_breakpoints(CPUState *current_env)
struct kvm_sw_breakpoint *bp, *next;
CPUState *env;
- TAILQ_FOREACH_SAFE(bp, &kvm_sw_breakpoints, entry, next) {
+ TAILQ_FOREACH_SAFE(bp, ¤t_env->kvm_state->kvm_sw_breakpoints, entry, next) {
if (kvm_arch_remove_sw_breakpoint(current_env, bp) != 0) {
/* Try harder to find a CPU that currently sees the breakpoint. */
for (env = first_cpu; env != NULL; env = env->next_cpu) {
@@ -971,12 +971,12 @@ struct kvm_sw_breakpoint {
int use_count;
TAILQ_ENTRY(kvm_sw_breakpoint) entry;
};
-TAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint);
-extern struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
+TAILQ_HEAD(kvm_sw_breakpoint_head, kvm_sw_breakpoint);
int kvm_arch_debug(struct kvm_debug_exit_arch *arch_info);
-struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(target_ulong pc);
+int kvm_sw_breakpoints_active(CPUState *env);
+struct kvm_sw_breakpoint *kvm_find_sw_breakpoint(CPUState *env, target_ulong pc);
int kvm_arch_insert_sw_breakpoint(CPUState *current_env,
struct kvm_sw_breakpoint *bp);
int kvm_arch_remove_sw_breakpoint(CPUState *current_env,
@@ -1133,6 +1133,9 @@ typedef struct KVMState
int coalesced_mmio;
int broken_set_mem_region;
int migration_log;
+#ifdef KVM_CAP_SET_GUEST_DEBUG
+ struct kvm_sw_breakpoint_head kvm_sw_breakpoints;
+#endif
struct kvm_context kvm_context;
} KVMState;
Signed-off-by: Glauber Costa <glommer@redhat.com> --- qemu-kvm-x86.c | 4 ++-- qemu-kvm.c | 27 ++++++++++++++++++--------- qemu-kvm.h | 9 ++++++--- 3 files changed, 26 insertions(+), 14 deletions(-)