accel: replace struct CpusAccel with AccelOpsClass

This will allow us to centralize the registration of
the cpus.c module accelerator operations (in accel/accel-softmmu.c),
and trigger it automatically using object hierarchy lookup from the
new accel_init_interfaces() initialization step, depending just on
which accelerators are available in the code.

Rename all tcg-cpus.c, kvm-cpus.c, etc to tcg-accel-ops.c,
kvm-accel-ops.c, etc, matching the object type names.

Signed-off-by: Claudio Fontana <cfontana@suse.de>
Message-Id: <20210204163931.7358-18-cfontana@suse.de>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Claudio Fontana 2021-02-04 17:39:25 +01:00 committed by Richard Henderson
parent 940e43aa30
commit b86f59c715
44 changed files with 361 additions and 163 deletions

View File

@ -439,7 +439,8 @@ M: Richard Henderson <richard.henderson@linaro.org>
R: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: include/qemu/accel.h
F: accel/accel.c
F: include/sysemu/accel-ops.h
F: accel/accel-*.c
F: accel/Makefile.objs
F: accel/stubs/Makefile.objs

View File

@ -26,6 +26,10 @@
#include "qemu/osdep.h"
#include "qemu/accel.h"
#ifndef CONFIG_USER_ONLY
#include "accel-softmmu.h"
#endif /* !CONFIG_USER_ONLY */
static const TypeInfo accel_type = {
.name = TYPE_ACCEL,
.parent = TYPE_OBJECT,
@ -42,6 +46,13 @@ AccelClass *accel_find(const char *opt_name)
return ac;
}
void accel_init_interfaces(AccelClass *ac)
{
#ifndef CONFIG_USER_ONLY
accel_init_ops_interfaces(ac);
#endif /* !CONFIG_USER_ONLY */
}
static void register_accel_types(void)
{
type_register_static(&accel_type);

View File

@ -26,9 +26,9 @@
#include "qemu/osdep.h"
#include "qemu/accel.h"
#include "hw/boards.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "qom/object.h"
#include "sysemu/cpus.h"
#include "accel-softmmu.h"
int accel_init_machine(AccelState *accel, MachineState *ms)
{
@ -60,3 +60,41 @@ void accel_setup_post(MachineState *ms)
acc->setup_post(ms, accel);
}
}
/* initialize the arch-independent accel operation interfaces */
void accel_init_ops_interfaces(AccelClass *ac)
{
const char *ac_name;
char *ops_name;
AccelOpsClass *ops;
ac_name = object_class_get_name(OBJECT_CLASS(ac));
g_assert(ac_name != NULL);
ops_name = g_strdup_printf("%s" ACCEL_OPS_SUFFIX, ac_name);
ops = ACCEL_OPS_CLASS(object_class_by_name(ops_name));
g_free(ops_name);
/*
* all accelerators need to define ops, providing at least a mandatory
* non-NULL create_vcpu_thread operation.
*/
g_assert(ops != NULL);
if (ops->ops_init) {
ops->ops_init(ops);
}
cpus_register_accel(ops);
}
static const TypeInfo accel_ops_type_info = {
.name = TYPE_ACCEL_OPS,
.parent = TYPE_OBJECT,
.abstract = true,
.class_size = sizeof(AccelOpsClass),
};
static void accel_softmmu_register_types(void)
{
type_register_static(&accel_ops_type_info);
}
type_init(accel_softmmu_register_types);

15
accel/accel-softmmu.h Normal file
View File

@ -0,0 +1,15 @@
/*
* QEMU System Emulation accel internal functions
*
* Copyright 2021 SUSE LLC
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef ACCEL_SOFTMMU_H
#define ACCEL_SOFTMMU_H
void accel_init_ops_interfaces(AccelClass *ac);
#endif /* ACCEL_SOFTMMU_H */

View File

@ -74,11 +74,27 @@ static void kvm_start_vcpu_thread(CPUState *cpu)
cpu, QEMU_THREAD_JOINABLE);
}
const CpusAccel kvm_cpus = {
.create_vcpu_thread = kvm_start_vcpu_thread,
static void kvm_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
.synchronize_post_reset = kvm_cpu_synchronize_post_reset,
.synchronize_post_init = kvm_cpu_synchronize_post_init,
.synchronize_state = kvm_cpu_synchronize_state,
.synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm,
ops->create_vcpu_thread = kvm_start_vcpu_thread;
ops->synchronize_post_reset = kvm_cpu_synchronize_post_reset;
ops->synchronize_post_init = kvm_cpu_synchronize_post_init;
ops->synchronize_state = kvm_cpu_synchronize_state;
ops->synchronize_pre_loadvm = kvm_cpu_synchronize_pre_loadvm;
}
static const TypeInfo kvm_accel_ops_type = {
.name = ACCEL_OPS_NAME("kvm"),
.parent = TYPE_ACCEL_OPS,
.class_init = kvm_accel_ops_class_init,
.abstract = true,
};
static void kvm_accel_ops_register_types(void)
{
type_register_static(&kvm_accel_ops_type);
}
type_init(kvm_accel_ops_register_types);

View File

@ -2256,8 +2256,6 @@ static int kvm_init(MachineState *ms)
ret = ram_block_discard_disable(true);
assert(!ret);
}
cpus_register_accel(&kvm_cpus);
return 0;
err:

View File

@ -12,8 +12,6 @@
#include "sysemu/cpus.h"
extern const CpusAccel kvm_cpus;
int kvm_init_vcpu(CPUState *cpu, Error **errp);
int kvm_cpu_exec(CPUState *cpu);
void kvm_destroy_vcpu(CPUState *cpu);

View File

@ -1,7 +1,7 @@
kvm_ss = ss.source_set()
kvm_ss.add(files(
'kvm-all.c',
'kvm-cpus.c',
'kvm-accel-ops.c',
))
kvm_ss.add(when: 'CONFIG_SEV', if_false: files('sev-stub.c'))

View File

@ -25,14 +25,8 @@
#include "qemu/main-loop.h"
#include "hw/core/cpu.h"
const CpusAccel qtest_cpus = {
.create_vcpu_thread = dummy_start_vcpu_thread,
.get_virtual_clock = qtest_get_virtual_clock,
};
static int qtest_init_accel(MachineState *ms)
{
cpus_register_accel(&qtest_cpus);
return 0;
}
@ -52,9 +46,26 @@ static const TypeInfo qtest_accel_type = {
.class_init = qtest_accel_class_init,
};
static void qtest_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
ops->create_vcpu_thread = dummy_start_vcpu_thread;
ops->get_virtual_clock = qtest_get_virtual_clock;
};
static const TypeInfo qtest_accel_ops_type = {
.name = ACCEL_OPS_NAME("qtest"),
.parent = TYPE_ACCEL_OPS,
.class_init = qtest_accel_ops_class_init,
.abstract = true,
};
static void qtest_type_init(void)
{
type_register_static(&qtest_accel_type);
type_register_static(&qtest_accel_ops_type);
}
type_init(qtest_type_init);

View File

@ -15,8 +15,8 @@ specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files(
'cputlb.c',
'tcg-cpus.c',
'tcg-cpus-mttcg.c',
'tcg-cpus-icount.c',
'tcg-cpus-rr.c'
'tcg-accel-ops.c',
'tcg-accel-ops-mttcg.c',
'tcg-accel-ops-icount.c',
'tcg-accel-ops-rr.c'
))

View File

@ -32,9 +32,9 @@
#include "exec/exec-all.h"
#include "hw/boards.h"
#include "tcg-cpus.h"
#include "tcg-cpus-icount.h"
#include "tcg-cpus-rr.h"
#include "tcg-accel-ops.h"
#include "tcg-accel-ops-icount.h"
#include "tcg-accel-ops-rr.h"
static int64_t icount_get_limit(void)
{
@ -93,7 +93,7 @@ void icount_prepare_for_run(CPUState *cpu)
/*
* These should always be cleared by icount_process_data after
* each vCPU execution. However u16.high can be raised
* asynchronously by cpu_exit/cpu_interrupt/tcg_cpus_handle_interrupt
* asynchronously by cpu_exit/cpu_interrupt/tcg_handle_interrupt
*/
g_assert(cpu_neg(cpu)->icount_decr.u16.low == 0);
g_assert(cpu->icount_extra == 0);
@ -125,23 +125,14 @@ void icount_process_data(CPUState *cpu)
replay_mutex_unlock();
}
static void icount_handle_interrupt(CPUState *cpu, int mask)
void icount_handle_interrupt(CPUState *cpu, int mask)
{
int old_mask = cpu->interrupt_request;
tcg_cpus_handle_interrupt(cpu, mask);
tcg_handle_interrupt(cpu, mask);
if (qemu_cpu_is_self(cpu) &&
!cpu->can_do_io
&& (mask & ~old_mask) != 0) {
cpu_abort(cpu, "Raised interrupt while not in I/O function");
}
}
const CpusAccel tcg_cpus_icount = {
.create_vcpu_thread = rr_start_vcpu_thread,
.kick_vcpu_thread = rr_kick_vcpu_thread,
.handle_interrupt = icount_handle_interrupt,
.get_virtual_clock = icount_get,
.get_elapsed_ticks = icount_get,
};

View File

@ -14,4 +14,6 @@ void icount_handle_deadline(void);
void icount_prepare_for_run(CPUState *cpu);
void icount_process_data(CPUState *cpu);
void icount_handle_interrupt(CPUState *cpu, int mask);
#endif /* TCG_CPUS_ICOUNT_H */

View File

@ -32,7 +32,8 @@
#include "exec/exec-all.h"
#include "hw/boards.h"
#include "tcg-cpus.h"
#include "tcg-accel-ops.h"
#include "tcg-accel-ops-mttcg.h"
/*
* In the multi-threaded case each vCPU has its own thread. The TLS
@ -103,12 +104,12 @@ static void *mttcg_cpu_thread_fn(void *arg)
return NULL;
}
static void mttcg_kick_vcpu_thread(CPUState *cpu)
void mttcg_kick_vcpu_thread(CPUState *cpu)
{
cpu_exit(cpu);
}
static void mttcg_start_vcpu_thread(CPUState *cpu)
void mttcg_start_vcpu_thread(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
@ -131,10 +132,3 @@ static void mttcg_start_vcpu_thread(CPUState *cpu)
cpu->hThread = qemu_thread_get_handle(cpu->thread);
#endif
}
const CpusAccel tcg_cpus_mttcg = {
.create_vcpu_thread = mttcg_start_vcpu_thread,
.kick_vcpu_thread = mttcg_kick_vcpu_thread,
.handle_interrupt = tcg_cpus_handle_interrupt,
};

View File

@ -0,0 +1,19 @@
/*
* QEMU TCG Multi Threaded vCPUs implementation
*
* Copyright 2021 SUSE LLC
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef TCG_CPUS_MTTCG_H
#define TCG_CPUS_MTTCG_H
/* kick MTTCG vCPU thread */
void mttcg_kick_vcpu_thread(CPUState *cpu);
/* start an mttcg vCPU thread */
void mttcg_start_vcpu_thread(CPUState *cpu);
#endif /* TCG_CPUS_MTTCG_H */

View File

@ -32,9 +32,9 @@
#include "exec/exec-all.h"
#include "hw/boards.h"
#include "tcg-cpus.h"
#include "tcg-cpus-rr.h"
#include "tcg-cpus-icount.h"
#include "tcg-accel-ops.h"
#include "tcg-accel-ops-rr.h"
#include "tcg-accel-ops-icount.h"
/* Kick all RR vCPUs */
void rr_kick_vcpu_thread(CPUState *unused)
@ -296,10 +296,3 @@ void rr_start_vcpu_thread(CPUState *cpu)
cpu->created = true;
}
}
const CpusAccel tcg_cpus_rr = {
.create_vcpu_thread = rr_start_vcpu_thread,
.kick_vcpu_thread = rr_kick_vcpu_thread,
.handle_interrupt = tcg_cpus_handle_interrupt,
};

View File

@ -34,7 +34,10 @@
#include "exec/exec-all.h"
#include "hw/boards.h"
#include "tcg-cpus.h"
#include "tcg-accel-ops.h"
#include "tcg-accel-ops-mttcg.h"
#include "tcg-accel-ops-rr.h"
#include "tcg-accel-ops-icount.h"
/* common functionality among all TCG variants */
@ -64,7 +67,7 @@ int tcg_cpus_exec(CPUState *cpu)
}
/* mask must never be zero, except for A20 change call */
void tcg_cpus_handle_interrupt(CPUState *cpu, int mask)
void tcg_handle_interrupt(CPUState *cpu, int mask)
{
g_assert(qemu_mutex_iothread_locked());
@ -80,3 +83,43 @@ void tcg_cpus_handle_interrupt(CPUState *cpu, int mask)
qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1);
}
}
static void tcg_accel_ops_init(AccelOpsClass *ops)
{
if (qemu_tcg_mttcg_enabled()) {
ops->create_vcpu_thread = mttcg_start_vcpu_thread;
ops->kick_vcpu_thread = mttcg_kick_vcpu_thread;
ops->handle_interrupt = tcg_handle_interrupt;
} else if (icount_enabled()) {
ops->create_vcpu_thread = rr_start_vcpu_thread;
ops->kick_vcpu_thread = rr_kick_vcpu_thread;
ops->handle_interrupt = icount_handle_interrupt;
ops->get_virtual_clock = icount_get;
ops->get_elapsed_ticks = icount_get;
} else {
ops->create_vcpu_thread = rr_start_vcpu_thread;
ops->kick_vcpu_thread = rr_kick_vcpu_thread;
ops->handle_interrupt = tcg_handle_interrupt;
}
}
static void tcg_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
ops->ops_init = tcg_accel_ops_init;
}
static const TypeInfo tcg_accel_ops_type = {
.name = ACCEL_OPS_NAME("tcg"),
.parent = TYPE_ACCEL_OPS,
.class_init = tcg_accel_ops_class_init,
.abstract = true,
};
static void tcg_accel_ops_register_types(void)
{
type_register_static(&tcg_accel_ops_type);
}
type_init(tcg_accel_ops_register_types);

View File

@ -14,12 +14,8 @@
#include "sysemu/cpus.h"
extern const CpusAccel tcg_cpus_mttcg;
extern const CpusAccel tcg_cpus_icount;
extern const CpusAccel tcg_cpus_rr;
void tcg_cpus_destroy(CPUState *cpu);
int tcg_cpus_exec(CPUState *cpu);
void tcg_cpus_handle_interrupt(CPUState *cpu, int mask);
void tcg_handle_interrupt(CPUState *cpu, int mask);
#endif /* TCG_CPUS_H */

View File

@ -33,10 +33,6 @@
#include "qemu/accel.h"
#include "qapi/qapi-builtin-visit.h"
#ifndef CONFIG_USER_ONLY
#include "tcg-cpus.h"
#endif /* CONFIG_USER_ONLY */
struct TCGState {
AccelState parent_obj;
@ -124,14 +120,6 @@ static int tcg_init(MachineState *ms)
*/
#ifndef CONFIG_USER_ONLY
tcg_region_init();
if (mttcg_enabled) {
cpus_register_accel(&tcg_cpus_mttcg);
} else if (icount_enabled()) {
cpus_register_accel(&tcg_cpus_icount);
} else {
cpus_register_accel(&tcg_cpus_rr);
}
#endif /* !CONFIG_USER_ONLY */
return 0;

View File

@ -154,10 +154,6 @@ static void xen_setup_post(MachineState *ms, AccelState *accel)
}
}
const CpusAccel xen_cpus = {
.create_vcpu_thread = dummy_start_vcpu_thread,
};
static int xen_init(MachineState *ms)
{
MachineClass *mc = MACHINE_GET_CLASS(ms);
@ -185,9 +181,6 @@ static int xen_init(MachineState *ms)
* opt out of system RAM being allocated by generic code
*/
mc->default_ram_id = NULL;
cpus_register_accel(&xen_cpus);
return 0;
}
@ -222,9 +215,24 @@ static const TypeInfo xen_accel_type = {
.class_init = xen_accel_class_init,
};
static void xen_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
ops->create_vcpu_thread = dummy_start_vcpu_thread;
}
static const TypeInfo xen_accel_ops_type = {
.name = ACCEL_OPS_NAME("xen"),
.parent = TYPE_ACCEL_OPS,
.class_init = xen_accel_ops_class_init,
.abstract = true,
};
static void xen_type_init(void)
{
type_register_static(&xen_accel_type);
type_register_static(&xen_accel_ops_type);
}
type_init(xen_type_init);

View File

@ -909,13 +909,14 @@ int main(int argc, char **argv)
#endif
}
cpu_type = parse_cpu_option(cpu_model);
/* init tcg before creating CPUs and to get qemu_host_page_size */
{
AccelClass *ac = ACCEL_GET_CLASS(current_accel());
ac->init_machine(NULL);
accel_init_interfaces(ac);
}
cpu_type = parse_cpu_option(cpu_model);
cpu = cpu_create(cpu_type);
env = cpu->env_ptr;
#if defined(TARGET_SPARC) || defined(TARGET_PPC)

View File

@ -69,6 +69,8 @@ typedef struct AccelClass {
AccelClass *accel_find(const char *opt_name);
AccelState *current_accel(void);
void accel_init_interfaces(AccelClass *ac);
#ifndef CONFIG_USER_ONLY
int accel_init_machine(AccelState *accel, MachineState *ms);

View File

@ -0,0 +1,45 @@
/*
* Accelerator OPS, used for cpus.c module
*
* Copyright 2021 SUSE LLC
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#ifndef ACCEL_OPS_H
#define ACCEL_OPS_H
#include "qom/object.h"
#define ACCEL_OPS_SUFFIX "-ops"
#define TYPE_ACCEL_OPS "accel" ACCEL_OPS_SUFFIX
#define ACCEL_OPS_NAME(name) (name "-" TYPE_ACCEL_OPS)
typedef struct AccelOpsClass AccelOpsClass;
DECLARE_CLASS_CHECKERS(AccelOpsClass, ACCEL_OPS, TYPE_ACCEL_OPS)
/* cpus.c operations interface */
struct AccelOpsClass {
/*< private >*/
ObjectClass parent_class;
/*< public >*/
/* initialization function called when accel is chosen */
void (*ops_init)(AccelOpsClass *ops);
void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY NON-NULL */
void (*kick_vcpu_thread)(CPUState *cpu);
void (*synchronize_post_reset)(CPUState *cpu);
void (*synchronize_post_init)(CPUState *cpu);
void (*synchronize_state)(CPUState *cpu);
void (*synchronize_pre_loadvm)(CPUState *cpu);
void (*handle_interrupt)(CPUState *cpu, int mask);
int64_t (*get_virtual_clock)(void);
int64_t (*get_elapsed_ticks)(void);
};
#endif /* ACCEL_OPS_H */

View File

@ -2,30 +2,14 @@
#define QEMU_CPUS_H
#include "qemu/timer.h"
#include "sysemu/accel-ops.h"
/* cpus.c */
/* register accel-specific operations */
void cpus_register_accel(const AccelOpsClass *i);
/* CPU execution threads */
/* accel/dummy-cpus.c */
typedef struct CpusAccel {
void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY */
void (*kick_vcpu_thread)(CPUState *cpu);
void (*synchronize_post_reset)(CPUState *cpu);
void (*synchronize_post_init)(CPUState *cpu);
void (*synchronize_state)(CPUState *cpu);
void (*synchronize_pre_loadvm)(CPUState *cpu);
void (*handle_interrupt)(CPUState *cpu, int mask);
int64_t (*get_virtual_clock)(void);
int64_t (*get_elapsed_ticks)(void);
} CpusAccel;
/* register accel-specific cpus interface implementation */
void cpus_register_accel(const CpusAccel *i);
/* Create a dummy vcpu for CpusAccel->create_vcpu_thread */
/* Create a dummy vcpu for AccelOpsClass->create_vcpu_thread */
void dummy_start_vcpu_thread(CPUState *);
/* interface available for cpus accelerator threads */

View File

@ -706,6 +706,7 @@ int main(int argc, char **argv, char **envp)
AccelClass *ac = ACCEL_GET_CLASS(current_accel());
ac->init_machine(NULL);
accel_init_interfaces(ac);
}
cpu = cpu_create(cpu_type);
env = cpu->env_ptr;

View File

@ -128,7 +128,7 @@ void hw_error(const char *fmt, ...)
/*
* The chosen accelerator is supposed to register this.
*/
static const CpusAccel *cpus_accel;
static const AccelOpsClass *cpus_accel;
void cpu_synchronize_all_states(void)
{
@ -594,11 +594,11 @@ void cpu_remove_sync(CPUState *cpu)
qemu_mutex_lock_iothread();
}
void cpus_register_accel(const CpusAccel *ca)
void cpus_register_accel(const AccelOpsClass *ops)
{
assert(ca != NULL);
assert(ca->create_vcpu_thread != NULL); /* mandatory */
cpus_accel = ca;
assert(ops != NULL);
assert(ops->create_vcpu_thread != NULL); /* mandatory */
cpus_accel = ops;
}
void qemu_init_vcpu(CPUState *cpu)
@ -618,7 +618,7 @@ void qemu_init_vcpu(CPUState *cpu)
cpu_address_space_init(cpu, 0, "cpu-memory", cpu->memory);
}
/* accelerators all implement the CpusAccel interface */
/* accelerators all implement the AccelOpsClass */
g_assert(cpus_accel != NULL && cpus_accel->create_vcpu_thread != NULL);
cpus_accel->create_vcpu_thread(cpu);

View File

@ -1726,7 +1726,8 @@ static bool object_create_early(const char *type, QemuOpts *opts)
return false;
}
/* Allocation of large amounts of memory may delay
/*
* Allocation of large amounts of memory may delay
* chardev initialization for too long, and trigger timeouts
* on software that waits for a monitor socket to be created
* (e.g. libvirt).
@ -3497,7 +3498,7 @@ void qemu_init(int argc, char **argv, char **envp)
*
* Machine compat properties: object_set_machine_compat_props().
* Accelerator compat props: object_set_accelerator_compat_props(),
* called from configure_accelerator().
* called from do_configure_accelerator().
*/
machine_class = MACHINE_GET_CLASS(current_machine);
@ -3519,6 +3520,8 @@ void qemu_init(int argc, char **argv, char **envp)
if (cpu_option) {
current_machine->cpu_type = parse_cpu_option(cpu_option);
}
/* NB: for machine none cpu_type could STILL be NULL here! */
accel_init_interfaces(ACCEL_GET_CLASS(current_machine->accelerator));
qemu_resolve_machine_memdev();
parse_numa_opts(current_machine);

View File

@ -26,7 +26,7 @@
#include "sysemu/cpus.h"
#include "qemu/guest-random.h"
#include "hax-cpus.h"
#include "hax-accel-ops.h"
static void *hax_cpu_thread_fn(void *arg)
{
@ -74,12 +74,29 @@ static void hax_start_vcpu_thread(CPUState *cpu)
#endif
}
const CpusAccel hax_cpus = {
.create_vcpu_thread = hax_start_vcpu_thread,
.kick_vcpu_thread = hax_kick_vcpu_thread,
static void hax_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
.synchronize_post_reset = hax_cpu_synchronize_post_reset,
.synchronize_post_init = hax_cpu_synchronize_post_init,
.synchronize_state = hax_cpu_synchronize_state,
.synchronize_pre_loadvm = hax_cpu_synchronize_pre_loadvm,
ops->create_vcpu_thread = hax_start_vcpu_thread;
ops->kick_vcpu_thread = hax_kick_vcpu_thread;
ops->synchronize_post_reset = hax_cpu_synchronize_post_reset;
ops->synchronize_post_init = hax_cpu_synchronize_post_init;
ops->synchronize_state = hax_cpu_synchronize_state;
ops->synchronize_pre_loadvm = hax_cpu_synchronize_pre_loadvm;
}
static const TypeInfo hax_accel_ops_type = {
.name = ACCEL_OPS_NAME("hax"),
.parent = TYPE_ACCEL_OPS,
.class_init = hax_accel_ops_class_init,
.abstract = true,
};
static void hax_accel_ops_register_types(void)
{
type_register_static(&hax_accel_ops_type);
}
type_init(hax_accel_ops_register_types);

View File

@ -12,8 +12,6 @@
#include "sysemu/cpus.h"
extern const CpusAccel hax_cpus;
#include "hax-interface.h"
#include "hax-i386.h"

View File

@ -33,7 +33,7 @@
#include "sysemu/runstate.h"
#include "hw/boards.h"
#include "hax-cpus.h"
#include "hax-accel-ops.h"
#define DEBUG_HAX 0
@ -364,9 +364,6 @@ static int hax_accel_init(MachineState *ms)
!ret ? "working" : "not working",
!ret ? "fast virt" : "emulation");
}
if (ret == 0) {
cpus_register_accel(&hax_cpus);
}
return ret;
}

View File

@ -13,7 +13,7 @@
#include "exec/address-spaces.h"
#include "qemu/error-report.h"
#include "hax-cpus.h"
#include "hax-accel-ops.h"
#include "qemu/queue.h"
#define DEBUG_HAX_MEM 0

View File

@ -15,7 +15,7 @@
#include <sys/ioctl.h>
#include "sysemu/cpus.h"
#include "hax-cpus.h"
#include "hax-accel-ops.h"
hax_fd hax_mod_open(void)
{

View File

@ -12,7 +12,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "hax-cpus.h"
#include "hax-accel-ops.h"
/*
* return 0 when success, -1 when driver not loaded,

View File

@ -23,7 +23,7 @@
#include <winioctl.h>
#include <windef.h>
#include "hax-cpus.h"
#include "hax-accel-ops.h"
#define HAX_INVALID_FD INVALID_HANDLE_VALUE

View File

@ -1,7 +1,7 @@
i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files(
'hax-all.c',
'hax-mem.c',
'hax-cpus.c',
'hax-accel-ops.c',
))
i386_softmmu_ss.add(when: ['CONFIG_HAX', 'CONFIG_POSIX'], if_true: files('hax-posix.c'))
i386_softmmu_ss.add(when: ['CONFIG_HAX', 'CONFIG_WIN32'], if_true: files('hax-windows.c'))

View File

@ -55,7 +55,7 @@
#include "target/i386/cpu.h"
#include "qemu/guest-random.h"
#include "hvf-cpus.h"
#include "hvf-accel-ops.h"
/*
* The HVF-specific vCPU thread function. This one should only run when the host
@ -121,11 +121,26 @@ static void hvf_start_vcpu_thread(CPUState *cpu)
cpu, QEMU_THREAD_JOINABLE);
}
const CpusAccel hvf_cpus = {
.create_vcpu_thread = hvf_start_vcpu_thread,
static void hvf_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
.synchronize_post_reset = hvf_cpu_synchronize_post_reset,
.synchronize_post_init = hvf_cpu_synchronize_post_init,
.synchronize_state = hvf_cpu_synchronize_state,
.synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm,
ops->create_vcpu_thread = hvf_start_vcpu_thread;
ops->synchronize_post_reset = hvf_cpu_synchronize_post_reset;
ops->synchronize_post_init = hvf_cpu_synchronize_post_init;
ops->synchronize_state = hvf_cpu_synchronize_state;
ops->synchronize_pre_loadvm = hvf_cpu_synchronize_pre_loadvm;
};
static const TypeInfo hvf_accel_ops_type = {
.name = ACCEL_OPS_NAME("hvf"),
.parent = TYPE_ACCEL_OPS,
.class_init = hvf_accel_ops_class_init,
.abstract = true,
};
static void hvf_accel_ops_register_types(void)
{
type_register_static(&hvf_accel_ops_type);
}
type_init(hvf_accel_ops_register_types);

View File

@ -12,8 +12,6 @@
#include "sysemu/cpus.h"
extern const CpusAccel hvf_cpus;
int hvf_init_vcpu(CPUState *);
int hvf_vcpu_exec(CPUState *);
void hvf_cpu_synchronize_state(CPUState *);

View File

@ -72,7 +72,7 @@
#include "qemu/accel.h"
#include "target/i386/cpu.h"
#include "hvf-cpus.h"
#include "hvf-accel-ops.h"
HVFState *hvf_state;
@ -887,7 +887,6 @@ static int hvf_accel_init(MachineState *ms)
hvf_state = s;
memory_listener_register(&hvf_memory_listener, &address_space_memory);
cpus_register_accel(&hvf_cpus);
return 0;
}

View File

@ -1,6 +1,6 @@
i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
'hvf.c',
'hvf-cpus.c',
'hvf-accel-ops.c',
'x86.c',
'x86_cpuid.c',
'x86_decode.c',

View File

@ -32,7 +32,7 @@
#include <Hypervisor/hv.h>
#include <Hypervisor/hv_vmx.h>
#include "hvf-cpus.h"
#include "hvf-accel-ops.h"
void hvf_set_segment(struct CPUState *cpu, struct vmx_segment *vmx_seg,
SegmentCache *qseg, bool is_tr)

View File

@ -1,5 +1,5 @@
i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files(
'whpx-all.c',
'whpx-apic.c',
'whpx-cpus.c',
'whpx-accel-ops.c',
))

View File

@ -16,7 +16,7 @@
#include "sysemu/whpx.h"
#include "whpx-internal.h"
#include "whpx-cpus.h"
#include "whpx-accel-ops.h"
static void *whpx_cpu_thread_fn(void *arg)
{
@ -83,12 +83,29 @@ static void whpx_kick_vcpu_thread(CPUState *cpu)
}
}
const CpusAccel whpx_cpus = {
.create_vcpu_thread = whpx_start_vcpu_thread,
.kick_vcpu_thread = whpx_kick_vcpu_thread,
static void whpx_accel_ops_class_init(ObjectClass *oc, void *data)
{
AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
.synchronize_post_reset = whpx_cpu_synchronize_post_reset,
.synchronize_post_init = whpx_cpu_synchronize_post_init,
.synchronize_state = whpx_cpu_synchronize_state,
.synchronize_pre_loadvm = whpx_cpu_synchronize_pre_loadvm,
ops->create_vcpu_thread = whpx_start_vcpu_thread;
ops->kick_vcpu_thread = whpx_kick_vcpu_thread;
ops->synchronize_post_reset = whpx_cpu_synchronize_post_reset;
ops->synchronize_post_init = whpx_cpu_synchronize_post_init;
ops->synchronize_state = whpx_cpu_synchronize_state;
ops->synchronize_pre_loadvm = whpx_cpu_synchronize_pre_loadvm;
}
static const TypeInfo whpx_accel_ops_type = {
.name = ACCEL_OPS_NAME("whpx"),
.parent = TYPE_ACCEL_OPS,
.class_init = whpx_accel_ops_class_init,
.abstract = true,
};
static void whpx_accel_ops_register_types(void)
{
type_register_static(&whpx_accel_ops_type);
}
type_init(whpx_accel_ops_register_types);

View File

@ -12,8 +12,6 @@
#include "sysemu/cpus.h"
extern const CpusAccel whpx_cpus;
int whpx_init_vcpu(CPUState *cpu);
int whpx_vcpu_exec(CPUState *cpu);
void whpx_destroy_vcpu(CPUState *cpu);

View File

@ -28,8 +28,11 @@
#include "migration/blocker.h"
#include <winerror.h>
#include "whpx-cpus.h"
#include "whpx-internal.h"
#include "whpx-accel-ops.h"
#include <WinHvPlatform.h>
#include <WinHvEmulation.h>
#define HYPERV_APIC_BUS_FREQUENCY (200000000ULL)
@ -1846,8 +1849,6 @@ static int whpx_accel_init(MachineState *ms)
whpx_memory_init();
cpus_register_accel(&whpx_cpus);
printf("Windows Hypervisor Platform accelerator is operational\n");
return 0;