aboutsummaryrefslogtreecommitdiff
path: root/accel
diff options
context:
space:
mode:
Diffstat (limited to 'accel')
-rw-r--r--accel/accel-common.c11
-rw-r--r--accel/accel-softmmu.c44
-rw-r--r--accel/accel-softmmu.h15
-rw-r--r--accel/kvm/kvm-accel-ops.c (renamed from accel/kvm/kvm-cpus.c)28
-rw-r--r--accel/kvm/kvm-all.c2
-rw-r--r--accel/kvm/kvm-cpus.h2
-rw-r--r--accel/kvm/meson.build2
-rw-r--r--accel/qtest/qtest.c23
-rw-r--r--accel/tcg/meson.build8
-rw-r--r--accel/tcg/tcg-accel-ops-icount.c (renamed from accel/tcg/tcg-cpus-icount.c)21
-rw-r--r--accel/tcg/tcg-accel-ops-icount.h (renamed from accel/tcg/tcg-cpus-icount.h)2
-rw-r--r--accel/tcg/tcg-accel-ops-mttcg.c (renamed from accel/tcg/tcg-cpus-mttcg.c)14
-rw-r--r--accel/tcg/tcg-accel-ops-mttcg.h19
-rw-r--r--accel/tcg/tcg-accel-ops-rr.c (renamed from accel/tcg/tcg-cpus-rr.c)13
-rw-r--r--accel/tcg/tcg-accel-ops-rr.h (renamed from accel/tcg/tcg-cpus-rr.h)0
-rw-r--r--accel/tcg/tcg-accel-ops.c (renamed from accel/tcg/tcg-cpus.c)47
-rw-r--r--accel/tcg/tcg-accel-ops.h (renamed from accel/tcg/tcg-cpus.h)6
-rw-r--r--accel/tcg/tcg-all.c12
-rw-r--r--accel/xen/xen-all.c24
19 files changed, 207 insertions, 86 deletions
diff --git a/accel/accel-common.c b/accel/accel-common.c
index ddec8cb5ae..6b59873419 100644
--- a/accel/accel-common.c
+++ b/accel/accel-common.c
@@ -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);
diff --git a/accel/accel-softmmu.c b/accel/accel-softmmu.c
index f89da8f9d1..50fa5acaa4 100644
--- a/accel/accel-softmmu.c
+++ b/accel/accel-softmmu.c
@@ -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);
diff --git a/accel/accel-softmmu.h b/accel/accel-softmmu.h
new file mode 100644
index 0000000000..5e192f1882
--- /dev/null
+++ b/accel/accel-softmmu.h
@@ -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 */
diff --git a/accel/kvm/kvm-cpus.c b/accel/kvm/kvm-accel-ops.c
index d809b1e74c..7516c67a3f 100644
--- a/accel/kvm/kvm-cpus.c
+++ b/accel/kvm/kvm-accel-ops.c
@@ -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);
+
+ 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"),
- .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,
+ .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);
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index 3feb17d965..5164d838b9 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -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:
diff --git a/accel/kvm/kvm-cpus.h b/accel/kvm/kvm-cpus.h
index 3df732b816..bf0bd1bee4 100644
--- a/accel/kvm/kvm-cpus.h
+++ b/accel/kvm/kvm-cpus.h
@@ -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);
diff --git a/accel/kvm/meson.build b/accel/kvm/meson.build
index 7e9dafe24c..8d219bea50 100644
--- a/accel/kvm/meson.build
+++ b/accel/kvm/meson.build
@@ -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'))
diff --git a/accel/qtest/qtest.c b/accel/qtest/qtest.c
index b4e731cb2b..edb29f6fa4 100644
--- a/accel/qtest/qtest.c
+++ b/accel/qtest/qtest.c
@@ -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);
diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
index 424d9bb1fc..1236ac7b91 100644
--- a/accel/tcg/meson.build
+++ b/accel/tcg/meson.build
@@ -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'
))
diff --git a/accel/tcg/tcg-cpus-icount.c b/accel/tcg/tcg-accel-ops-icount.c
index 9f45432275..87762b469c 100644
--- a/accel/tcg/tcg-cpus-icount.c
+++ b/accel/tcg/tcg-accel-ops-icount.c
@@ -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,
-};
diff --git a/accel/tcg/tcg-cpus-icount.h b/accel/tcg/tcg-accel-ops-icount.h
index b695939dfa..d884aa2aaa 100644
--- a/accel/tcg/tcg-cpus-icount.h
+++ b/accel/tcg/tcg-accel-ops-icount.h
@@ -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 */
diff --git a/accel/tcg/tcg-cpus-mttcg.c b/accel/tcg/tcg-accel-ops-mttcg.c
index 9c3767d260..42973fb062 100644
--- a/accel/tcg/tcg-cpus-mttcg.c
+++ b/accel/tcg/tcg-accel-ops-mttcg.c
@@ -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,
-};
diff --git a/accel/tcg/tcg-accel-ops-mttcg.h b/accel/tcg/tcg-accel-ops-mttcg.h
new file mode 100644
index 0000000000..9fdc5a2ab5
--- /dev/null
+++ b/accel/tcg/tcg-accel-ops-mttcg.h
@@ -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 */
diff --git a/accel/tcg/tcg-cpus-rr.c b/accel/tcg/tcg-accel-ops-rr.c
index 0181d2e4eb..4a66055e0d 100644
--- a/accel/tcg/tcg-cpus-rr.c
+++ b/accel/tcg/tcg-accel-ops-rr.c
@@ -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,
-};
diff --git a/accel/tcg/tcg-cpus-rr.h b/accel/tcg/tcg-accel-ops-rr.h
index 54f6ae6e86..54f6ae6e86 100644
--- a/accel/tcg/tcg-cpus-rr.h
+++ b/accel/tcg/tcg-accel-ops-rr.h
diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-accel-ops.c
index e335f9f155..6144d9df87 100644
--- a/accel/tcg/tcg-cpus.c
+++ b/accel/tcg/tcg-accel-ops.c
@@ -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);
diff --git a/accel/tcg/tcg-cpus.h b/accel/tcg/tcg-accel-ops.h
index d6893a32f8..48130006de 100644
--- a/accel/tcg/tcg-cpus.h
+++ b/accel/tcg/tcg-accel-ops.h
@@ -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 */
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 642a7b94a7..e378c2db73 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -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;
diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c
index 594aaf6b49..e9d2d6aaaa 100644
--- a/accel/xen/xen-all.c
+++ b/accel/xen/xen-all.c
@@ -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);