@@ -43,6 +43,10 @@ typedef struct AccelClass {
bool (*has_memory)(MachineState *ms, AddressSpace *as,
hwaddr start_addr, hwaddr size);
#endif
+
+ /* gdbstub related hooks */
+ int (*gdbstub_supported_sstep_flags)(void);
+
bool *allowed;
/*
* Array of global properties that would be applied when specific
@@ -92,4 +96,12 @@ void accel_cpu_instance_init(CPUState *cpu);
*/
bool accel_cpu_realizefn(CPUState *cpu, Error **errp);
+/**
+ * accel_supported_gdbstub_sstep_flags:
+ *
+ * Returns the supported single step modes for the configured
+ * accelerator.
+ */
+int accel_supported_gdbstub_sstep_flags(void);
+
#endif /* QEMU_ACCEL_H */
@@ -47,7 +47,6 @@ extern bool kvm_direct_msi_allowed;
extern bool kvm_ioeventfd_any_length_allowed;
extern bool kvm_msi_use_devid;
extern bool kvm_has_guest_debug;
-extern int kvm_sstep_flags;
#define kvm_enabled() (kvm_allowed)
/**
@@ -174,12 +173,6 @@ extern int kvm_sstep_flags;
*/
#define kvm_supports_guest_debug() (kvm_has_guest_debug)
-/*
- * kvm_supported_sstep_flags
- * Returns: SSTEP_* flags that KVM supports for guest debug
- */
-#define kvm_get_supported_sstep_flags() (kvm_sstep_flags)
-
#else
#define kvm_enabled() (0)
@@ -198,7 +191,6 @@ extern int kvm_sstep_flags;
#define kvm_ioeventfd_any_length_enabled() (false)
#define kvm_msi_devid_required() (false)
#define kvm_supports_guest_debug() (false)
-#define kvm_get_supported_sstep_flags() (0)
#endif /* CONFIG_KVM_IS_POSSIBLE */
@@ -129,6 +129,16 @@ bool accel_cpu_realizefn(CPUState *cpu, Error **errp)
return true;
}
+int accel_supported_gdbstub_sstep_flags(void)
+{
+ AccelState *accel = current_accel();
+ AccelClass *acc = ACCEL_GET_CLASS(accel);
+ if (acc->gdbstub_supported_sstep_flags) {
+ return acc->gdbstub_supported_sstep_flags();
+ }
+ return 0;
+}
+
static const TypeInfo accel_cpu_type = {
.name = TYPE_ACCEL_CPU,
.parent = TYPE_OBJECT,
@@ -175,7 +175,7 @@ bool kvm_direct_msi_allowed;
bool kvm_ioeventfd_any_length_allowed;
bool kvm_msi_use_devid;
bool kvm_has_guest_debug;
-int kvm_sstep_flags;
+static int kvm_sstep_flags;
static bool kvm_immediate_exit;
static hwaddr kvm_max_slot_size = ~0;
@@ -3712,6 +3712,17 @@ static void kvm_accel_instance_init(Object *obj)
s->kvm_dirty_ring_size = 0;
}
+/**
+ * kvm_gdbstub_sstep_flags():
+ *
+ * Returns: SSTEP_* flags that KVM supports for guest debug. The
+ * support is probed during kvm_init()
+ */
+static int kvm_gdbstub_sstep_flags(void)
+{
+ return kvm_sstep_flags;
+}
+
static void kvm_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
@@ -3719,6 +3730,7 @@ static void kvm_accel_class_init(ObjectClass *oc, void *data)
ac->init_machine = kvm_init;
ac->has_memory = kvm_accel_has_memory;
ac->allowed = &kvm_allowed;
+ ac->gdbstub_supported_sstep_flags = kvm_gdbstub_sstep_flags;
object_class_property_add(oc, "kernel-irqchip", "on|off|split",
NULL, kvm_set_kernel_irqchip,
@@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "sysemu/tcg.h"
+#include "sysemu/replay.h"
#include "sysemu/cpu-timers.h"
#include "tcg/tcg.h"
#include "qapi/error.h"
@@ -207,12 +208,28 @@ static void tcg_set_splitwx(Object *obj, bool value, Error **errp)
s->splitwx_enabled = value;
}
+static int tcg_gdbstub_supported_sstep_flags(void)
+{
+ /*
+ * In replay mode all events will come from the log and can't be
+ * suppressed otherwise we would break determinism. However as those
+ * events are tied to the number of executed instructions we won't see
+ * them occurring every time we single step.
+ */
+ if (replay_mode != REPLAY_MODE_NONE) {
+ return SSTEP_ENABLE;
+ } else {
+ return SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
+ }
+}
+
static void tcg_accel_class_init(ObjectClass *oc, void *data)
{
AccelClass *ac = ACCEL_CLASS(oc);
ac->name = "tcg";
ac->init_machine = tcg_init_machine;
ac->allowed = &tcg_allowed;
+ ac->gdbstub_supported_sstep_flags = tcg_gdbstub_supported_sstep_flags;
object_class_property_add_str(oc, "thread",
tcg_get_thread,
@@ -383,27 +383,13 @@ static void init_gdbserver_state(void)
gdbserver_state.last_packet = g_byte_array_sized_new(MAX_PACKET_LENGTH + 4);
/*
- * In replay mode all events will come from the log and can't be
- * suppressed otherwise we would break determinism. However as those
- * events are tied to the number of executed instructions we won't see
- * them occurring every time we single step.
- */
- if (replay_mode != REPLAY_MODE_NONE) {
- gdbserver_state.supported_sstep_flags = SSTEP_ENABLE;
- } else if (kvm_enabled()) {
- gdbserver_state.supported_sstep_flags = kvm_get_supported_sstep_flags();
- } else {
- gdbserver_state.supported_sstep_flags =
- SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
- }
-
- /*
- * By default use no IRQs and no timers while single stepping so as to
- * make single stepping like an ICE HW step.
+ * What single-step modes are supported is accelerator dependent.
+ * By default try to use no IRQs and no timers while single
+ * stepping so as to make single stepping like a typical ICE HW step.
*/
+ gdbserver_state.supported_sstep_flags = accel_supported_gdbstub_sstep_flags();
gdbserver_state.sstep_flags = SSTEP_ENABLE | SSTEP_NOIRQ | SSTEP_NOTIMER;
gdbserver_state.sstep_flags &= gdbserver_state.supported_sstep_flags;
-
}
#ifndef CONFIG_USER_ONLY