Commit 0533f08413 for qemu.org
commit 0533f0841378ae17b96169a2ddafe8b1b010b09b
Author: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Date: Fri Jul 3 15:06:57 2026 +0200
accel: Remove AccelOpsClass::supports_guest_debug
Now accelerators hold the 'guest debug supported' information
in their state, accessible by the common code. No need to call
a per-accelerator handler, simply check for the SSTEP_ENABLE
in AccelGdbConfig::sstep_flags.
Remove all AccelOpsClass::supports_guest_debug implementations,
inline gdb_supports_guest_debug() and remove the now unnecessary
KVMState::have_guest_debug field.
Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20260705215729.62196-18-philmd@oss.qualcomm.com>
diff --git a/accel/accel-common.c b/accel/accel-common.c
index f31d68a9b7..00a400243f 100644
--- a/accel/accel-common.c
+++ b/accel/accel-common.c
@@ -70,6 +70,11 @@ void accel_init_interfaces(AccelClass *ac)
accel_init_cpu_interfaces(ac);
}
+bool accel_supports_guest_debug(AccelState *accel)
+{
+ return accel->gdbstub.sstep_flags & SSTEP_ENABLE;
+}
+
void accel_cpu_instance_init(CPUState *cpu)
{
if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) {
diff --git a/accel/hvf/hvf-accel-ops.c b/accel/hvf/hvf-accel-ops.c
index dd2b45b7cb..ecc0cd1b55 100644
--- a/accel/hvf/hvf-accel-ops.c
+++ b/accel/hvf/hvf-accel-ops.c
@@ -369,7 +369,6 @@ static void hvf_accel_ops_class_init(ObjectClass *oc, const void *data)
ops->remove_breakpoint = hvf_remove_breakpoint;
ops->remove_all_breakpoints = hvf_remove_all_breakpoints;
ops->update_guest_debug = hvf_update_guest_debug;
- ops->supports_guest_debug = hvf_arch_supports_guest_debug;
ops->get_vcpu_stats = hvf_get_vcpu_stats;
};
diff --git a/accel/kvm/kvm-accel-ops.c b/accel/kvm/kvm-accel-ops.c
index d7967bc922..4533032790 100644
--- a/accel/kvm/kvm-accel-ops.c
+++ b/accel/kvm/kvm-accel-ops.c
@@ -105,7 +105,6 @@ static void kvm_accel_ops_class_init(ObjectClass *oc, const void *data)
ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm;
ops->handle_interrupt = generic_handle_interrupt;
- ops->supports_guest_debug = kvm_supports_guest_debug;
#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
ops->update_guest_debug = kvm_update_guest_debug_ops;
ops->insert_breakpoint = kvm_insert_breakpoint;
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index ceb0b33abd..b03488ebac 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -3036,10 +3036,7 @@ static int kvm_init(AccelState *as, MachineState *ms)
(kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES) > 0);
#ifdef TARGET_KVM_HAVE_GUEST_DEBUG
- s->have_guest_debug =
- (kvm_check_extension(s, KVM_CAP_SET_GUEST_DEBUG) > 0);
-
- if (s->have_guest_debug) {
+ if (kvm_check_extension(s, KVM_CAP_SET_GUEST_DEBUG) > 0) {
as->gdbstub.sstep_flags = SSTEP_ENABLE;
int guest_debug_flags =
@@ -3829,14 +3826,6 @@ int kvm_update_guest_debug(CPUState *cpu, unsigned long reinject_trap)
return data.err;
}
-bool kvm_supports_guest_debug(void)
-{
- KVMState *s = KVM_STATE(as);
-
- /* probed during kvm_init() */
- return s->have_guest_debug;
-}
-
int kvm_insert_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len)
{
struct kvm_sw_breakpoint *bp;
diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index 688511151c..3185659562 100644
--- a/accel/kvm/kvm-cpus.h
+++ b/accel/kvm/kvm-cpus.h
@@ -16,7 +16,6 @@ void kvm_destroy_vcpu(CPUState *cpu);
void kvm_cpu_synchronize_post_reset(CPUState *cpu);
void kvm_cpu_synchronize_post_init(CPUState *cpu);
void kvm_cpu_synchronize_pre_loadvm(CPUState *cpu);
-bool kvm_supports_guest_debug(void);
int kvm_insert_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len);
int kvm_remove_breakpoint(CPUState *cpu, int type, vaddr addr, vaddr len);
void kvm_remove_all_breakpoints(CPUState *cpu);
diff --git a/accel/tcg/tcg-accel-ops.c b/accel/tcg/tcg-accel-ops.c
index c179cd4ade..927af6c1db 100644
--- a/accel/tcg/tcg-accel-ops.c
+++ b/accel/tcg/tcg-accel-ops.c
@@ -109,11 +109,6 @@ void tcg_handle_interrupt(CPUState *cpu, int mask)
}
}
-static bool tcg_supports_guest_debug(void)
-{
- return true;
-}
-
/* Translate GDB watchpoint type to a flags value for cpu_watchpoint_* */
static inline int xlat_gdb_type(CPUState *cpu, int gdbtype)
{
@@ -221,7 +216,6 @@ static void tcg_accel_ops_init(AccelClass *ac)
}
ops->cpu_reset_hold = tcg_cpu_reset_hold;
- ops->supports_guest_debug = tcg_supports_guest_debug;
ops->insert_breakpoint = tcg_insert_breakpoint;
ops->remove_breakpoint = tcg_remove_breakpoint;
ops->remove_all_breakpoints = tcg_remove_all_breakpoints;
diff --git a/accel/whpx/whpx-accel-ops.c b/accel/whpx/whpx-accel-ops.c
index b8f41544cb..ca5a119521 100644
--- a/accel/whpx/whpx-accel-ops.c
+++ b/accel/whpx/whpx-accel-ops.c
@@ -82,11 +82,6 @@ static bool whpx_vcpu_thread_is_idle(CPUState *cpu)
return !whpx_irqchip_in_kernel();
}
-static bool whpx_supports_guest_debug(void)
-{
- return whpx_arch_supports_guest_debug();
-}
-
static void whpx_accel_ops_class_init(ObjectClass *oc, const void *data)
{
@@ -96,7 +91,6 @@ static void whpx_accel_ops_class_init(ObjectClass *oc, const void *data)
ops->kick_vcpu_thread = whpx_kick_vcpu_thread;
ops->cpu_thread_is_idle = whpx_vcpu_thread_is_idle;
ops->handle_interrupt = generic_handle_interrupt;
- ops->supports_guest_debug = whpx_supports_guest_debug;
ops->synchronize_post_reset = whpx_cpu_synchronize_post_reset;
ops->synchronize_post_init = whpx_cpu_synchronize_post_init;
diff --git a/docs/system/gdb.rst b/docs/system/gdb.rst
index d50470b135..b6d8f8e77d 100644
--- a/docs/system/gdb.rst
+++ b/docs/system/gdb.rst
@@ -54,7 +54,7 @@ While GDB can always fall back to inserting breakpoints into memory
accelerator. For TCG system emulation we advertise an infinite number
of hardware assisted breakpoints and watchpoints. For other
accelerators it will depend on if support has been added (see
-supports_guest_debug and related hooks in AccelOpsClass).
+the AccelGdbConfig structure).
As TCG cannot track all memory accesses in user-mode there is no
support for watchpoints.
diff --git a/gdbstub/system.c b/gdbstub/system.c
index 2e8c457097..bf7aa1ac23 100644
--- a/gdbstub/system.c
+++ b/gdbstub/system.c
@@ -331,8 +331,6 @@ static void create_processes(GDBState *s)
gdb_create_default_process(s);
}
-static bool gdb_supports_guest_debug(void);
-
bool gdbserver_start(const char *device, Error **errp)
{
Chardev *chr = NULL;
@@ -345,7 +343,7 @@ bool gdbserver_start(const char *device, Error **errp)
return false;
}
- if (!gdb_supports_guest_debug()) {
+ if (!accel_supports_guest_debug(current_accel())) {
error_setg(errp, "gdbstub: current accelerator doesn't "
"support guest debugging");
return false;
@@ -624,15 +622,6 @@ int gdb_signal_to_target(int sig)
* Break/Watch point helpers
*/
-static bool gdb_supports_guest_debug(void)
-{
- const AccelOpsClass *ops = cpus_get_accel();
- if (ops->supports_guest_debug) {
- return ops->supports_guest_debug();
- }
- return false;
-}
-
int gdb_breakpoint_insert(CPUState *cs, int type, vaddr addr, vaddr len)
{
const AccelOpsClass *ops = cpus_get_accel();
diff --git a/include/accel/accel-cpu-ops.h b/include/accel/accel-cpu-ops.h
index 9c07a903ea..b23a0606c7 100644
--- a/include/accel/accel-cpu-ops.h
+++ b/include/accel/accel-cpu-ops.h
@@ -84,7 +84,6 @@ struct AccelOpsClass {
int64_t (*get_elapsed_ticks)(void);
/* gdbstub hooks */
- bool (*supports_guest_debug)(void);
int (*update_guest_debug)(CPUState *cpu);
int (*insert_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
int (*remove_breakpoint)(CPUState *cpu, int type, vaddr addr, vaddr len);
diff --git a/include/qemu/accel.h b/include/qemu/accel.h
index 8e0c3dfe08..6f65f1cb89 100644
--- a/include/qemu/accel.h
+++ b/include/qemu/accel.h
@@ -84,4 +84,6 @@ typedef struct AccelGdbConfig {
bool can_reverse;
} AccelGdbConfig;
+bool accel_supports_guest_debug(AccelState *accel);
+
#endif /* QEMU_ACCEL_H */
diff --git a/include/system/hvf_int.h b/include/system/hvf_int.h
index 58fb865eba..d64f494255 100644
--- a/include/system/hvf_int.h
+++ b/include/system/hvf_int.h
@@ -104,11 +104,6 @@ void hvf_arch_remove_all_hw_breakpoints(void);
*/
int hvf_update_guest_debug(CPUState *cpu);
-/*
- * Return whether the guest supports debugging.
- */
-bool hvf_arch_supports_guest_debug(void);
-
bool hvf_arch_cpu_realize(CPUState *cpu, Error **errp);
uint32_t hvf_arch_get_default_ipa_bit_size(void);
uint32_t hvf_arch_get_max_ipa_bit_size(void);
diff --git a/include/system/kvm_int.h b/include/system/kvm_int.h
index 53bb0fcf18..0876aac938 100644
--- a/include/system/kvm_int.h
+++ b/include/system/kvm_int.h
@@ -118,7 +118,6 @@ struct KVMState
#endif
int max_nested_state_len;
int kvm_shadow_mem;
- bool have_guest_debug;
bool kernel_irqchip_allowed;
bool kernel_irqchip_required;
OnOffAuto kernel_irqchip_split;
diff --git a/include/system/whpx-all.h b/include/system/whpx-all.h
index 4022571fff..d018e67e4f 100644
--- a/include/system/whpx-all.h
+++ b/include/system/whpx-all.h
@@ -22,7 +22,4 @@ void whpx_translate_cpu_breakpoints(
void whpx_arch_destroy_vcpu(CPUState *cpu);
void whpx_arch_accel_class_init(ObjectClass *oc);
-/* called by whpx-accel-ops */
-bool whpx_arch_supports_guest_debug(void);
-
#endif
diff --git a/target/arm/hvf/hvf.c b/target/arm/hvf/hvf.c
index 8b902c6882..e16457c3cf 100644
--- a/target/arm/hvf/hvf.c
+++ b/target/arm/hvf/hvf.c
@@ -2900,8 +2900,3 @@ void hvf_arch_update_guest_debug(CPUState *cpu)
hvf_arch_set_traps(cpu);
}
-
-bool hvf_arch_supports_guest_debug(void)
-{
- return true;
-}
diff --git a/target/arm/whpx/whpx-all.c b/target/arm/whpx/whpx-all.c
index 3079c6293c..00a5de8cdc 100644
--- a/target/arm/whpx/whpx-all.c
+++ b/target/arm/whpx/whpx-all.c
@@ -295,11 +295,6 @@ void whpx_translate_cpu_breakpoints(
/* Breakpoints aren’t supported on this platform */
}
-bool whpx_arch_supports_guest_debug(void)
-{
- return false;
-}
-
void whpx_arch_destroy_vcpu(CPUState *cpu)
{
/* currently empty on Arm */
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index 2d1a943b96..19ad64a1d9 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -1066,8 +1066,3 @@ void hvf_arch_remove_all_hw_breakpoints(void)
void hvf_arch_update_guest_debug(CPUState *cpu)
{
}
-
-bool hvf_arch_supports_guest_debug(void)
-{
- return false;
-}
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 467ac6bed4..11b5d1fc60 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -1853,11 +1853,6 @@ void whpx_apply_breakpoints(
}
}
-bool whpx_arch_supports_guest_debug(void)
-{
- return true;
-}
-
void whpx_arch_destroy_vcpu(CPUState *cpu)
{
X86CPU *x86cpu = X86_CPU(cpu);