Accelerators patches

- Unify x86/arm hw/xen/arch_hvm.h header
 - Move non-system-specific 'accel/accel-ops.h' and 'accel-cpu-ops.h' to accel/
 - Move KVM definitions qapi/accelerator.json
 - Add @qom-type field to CpuInfoFast QAPI structure
 - Display CPU model name in 'info cpus' HMP command
 - Introduce @x-accel-stats QMP command
 - Add 'info accel' on HMP
 - Improve qemu_add_vm_change_state_handler*() docstring
 - Extract TCG statistic related code to tcg-stats.c
 - Implement AccelClass::get_[vcpu]_stats() handlers for TCG and HVF
 - Do not dump NaN in TCG statistics
 - Revert incomplete "accel/tcg: Unregister the RCU before exiting RR thread"
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmh2r4UACgkQ4+MsLN6t
 wN5i6xAAkOvwFh1GmsPUdz5RxzsWoIUDvyENg6E8Axwe5tSEMRFiPjabbTQJomQg
 GZt75XIS24LZFZ+hvqrLSA+dFgXTgWv08ZE81EjwjmAMBlLCOPhCgeN6C1p8100Y
 scSvRJbP9k9lpA5K7et/1X4AkK2cZyh+LGJgCjr2Al2mbERpPueDF8fxqeohFvXQ
 nTSks4XlA0yQ06+9r49aQAiuXvgg9lDT1wIglD2HEV7vOVs/ud+yyL8+z5YMeFzx
 pSIc6wDu4PqdA46w4MZs90uTy7S/PMvBiYDEiV3tKzg0MLttvFGlT58/YjVtguTP
 mNkfwIEwQtDQzoxsFIJO7yBTlTRBs95V4aIVk3pB+Gb/bideRPIkeVQvgMSEBKj7
 N0pEXWOxfB9iIWO6b1utYpQ4uxeDOU/8DPUCit1IBbNgKTaJkJb77fboYk7NaB0K
 KEtObAk6jMatB/xr+vUFWc4sMk9wlm72w8wcQzgKZ0xV2U3d1/Y/9nS4GvI510ev
 TRQ3mKj7N319uCeId1czF6W8rillCJ2u8ZK53u+Nfp7R3PbsRSMc6IDJ1UdDUlyR
 HFcWHxbcbEGhe8SnFGab4Qd6fWChcn2EaEoAJJz+Rqv0k3zcwqccNM5waCABAjTE
 0S22JIHePJKcpkMLGq3EOUAQuu+8Zsol7gPCLxSAMclVqPTl9ck=
 =rAav
 -----END PGP SIGNATURE-----

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

Accelerators patches

- Unify x86/arm hw/xen/arch_hvm.h header
- Move non-system-specific 'accel/accel-ops.h' and 'accel-cpu-ops.h' to accel/
- Move KVM definitions qapi/accelerator.json
- Add @qom-type field to CpuInfoFast QAPI structure
- Display CPU model name in 'info cpus' HMP command
- Introduce @x-accel-stats QMP command
- Add 'info accel' on HMP
- Improve qemu_add_vm_change_state_handler*() docstring
- Extract TCG statistic related code to tcg-stats.c
- Implement AccelClass::get_[vcpu]_stats() handlers for TCG and HVF
- Do not dump NaN in TCG statistics
- Revert incomplete "accel/tcg: Unregister the RCU before exiting RR thread"

 # -----BEGIN PGP SIGNATURE-----
 #
 # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmh2r4UACgkQ4+MsLN6t
 # wN5i6xAAkOvwFh1GmsPUdz5RxzsWoIUDvyENg6E8Axwe5tSEMRFiPjabbTQJomQg
 # GZt75XIS24LZFZ+hvqrLSA+dFgXTgWv08ZE81EjwjmAMBlLCOPhCgeN6C1p8100Y
 # scSvRJbP9k9lpA5K7et/1X4AkK2cZyh+LGJgCjr2Al2mbERpPueDF8fxqeohFvXQ
 # nTSks4XlA0yQ06+9r49aQAiuXvgg9lDT1wIglD2HEV7vOVs/ud+yyL8+z5YMeFzx
 # pSIc6wDu4PqdA46w4MZs90uTy7S/PMvBiYDEiV3tKzg0MLttvFGlT58/YjVtguTP
 # mNkfwIEwQtDQzoxsFIJO7yBTlTRBs95V4aIVk3pB+Gb/bideRPIkeVQvgMSEBKj7
 # N0pEXWOxfB9iIWO6b1utYpQ4uxeDOU/8DPUCit1IBbNgKTaJkJb77fboYk7NaB0K
 # KEtObAk6jMatB/xr+vUFWc4sMk9wlm72w8wcQzgKZ0xV2U3d1/Y/9nS4GvI510ev
 # TRQ3mKj7N319uCeId1czF6W8rillCJ2u8ZK53u+Nfp7R3PbsRSMc6IDJ1UdDUlyR
 # HFcWHxbcbEGhe8SnFGab4Qd6fWChcn2EaEoAJJz+Rqv0k3zcwqccNM5waCABAjTE
 # 0S22JIHePJKcpkMLGq3EOUAQuu+8Zsol7gPCLxSAMclVqPTl9ck=
 # =rAav
 # -----END PGP SIGNATURE-----
 # gpg: Signature made Tue 15 Jul 2025 15:44:05 EDT
 # 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-20250715' of https://github.com/philmd/qemu:
  system/runstate: Document qemu_add_vm_change_state_handler_prio* in hdr
  system/runstate: Document qemu_add_vm_change_state_handler()
  accel/hvf: Implement AccelClass::get_vcpu_stats() handler
  accel/tcg: Implement AccelClass::get_stats() handler
  accel/tcg: Propagate AccelState to dump_accel_info()
  accel/system: Add 'info accel' on human monitor
  accel/system: Introduce @x-accel-stats QMP command
  accel/tcg: Extract statistic related code to tcg-stats.c
  Revert "accel/tcg: Unregister the RCU before exiting RR thread"
  accel: Extract AccelClass definition to 'accel/accel-ops.h'
  accel: Rename 'system/accel-ops.h' -> 'accel/accel-cpu-ops.h'
  accel/tcg: Do not dump NaN statistics
  hw/core/machine: Display CPU model name in 'info cpus' command
  qapi/machine: Add @qom-type field to CpuInfoFast structure
  qapi/accel: Move definitions related to accelerators in their own file
  hw/arm/xen-pvh: Remove unnecessary 'hw/xen/arch_hvm.h' header
  hw/xen/arch_hvm: Unify x86 and ARM variants

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

Conflicts:
  qapi/machine.json
  Commit 0462da9d6b ("qapi: remove trivial "Returns:" sections")
  removed trivial "Returns:". This caused a conflict with the move from
  machine.json to accelerator.json.
This commit is contained in:
Stefan Hajnoczi 2025-07-16 07:13:40 -04:00
commit f96b157ebb
47 changed files with 513 additions and 333 deletions

View file

@ -1,5 +1,5 @@
/*
* Accelerator OPS, used for cpus.c module
* Accelerator per-vCPU handlers
*
* Copyright 2021 SUSE LLC
*
@ -7,8 +7,8 @@
* See the COPYING file in the top-level directory.
*/
#ifndef ACCEL_OPS_H
#define ACCEL_OPS_H
#ifndef QEMU_ACCEL_CPU_OPS_H
#define QEMU_ACCEL_CPU_OPS_H
#include "qemu/accel.h"
#include "exec/vaddr.h"
@ -65,6 +65,9 @@ struct AccelOpsClass {
/* handle_interrupt is mandatory. */
void (*handle_interrupt)(CPUState *cpu, int mask);
/* get_vcpu_stats: Append statistics of this @cpu to @buf */
void (*get_vcpu_stats)(CPUState *cpu, GString *buf);
/**
* @get_virtual_clock: fetch virtual clock
* @set_virtual_clock: set virtual clock
@ -89,4 +92,4 @@ struct AccelOpsClass {
void generic_handle_interrupt(CPUState *cpu, int mask);
#endif /* ACCEL_OPS_H */
#endif /* QEMU_ACCEL_CPU_OPS_H */

51
include/accel/accel-ops.h Normal file
View file

@ -0,0 +1,51 @@
/*
* Accelerator handlers
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#ifndef ACCEL_OPS_H
#define ACCEL_OPS_H
#include "exec/hwaddr.h"
#include "qemu/accel.h"
#include "qom/object.h"
struct AccelState {
Object parent_obj;
};
struct AccelClass {
ObjectClass parent_class;
const char *name;
/* Cached by accel_init_ops_interfaces() when created */
AccelOpsClass *ops;
int (*init_machine)(AccelState *as, MachineState *ms);
bool (*cpu_common_realize)(CPUState *cpu, Error **errp);
void (*cpu_common_unrealize)(CPUState *cpu);
/* get_stats: Append statistics to @buf */
void (*get_stats)(AccelState *as, GString *buf);
/* system related hooks */
void (*setup_post)(AccelState *as);
void (*pre_resume_vm)(AccelState *as, bool step_pending);
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
* accelerator is chosen. It works like MachineClass.compat_props
* but it's for accelerators not machines. Accelerator-provided
* global properties may be overridden by machine-type
* compat_props or user-provided global properties.
*/
GPtrArray *compat_props;
};
#endif /* ACCEL_OPS_H */

View file

@ -1,9 +0,0 @@
#ifndef HW_XEN_ARCH_ARM_HVM_H
#define HW_XEN_ARCH_ARM_HVM_H
#include <xen/hvm/ioreq.h>
void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
void arch_xen_set_memory(XenIOState *state,
MemoryRegionSection *section,
bool add);
#endif

View file

@ -1,11 +0,0 @@
#ifndef HW_XEN_ARCH_I386_HVM_H
#define HW_XEN_ARCH_I386_HVM_H
#include <xen/hvm/ioreq.h>
#include "hw/xen/xen-hvm-common.h"
void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
void arch_xen_set_memory(XenIOState *state,
MemoryRegionSection *section,
bool add);
#endif

View file

@ -1,5 +1,11 @@
#if defined(TARGET_I386) || defined(TARGET_X86_64)
#include "hw/i386/xen_arch_hvm.h"
#elif defined(TARGET_ARM) || defined(TARGET_AARCH64)
#include "hw/arm/xen_arch_hvm.h"
#ifndef HW_XEN_ARCH_HVM_H
#define HW_XEN_ARCH_HVM_H
#include <xen/hvm/ioreq.h>
#include "hw/xen/xen-hvm-common.h"
void arch_handle_ioreq(XenIOState *state, ioreq_t *req);
void arch_xen_set_memory(XenIOState *state,
MemoryRegionSection *section,
bool add);
#endif

View file

@ -26,43 +26,8 @@
#include "qom/object.h"
#include "exec/hwaddr.h"
struct AccelState {
/*< private >*/
Object parent_obj;
};
typedef struct AccelClass {
/*< private >*/
ObjectClass parent_class;
/*< public >*/
const char *name;
/* Cached by accel_init_ops_interfaces() when created */
AccelOpsClass *ops;
int (*init_machine)(AccelState *as, MachineState *ms);
bool (*cpu_common_realize)(CPUState *cpu, Error **errp);
void (*cpu_common_unrealize)(CPUState *cpu);
/* system related hooks */
void (*setup_post)(AccelState *as);
void (*pre_resume_vm)(AccelState *as, bool step_pending);
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
* accelerator is chosen. It works like MachineClass.compat_props
* but it's for accelerators not machines. Accelerator-provided
* global properties may be overridden by machine-type
* compat_props or user-provided global properties.
*/
GPtrArray *compat_props;
} AccelClass;
typedef struct AccelState AccelState;
typedef struct AccelClass AccelClass;
#define TYPE_ACCEL "accel"

View file

@ -14,6 +14,7 @@
#include "qemu/queue.h"
#include "exec/vaddr.h"
#include "qom/object.h"
#include "accel/accel-ops.h"
#ifdef __aarch64__
#include <Hypervisor/Hypervisor.h>
@ -45,7 +46,7 @@ typedef struct hvf_vcpu_caps {
} hvf_vcpu_caps;
struct HVFState {
AccelState parent;
AccelState parent_obj;
hvf_slot slots[32];
int num_slots;

View file

@ -14,6 +14,7 @@
#include "qemu/accel.h"
#include "qemu/queue.h"
#include "system/kvm.h"
#include "accel/accel-ops.h"
#include "hw/boards.h"
#include "hw/i386/topology.h"
#include "io/channel-socket.h"

View file

@ -14,11 +14,51 @@ void runstate_replay_enable(void);
typedef void VMChangeStateHandler(void *opaque, bool running, RunState state);
typedef int VMChangeStateHandlerWithRet(void *opaque, bool running, RunState state);
/**
* qemu_add_vm_change_state_handler:
* @cb: the callback to invoke
* @opaque: user data passed to the callback
*
* Register a callback function that is invoked when the vm starts or stops
* running.
*
* Returns: an entry to be freed using qemu_del_vm_change_state_handler()
*/
VMChangeStateEntry *qemu_add_vm_change_state_handler(VMChangeStateHandler *cb,
void *opaque);
/**
* qemu_add_vm_change_state_handler_prio:
* @cb: the callback to invoke
* @opaque: user data passed to the callback
* @priority: low priorities execute first when the vm runs and the reverse is
* true when the vm stops
*
* Register a callback function that is invoked when the vm starts or stops
* running.
*
* Returns: an entry to be freed using qemu_del_vm_change_state_handler()
*/
VMChangeStateEntry *qemu_add_vm_change_state_handler_prio(
VMChangeStateHandler *cb, void *opaque, int priority);
VMChangeStateEntry *
/**
* qemu_add_vm_change_state_handler_prio_full:
* @cb: the main callback to invoke
* @prepare_cb: a callback to invoke before the main callback
* @cb_ret: the main callback to invoke with return value
* @opaque: user data passed to the callbacks
* @priority: low priorities execute first when the vm runs and the reverse is
* true when the vm stops
*
* Register a main callback function and an optional prepare callback function
* that are invoked when the vm starts or stops running. The main callback and
* the prepare callback are called in two separate phases: First all prepare
* callbacks are called and only then all main callbacks are called. As its
* name suggests, the prepare callback can be used to do some preparatory work
* before invoking the main callback.
*
* Returns: an entry to be freed using qemu_del_vm_change_state_handler()
*/
qemu_add_vm_change_state_handler_prio_full(VMChangeStateHandler *cb,
VMChangeStateHandler *prepare_cb,
VMChangeStateHandlerWithRet *cb_ret,

View file

@ -1005,5 +1005,7 @@ static inline const TCGOpcode *tcg_swap_vecop_list(const TCGOpcode *n)
bool tcg_can_emit_vecop_list(const TCGOpcode *, TCGType, unsigned);
void tcg_dump_ops(TCGContext *s, FILE *f, bool have_prefs);
/* tcg_dump_stats: Append TCG statistics to @buf */
void tcg_dump_stats(GString *buf);
#endif /* TCG_H */