Merge tag 'accel-20260706' of https://github.com/philmd/qemu into staging

Accelerators patches queue

- Various cleanups around debugging APIs
- Correctly check singlestep flag enabled in CPUState
- Fix possible memory corruption with MSHV (CID 1660876)

# -----BEGIN PGP SIGNATURE-----
#
# iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmpLsRwACgkQ4+MsLN6t
# wN7TRRAAhTnAG0VuUat9MYUCuWWSiTrNKm6m2vVcO+Zec/bBbU1+twBSBzVQ/rwm
# kGzImAWip6nYorU5BxTKePlpCy6Rm+t0evYaA5ixF0aXtmm3n6IGIMSsi5yEJxF5
# YHDXxvpD56Z1p8kRvkp4ynABiiF5gfBFqbSuI7/gxSI2tcJ2uSx8MC+HEO/X4vJc
# +Clich5n4eyN7YL7vqGrVl84cqHOwe40bXAm1OOa5S83/y2hc//SHgFqTB8BL1P7
# 9SafbFIFiqbfy4kWV86mSu3LDsSYLoIU7bgpRb9mX9WVrvfuoQeVUf7XH+fjmqIo
# s/2uHN6ha/h12jS1q0nCYu585EzXCuPRF3upSslPaoEd16sFEO6ZiODmaMIsomA2
# SlCM3jGYUUw+vkfS/+SJUF17QEHtv0R8Dp5IfseE9Tp+huYvJuwn3Qh4UwbVRg0P
# YHoRa2KiXvBPntY/GkyhCL9Y5oWC5RaRHyKxMs83tdUouOeBy2t/ftnVtDqeRn3p
# 04W+pilUEodSnzcNfAGxQhkqDeGIOveRubaeNICgmxO0Bp9dMUZIOju84hY77KEw
# hClBI87cOc1REC7YNXkoouWcr8moNSZlKAyIbTf/Ag5cAheYOSvO5UDDVVepudSl
# kER+S1iuPkeb0uVvnvk5Kh4UBCMwdfYKe9bNu/SB0ab6N3IpY4s=
# =knBq
# -----END PGP SIGNATURE-----
# gpg: Signature made Mon 06 Jul 2026 15:43:56 CEST
# gpg:                using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE
# gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [full]
# Primary key fingerprint: FAAB E75E 1291 7221 DCFD  6BB2 E3E3 2C2C DEAD C0DE

* tag 'accel-20260706' of https://github.com/philmd/qemu: (32 commits)
  cpu: Only check SSTEP_ENABLE flag in cpu_single_stepping()
  cpu: Rename CPUState @singlestep_enabled -> @singlestep_flags
  cpu: Introduce cpu_single_stepping() helper
  cpu: Better name cpu_single_step() trace event
  accel/tcg: Improve docstrings around TCGCPUOps::*watchpoint* handlers
  target/ppc: Ensure TCG is used in ppc_update_daw()
  target/arm: Inline check_watchpoints() in arm_debug_check_watchpoint()
  accel: Use GdbBreakpointType enum
  gdbstub: Introduce GdbBreakpointType enumerator
  gdbstub: Reduce @type variable scope
  gdbstub/user: Directly call gdb_breakpoint_remove_all() in user mode
  accel: Remove unnecessary 'inline' qualifier in remove_all_breakpoints
  cpu: Move BREAKPOINT definitions to 'exec/breakpoint.h'
  cpu: Move cpu_breakpoint_test out of line
  accel: Remove AccelOpsClass::supports_guest_debug
  accel: Hold @can_reverse information in AccelGdbConfig
  gdbstub: Make default replay_mode value explicit in stubs
  accel: Have each implementation return their AccelGdbConfig
  gdbstub: Move supported_sstep_flags in AccelGdbConfig structure
  gdbstub: Reduce gdb_supports_guest_debug() scope
  ...

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi
2026-07-06 18:38:14 +02:00
59 changed files with 338 additions and 374 deletions

View File

@@ -13,6 +13,7 @@
#include "qemu/accel.h"
#include "exec/vaddr.h"
#include "qom/object.h"
#include "gdbstub/enums.h"
#define ACCEL_OPS_SUFFIX "-ops"
#define TYPE_ACCEL_OPS "accel" ACCEL_OPS_SUFFIX
@@ -84,11 +85,12 @@ 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);
void (*remove_all_breakpoints)(CPUState *cpu);
int (*insert_gdbstub_breakpoint)(CPUState *cpu, GdbBreakpointType type,
vaddr addr, vaddr len);
int (*remove_gdbstub_breakpoint)(CPUState *cpu, GdbBreakpointType type,
vaddr addr, vaddr len);
void (*remove_all_gdbstub_breakpoints)(CPUState *cpu);
};
void generic_handle_interrupt(CPUState *cpu, int mask);

View File

@@ -13,6 +13,8 @@
struct AccelState {
Object parent_obj;
AccelGdbConfig gdbstub;
};
struct AccelClass {
@@ -36,9 +38,6 @@ struct AccelClass {
bool (*has_memory)(AccelState *accel, AddressSpace *as,
hwaddr start_addr, hwaddr size);
/* gdbstub related hooks */
int (*gdbstub_supported_sstep_flags)(AccelState *as);
bool *allowed;
/*
* Array of global properties that would be applied when specific

View File

@@ -250,14 +250,13 @@ struct TCGCPUOps {
int mmu_idx, uintptr_t retaddr);
/**
* @adjust_watchpoint_address: hack for cpu_check_watchpoint used by ARM
* @adjust_watchpoint_address: hack for cpu_check_watchpoint (used by ARM)
*/
vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
/**
* @debug_check_watchpoint: return true if the architectural
* watchpoint whose address has matched should really fire, used by ARM
* and RISC-V
* watchpoint whose address has matched should really fire.
*/
bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);

View File

@@ -12,6 +12,20 @@
#include "exec/vaddr.h"
#include "exec/memattrs.h"
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ 0x01
#define BP_MEM_WRITE 0x02
#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
#define BP_STOP_BEFORE_ACCESS 0x04
/* 0x08 currently unused */
#define BP_GDB 0x10
#define BP_CPU 0x20
#define BP_ANY (BP_GDB | BP_CPU)
#define BP_HIT_SHIFT 6
#define BP_WATCHPOINT_HIT_READ (BP_MEM_READ << BP_HIT_SHIFT)
#define BP_WATCHPOINT_HIT_WRITE (BP_MEM_WRITE << BP_HIT_SHIFT)
#define BP_WATCHPOINT_HIT (BP_MEM_ACCESS << BP_HIT_SHIFT)
typedef struct CPUBreakpoint {
vaddr pc;
int flags; /* BP_* */

View File

@@ -24,14 +24,10 @@
#include "exec/hwaddr.h"
#include "exec/memattrs.h"
#include "exec/vaddr.h"
#include "system/ram_addr.h"
#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
void tlb_protect_code(ram_addr_t ram_addr);
void tlb_unprotect_code(ram_addr_t ram_addr);
#endif
#ifndef CONFIG_USER_ONLY
#include "system/ram_addr.h"
void tlb_reset_dirty(CPUState *cpu, uintptr_t start, uintptr_t length);
void tlb_reset_dirty_range_all(ram_addr_t start, ram_addr_t length);
#endif

View File

@@ -12,10 +12,12 @@
#define DEFAULT_GDBSTUB_PORT "1234"
/* GDB breakpoint/watchpoint types */
#define GDB_BREAKPOINT_SW 0
#define GDB_BREAKPOINT_HW 1
#define GDB_WATCHPOINT_WRITE 2
#define GDB_WATCHPOINT_READ 3
#define GDB_WATCHPOINT_ACCESS 4
typedef enum GdbBreakpointType {
GDB_BREAKPOINT_SW = 0,
GDB_BREAKPOINT_HW = 1,
GDB_WATCHPOINT_WRITE = 2,
GDB_WATCHPOINT_READ = 3,
GDB_WATCHPOINT_ACCESS = 4,
} GdbBreakpointType;
#endif /* GDBSTUB_ENUMS_H */

View File

@@ -440,7 +440,7 @@ struct qemu_work_item;
* @stopped: Indicates the CPU has been artificially stopped.
* @unplug: Indicates a pending CPU unplug request.
* @crash_occurred: Indicates the OS reported a crash (panic) for this CPU
* @singlestep_enabled: Flags for single-stepping.
* @singlestep_flags: Flags for single-stepping.
* @icount_extra: Instructions until next timer event.
* @cpu_ases: Pointer to array of CPUAddressSpaces (which define the
* AddressSpaces this CPU has)
@@ -480,7 +480,7 @@ struct CPUState {
/*< private >*/
DeviceState parent_obj;
/* cache to avoid expensive CPU_GET_CLASS */
CPUClass *cc;
const CPUClass *cc;
/*< public >*/
int nr_threads;
@@ -505,7 +505,7 @@ struct CPUState {
int exclusive_context_count;
uint32_t cflags_next_tb;
uint32_t interrupt_request;
int singlestep_enabled;
unsigned singlestep_flags;
int64_t icount_budget;
int64_t icount_extra;
uint64_t random_seed;
@@ -1132,46 +1132,29 @@ void qemu_init_vcpu(CPUState *cpu);
/**
* cpu_single_step:
* @cpu: CPU to the flags for.
* @enabled: Flags to enable.
* @flags: Flags to enable.
*
* Enables or disables single-stepping for @cpu.
*/
void cpu_single_step(CPUState *cpu, int enabled);
void cpu_single_step(CPUState *cpu, unsigned flags);
/* Breakpoint/watchpoint flags */
#define BP_MEM_READ 0x01
#define BP_MEM_WRITE 0x02
#define BP_MEM_ACCESS (BP_MEM_READ | BP_MEM_WRITE)
#define BP_STOP_BEFORE_ACCESS 0x04
/* 0x08 currently unused */
#define BP_GDB 0x10
#define BP_CPU 0x20
#define BP_ANY (BP_GDB | BP_CPU)
#define BP_HIT_SHIFT 6
#define BP_WATCHPOINT_HIT_READ (BP_MEM_READ << BP_HIT_SHIFT)
#define BP_WATCHPOINT_HIT_WRITE (BP_MEM_WRITE << BP_HIT_SHIFT)
#define BP_WATCHPOINT_HIT (BP_MEM_ACCESS << BP_HIT_SHIFT)
/**
* cpu_single_stepping:
* @cpu: The vCPU to check
*
* Returns whether the vCPU has single-stepping enabled.
*/
static inline bool cpu_single_stepping(const CPUState *cpu)
{
return cpu->singlestep_flags & SSTEP_ENABLE;
}
int cpu_breakpoint_insert(CPUState *cpu, vaddr pc, int flags,
CPUBreakpoint **breakpoint);
int cpu_breakpoint_remove(CPUState *cpu, vaddr pc, int flags);
void cpu_breakpoint_remove_by_ref(CPUState *cpu, CPUBreakpoint *breakpoint);
void cpu_breakpoint_remove_all(CPUState *cpu, int mask);
/* Return true if PC matches an installed breakpoint. */
static inline bool cpu_breakpoint_test(CPUState *cpu, vaddr pc, int mask)
{
CPUBreakpoint *bp;
if (unlikely(!QTAILQ_EMPTY(&cpu->breakpoints))) {
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
if (bp->pc == pc && (bp->flags & mask)) {
return true;
}
}
}
return false;
}
bool cpu_breakpoint_test(CPUState *cpu, vaddr pc, int mask);
/**
* cpu_get_address_space:

View File

@@ -74,11 +74,16 @@ bool accel_cpu_common_realize(CPUState *cpu, Error **errp);
void accel_cpu_common_unrealize(CPUState *cpu);
/**
* accel_supported_gdbstub_sstep_flags:
* struct AccelGdbConfig - gdbstub configuration for an accelerator.
*
* Returns the supported single step modes for the configured
* accelerator.
* @sstep_flags: Set SSTEP_* flags that accelerator supports for guest debug.
* @can_reverse: Whether reverse mode is supported.
*/
int accel_supported_gdbstub_sstep_flags(void);
typedef struct AccelGdbConfig {
unsigned sstep_flags;
bool can_reverse;
} AccelGdbConfig;
bool accel_supports_guest_debug(AccelState *accel);
#endif /* QEMU_ACCEL_H */

View File

@@ -13,6 +13,7 @@
#include "qemu/queue.h"
#include "exec/vaddr.h"
#include "gdbstub/enums.h"
#include "qom/object.h"
#include "accel/accel-ops.h"
@@ -91,9 +92,11 @@ int hvf_sw_breakpoints_active(CPUState *cpu);
int hvf_arch_insert_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp);
int hvf_arch_remove_sw_breakpoint(CPUState *cpu, struct hvf_sw_breakpoint *bp);
int hvf_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type);
int hvf_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type);
void hvf_arch_remove_all_hw_breakpoints(void);
int hvf_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
GdbBreakpointType type);
int hvf_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
GdbBreakpointType type);
void hvf_arch_remove_all_gdbstub_hw_breakpoints(void);
/*
* hvf_update_guest_debug:
@@ -104,11 +107,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);

View File

@@ -17,6 +17,7 @@
#define QEMU_KVM_H
#include "exec/memattrs.h"
#include "gdbstub/enums.h"
#include "qemu/accel.h"
#include "accel/accel-route.h"
#include "qom/object.h"
@@ -412,9 +413,11 @@ int kvm_arch_insert_sw_breakpoint(CPUState *cpu,
struct kvm_sw_breakpoint *bp);
int kvm_arch_remove_sw_breakpoint(CPUState *cpu,
struct kvm_sw_breakpoint *bp);
int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type);
int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type);
void kvm_arch_remove_all_hw_breakpoints(void);
int kvm_arch_insert_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
GdbBreakpointType type);
int kvm_arch_remove_gdbstub_hw_breakpoint(vaddr addr, vaddr len,
GdbBreakpointType type);
void kvm_arch_remove_all_gdbstub_hw_breakpoints(void);
void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg);

View File

@@ -43,7 +43,6 @@ typedef struct MshvHvCallArgs {
struct AccelCPUState {
int cpufd;
bool dirty;
MshvHvCallArgs hvcall_args;
};

View File

@@ -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