* [RFC v8 01/27] accel/tcg: split CpusAccel into three TCG variants
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:14 ` [RFC v8 02/27] accel/tcg: split tcg_start_vcpu_thread Claudio Fontana
` (26 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Philippe Mathieu-Daudé,
Eduardo Habkost, Paul Durrant, Jason Wang, Marcelo Tosatti,
qemu-devel, Peter Xu, Dario Faggioli, Cameron Esfahani,
haxm-team, Claudio Fontana, Anthony Perard, Bruce Rogers,
Olaf Hering, Emilio G . Cota, Colin Xu
split up the CpusAccel tcg_cpus into three TCG variants:
tcg_cpus_rr (single threaded, round robin cpus)
tcg_cpus_icount (same as rr, but with instruction counting enabled)
tcg_cpus_mttcg (multi-threaded cpus)
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
accel/tcg/meson.build | 9 +-
accel/tcg/tcg-all.c | 8 +-
accel/tcg/tcg-cpus-icount.c | 147 +++++++++++
accel/tcg/tcg-cpus-icount.h | 17 ++
accel/tcg/tcg-cpus-mttcg.c | 117 +++++++++
accel/tcg/tcg-cpus-mttcg.h | 21 ++
accel/tcg/tcg-cpus-rr.c | 270 ++++++++++++++++++++
accel/tcg/tcg-cpus-rr.h | 20 ++
accel/tcg/tcg-cpus.c | 484 ++----------------------------------
accel/tcg/tcg-cpus.h | 13 +-
softmmu/icount.c | 2 +-
11 files changed, 646 insertions(+), 462 deletions(-)
create mode 100644 accel/tcg/tcg-cpus-icount.c
create mode 100644 accel/tcg/tcg-cpus-icount.h
create mode 100644 accel/tcg/tcg-cpus-mttcg.c
create mode 100644 accel/tcg/tcg-cpus-mttcg.h
create mode 100644 accel/tcg/tcg-cpus-rr.c
create mode 100644 accel/tcg/tcg-cpus-rr.h
diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
index 19b9343d5b..f39aab0a0c 100644
--- a/accel/tcg/meson.build
+++ b/accel/tcg/meson.build
@@ -12,4 +12,11 @@ tcg_ss.add(when: 'CONFIG_SOFTMMU', if_false: files('user-exec-stub.c'))
tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c'), libdl])
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
-specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files('tcg-all.c', 'cputlb.c', 'tcg-cpus.c'))
+specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files(
+ 'tcg-all.c',
+ 'cputlb.c',
+ 'tcg-cpus.c',
+ 'tcg-cpus-mttcg.c',
+ 'tcg-cpus-icount.c',
+ 'tcg-cpus-rr.c'
+))
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index fa1208158f..e42a028043 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -104,8 +104,14 @@ static int tcg_init(MachineState *ms)
tcg_exec_init(s->tb_size * 1024 * 1024);
mttcg_enabled = s->mttcg_enabled;
- cpus_register_accel(&tcg_cpus);
+ 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);
+ }
return 0;
}
diff --git a/accel/tcg/tcg-cpus-icount.c b/accel/tcg/tcg-cpus-icount.c
new file mode 100644
index 0000000000..d3af3afb6d
--- /dev/null
+++ b/accel/tcg/tcg-cpus-icount.c
@@ -0,0 +1,147 @@
+/*
+ * QEMU TCG Single Threaded vCPUs implementation using instruction counting
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2014 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/tcg.h"
+#include "sysemu/replay.h"
+#include "qemu/main-loop.h"
+#include "qemu/guest-random.h"
+#include "exec/exec-all.h"
+#include "hw/boards.h"
+
+#include "tcg-cpus.h"
+#include "tcg-cpus-icount.h"
+#include "tcg-cpus-rr.h"
+
+static int64_t tcg_get_icount_limit(void)
+{
+ int64_t deadline;
+
+ if (replay_mode != REPLAY_MODE_PLAY) {
+ /*
+ * Include all the timers, because they may need an attention.
+ * Too long CPU execution may create unnecessary delay in UI.
+ */
+ deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+ QEMU_TIMER_ATTR_ALL);
+ /* Check realtime timers, because they help with input processing */
+ deadline = qemu_soonest_timeout(deadline,
+ qemu_clock_deadline_ns_all(QEMU_CLOCK_REALTIME,
+ QEMU_TIMER_ATTR_ALL));
+
+ /*
+ * Maintain prior (possibly buggy) behaviour where if no deadline
+ * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
+ * INT32_MAX nanoseconds ahead, we still use INT32_MAX
+ * nanoseconds.
+ */
+ if ((deadline < 0) || (deadline > INT32_MAX)) {
+ deadline = INT32_MAX;
+ }
+
+ return icount_round(deadline);
+ } else {
+ return replay_get_instructions();
+ }
+}
+
+static void notify_aio_contexts(void)
+{
+ /* Wake up other AioContexts. */
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
+}
+
+void handle_icount_deadline(void)
+{
+ assert(qemu_in_vcpu_thread());
+ int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+ QEMU_TIMER_ATTR_ALL);
+
+ if (deadline == 0) {
+ notify_aio_contexts();
+ }
+}
+
+void prepare_icount_for_run(CPUState *cpu)
+{
+ int insns_left;
+
+ /*
+ * These should always be cleared by process_icount_data after
+ * each vCPU execution. However u16.high can be raised
+ * 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);
+
+ cpu->icount_budget = tcg_get_icount_limit();
+ insns_left = MIN(0xffff, cpu->icount_budget);
+ cpu_neg(cpu)->icount_decr.u16.low = insns_left;
+ cpu->icount_extra = cpu->icount_budget - insns_left;
+
+ replay_mutex_lock();
+
+ if (cpu->icount_budget == 0 && replay_has_checkpoint()) {
+ notify_aio_contexts();
+ }
+}
+
+void process_icount_data(CPUState *cpu)
+{
+ /* Account for executed instructions */
+ icount_update(cpu);
+
+ /* Reset the counters */
+ cpu_neg(cpu)->icount_decr.u16.low = 0;
+ cpu->icount_extra = 0;
+ cpu->icount_budget = 0;
+
+ replay_account_executed_instructions();
+
+ replay_mutex_unlock();
+}
+
+static void icount_handle_interrupt(CPUState *cpu, int mask)
+{
+ int old_mask = cpu->interrupt_request;
+
+ 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 = tcg_start_vcpu_thread,
+ .kick_vcpu_thread = qemu_cpu_kick_rr_cpus,
+
+ .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-cpus-icount.h
new file mode 100644
index 0000000000..cbcf76b413
--- /dev/null
+++ b/accel/tcg/tcg-cpus-icount.h
@@ -0,0 +1,17 @@
+/*
+ * QEMU TCG Single Threaded vCPUs implementation using instruction counting
+ *
+ * Copyright 2020 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_ICOUNT_H
+#define TCG_CPUS_ICOUNT_H
+
+void handle_icount_deadline(void);
+void prepare_icount_for_run(CPUState *cpu);
+void process_icount_data(CPUState *cpu);
+
+#endif /* TCG_CPUS_ICOUNT_H */
diff --git a/accel/tcg/tcg-cpus-mttcg.c b/accel/tcg/tcg-cpus-mttcg.c
new file mode 100644
index 0000000000..dac724fc85
--- /dev/null
+++ b/accel/tcg/tcg-cpus-mttcg.c
@@ -0,0 +1,117 @@
+/*
+ * QEMU TCG Multi Threaded vCPUs implementation
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2014 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/tcg.h"
+#include "sysemu/replay.h"
+#include "qemu/main-loop.h"
+#include "qemu/guest-random.h"
+#include "exec/exec-all.h"
+#include "hw/boards.h"
+
+#include "tcg-cpus.h"
+#include "tcg-cpus-mttcg.h"
+
+/*
+ * In the multi-threaded case each vCPU has its own thread. The TLS
+ * variable current_cpu can be used deep in the code to find the
+ * current CPUState for a given thread.
+ */
+
+void *tcg_cpu_thread_fn(void *arg)
+{
+ CPUState *cpu = arg;
+
+ assert(tcg_enabled());
+ g_assert(!icount_enabled());
+
+ rcu_register_thread();
+ tcg_register_thread();
+
+ qemu_mutex_lock_iothread();
+ qemu_thread_get_self(cpu->thread);
+
+ cpu->thread_id = qemu_get_thread_id();
+ cpu->can_do_io = 1;
+ current_cpu = cpu;
+ cpu_thread_signal_created(cpu);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
+
+ /* process any pending work */
+ cpu->exit_request = 1;
+
+ do {
+ if (cpu_can_run(cpu)) {
+ int r;
+ qemu_mutex_unlock_iothread();
+ r = tcg_cpu_exec(cpu);
+ qemu_mutex_lock_iothread();
+ switch (r) {
+ case EXCP_DEBUG:
+ cpu_handle_guest_debug(cpu);
+ break;
+ case EXCP_HALTED:
+ /*
+ * during start-up the vCPU is reset and the thread is
+ * kicked several times. If we don't ensure we go back
+ * to sleep in the halted state we won't cleanly
+ * start-up when the vCPU is enabled.
+ *
+ * cpu->halted should ensure we sleep in wait_io_event
+ */
+ g_assert(cpu->halted);
+ break;
+ case EXCP_ATOMIC:
+ qemu_mutex_unlock_iothread();
+ cpu_exec_step_atomic(cpu);
+ qemu_mutex_lock_iothread();
+ default:
+ /* Ignore everything else? */
+ break;
+ }
+ }
+
+ qatomic_mb_set(&cpu->exit_request, 0);
+ qemu_wait_io_event(cpu);
+ } while (!cpu->unplug || cpu_can_run(cpu));
+
+ qemu_tcg_destroy_vcpu(cpu);
+ qemu_mutex_unlock_iothread();
+ rcu_unregister_thread();
+ return NULL;
+}
+
+static void mttcg_kick_vcpu_thread(CPUState *cpu)
+{
+ cpu_exit(cpu);
+}
+
+const CpusAccel tcg_cpus_mttcg = {
+ .create_vcpu_thread = tcg_start_vcpu_thread,
+ .kick_vcpu_thread = mttcg_kick_vcpu_thread,
+
+ .handle_interrupt = tcg_handle_interrupt,
+};
diff --git a/accel/tcg/tcg-cpus-mttcg.h b/accel/tcg/tcg-cpus-mttcg.h
new file mode 100644
index 0000000000..d1bd771f49
--- /dev/null
+++ b/accel/tcg/tcg-cpus-mttcg.h
@@ -0,0 +1,21 @@
+/*
+ * QEMU TCG Multi Threaded vCPUs implementation
+ *
+ * Copyright 2020 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
+
+/*
+ * In the multi-threaded case each vCPU has its own thread. The TLS
+ * variable current_cpu can be used deep in the code to find the
+ * current CPUState for a given thread.
+ */
+
+void *tcg_cpu_thread_fn(void *arg);
+
+#endif /* TCG_CPUS_MTTCG_H */
diff --git a/accel/tcg/tcg-cpus-rr.c b/accel/tcg/tcg-cpus-rr.c
new file mode 100644
index 0000000000..ad50a3765f
--- /dev/null
+++ b/accel/tcg/tcg-cpus-rr.c
@@ -0,0 +1,270 @@
+/*
+ * QEMU TCG Single Threaded vCPUs implementation
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2014 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu-common.h"
+#include "sysemu/tcg.h"
+#include "sysemu/replay.h"
+#include "qemu/main-loop.h"
+#include "qemu/guest-random.h"
+#include "exec/exec-all.h"
+#include "hw/boards.h"
+
+#include "tcg-cpus.h"
+#include "tcg-cpus-rr.h"
+#include "tcg-cpus-icount.h"
+
+/* Kick all RR vCPUs */
+void qemu_cpu_kick_rr_cpus(CPUState *unused)
+{
+ CPUState *cpu;
+
+ CPU_FOREACH(cpu) {
+ cpu_exit(cpu);
+ };
+}
+
+/*
+ * TCG vCPU kick timer
+ *
+ * The kick timer is responsible for moving single threaded vCPU
+ * emulation on to the next vCPU. If more than one vCPU is running a
+ * timer event with force a cpu->exit so the next vCPU can get
+ * scheduled.
+ *
+ * The timer is removed if all vCPUs are idle and restarted again once
+ * idleness is complete.
+ */
+
+static QEMUTimer *tcg_kick_vcpu_timer;
+static CPUState *tcg_current_rr_cpu;
+
+#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
+
+static inline int64_t qemu_tcg_next_kick(void)
+{
+ return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;
+}
+
+/* Kick the currently round-robin scheduled vCPU to next */
+static void qemu_cpu_kick_rr_next_cpu(void)
+{
+ CPUState *cpu;
+ do {
+ cpu = qatomic_mb_read(&tcg_current_rr_cpu);
+ if (cpu) {
+ cpu_exit(cpu);
+ }
+ } while (cpu != qatomic_mb_read(&tcg_current_rr_cpu));
+}
+
+static void kick_tcg_thread(void *opaque)
+{
+ timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
+ qemu_cpu_kick_rr_next_cpu();
+}
+
+static void start_tcg_kick_timer(void)
+{
+ if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
+ tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ kick_tcg_thread, NULL);
+ }
+ if (tcg_kick_vcpu_timer && !timer_pending(tcg_kick_vcpu_timer)) {
+ timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
+ }
+}
+
+static void stop_tcg_kick_timer(void)
+{
+ if (tcg_kick_vcpu_timer && timer_pending(tcg_kick_vcpu_timer)) {
+ timer_del(tcg_kick_vcpu_timer);
+ }
+}
+
+static void qemu_tcg_rr_wait_io_event(void)
+{
+ CPUState *cpu;
+
+ while (all_cpu_threads_idle()) {
+ stop_tcg_kick_timer();
+ qemu_cond_wait_iothread(first_cpu->halt_cond);
+ }
+
+ start_tcg_kick_timer();
+
+ CPU_FOREACH(cpu) {
+ qemu_wait_io_event_common(cpu);
+ }
+}
+
+/*
+ * Destroy any remaining vCPUs which have been unplugged and have
+ * finished running
+ */
+static void deal_with_unplugged_cpus(void)
+{
+ CPUState *cpu;
+
+ CPU_FOREACH(cpu) {
+ if (cpu->unplug && !cpu_can_run(cpu)) {
+ qemu_tcg_destroy_vcpu(cpu);
+ break;
+ }
+ }
+}
+
+/*
+ * In the single-threaded case each vCPU is simulated in turn. If
+ * there is more than a single vCPU we create a simple timer to kick
+ * the vCPU and ensure we don't get stuck in a tight loop in one vCPU.
+ * This is done explicitly rather than relying on side-effects
+ * elsewhere.
+ */
+
+void *tcg_rr_cpu_thread_fn(void *arg)
+{
+ CPUState *cpu = arg;
+
+ assert(tcg_enabled());
+ rcu_register_thread();
+ tcg_register_thread();
+
+ qemu_mutex_lock_iothread();
+ qemu_thread_get_self(cpu->thread);
+
+ cpu->thread_id = qemu_get_thread_id();
+ cpu->can_do_io = 1;
+ cpu_thread_signal_created(cpu);
+ qemu_guest_random_seed_thread_part2(cpu->random_seed);
+
+ /* wait for initial kick-off after machine start */
+ while (first_cpu->stopped) {
+ qemu_cond_wait_iothread(first_cpu->halt_cond);
+
+ /* process any pending work */
+ CPU_FOREACH(cpu) {
+ current_cpu = cpu;
+ qemu_wait_io_event_common(cpu);
+ }
+ }
+
+ start_tcg_kick_timer();
+
+ cpu = first_cpu;
+
+ /* process any pending work */
+ cpu->exit_request = 1;
+
+ while (1) {
+ qemu_mutex_unlock_iothread();
+ replay_mutex_lock();
+ qemu_mutex_lock_iothread();
+
+ if (icount_enabled()) {
+ /* Account partial waits to QEMU_CLOCK_VIRTUAL. */
+ icount_account_warp_timer();
+ /*
+ * Run the timers here. This is much more efficient than
+ * waking up the I/O thread and waiting for completion.
+ */
+ handle_icount_deadline();
+ }
+
+ replay_mutex_unlock();
+
+ if (!cpu) {
+ cpu = first_cpu;
+ }
+
+ while (cpu && cpu_work_list_empty(cpu) && !cpu->exit_request) {
+
+ qatomic_mb_set(&tcg_current_rr_cpu, cpu);
+ current_cpu = cpu;
+
+ qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
+ (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
+
+ if (cpu_can_run(cpu)) {
+ int r;
+
+ qemu_mutex_unlock_iothread();
+ if (icount_enabled()) {
+ prepare_icount_for_run(cpu);
+ }
+ r = tcg_cpu_exec(cpu);
+ if (icount_enabled()) {
+ process_icount_data(cpu);
+ }
+ qemu_mutex_lock_iothread();
+
+ if (r == EXCP_DEBUG) {
+ cpu_handle_guest_debug(cpu);
+ break;
+ } else if (r == EXCP_ATOMIC) {
+ qemu_mutex_unlock_iothread();
+ cpu_exec_step_atomic(cpu);
+ qemu_mutex_lock_iothread();
+ break;
+ }
+ } else if (cpu->stop) {
+ if (cpu->unplug) {
+ cpu = CPU_NEXT(cpu);
+ }
+ break;
+ }
+
+ cpu = CPU_NEXT(cpu);
+ } /* while (cpu && !cpu->exit_request).. */
+
+ /* Does not need qatomic_mb_set because a spurious wakeup is okay. */
+ qatomic_set(&tcg_current_rr_cpu, NULL);
+
+ if (cpu && cpu->exit_request) {
+ qatomic_mb_set(&cpu->exit_request, 0);
+ }
+
+ if (icount_enabled() && all_cpu_threads_idle()) {
+ /*
+ * When all cpus are sleeping (e.g in WFI), to avoid a deadlock
+ * in the main_loop, wake it up in order to start the warp timer.
+ */
+ qemu_notify_event();
+ }
+
+ qemu_tcg_rr_wait_io_event();
+ deal_with_unplugged_cpus();
+ }
+
+ rcu_unregister_thread();
+ return NULL;
+}
+
+const CpusAccel tcg_cpus_rr = {
+ .create_vcpu_thread = tcg_start_vcpu_thread,
+ .kick_vcpu_thread = qemu_cpu_kick_rr_cpus,
+
+ .handle_interrupt = tcg_handle_interrupt,
+};
diff --git a/accel/tcg/tcg-cpus-rr.h b/accel/tcg/tcg-cpus-rr.h
new file mode 100644
index 0000000000..1936fd16ab
--- /dev/null
+++ b/accel/tcg/tcg-cpus-rr.h
@@ -0,0 +1,20 @@
+/*
+ * QEMU TCG Single Threaded vCPUs implementation
+ *
+ * Copyright 2020 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_RR_H
+#define TCG_CPUS_RR_H
+
+#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
+
+/* Kick all RR vCPUs. */
+void qemu_cpu_kick_rr_cpus(CPUState *unused);
+
+void *tcg_rr_cpu_thread_fn(void *arg);
+
+#endif /* TCG_CPUS_RR_H */
diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-cpus.c
index da1c63d8f6..f2b9bbf99e 100644
--- a/accel/tcg/tcg-cpus.c
+++ b/accel/tcg/tcg-cpus.c
@@ -1,5 +1,7 @@
/*
- * QEMU System Emulator
+ * QEMU TCG vCPU common functionality
+ *
+ * Functionality common to all TCG vCPU variants: mttcg, rr and icount.
*
* Copyright (c) 2003-2008 Fabrice Bellard
* Copyright (c) 2014 Red Hat Inc.
@@ -33,436 +35,12 @@
#include "hw/boards.h"
#include "tcg-cpus.h"
+#include "tcg-cpus-mttcg.h"
+#include "tcg-cpus-rr.h"
-/* Kick all RR vCPUs */
-static void qemu_cpu_kick_rr_cpus(void)
-{
- CPUState *cpu;
+/* common functionality among all TCG variants */
- CPU_FOREACH(cpu) {
- cpu_exit(cpu);
- };
-}
-
-static void tcg_kick_vcpu_thread(CPUState *cpu)
-{
- if (qemu_tcg_mttcg_enabled()) {
- cpu_exit(cpu);
- } else {
- qemu_cpu_kick_rr_cpus();
- }
-}
-
-/*
- * TCG vCPU kick timer
- *
- * The kick timer is responsible for moving single threaded vCPU
- * emulation on to the next vCPU. If more than one vCPU is running a
- * timer event with force a cpu->exit so the next vCPU can get
- * scheduled.
- *
- * The timer is removed if all vCPUs are idle and restarted again once
- * idleness is complete.
- */
-
-static QEMUTimer *tcg_kick_vcpu_timer;
-static CPUState *tcg_current_rr_cpu;
-
-#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
-
-static inline int64_t qemu_tcg_next_kick(void)
-{
- return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;
-}
-
-/* Kick the currently round-robin scheduled vCPU to next */
-static void qemu_cpu_kick_rr_next_cpu(void)
-{
- CPUState *cpu;
- do {
- cpu = qatomic_mb_read(&tcg_current_rr_cpu);
- if (cpu) {
- cpu_exit(cpu);
- }
- } while (cpu != qatomic_mb_read(&tcg_current_rr_cpu));
-}
-
-static void kick_tcg_thread(void *opaque)
-{
- timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
- qemu_cpu_kick_rr_next_cpu();
-}
-
-static void start_tcg_kick_timer(void)
-{
- assert(!mttcg_enabled);
- if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
- tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
- kick_tcg_thread, NULL);
- }
- if (tcg_kick_vcpu_timer && !timer_pending(tcg_kick_vcpu_timer)) {
- timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
- }
-}
-
-static void stop_tcg_kick_timer(void)
-{
- assert(!mttcg_enabled);
- if (tcg_kick_vcpu_timer && timer_pending(tcg_kick_vcpu_timer)) {
- timer_del(tcg_kick_vcpu_timer);
- }
-}
-
-static void qemu_tcg_destroy_vcpu(CPUState *cpu)
-{
-}
-
-static void qemu_tcg_rr_wait_io_event(void)
-{
- CPUState *cpu;
-
- while (all_cpu_threads_idle()) {
- stop_tcg_kick_timer();
- qemu_cond_wait_iothread(first_cpu->halt_cond);
- }
-
- start_tcg_kick_timer();
-
- CPU_FOREACH(cpu) {
- qemu_wait_io_event_common(cpu);
- }
-}
-
-static int64_t tcg_get_icount_limit(void)
-{
- int64_t deadline;
-
- if (replay_mode != REPLAY_MODE_PLAY) {
- /*
- * Include all the timers, because they may need an attention.
- * Too long CPU execution may create unnecessary delay in UI.
- */
- deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
- QEMU_TIMER_ATTR_ALL);
- /* Check realtime timers, because they help with input processing */
- deadline = qemu_soonest_timeout(deadline,
- qemu_clock_deadline_ns_all(QEMU_CLOCK_REALTIME,
- QEMU_TIMER_ATTR_ALL));
-
- /*
- * Maintain prior (possibly buggy) behaviour where if no deadline
- * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
- * INT32_MAX nanoseconds ahead, we still use INT32_MAX
- * nanoseconds.
- */
- if ((deadline < 0) || (deadline > INT32_MAX)) {
- deadline = INT32_MAX;
- }
-
- return icount_round(deadline);
- } else {
- return replay_get_instructions();
- }
-}
-
-static void notify_aio_contexts(void)
-{
- /* Wake up other AioContexts. */
- qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
- qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
-}
-
-static void handle_icount_deadline(void)
-{
- assert(qemu_in_vcpu_thread());
- if (icount_enabled()) {
- int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
- QEMU_TIMER_ATTR_ALL);
-
- if (deadline == 0) {
- notify_aio_contexts();
- }
- }
-}
-
-static void prepare_icount_for_run(CPUState *cpu)
-{
- if (icount_enabled()) {
- int insns_left;
-
- /*
- * These should always be cleared by process_icount_data after
- * each vCPU execution. However u16.high can be raised
- * 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);
-
- cpu->icount_budget = tcg_get_icount_limit();
- insns_left = MIN(0xffff, cpu->icount_budget);
- cpu_neg(cpu)->icount_decr.u16.low = insns_left;
- cpu->icount_extra = cpu->icount_budget - insns_left;
-
- replay_mutex_lock();
-
- if (cpu->icount_budget == 0 && replay_has_checkpoint()) {
- notify_aio_contexts();
- }
- }
-}
-
-static void process_icount_data(CPUState *cpu)
-{
- if (icount_enabled()) {
- /* Account for executed instructions */
- icount_update(cpu);
-
- /* Reset the counters */
- cpu_neg(cpu)->icount_decr.u16.low = 0;
- cpu->icount_extra = 0;
- cpu->icount_budget = 0;
-
- replay_account_executed_instructions();
-
- replay_mutex_unlock();
- }
-}
-
-static int tcg_cpu_exec(CPUState *cpu)
-{
- int ret;
-#ifdef CONFIG_PROFILER
- int64_t ti;
-#endif
-
- assert(tcg_enabled());
-#ifdef CONFIG_PROFILER
- ti = profile_getclock();
-#endif
- cpu_exec_start(cpu);
- ret = cpu_exec(cpu);
- cpu_exec_end(cpu);
-#ifdef CONFIG_PROFILER
- qatomic_set(&tcg_ctx->prof.cpu_exec_time,
- tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti);
-#endif
- return ret;
-}
-
-/*
- * Destroy any remaining vCPUs which have been unplugged and have
- * finished running
- */
-static void deal_with_unplugged_cpus(void)
-{
- CPUState *cpu;
-
- CPU_FOREACH(cpu) {
- if (cpu->unplug && !cpu_can_run(cpu)) {
- qemu_tcg_destroy_vcpu(cpu);
- cpu_thread_signal_destroyed(cpu);
- break;
- }
- }
-}
-
-/*
- * Single-threaded TCG
- *
- * In the single-threaded case each vCPU is simulated in turn. If
- * there is more than a single vCPU we create a simple timer to kick
- * the vCPU and ensure we don't get stuck in a tight loop in one vCPU.
- * This is done explicitly rather than relying on side-effects
- * elsewhere.
- */
-
-static void *tcg_rr_cpu_thread_fn(void *arg)
-{
- CPUState *cpu = arg;
-
- assert(tcg_enabled());
- rcu_register_thread();
- tcg_register_thread();
-
- qemu_mutex_lock_iothread();
- qemu_thread_get_self(cpu->thread);
-
- cpu->thread_id = qemu_get_thread_id();
- cpu->can_do_io = 1;
- cpu_thread_signal_created(cpu);
- qemu_guest_random_seed_thread_part2(cpu->random_seed);
-
- /* wait for initial kick-off after machine start */
- while (first_cpu->stopped) {
- qemu_cond_wait_iothread(first_cpu->halt_cond);
-
- /* process any pending work */
- CPU_FOREACH(cpu) {
- current_cpu = cpu;
- qemu_wait_io_event_common(cpu);
- }
- }
-
- start_tcg_kick_timer();
-
- cpu = first_cpu;
-
- /* process any pending work */
- cpu->exit_request = 1;
-
- while (1) {
- qemu_mutex_unlock_iothread();
- replay_mutex_lock();
- qemu_mutex_lock_iothread();
- /* Account partial waits to QEMU_CLOCK_VIRTUAL. */
- icount_account_warp_timer();
-
- /*
- * Run the timers here. This is much more efficient than
- * waking up the I/O thread and waiting for completion.
- */
- handle_icount_deadline();
-
- replay_mutex_unlock();
-
- if (!cpu) {
- cpu = first_cpu;
- }
-
- while (cpu && cpu_work_list_empty(cpu) && !cpu->exit_request) {
-
- qatomic_mb_set(&tcg_current_rr_cpu, cpu);
- current_cpu = cpu;
-
- qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
- (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
-
- if (cpu_can_run(cpu)) {
- int r;
-
- qemu_mutex_unlock_iothread();
- prepare_icount_for_run(cpu);
-
- r = tcg_cpu_exec(cpu);
-
- process_icount_data(cpu);
- qemu_mutex_lock_iothread();
-
- if (r == EXCP_DEBUG) {
- cpu_handle_guest_debug(cpu);
- break;
- } else if (r == EXCP_ATOMIC) {
- qemu_mutex_unlock_iothread();
- cpu_exec_step_atomic(cpu);
- qemu_mutex_lock_iothread();
- break;
- }
- } else if (cpu->stop) {
- if (cpu->unplug) {
- cpu = CPU_NEXT(cpu);
- }
- break;
- }
-
- cpu = CPU_NEXT(cpu);
- } /* while (cpu && !cpu->exit_request).. */
-
- /* Does not need qatomic_mb_set because a spurious wakeup is okay. */
- qatomic_set(&tcg_current_rr_cpu, NULL);
-
- if (cpu && cpu->exit_request) {
- qatomic_mb_set(&cpu->exit_request, 0);
- }
-
- if (icount_enabled() && all_cpu_threads_idle()) {
- /*
- * When all cpus are sleeping (e.g in WFI), to avoid a deadlock
- * in the main_loop, wake it up in order to start the warp timer.
- */
- qemu_notify_event();
- }
-
- qemu_tcg_rr_wait_io_event();
- deal_with_unplugged_cpus();
- }
-
- rcu_unregister_thread();
- return NULL;
-}
-
-/*
- * Multi-threaded TCG
- *
- * In the multi-threaded case each vCPU has its own thread. The TLS
- * variable current_cpu can be used deep in the code to find the
- * current CPUState for a given thread.
- */
-
-static void *tcg_cpu_thread_fn(void *arg)
-{
- CPUState *cpu = arg;
-
- assert(tcg_enabled());
- g_assert(!icount_enabled());
-
- rcu_register_thread();
- tcg_register_thread();
-
- qemu_mutex_lock_iothread();
- qemu_thread_get_self(cpu->thread);
-
- cpu->thread_id = qemu_get_thread_id();
- cpu->can_do_io = 1;
- current_cpu = cpu;
- cpu_thread_signal_created(cpu);
- qemu_guest_random_seed_thread_part2(cpu->random_seed);
-
- /* process any pending work */
- cpu->exit_request = 1;
-
- do {
- if (cpu_can_run(cpu)) {
- int r;
- qemu_mutex_unlock_iothread();
- r = tcg_cpu_exec(cpu);
- qemu_mutex_lock_iothread();
- switch (r) {
- case EXCP_DEBUG:
- cpu_handle_guest_debug(cpu);
- break;
- case EXCP_HALTED:
- /*
- * during start-up the vCPU is reset and the thread is
- * kicked several times. If we don't ensure we go back
- * to sleep in the halted state we won't cleanly
- * start-up when the vCPU is enabled.
- *
- * cpu->halted should ensure we sleep in wait_io_event
- */
- g_assert(cpu->halted);
- break;
- case EXCP_ATOMIC:
- qemu_mutex_unlock_iothread();
- cpu_exec_step_atomic(cpu);
- qemu_mutex_lock_iothread();
- default:
- /* Ignore everything else? */
- break;
- }
- }
-
- qatomic_mb_set(&cpu->exit_request, 0);
- qemu_wait_io_event(cpu);
- } while (!cpu->unplug || cpu_can_run(cpu));
-
- qemu_tcg_destroy_vcpu(cpu);
- cpu_thread_signal_destroyed(cpu);
- qemu_mutex_unlock_iothread();
- rcu_unregister_thread();
- return NULL;
-}
-
-static void tcg_start_vcpu_thread(CPUState *cpu)
+void tcg_start_vcpu_thread(CPUState *cpu)
{
char thread_name[VCPU_THREAD_NAME_SIZE];
static QemuCond *single_tcg_halt_cond;
@@ -518,29 +96,36 @@ static void tcg_start_vcpu_thread(CPUState *cpu)
}
}
-static int64_t tcg_get_virtual_clock(void)
+void qemu_tcg_destroy_vcpu(CPUState *cpu)
{
- if (icount_enabled()) {
- return icount_get();
- }
- return cpu_get_clock();
+ cpu_thread_signal_destroyed(cpu);
}
-static int64_t tcg_get_elapsed_ticks(void)
+int tcg_cpu_exec(CPUState *cpu)
{
- if (icount_enabled()) {
- return icount_get();
- }
- return cpu_get_ticks();
+ int ret;
+#ifdef CONFIG_PROFILER
+ int64_t ti;
+#endif
+ assert(tcg_enabled());
+#ifdef CONFIG_PROFILER
+ ti = profile_getclock();
+#endif
+ cpu_exec_start(cpu);
+ ret = cpu_exec(cpu);
+ cpu_exec_end(cpu);
+#ifdef CONFIG_PROFILER
+ qatomic_set(&tcg_ctx->prof.cpu_exec_time,
+ tcg_ctx->prof.cpu_exec_time + profile_getclock() - ti);
+#endif
+ return ret;
}
/* mask must never be zero, except for A20 change call */
-static void tcg_handle_interrupt(CPUState *cpu, int mask)
+void tcg_handle_interrupt(CPUState *cpu, int mask)
{
- int old_mask;
g_assert(qemu_mutex_iothread_locked());
- old_mask = cpu->interrupt_request;
cpu->interrupt_request |= mask;
/*
@@ -551,20 +136,5 @@ static void tcg_handle_interrupt(CPUState *cpu, int mask)
qemu_cpu_kick(cpu);
} else {
qatomic_set(&cpu_neg(cpu)->icount_decr.u16.high, -1);
- if (icount_enabled() &&
- !cpu->can_do_io
- && (mask & ~old_mask) != 0) {
- cpu_abort(cpu, "Raised interrupt while not in I/O function");
- }
}
}
-
-const CpusAccel tcg_cpus = {
- .create_vcpu_thread = tcg_start_vcpu_thread,
- .kick_vcpu_thread = tcg_kick_vcpu_thread,
-
- .handle_interrupt = tcg_handle_interrupt,
-
- .get_virtual_clock = tcg_get_virtual_clock,
- .get_elapsed_ticks = tcg_get_elapsed_ticks,
-};
diff --git a/accel/tcg/tcg-cpus.h b/accel/tcg/tcg-cpus.h
index 8b1d9d2abc..279ba72e1f 100644
--- a/accel/tcg/tcg-cpus.h
+++ b/accel/tcg/tcg-cpus.h
@@ -1,5 +1,7 @@
/*
- * Accelerator CPUS Interface
+ * QEMU TCG vCPU common functionality
+ *
+ * Functionality common to all TCG vcpu variants: mttcg, rr and icount.
*
* Copyright 2020 SUSE LLC
*
@@ -12,6 +14,13 @@
#include "sysemu/cpus.h"
-extern const CpusAccel tcg_cpus;
+extern const CpusAccel tcg_cpus_mttcg;
+extern const CpusAccel tcg_cpus_icount;
+extern const CpusAccel tcg_cpus_rr;
+
+void tcg_start_vcpu_thread(CPUState *cpu);
+void qemu_tcg_destroy_vcpu(CPUState *cpu);
+int tcg_cpu_exec(CPUState *cpu);
+void tcg_handle_interrupt(CPUState *cpu, int mask);
#endif /* TCG_CPUS_H */
diff --git a/softmmu/icount.c b/softmmu/icount.c
index 020a201a01..dbcd8c3594 100644
--- a/softmmu/icount.c
+++ b/softmmu/icount.c
@@ -396,7 +396,7 @@ void icount_start_warp_timer(void)
void icount_account_warp_timer(void)
{
- if (!icount_enabled() || !icount_sleep) {
+ if (!icount_sleep) {
return;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 02/27] accel/tcg: split tcg_start_vcpu_thread
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
2020-12-05 16:14 ` [RFC v8 01/27] accel/tcg: split CpusAccel into three TCG variants Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:14 ` [RFC v8 03/27] accel/tcg: rename tcg-cpus functions to match module name Claudio Fontana
` (25 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
after the initial split into 3 tcg variants, we proceed to also
split tcg_start_vcpu_thread.
We actually split it in 2 this time, since the icount variant
just uses the round robin function.
Suggested-by: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/tcg-all.c | 5 ++++
accel/tcg/tcg-cpus-icount.c | 2 +-
accel/tcg/tcg-cpus-mttcg.c | 29 +++++++++++++++++--
accel/tcg/tcg-cpus-mttcg.h | 21 --------------
accel/tcg/tcg-cpus-rr.c | 39 +++++++++++++++++++++++--
accel/tcg/tcg-cpus-rr.h | 3 +-
accel/tcg/tcg-cpus.c | 58 -------------------------------------
accel/tcg/tcg-cpus.h | 1 -
8 files changed, 71 insertions(+), 87 deletions(-)
delete mode 100644 accel/tcg/tcg-cpus-mttcg.h
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index e42a028043..1ac0b76515 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -105,6 +105,11 @@ static int tcg_init(MachineState *ms)
tcg_exec_init(s->tb_size * 1024 * 1024);
mttcg_enabled = s->mttcg_enabled;
+ /*
+ * Initialize TCG regions
+ */
+ tcg_region_init();
+
if (mttcg_enabled) {
cpus_register_accel(&tcg_cpus_mttcg);
} else if (icount_enabled()) {
diff --git a/accel/tcg/tcg-cpus-icount.c b/accel/tcg/tcg-cpus-icount.c
index d3af3afb6d..82dbe2cacf 100644
--- a/accel/tcg/tcg-cpus-icount.c
+++ b/accel/tcg/tcg-cpus-icount.c
@@ -138,7 +138,7 @@ static void icount_handle_interrupt(CPUState *cpu, int mask)
}
const CpusAccel tcg_cpus_icount = {
- .create_vcpu_thread = tcg_start_vcpu_thread,
+ .create_vcpu_thread = rr_start_vcpu_thread,
.kick_vcpu_thread = qemu_cpu_kick_rr_cpus,
.handle_interrupt = icount_handle_interrupt,
diff --git a/accel/tcg/tcg-cpus-mttcg.c b/accel/tcg/tcg-cpus-mttcg.c
index dac724fc85..f2b892a380 100644
--- a/accel/tcg/tcg-cpus-mttcg.c
+++ b/accel/tcg/tcg-cpus-mttcg.c
@@ -33,7 +33,6 @@
#include "hw/boards.h"
#include "tcg-cpus.h"
-#include "tcg-cpus-mttcg.h"
/*
* In the multi-threaded case each vCPU has its own thread. The TLS
@@ -41,7 +40,7 @@
* current CPUState for a given thread.
*/
-void *tcg_cpu_thread_fn(void *arg)
+static void *tcg_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
@@ -109,8 +108,32 @@ static void mttcg_kick_vcpu_thread(CPUState *cpu)
cpu_exit(cpu);
}
+static void mttcg_start_vcpu_thread(CPUState *cpu)
+{
+ char thread_name[VCPU_THREAD_NAME_SIZE];
+
+ g_assert(tcg_enabled());
+
+ parallel_cpus = (current_machine->smp.max_cpus > 1);
+
+ cpu->thread = g_malloc0(sizeof(QemuThread));
+ cpu->halt_cond = g_malloc0(sizeof(QemuCond));
+ qemu_cond_init(cpu->halt_cond);
+
+ /* create a thread per vCPU with TCG (MTTCG) */
+ snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
+ cpu->cpu_index);
+
+ qemu_thread_create(cpu->thread, thread_name, tcg_cpu_thread_fn,
+ cpu, QEMU_THREAD_JOINABLE);
+
+#ifdef _WIN32
+ cpu->hThread = qemu_thread_get_handle(cpu->thread);
+#endif
+}
+
const CpusAccel tcg_cpus_mttcg = {
- .create_vcpu_thread = tcg_start_vcpu_thread,
+ .create_vcpu_thread = mttcg_start_vcpu_thread,
.kick_vcpu_thread = mttcg_kick_vcpu_thread,
.handle_interrupt = tcg_handle_interrupt,
diff --git a/accel/tcg/tcg-cpus-mttcg.h b/accel/tcg/tcg-cpus-mttcg.h
deleted file mode 100644
index d1bd771f49..0000000000
--- a/accel/tcg/tcg-cpus-mttcg.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * QEMU TCG Multi Threaded vCPUs implementation
- *
- * Copyright 2020 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
-
-/*
- * In the multi-threaded case each vCPU has its own thread. The TLS
- * variable current_cpu can be used deep in the code to find the
- * current CPUState for a given thread.
- */
-
-void *tcg_cpu_thread_fn(void *arg);
-
-#endif /* TCG_CPUS_MTTCG_H */
diff --git a/accel/tcg/tcg-cpus-rr.c b/accel/tcg/tcg-cpus-rr.c
index ad50a3765f..f3b262bec7 100644
--- a/accel/tcg/tcg-cpus-rr.c
+++ b/accel/tcg/tcg-cpus-rr.c
@@ -144,7 +144,7 @@ static void deal_with_unplugged_cpus(void)
* elsewhere.
*/
-void *tcg_rr_cpu_thread_fn(void *arg)
+static void *tcg_rr_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
@@ -262,8 +262,43 @@ void *tcg_rr_cpu_thread_fn(void *arg)
return NULL;
}
+void rr_start_vcpu_thread(CPUState *cpu)
+{
+ char thread_name[VCPU_THREAD_NAME_SIZE];
+ static QemuCond *single_tcg_halt_cond;
+ static QemuThread *single_tcg_cpu_thread;
+
+ g_assert(tcg_enabled());
+ parallel_cpus = false;
+
+ if (!single_tcg_cpu_thread) {
+ cpu->thread = g_malloc0(sizeof(QemuThread));
+ cpu->halt_cond = g_malloc0(sizeof(QemuCond));
+ qemu_cond_init(cpu->halt_cond);
+
+ /* share a single thread for all cpus with TCG */
+ snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG");
+ qemu_thread_create(cpu->thread, thread_name,
+ tcg_rr_cpu_thread_fn,
+ cpu, QEMU_THREAD_JOINABLE);
+
+ single_tcg_halt_cond = cpu->halt_cond;
+ single_tcg_cpu_thread = cpu->thread;
+#ifdef _WIN32
+ cpu->hThread = qemu_thread_get_handle(cpu->thread);
+#endif
+ } else {
+ /* we share the thread */
+ cpu->thread = single_tcg_cpu_thread;
+ cpu->halt_cond = single_tcg_halt_cond;
+ cpu->thread_id = first_cpu->thread_id;
+ cpu->can_do_io = 1;
+ cpu->created = true;
+ }
+}
+
const CpusAccel tcg_cpus_rr = {
- .create_vcpu_thread = tcg_start_vcpu_thread,
+ .create_vcpu_thread = rr_start_vcpu_thread,
.kick_vcpu_thread = qemu_cpu_kick_rr_cpus,
.handle_interrupt = tcg_handle_interrupt,
diff --git a/accel/tcg/tcg-cpus-rr.h b/accel/tcg/tcg-cpus-rr.h
index 1936fd16ab..2e5943eda9 100644
--- a/accel/tcg/tcg-cpus-rr.h
+++ b/accel/tcg/tcg-cpus-rr.h
@@ -15,6 +15,7 @@
/* Kick all RR vCPUs. */
void qemu_cpu_kick_rr_cpus(CPUState *unused);
-void *tcg_rr_cpu_thread_fn(void *arg);
+/* start the round robin vcpu thread */
+void rr_start_vcpu_thread(CPUState *cpu);
#endif /* TCG_CPUS_RR_H */
diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-cpus.c
index f2b9bbf99e..86fd09545a 100644
--- a/accel/tcg/tcg-cpus.c
+++ b/accel/tcg/tcg-cpus.c
@@ -35,67 +35,9 @@
#include "hw/boards.h"
#include "tcg-cpus.h"
-#include "tcg-cpus-mttcg.h"
-#include "tcg-cpus-rr.h"
/* common functionality among all TCG variants */
-void tcg_start_vcpu_thread(CPUState *cpu)
-{
- char thread_name[VCPU_THREAD_NAME_SIZE];
- static QemuCond *single_tcg_halt_cond;
- static QemuThread *single_tcg_cpu_thread;
- static int tcg_region_inited;
-
- assert(tcg_enabled());
- /*
- * Initialize TCG regions--once. Now is a good time, because:
- * (1) TCG's init context, prologue and target globals have been set up.
- * (2) qemu_tcg_mttcg_enabled() works now (TCG init code runs before the
- * -accel flag is processed, so the check doesn't work then).
- */
- if (!tcg_region_inited) {
- tcg_region_inited = 1;
- tcg_region_init();
- parallel_cpus = qemu_tcg_mttcg_enabled() && current_machine->smp.max_cpus > 1;
- }
-
- if (qemu_tcg_mttcg_enabled() || !single_tcg_cpu_thread) {
- cpu->thread = g_malloc0(sizeof(QemuThread));
- cpu->halt_cond = g_malloc0(sizeof(QemuCond));
- qemu_cond_init(cpu->halt_cond);
-
- if (qemu_tcg_mttcg_enabled()) {
- /* create a thread per vCPU with TCG (MTTCG) */
- snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
- cpu->cpu_index);
-
- qemu_thread_create(cpu->thread, thread_name, tcg_cpu_thread_fn,
- cpu, QEMU_THREAD_JOINABLE);
-
- } else {
- /* share a single thread for all cpus with TCG */
- snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG");
- qemu_thread_create(cpu->thread, thread_name,
- tcg_rr_cpu_thread_fn,
- cpu, QEMU_THREAD_JOINABLE);
-
- single_tcg_halt_cond = cpu->halt_cond;
- single_tcg_cpu_thread = cpu->thread;
- }
-#ifdef _WIN32
- cpu->hThread = qemu_thread_get_handle(cpu->thread);
-#endif
- } else {
- /* For non-MTTCG cases we share the thread */
- cpu->thread = single_tcg_cpu_thread;
- cpu->halt_cond = single_tcg_halt_cond;
- cpu->thread_id = first_cpu->thread_id;
- cpu->can_do_io = 1;
- cpu->created = true;
- }
-}
-
void qemu_tcg_destroy_vcpu(CPUState *cpu)
{
cpu_thread_signal_destroyed(cpu);
diff --git a/accel/tcg/tcg-cpus.h b/accel/tcg/tcg-cpus.h
index 279ba72e1f..b7ca954e13 100644
--- a/accel/tcg/tcg-cpus.h
+++ b/accel/tcg/tcg-cpus.h
@@ -18,7 +18,6 @@ extern const CpusAccel tcg_cpus_mttcg;
extern const CpusAccel tcg_cpus_icount;
extern const CpusAccel tcg_cpus_rr;
-void tcg_start_vcpu_thread(CPUState *cpu);
void qemu_tcg_destroy_vcpu(CPUState *cpu);
int tcg_cpu_exec(CPUState *cpu);
void tcg_handle_interrupt(CPUState *cpu, int mask);
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 03/27] accel/tcg: rename tcg-cpus functions to match module name
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
2020-12-05 16:14 ` [RFC v8 01/27] accel/tcg: split CpusAccel into three TCG variants Claudio Fontana
2020-12-05 16:14 ` [RFC v8 02/27] accel/tcg: split tcg_start_vcpu_thread Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:14 ` [RFC v8 04/27] i386: move kvm accel files into kvm/ Claudio Fontana
` (24 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Philippe Mathieu-Daudé,
Eduardo Habkost, Paul Durrant, Jason Wang, Marcelo Tosatti,
qemu-devel, Peter Xu, Dario Faggioli, Cameron Esfahani,
haxm-team, Claudio Fontana, Anthony Perard, Bruce Rogers,
Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
accel/tcg/tcg-cpus-icount.c | 24 ++++++------
accel/tcg/tcg-cpus-icount.h | 6 +--
accel/tcg/tcg-cpus-mttcg.c | 10 ++---
accel/tcg/tcg-cpus-rr.c | 74 ++++++++++++++++++-------------------
accel/tcg/tcg-cpus-rr.h | 2 +-
accel/tcg/tcg-cpus.c | 6 +--
accel/tcg/tcg-cpus.h | 6 +--
7 files changed, 64 insertions(+), 64 deletions(-)
diff --git a/accel/tcg/tcg-cpus-icount.c b/accel/tcg/tcg-cpus-icount.c
index 82dbe2cacf..9f45432275 100644
--- a/accel/tcg/tcg-cpus-icount.c
+++ b/accel/tcg/tcg-cpus-icount.c
@@ -36,7 +36,7 @@
#include "tcg-cpus-icount.h"
#include "tcg-cpus-rr.h"
-static int64_t tcg_get_icount_limit(void)
+static int64_t icount_get_limit(void)
{
int64_t deadline;
@@ -68,37 +68,37 @@ static int64_t tcg_get_icount_limit(void)
}
}
-static void notify_aio_contexts(void)
+static void icount_notify_aio_contexts(void)
{
/* Wake up other AioContexts. */
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
qemu_clock_run_timers(QEMU_CLOCK_VIRTUAL);
}
-void handle_icount_deadline(void)
+void icount_handle_deadline(void)
{
assert(qemu_in_vcpu_thread());
int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
QEMU_TIMER_ATTR_ALL);
if (deadline == 0) {
- notify_aio_contexts();
+ icount_notify_aio_contexts();
}
}
-void prepare_icount_for_run(CPUState *cpu)
+void icount_prepare_for_run(CPUState *cpu)
{
int insns_left;
/*
- * These should always be cleared by process_icount_data after
+ * 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_handle_interrupt
+ * asynchronously by cpu_exit/cpu_interrupt/tcg_cpus_handle_interrupt
*/
g_assert(cpu_neg(cpu)->icount_decr.u16.low == 0);
g_assert(cpu->icount_extra == 0);
- cpu->icount_budget = tcg_get_icount_limit();
+ cpu->icount_budget = icount_get_limit();
insns_left = MIN(0xffff, cpu->icount_budget);
cpu_neg(cpu)->icount_decr.u16.low = insns_left;
cpu->icount_extra = cpu->icount_budget - insns_left;
@@ -106,11 +106,11 @@ void prepare_icount_for_run(CPUState *cpu)
replay_mutex_lock();
if (cpu->icount_budget == 0 && replay_has_checkpoint()) {
- notify_aio_contexts();
+ icount_notify_aio_contexts();
}
}
-void process_icount_data(CPUState *cpu)
+void icount_process_data(CPUState *cpu)
{
/* Account for executed instructions */
icount_update(cpu);
@@ -129,7 +129,7 @@ static void icount_handle_interrupt(CPUState *cpu, int mask)
{
int old_mask = cpu->interrupt_request;
- tcg_handle_interrupt(cpu, mask);
+ tcg_cpus_handle_interrupt(cpu, mask);
if (qemu_cpu_is_self(cpu) &&
!cpu->can_do_io
&& (mask & ~old_mask) != 0) {
@@ -139,7 +139,7 @@ static void icount_handle_interrupt(CPUState *cpu, int mask)
const CpusAccel tcg_cpus_icount = {
.create_vcpu_thread = rr_start_vcpu_thread,
- .kick_vcpu_thread = qemu_cpu_kick_rr_cpus,
+ .kick_vcpu_thread = rr_kick_vcpu_thread,
.handle_interrupt = icount_handle_interrupt,
.get_virtual_clock = icount_get,
diff --git a/accel/tcg/tcg-cpus-icount.h b/accel/tcg/tcg-cpus-icount.h
index cbcf76b413..b695939dfa 100644
--- a/accel/tcg/tcg-cpus-icount.h
+++ b/accel/tcg/tcg-cpus-icount.h
@@ -10,8 +10,8 @@
#ifndef TCG_CPUS_ICOUNT_H
#define TCG_CPUS_ICOUNT_H
-void handle_icount_deadline(void);
-void prepare_icount_for_run(CPUState *cpu);
-void process_icount_data(CPUState *cpu);
+void icount_handle_deadline(void);
+void icount_prepare_for_run(CPUState *cpu);
+void icount_process_data(CPUState *cpu);
#endif /* TCG_CPUS_ICOUNT_H */
diff --git a/accel/tcg/tcg-cpus-mttcg.c b/accel/tcg/tcg-cpus-mttcg.c
index f2b892a380..9c3767d260 100644
--- a/accel/tcg/tcg-cpus-mttcg.c
+++ b/accel/tcg/tcg-cpus-mttcg.c
@@ -40,7 +40,7 @@
* current CPUState for a given thread.
*/
-static void *tcg_cpu_thread_fn(void *arg)
+static void *mttcg_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
@@ -66,7 +66,7 @@ static void *tcg_cpu_thread_fn(void *arg)
if (cpu_can_run(cpu)) {
int r;
qemu_mutex_unlock_iothread();
- r = tcg_cpu_exec(cpu);
+ r = tcg_cpus_exec(cpu);
qemu_mutex_lock_iothread();
switch (r) {
case EXCP_DEBUG:
@@ -97,7 +97,7 @@ static void *tcg_cpu_thread_fn(void *arg)
qemu_wait_io_event(cpu);
} while (!cpu->unplug || cpu_can_run(cpu));
- qemu_tcg_destroy_vcpu(cpu);
+ tcg_cpus_destroy(cpu);
qemu_mutex_unlock_iothread();
rcu_unregister_thread();
return NULL;
@@ -124,7 +124,7 @@ static void mttcg_start_vcpu_thread(CPUState *cpu)
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
cpu->cpu_index);
- qemu_thread_create(cpu->thread, thread_name, tcg_cpu_thread_fn,
+ qemu_thread_create(cpu->thread, thread_name, mttcg_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE);
#ifdef _WIN32
@@ -136,5 +136,5 @@ const CpusAccel tcg_cpus_mttcg = {
.create_vcpu_thread = mttcg_start_vcpu_thread,
.kick_vcpu_thread = mttcg_kick_vcpu_thread,
- .handle_interrupt = tcg_handle_interrupt,
+ .handle_interrupt = tcg_cpus_handle_interrupt,
};
diff --git a/accel/tcg/tcg-cpus-rr.c b/accel/tcg/tcg-cpus-rr.c
index f3b262bec7..0181d2e4eb 100644
--- a/accel/tcg/tcg-cpus-rr.c
+++ b/accel/tcg/tcg-cpus-rr.c
@@ -37,7 +37,7 @@
#include "tcg-cpus-icount.h"
/* Kick all RR vCPUs */
-void qemu_cpu_kick_rr_cpus(CPUState *unused)
+void rr_kick_vcpu_thread(CPUState *unused)
{
CPUState *cpu;
@@ -58,62 +58,62 @@ void qemu_cpu_kick_rr_cpus(CPUState *unused)
* idleness is complete.
*/
-static QEMUTimer *tcg_kick_vcpu_timer;
-static CPUState *tcg_current_rr_cpu;
+static QEMUTimer *rr_kick_vcpu_timer;
+static CPUState *rr_current_cpu;
#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
-static inline int64_t qemu_tcg_next_kick(void)
+static inline int64_t rr_next_kick_time(void)
{
return qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + TCG_KICK_PERIOD;
}
/* Kick the currently round-robin scheduled vCPU to next */
-static void qemu_cpu_kick_rr_next_cpu(void)
+static void rr_kick_next_cpu(void)
{
CPUState *cpu;
do {
- cpu = qatomic_mb_read(&tcg_current_rr_cpu);
+ cpu = qatomic_mb_read(&rr_current_cpu);
if (cpu) {
cpu_exit(cpu);
}
- } while (cpu != qatomic_mb_read(&tcg_current_rr_cpu));
+ } while (cpu != qatomic_mb_read(&rr_current_cpu));
}
-static void kick_tcg_thread(void *opaque)
+static void rr_kick_thread(void *opaque)
{
- timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
- qemu_cpu_kick_rr_next_cpu();
+ timer_mod(rr_kick_vcpu_timer, rr_next_kick_time());
+ rr_kick_next_cpu();
}
-static void start_tcg_kick_timer(void)
+static void rr_start_kick_timer(void)
{
- if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
- tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
- kick_tcg_thread, NULL);
+ if (!rr_kick_vcpu_timer && CPU_NEXT(first_cpu)) {
+ rr_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
+ rr_kick_thread, NULL);
}
- if (tcg_kick_vcpu_timer && !timer_pending(tcg_kick_vcpu_timer)) {
- timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick());
+ if (rr_kick_vcpu_timer && !timer_pending(rr_kick_vcpu_timer)) {
+ timer_mod(rr_kick_vcpu_timer, rr_next_kick_time());
}
}
-static void stop_tcg_kick_timer(void)
+static void rr_stop_kick_timer(void)
{
- if (tcg_kick_vcpu_timer && timer_pending(tcg_kick_vcpu_timer)) {
- timer_del(tcg_kick_vcpu_timer);
+ if (rr_kick_vcpu_timer && timer_pending(rr_kick_vcpu_timer)) {
+ timer_del(rr_kick_vcpu_timer);
}
}
-static void qemu_tcg_rr_wait_io_event(void)
+static void rr_wait_io_event(void)
{
CPUState *cpu;
while (all_cpu_threads_idle()) {
- stop_tcg_kick_timer();
+ rr_stop_kick_timer();
qemu_cond_wait_iothread(first_cpu->halt_cond);
}
- start_tcg_kick_timer();
+ rr_start_kick_timer();
CPU_FOREACH(cpu) {
qemu_wait_io_event_common(cpu);
@@ -124,13 +124,13 @@ static void qemu_tcg_rr_wait_io_event(void)
* Destroy any remaining vCPUs which have been unplugged and have
* finished running
*/
-static void deal_with_unplugged_cpus(void)
+static void rr_deal_with_unplugged_cpus(void)
{
CPUState *cpu;
CPU_FOREACH(cpu) {
if (cpu->unplug && !cpu_can_run(cpu)) {
- qemu_tcg_destroy_vcpu(cpu);
+ tcg_cpus_destroy(cpu);
break;
}
}
@@ -144,7 +144,7 @@ static void deal_with_unplugged_cpus(void)
* elsewhere.
*/
-static void *tcg_rr_cpu_thread_fn(void *arg)
+static void *rr_cpu_thread_fn(void *arg)
{
CPUState *cpu = arg;
@@ -171,7 +171,7 @@ static void *tcg_rr_cpu_thread_fn(void *arg)
}
}
- start_tcg_kick_timer();
+ rr_start_kick_timer();
cpu = first_cpu;
@@ -190,7 +190,7 @@ static void *tcg_rr_cpu_thread_fn(void *arg)
* Run the timers here. This is much more efficient than
* waking up the I/O thread and waiting for completion.
*/
- handle_icount_deadline();
+ icount_handle_deadline();
}
replay_mutex_unlock();
@@ -201,7 +201,7 @@ static void *tcg_rr_cpu_thread_fn(void *arg)
while (cpu && cpu_work_list_empty(cpu) && !cpu->exit_request) {
- qatomic_mb_set(&tcg_current_rr_cpu, cpu);
+ qatomic_mb_set(&rr_current_cpu, cpu);
current_cpu = cpu;
qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
@@ -212,11 +212,11 @@ static void *tcg_rr_cpu_thread_fn(void *arg)
qemu_mutex_unlock_iothread();
if (icount_enabled()) {
- prepare_icount_for_run(cpu);
+ icount_prepare_for_run(cpu);
}
- r = tcg_cpu_exec(cpu);
+ r = tcg_cpus_exec(cpu);
if (icount_enabled()) {
- process_icount_data(cpu);
+ icount_process_data(cpu);
}
qemu_mutex_lock_iothread();
@@ -240,7 +240,7 @@ static void *tcg_rr_cpu_thread_fn(void *arg)
} /* while (cpu && !cpu->exit_request).. */
/* Does not need qatomic_mb_set because a spurious wakeup is okay. */
- qatomic_set(&tcg_current_rr_cpu, NULL);
+ qatomic_set(&rr_current_cpu, NULL);
if (cpu && cpu->exit_request) {
qatomic_mb_set(&cpu->exit_request, 0);
@@ -254,8 +254,8 @@ static void *tcg_rr_cpu_thread_fn(void *arg)
qemu_notify_event();
}
- qemu_tcg_rr_wait_io_event();
- deal_with_unplugged_cpus();
+ rr_wait_io_event();
+ rr_deal_with_unplugged_cpus();
}
rcu_unregister_thread();
@@ -279,7 +279,7 @@ void rr_start_vcpu_thread(CPUState *cpu)
/* share a single thread for all cpus with TCG */
snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "ALL CPUs/TCG");
qemu_thread_create(cpu->thread, thread_name,
- tcg_rr_cpu_thread_fn,
+ rr_cpu_thread_fn,
cpu, QEMU_THREAD_JOINABLE);
single_tcg_halt_cond = cpu->halt_cond;
@@ -299,7 +299,7 @@ void rr_start_vcpu_thread(CPUState *cpu)
const CpusAccel tcg_cpus_rr = {
.create_vcpu_thread = rr_start_vcpu_thread,
- .kick_vcpu_thread = qemu_cpu_kick_rr_cpus,
+ .kick_vcpu_thread = rr_kick_vcpu_thread,
- .handle_interrupt = tcg_handle_interrupt,
+ .handle_interrupt = tcg_cpus_handle_interrupt,
};
diff --git a/accel/tcg/tcg-cpus-rr.h b/accel/tcg/tcg-cpus-rr.h
index 2e5943eda9..54f6ae6e86 100644
--- a/accel/tcg/tcg-cpus-rr.h
+++ b/accel/tcg/tcg-cpus-rr.h
@@ -13,7 +13,7 @@
#define TCG_KICK_PERIOD (NANOSECONDS_PER_SECOND / 10)
/* Kick all RR vCPUs. */
-void qemu_cpu_kick_rr_cpus(CPUState *unused);
+void rr_kick_vcpu_thread(CPUState *unused);
/* start the round robin vcpu thread */
void rr_start_vcpu_thread(CPUState *cpu);
diff --git a/accel/tcg/tcg-cpus.c b/accel/tcg/tcg-cpus.c
index 86fd09545a..e335f9f155 100644
--- a/accel/tcg/tcg-cpus.c
+++ b/accel/tcg/tcg-cpus.c
@@ -38,12 +38,12 @@
/* common functionality among all TCG variants */
-void qemu_tcg_destroy_vcpu(CPUState *cpu)
+void tcg_cpus_destroy(CPUState *cpu)
{
cpu_thread_signal_destroyed(cpu);
}
-int tcg_cpu_exec(CPUState *cpu)
+int tcg_cpus_exec(CPUState *cpu)
{
int ret;
#ifdef CONFIG_PROFILER
@@ -64,7 +64,7 @@ int tcg_cpu_exec(CPUState *cpu)
}
/* mask must never be zero, except for A20 change call */
-void tcg_handle_interrupt(CPUState *cpu, int mask)
+void tcg_cpus_handle_interrupt(CPUState *cpu, int mask)
{
g_assert(qemu_mutex_iothread_locked());
diff --git a/accel/tcg/tcg-cpus.h b/accel/tcg/tcg-cpus.h
index b7ca954e13..d6893a32f8 100644
--- a/accel/tcg/tcg-cpus.h
+++ b/accel/tcg/tcg-cpus.h
@@ -18,8 +18,8 @@ extern const CpusAccel tcg_cpus_mttcg;
extern const CpusAccel tcg_cpus_icount;
extern const CpusAccel tcg_cpus_rr;
-void qemu_tcg_destroy_vcpu(CPUState *cpu);
-int tcg_cpu_exec(CPUState *cpu);
-void tcg_handle_interrupt(CPUState *cpu, int mask);
+void tcg_cpus_destroy(CPUState *cpu);
+int tcg_cpus_exec(CPUState *cpu);
+void tcg_cpus_handle_interrupt(CPUState *cpu, int mask);
#endif /* TCG_CPUS_H */
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 04/27] i386: move kvm accel files into kvm/
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (2 preceding siblings ...)
2020-12-05 16:14 ` [RFC v8 03/27] accel/tcg: rename tcg-cpus functions to match module name Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:14 ` [RFC v8 05/27] i386: move whpx accel files into whpx/ Claudio Fontana
` (23 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
MAINTAINERS | 2 +-
hw/i386/fw_cfg.c | 2 +-
hw/i386/intel_iommu.c | 2 +-
hw/i386/kvm/apic.c | 2 +-
hw/i386/kvm/clock.c | 2 +-
hw/i386/microvm.c | 2 +-
hw/i386/pc.c | 2 +-
hw/i386/x86.c | 2 +-
meson.build | 1 +
target/i386/cpu.c | 2 +-
target/i386/cpu.h | 2 +-
target/i386/helper.c | 2 +-
target/i386/{ => kvm}/hyperv-proto.h | 0
target/i386/{ => kvm}/hyperv-stub.c | 0
target/i386/{ => kvm}/hyperv.c | 0
target/i386/{ => kvm}/hyperv.h | 0
target/i386/{ => kvm}/kvm-stub.c | 0
target/i386/{ => kvm}/kvm.c | 0
target/i386/{ => kvm}/kvm_i386.h | 0
target/i386/kvm/meson.build | 3 +++
target/i386/kvm/trace-events | 7 +++++++
target/i386/kvm/trace.h | 1 +
target/i386/machine.c | 4 ++--
target/i386/meson.build | 4 +---
target/i386/trace-events | 6 ------
25 files changed, 26 insertions(+), 22 deletions(-)
rename target/i386/{ => kvm}/hyperv-proto.h (100%)
rename target/i386/{ => kvm}/hyperv-stub.c (100%)
rename target/i386/{ => kvm}/hyperv.c (100%)
rename target/i386/{ => kvm}/hyperv.h (100%)
rename target/i386/{ => kvm}/kvm-stub.c (100%)
rename target/i386/{ => kvm}/kvm.c (100%)
rename target/i386/{ => kvm}/kvm_i386.h (100%)
create mode 100644 target/i386/kvm/meson.build
create mode 100644 target/i386/kvm/trace-events
create mode 100644 target/i386/kvm/trace.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 68bc160f41..5b3eced829 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -425,7 +425,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
M: Marcelo Tosatti <mtosatti@redhat.com>
L: kvm@vger.kernel.org
S: Supported
-F: target/i386/kvm.c
+F: target/i386/kvm/
F: scripts/kvm/vmxcap
Guest CPU Cores (other accelerators)
diff --git a/hw/i386/fw_cfg.c b/hw/i386/fw_cfg.c
index e06579490c..fae1bb380f 100644
--- a/hw/i386/fw_cfg.c
+++ b/hw/i386/fw_cfg.c
@@ -21,7 +21,7 @@
#include "hw/timer/hpet.h"
#include "hw/nvram/fw_cfg.h"
#include "e820_memory_layout.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#include CONFIG_DEVICES
struct hpet_fw_config hpet_cfg = {.count = UINT8_MAX};
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 70ac837733..361b6cd238 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -37,7 +37,7 @@
#include "sysemu/kvm.h"
#include "sysemu/sysemu.h"
#include "hw/i386/apic_internal.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#include "migration/vmstate.h"
#include "trace.h"
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index dd29906061..07bebc1282 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -17,7 +17,7 @@
#include "hw/pci/msi.h"
#include "sysemu/hw_accel.h"
#include "sysemu/kvm.h"
-#include "target/i386/kvm_i386.h"
+#include "kvm/kvm_i386.h"
static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic,
int reg_id, uint32_t val)
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 24fe5091b6..2d8a366369 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -20,7 +20,7 @@
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
#include "sysemu/hw_accel.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#include "migration/vmstate.h"
#include "hw/sysbus.h"
#include "hw/kvm/clock.h"
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 5428448b70..3ed6adff83 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -51,7 +51,7 @@
#include "cpu.h"
#include "elf.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#include "hw/xen/start_info.h"
#define MICROVM_QBOOT_FILENAME "qboot.rom"
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 17b514d1da..299aaba8e9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -61,7 +61,7 @@
#include "sysemu/qtest.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#include "hw/xen/xen.h"
#include "hw/xen/start_info.h"
#include "ui/qemu-spice.h"
diff --git a/hw/i386/x86.c b/hw/i386/x86.c
index 5944fc44ed..88d0c70e12 100644
--- a/hw/i386/x86.c
+++ b/hw/i386/x86.c
@@ -52,7 +52,7 @@
#include "elf.h"
#include "standard-headers/asm-x86/bootparam.h"
#include CONFIG_DEVICES
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#define BIOS_FILENAME "bios.bin"
diff --git a/meson.build b/meson.build
index e3386196ba..198298e9d8 100644
--- a/meson.build
+++ b/meson.build
@@ -1467,6 +1467,7 @@ trace_events_subdirs += [
'target/arm',
'target/hppa',
'target/i386',
+ 'target/i386/kvm',
'target/mips',
'target/ppc',
'target/riscv',
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 5a8c96072e..b9bd249c8f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -30,7 +30,7 @@
#include "sysemu/hvf.h"
#include "sysemu/cpus.h"
#include "sysemu/xen.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#include "sev_i386.h"
#include "qemu/error-report.h"
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 88e8586f8f..9ecda75aec 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -22,7 +22,7 @@
#include "sysemu/tcg.h"
#include "cpu-qom.h"
-#include "hyperv-proto.h"
+#include "kvm/hyperv-proto.h"
#include "exec/cpu-defs.h"
#include "qapi/qapi-types-common.h"
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 034f46bcc2..a1b3367ab2 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -24,7 +24,7 @@
#include "qemu/qemu-print.h"
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#ifndef CONFIG_USER_ONLY
#include "sysemu/tcg.h"
#include "sysemu/hw_accel.h"
diff --git a/target/i386/hyperv-proto.h b/target/i386/kvm/hyperv-proto.h
similarity index 100%
rename from target/i386/hyperv-proto.h
rename to target/i386/kvm/hyperv-proto.h
diff --git a/target/i386/hyperv-stub.c b/target/i386/kvm/hyperv-stub.c
similarity index 100%
rename from target/i386/hyperv-stub.c
rename to target/i386/kvm/hyperv-stub.c
diff --git a/target/i386/hyperv.c b/target/i386/kvm/hyperv.c
similarity index 100%
rename from target/i386/hyperv.c
rename to target/i386/kvm/hyperv.c
diff --git a/target/i386/hyperv.h b/target/i386/kvm/hyperv.h
similarity index 100%
rename from target/i386/hyperv.h
rename to target/i386/kvm/hyperv.h
diff --git a/target/i386/kvm-stub.c b/target/i386/kvm/kvm-stub.c
similarity index 100%
rename from target/i386/kvm-stub.c
rename to target/i386/kvm/kvm-stub.c
diff --git a/target/i386/kvm.c b/target/i386/kvm/kvm.c
similarity index 100%
rename from target/i386/kvm.c
rename to target/i386/kvm/kvm.c
diff --git a/target/i386/kvm_i386.h b/target/i386/kvm/kvm_i386.h
similarity index 100%
rename from target/i386/kvm_i386.h
rename to target/i386/kvm/kvm_i386.h
diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build
new file mode 100644
index 0000000000..1d66559187
--- /dev/null
+++ b/target/i386/kvm/meson.build
@@ -0,0 +1,3 @@
+i386_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c'))
+i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
+i386_softmmu_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c'))
diff --git a/target/i386/kvm/trace-events b/target/i386/kvm/trace-events
new file mode 100644
index 0000000000..b4e2d9e4ea
--- /dev/null
+++ b/target/i386/kvm/trace-events
@@ -0,0 +1,7 @@
+# See docs/devel/tracing.txt for syntax documentation.
+
+# kvm.c
+kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %" PRIu32
+kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
+kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
+kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
diff --git a/target/i386/kvm/trace.h b/target/i386/kvm/trace.h
new file mode 100644
index 0000000000..46b75c6942
--- /dev/null
+++ b/target/i386/kvm/trace.h
@@ -0,0 +1 @@
+#include "trace/trace-target_i386_kvm.h"
diff --git a/target/i386/machine.c b/target/i386/machine.c
index 233e46bb70..1614e8c2f8 100644
--- a/target/i386/machine.c
+++ b/target/i386/machine.c
@@ -3,9 +3,9 @@
#include "exec/exec-all.h"
#include "hw/isa/isa.h"
#include "migration/cpu.h"
-#include "hyperv.h"
+#include "kvm/hyperv.h"
#include "hw/i386/x86.h"
-#include "kvm_i386.h"
+#include "kvm/kvm_i386.h"
#include "sysemu/kvm.h"
#include "sysemu/tcg.h"
diff --git a/target/i386/meson.build b/target/i386/meson.build
index a1a02f3e99..0209542a8a 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -18,7 +18,6 @@ i386_ss.add(when: 'CONFIG_TCG', if_true: files(
'smm_helper.c',
'svm_helper.c',
'translate.c'), if_false: files('tcg-stub.c'))
-i386_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c'))
i386_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-stub.c'))
i386_softmmu_ss = ss.source_set()
@@ -28,8 +27,6 @@ i386_softmmu_ss.add(files(
'machine.c',
'monitor.c',
))
-i386_softmmu_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c'))
-i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files(
'whpx-all.c',
'whpx-cpus.c',
@@ -42,6 +39,7 @@ i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files(
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'))
+subdir('kvm')
subdir('hvf')
target_arch += {'i386': i386_ss}
diff --git a/target/i386/trace-events b/target/i386/trace-events
index 789c700d4a..d166f9d5e0 100644
--- a/target/i386/trace-events
+++ b/target/i386/trace-events
@@ -1,11 +1,5 @@
# See docs/devel/tracing.txt for syntax documentation.
-# kvm.c
-kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %" PRIu32
-kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d"
-kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d"
-kvm_x86_update_msi_routes(int num) "Updated %d MSI routes"
-
# sev.c
kvm_sev_init(void) ""
kvm_memcrypt_register_region(void *addr, size_t len) "addr %p len 0x%zu"
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 05/27] i386: move whpx accel files into whpx/
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (3 preceding siblings ...)
2020-12-05 16:14 ` [RFC v8 04/27] i386: move kvm accel files into kvm/ Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:14 ` [RFC v8 06/27] i386: move hax accel files into hax/ Claudio Fontana
` (22 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
MAINTAINERS | 5 +----
target/i386/meson.build | 5 +----
target/i386/whpx/meson.build | 4 ++++
target/i386/{ => whpx}/whp-dispatch.h | 0
target/i386/{ => whpx}/whpx-all.c | 0
target/i386/{ => whpx}/whpx-cpus.c | 0
target/i386/{ => whpx}/whpx-cpus.h | 0
7 files changed, 6 insertions(+), 8 deletions(-)
create mode 100644 target/i386/whpx/meson.build
rename target/i386/{ => whpx}/whp-dispatch.h (100%)
rename target/i386/{ => whpx}/whpx-all.c (100%)
rename target/i386/{ => whpx}/whpx-cpus.c (100%)
rename target/i386/{ => whpx}/whpx-cpus.h (100%)
diff --git a/MAINTAINERS b/MAINTAINERS
index 5b3eced829..20e079f40c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -451,10 +451,7 @@ F: include/sysemu/hvf.h
WHPX CPUs
M: Sunil Muthuswamy <sunilmut@microsoft.com>
S: Supported
-F: target/i386/whpx-all.c
-F: target/i386/whpx-cpus.c
-F: target/i386/whp-dispatch.h
-F: accel/stubs/whpx-stub.c
+F: target/i386/whpx/
F: include/sysemu/whpx.h
Guest CPU Cores (Xen)
diff --git a/target/i386/meson.build b/target/i386/meson.build
index 0209542a8a..62cd042915 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -27,10 +27,6 @@ i386_softmmu_ss.add(files(
'machine.c',
'monitor.c',
))
-i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files(
- 'whpx-all.c',
- 'whpx-cpus.c',
-))
i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files(
'hax-all.c',
'hax-mem.c',
@@ -40,6 +36,7 @@ i386_softmmu_ss.add(when: ['CONFIG_HAX', 'CONFIG_POSIX'], if_true: files('hax-po
i386_softmmu_ss.add(when: ['CONFIG_HAX', 'CONFIG_WIN32'], if_true: files('hax-windows.c'))
subdir('kvm')
+subdir('whpx')
subdir('hvf')
target_arch += {'i386': i386_ss}
diff --git a/target/i386/whpx/meson.build b/target/i386/whpx/meson.build
new file mode 100644
index 0000000000..94a72c8efc
--- /dev/null
+++ b/target/i386/whpx/meson.build
@@ -0,0 +1,4 @@
+i386_softmmu_ss.add(when: 'CONFIG_WHPX', if_true: files(
+ 'whpx-all.c',
+ 'whpx-cpus.c',
+))
diff --git a/target/i386/whp-dispatch.h b/target/i386/whpx/whp-dispatch.h
similarity index 100%
rename from target/i386/whp-dispatch.h
rename to target/i386/whpx/whp-dispatch.h
diff --git a/target/i386/whpx-all.c b/target/i386/whpx/whpx-all.c
similarity index 100%
rename from target/i386/whpx-all.c
rename to target/i386/whpx/whpx-all.c
diff --git a/target/i386/whpx-cpus.c b/target/i386/whpx/whpx-cpus.c
similarity index 100%
rename from target/i386/whpx-cpus.c
rename to target/i386/whpx/whpx-cpus.c
diff --git a/target/i386/whpx-cpus.h b/target/i386/whpx/whpx-cpus.h
similarity index 100%
rename from target/i386/whpx-cpus.h
rename to target/i386/whpx/whpx-cpus.h
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 06/27] i386: move hax accel files into hax/
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (4 preceding siblings ...)
2020-12-05 16:14 ` [RFC v8 05/27] i386: move whpx accel files into whpx/ Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:14 ` [RFC v8 07/27] i386: hvf: remove stale MAINTAINERS entry for old hvf stubs Claudio Fontana
` (21 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
MAINTAINERS | 2 +-
target/i386/{ => hax}/hax-all.c | 0
target/i386/{ => hax}/hax-cpus.c | 0
target/i386/{ => hax}/hax-cpus.h | 0
target/i386/{ => hax}/hax-i386.h | 6 +++---
target/i386/{ => hax}/hax-interface.h | 0
target/i386/{ => hax}/hax-mem.c | 0
target/i386/{ => hax}/hax-posix.c | 0
target/i386/{ => hax}/hax-posix.h | 0
target/i386/{ => hax}/hax-windows.c | 0
target/i386/{ => hax}/hax-windows.h | 0
target/i386/hax/meson.build | 7 +++++++
target/i386/meson.build | 8 +-------
13 files changed, 12 insertions(+), 11 deletions(-)
rename target/i386/{ => hax}/hax-all.c (100%)
rename target/i386/{ => hax}/hax-cpus.c (100%)
rename target/i386/{ => hax}/hax-cpus.h (100%)
rename target/i386/{ => hax}/hax-i386.h (95%)
rename target/i386/{ => hax}/hax-interface.h (100%)
rename target/i386/{ => hax}/hax-mem.c (100%)
rename target/i386/{ => hax}/hax-posix.c (100%)
rename target/i386/{ => hax}/hax-posix.h (100%)
rename target/i386/{ => hax}/hax-windows.c (100%)
rename target/i386/{ => hax}/hax-windows.h (100%)
create mode 100644 target/i386/hax/meson.build
diff --git a/MAINTAINERS b/MAINTAINERS
index 20e079f40c..448593c904 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -491,7 +491,7 @@ W: https://github.com/intel/haxm/issues
S: Maintained
F: accel/stubs/hax-stub.c
F: include/sysemu/hax.h
-F: target/i386/hax-*
+F: target/i386/hax/
Hosts
-----
diff --git a/target/i386/hax-all.c b/target/i386/hax/hax-all.c
similarity index 100%
rename from target/i386/hax-all.c
rename to target/i386/hax/hax-all.c
diff --git a/target/i386/hax-cpus.c b/target/i386/hax/hax-cpus.c
similarity index 100%
rename from target/i386/hax-cpus.c
rename to target/i386/hax/hax-cpus.c
diff --git a/target/i386/hax-cpus.h b/target/i386/hax/hax-cpus.h
similarity index 100%
rename from target/i386/hax-cpus.h
rename to target/i386/hax/hax-cpus.h
diff --git a/target/i386/hax-i386.h b/target/i386/hax/hax-i386.h
similarity index 95%
rename from target/i386/hax-i386.h
rename to target/i386/hax/hax-i386.h
index 48c4abe14e..efbb346238 100644
--- a/target/i386/hax-i386.h
+++ b/target/i386/hax/hax-i386.h
@@ -84,13 +84,13 @@ void hax_memory_init(void);
#ifdef CONFIG_POSIX
-#include "target/i386/hax-posix.h"
+#include "hax-posix.h"
#endif
#ifdef CONFIG_WIN32
-#include "target/i386/hax-windows.h"
+#include "hax-windows.h"
#endif
-#include "target/i386/hax-interface.h"
+#include "hax-interface.h"
#endif
diff --git a/target/i386/hax-interface.h b/target/i386/hax/hax-interface.h
similarity index 100%
rename from target/i386/hax-interface.h
rename to target/i386/hax/hax-interface.h
diff --git a/target/i386/hax-mem.c b/target/i386/hax/hax-mem.c
similarity index 100%
rename from target/i386/hax-mem.c
rename to target/i386/hax/hax-mem.c
diff --git a/target/i386/hax-posix.c b/target/i386/hax/hax-posix.c
similarity index 100%
rename from target/i386/hax-posix.c
rename to target/i386/hax/hax-posix.c
diff --git a/target/i386/hax-posix.h b/target/i386/hax/hax-posix.h
similarity index 100%
rename from target/i386/hax-posix.h
rename to target/i386/hax/hax-posix.h
diff --git a/target/i386/hax-windows.c b/target/i386/hax/hax-windows.c
similarity index 100%
rename from target/i386/hax-windows.c
rename to target/i386/hax/hax-windows.c
diff --git a/target/i386/hax-windows.h b/target/i386/hax/hax-windows.h
similarity index 100%
rename from target/i386/hax-windows.h
rename to target/i386/hax/hax-windows.h
diff --git a/target/i386/hax/meson.build b/target/i386/hax/meson.build
new file mode 100644
index 0000000000..77ea431b30
--- /dev/null
+++ b/target/i386/hax/meson.build
@@ -0,0 +1,7 @@
+i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files(
+ 'hax-all.c',
+ 'hax-mem.c',
+ 'hax-cpus.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'))
diff --git a/target/i386/meson.build b/target/i386/meson.build
index 62cd042915..284d52ab81 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -27,15 +27,9 @@ i386_softmmu_ss.add(files(
'machine.c',
'monitor.c',
))
-i386_softmmu_ss.add(when: 'CONFIG_HAX', if_true: files(
- 'hax-all.c',
- 'hax-mem.c',
- 'hax-cpus.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'))
subdir('kvm')
+subdir('hax')
subdir('whpx')
subdir('hvf')
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 07/27] i386: hvf: remove stale MAINTAINERS entry for old hvf stubs
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (5 preceding siblings ...)
2020-12-05 16:14 ` [RFC v8 06/27] i386: move hax accel files into hax/ Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:14 ` [RFC v8 08/27] i386: move TCG accel files into tcg/ Claudio Fontana
` (20 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Roman Bolshakov <r.bolshakov@yadro.com>
---
MAINTAINERS | 1 -
1 file changed, 1 deletion(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 448593c904..f53f2678d8 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -444,7 +444,6 @@ M: Cameron Esfahani <dirty@apple.com>
M: Roman Bolshakov <r.bolshakov@yadro.com>
W: https://wiki.qemu.org/Features/HVF
S: Maintained
-F: accel/stubs/hvf-stub.c
F: target/i386/hvf/
F: include/sysemu/hvf.h
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 08/27] i386: move TCG accel files into tcg/
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (6 preceding siblings ...)
2020-12-05 16:14 ` [RFC v8 07/27] i386: hvf: remove stale MAINTAINERS entry for old hvf stubs Claudio Fontana
@ 2020-12-05 16:14 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 09/27] i386: move cpu dump out of helper.c into cpu-dump.c Claudio Fontana
` (19 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:14 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
target/i386/meson.build | 14 +-------------
target/i386/{ => tcg}/bpt_helper.c | 0
target/i386/{ => tcg}/cc_helper.c | 0
target/i386/{ => tcg}/excp_helper.c | 0
target/i386/{ => tcg}/fpu_helper.c | 0
target/i386/{ => tcg}/int_helper.c | 0
target/i386/{ => tcg}/mem_helper.c | 0
target/i386/tcg/meson.build | 13 +++++++++++++
target/i386/{ => tcg}/misc_helper.c | 0
target/i386/{ => tcg}/mpx_helper.c | 0
target/i386/{ => tcg}/seg_helper.c | 0
target/i386/{ => tcg}/smm_helper.c | 0
target/i386/{ => tcg}/svm_helper.c | 0
target/i386/{ => tcg}/tcg-stub.c | 0
target/i386/{ => tcg}/translate.c | 0
15 files changed, 14 insertions(+), 13 deletions(-)
rename target/i386/{ => tcg}/bpt_helper.c (100%)
rename target/i386/{ => tcg}/cc_helper.c (100%)
rename target/i386/{ => tcg}/excp_helper.c (100%)
rename target/i386/{ => tcg}/fpu_helper.c (100%)
rename target/i386/{ => tcg}/int_helper.c (100%)
rename target/i386/{ => tcg}/mem_helper.c (100%)
create mode 100644 target/i386/tcg/meson.build
rename target/i386/{ => tcg}/misc_helper.c (100%)
rename target/i386/{ => tcg}/mpx_helper.c (100%)
rename target/i386/{ => tcg}/seg_helper.c (100%)
rename target/i386/{ => tcg}/smm_helper.c (100%)
rename target/i386/{ => tcg}/svm_helper.c (100%)
rename target/i386/{ => tcg}/tcg-stub.c (100%)
rename target/i386/{ => tcg}/translate.c (100%)
diff --git a/target/i386/meson.build b/target/i386/meson.build
index 284d52ab81..750471c9f3 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -5,19 +5,6 @@ i386_ss.add(files(
'helper.c',
'xsave_helper.c',
))
-i386_ss.add(when: 'CONFIG_TCG', if_true: files(
- 'bpt_helper.c',
- 'cc_helper.c',
- 'excp_helper.c',
- 'fpu_helper.c',
- 'int_helper.c',
- 'mem_helper.c',
- 'misc_helper.c',
- 'mpx_helper.c',
- 'seg_helper.c',
- 'smm_helper.c',
- 'svm_helper.c',
- 'translate.c'), if_false: files('tcg-stub.c'))
i386_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-stub.c'))
i386_softmmu_ss = ss.source_set()
@@ -32,6 +19,7 @@ subdir('kvm')
subdir('hax')
subdir('whpx')
subdir('hvf')
+subdir('tcg')
target_arch += {'i386': i386_ss}
target_softmmu_arch += {'i386': i386_softmmu_ss}
diff --git a/target/i386/bpt_helper.c b/target/i386/tcg/bpt_helper.c
similarity index 100%
rename from target/i386/bpt_helper.c
rename to target/i386/tcg/bpt_helper.c
diff --git a/target/i386/cc_helper.c b/target/i386/tcg/cc_helper.c
similarity index 100%
rename from target/i386/cc_helper.c
rename to target/i386/tcg/cc_helper.c
diff --git a/target/i386/excp_helper.c b/target/i386/tcg/excp_helper.c
similarity index 100%
rename from target/i386/excp_helper.c
rename to target/i386/tcg/excp_helper.c
diff --git a/target/i386/fpu_helper.c b/target/i386/tcg/fpu_helper.c
similarity index 100%
rename from target/i386/fpu_helper.c
rename to target/i386/tcg/fpu_helper.c
diff --git a/target/i386/int_helper.c b/target/i386/tcg/int_helper.c
similarity index 100%
rename from target/i386/int_helper.c
rename to target/i386/tcg/int_helper.c
diff --git a/target/i386/mem_helper.c b/target/i386/tcg/mem_helper.c
similarity index 100%
rename from target/i386/mem_helper.c
rename to target/i386/tcg/mem_helper.c
diff --git a/target/i386/tcg/meson.build b/target/i386/tcg/meson.build
new file mode 100644
index 0000000000..02794226c2
--- /dev/null
+++ b/target/i386/tcg/meson.build
@@ -0,0 +1,13 @@
+i386_ss.add(when: 'CONFIG_TCG', if_true: files(
+ 'bpt_helper.c',
+ 'cc_helper.c',
+ 'excp_helper.c',
+ 'fpu_helper.c',
+ 'int_helper.c',
+ 'mem_helper.c',
+ 'misc_helper.c',
+ 'mpx_helper.c',
+ 'seg_helper.c',
+ 'smm_helper.c',
+ 'svm_helper.c',
+ 'translate.c'), if_false: files('tcg-stub.c'))
diff --git a/target/i386/misc_helper.c b/target/i386/tcg/misc_helper.c
similarity index 100%
rename from target/i386/misc_helper.c
rename to target/i386/tcg/misc_helper.c
diff --git a/target/i386/mpx_helper.c b/target/i386/tcg/mpx_helper.c
similarity index 100%
rename from target/i386/mpx_helper.c
rename to target/i386/tcg/mpx_helper.c
diff --git a/target/i386/seg_helper.c b/target/i386/tcg/seg_helper.c
similarity index 100%
rename from target/i386/seg_helper.c
rename to target/i386/tcg/seg_helper.c
diff --git a/target/i386/smm_helper.c b/target/i386/tcg/smm_helper.c
similarity index 100%
rename from target/i386/smm_helper.c
rename to target/i386/tcg/smm_helper.c
diff --git a/target/i386/svm_helper.c b/target/i386/tcg/svm_helper.c
similarity index 100%
rename from target/i386/svm_helper.c
rename to target/i386/tcg/svm_helper.c
diff --git a/target/i386/tcg-stub.c b/target/i386/tcg/tcg-stub.c
similarity index 100%
rename from target/i386/tcg-stub.c
rename to target/i386/tcg/tcg-stub.c
diff --git a/target/i386/translate.c b/target/i386/tcg/translate.c
similarity index 100%
rename from target/i386/translate.c
rename to target/i386/tcg/translate.c
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 09/27] i386: move cpu dump out of helper.c into cpu-dump.c
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (7 preceding siblings ...)
2020-12-05 16:14 ` [RFC v8 08/27] i386: move TCG accel files into tcg/ Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 10/27] i386: move TCG cpu class initialization out of helper.c Claudio Fontana
` (18 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
target/i386/cpu-dump.c | 537 ++++++++++++++++++++++++++++++++++++++++
target/i386/cpu.h | 1 +
target/i386/helper.c | 514 --------------------------------------
target/i386/meson.build | 1 +
4 files changed, 539 insertions(+), 514 deletions(-)
create mode 100644 target/i386/cpu-dump.c
diff --git a/target/i386/cpu-dump.c b/target/i386/cpu-dump.c
new file mode 100644
index 0000000000..aac21f1f60
--- /dev/null
+++ b/target/i386/cpu-dump.c
@@ -0,0 +1,537 @@
+/*
+ * i386 CPU dump to FILE
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "qemu/qemu-print.h"
+#ifndef CONFIG_USER_ONLY
+#include "hw/i386/apic_internal.h"
+#endif
+
+/***********************************************************/
+/* x86 debug */
+
+static const char *cc_op_str[CC_OP_NB] = {
+ "DYNAMIC",
+ "EFLAGS",
+
+ "MULB",
+ "MULW",
+ "MULL",
+ "MULQ",
+
+ "ADDB",
+ "ADDW",
+ "ADDL",
+ "ADDQ",
+
+ "ADCB",
+ "ADCW",
+ "ADCL",
+ "ADCQ",
+
+ "SUBB",
+ "SUBW",
+ "SUBL",
+ "SUBQ",
+
+ "SBBB",
+ "SBBW",
+ "SBBL",
+ "SBBQ",
+
+ "LOGICB",
+ "LOGICW",
+ "LOGICL",
+ "LOGICQ",
+
+ "INCB",
+ "INCW",
+ "INCL",
+ "INCQ",
+
+ "DECB",
+ "DECW",
+ "DECL",
+ "DECQ",
+
+ "SHLB",
+ "SHLW",
+ "SHLL",
+ "SHLQ",
+
+ "SARB",
+ "SARW",
+ "SARL",
+ "SARQ",
+
+ "BMILGB",
+ "BMILGW",
+ "BMILGL",
+ "BMILGQ",
+
+ "ADCX",
+ "ADOX",
+ "ADCOX",
+
+ "CLR",
+};
+
+static void
+cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f,
+ const char *name, struct SegmentCache *sc)
+{
+#ifdef TARGET_X86_64
+ if (env->hflags & HF_CS64_MASK) {
+ qemu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
+ sc->selector, sc->base, sc->limit,
+ sc->flags & 0x00ffff00);
+ } else
+#endif
+ {
+ qemu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
+ (uint32_t)sc->base, sc->limit,
+ sc->flags & 0x00ffff00);
+ }
+
+ if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
+ goto done;
+
+ qemu_fprintf(f, " DPL=%d ",
+ (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
+ if (sc->flags & DESC_S_MASK) {
+ if (sc->flags & DESC_CS_MASK) {
+ qemu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
+ ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
+ qemu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
+ (sc->flags & DESC_R_MASK) ? 'R' : '-');
+ } else {
+ qemu_fprintf(f, (sc->flags & DESC_B_MASK
+ || env->hflags & HF_LMA_MASK)
+ ? "DS " : "DS16");
+ qemu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
+ (sc->flags & DESC_W_MASK) ? 'W' : '-');
+ }
+ qemu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
+ } else {
+ static const char *sys_type_name[2][16] = {
+ { /* 32 bit mode */
+ "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
+ "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
+ "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
+ "CallGate32", "Reserved", "IntGate32", "TrapGate32"
+ },
+ { /* 64 bit mode */
+ "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
+ "Reserved", "Reserved", "Reserved", "Reserved",
+ "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
+ "Reserved", "IntGate64", "TrapGate64"
+ }
+ };
+ qemu_fprintf(f, "%s",
+ sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
+ [(sc->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT]);
+ }
+done:
+ qemu_fprintf(f, "\n");
+}
+
+#ifndef CONFIG_USER_ONLY
+
+/* ARRAY_SIZE check is not required because
+ * DeliveryMode(dm) has a size of 3 bit.
+ */
+static inline const char *dm2str(uint32_t dm)
+{
+ static const char *str[] = {
+ "Fixed",
+ "...",
+ "SMI",
+ "...",
+ "NMI",
+ "INIT",
+ "...",
+ "ExtINT"
+ };
+ return str[dm];
+}
+
+static void dump_apic_lvt(const char *name, uint32_t lvt, bool is_timer)
+{
+ uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
+ qemu_printf("%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
+ name, lvt,
+ lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
+ lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
+ lvt & APIC_LVT_MASKED ? "masked" : "",
+ lvt & APIC_LVT_DELIV_STS ? "pending" : "",
+ !is_timer ?
+ "" : lvt & APIC_LVT_TIMER_PERIODIC ?
+ "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
+ "tsc-deadline" : "one-shot",
+ dm2str(dm));
+ if (dm != APIC_DM_NMI) {
+ qemu_printf(" (vec %u)\n", lvt & APIC_VECTOR_MASK);
+ } else {
+ qemu_printf("\n");
+ }
+}
+
+/* ARRAY_SIZE check is not required because
+ * destination shorthand has a size of 2 bit.
+ */
+static inline const char *shorthand2str(uint32_t shorthand)
+{
+ const char *str[] = {
+ "no-shorthand", "self", "all-self", "all"
+ };
+ return str[shorthand];
+}
+
+static inline uint8_t divider_conf(uint32_t divide_conf)
+{
+ uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
+
+ return divide_val == 7 ? 1 : 2 << divide_val;
+}
+
+static inline void mask2str(char *str, uint32_t val, uint8_t size)
+{
+ while (size--) {
+ *str++ = (val >> size) & 1 ? '1' : '0';
+ }
+ *str = 0;
+}
+
+#define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
+
+static void dump_apic_icr(APICCommonState *s, CPUX86State *env)
+{
+ uint32_t icr = s->icr[0], icr2 = s->icr[1];
+ uint8_t dest_shorthand = \
+ (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
+ bool logical_mod = icr & APIC_ICR_DEST_MOD;
+ char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
+ uint32_t dest_field;
+ bool x2apic;
+
+ qemu_printf("ICR\t 0x%08x %s %s %s %s\n",
+ icr,
+ logical_mod ? "logical" : "physical",
+ icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
+ icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
+ shorthand2str(dest_shorthand));
+
+ qemu_printf("ICR2\t 0x%08x", icr2);
+ if (dest_shorthand != 0) {
+ qemu_printf("\n");
+ return;
+ }
+ x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
+ dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
+
+ if (!logical_mod) {
+ if (x2apic) {
+ qemu_printf(" cpu %u (X2APIC ID)\n", dest_field);
+ } else {
+ qemu_printf(" cpu %u (APIC ID)\n",
+ dest_field & APIC_LOGDEST_XAPIC_ID);
+ }
+ return;
+ }
+
+ if (s->dest_mode == 0xf) { /* flat mode */
+ mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
+ qemu_printf(" mask %s (APIC ID)\n", apic_id_str);
+ } else if (s->dest_mode == 0) { /* cluster mode */
+ if (x2apic) {
+ mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
+ qemu_printf(" cluster %u mask %s (X2APIC ID)\n",
+ dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
+ } else {
+ mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
+ qemu_printf(" cluster %u mask %s (APIC ID)\n",
+ dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
+ }
+ }
+}
+
+static void dump_apic_interrupt(const char *name, uint32_t *ireg_tab,
+ uint32_t *tmr_tab)
+{
+ int i, empty = true;
+
+ qemu_printf("%s\t ", name);
+ for (i = 0; i < 256; i++) {
+ if (apic_get_bit(ireg_tab, i)) {
+ qemu_printf("%u%s ", i,
+ apic_get_bit(tmr_tab, i) ? "(level)" : "");
+ empty = false;
+ }
+ }
+ qemu_printf("%s\n", empty ? "(none)" : "");
+}
+
+void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ APICCommonState *s = APIC_COMMON(cpu->apic_state);
+ if (!s) {
+ qemu_printf("local apic state not available\n");
+ return;
+ }
+ uint32_t *lvt = s->lvt;
+
+ qemu_printf("dumping local APIC state for CPU %-2u\n\n",
+ CPU(cpu)->cpu_index);
+ dump_apic_lvt("LVT0", lvt[APIC_LVT_LINT0], false);
+ dump_apic_lvt("LVT1", lvt[APIC_LVT_LINT1], false);
+ dump_apic_lvt("LVTPC", lvt[APIC_LVT_PERFORM], false);
+ dump_apic_lvt("LVTERR", lvt[APIC_LVT_ERROR], false);
+ dump_apic_lvt("LVTTHMR", lvt[APIC_LVT_THERMAL], false);
+ dump_apic_lvt("LVTT", lvt[APIC_LVT_TIMER], true);
+
+ qemu_printf("Timer\t DCR=0x%x (divide by %u) initial_count = %u"
+ " current_count = %u\n",
+ s->divide_conf & APIC_DCR_MASK,
+ divider_conf(s->divide_conf),
+ s->initial_count, apic_get_current_count(s));
+
+ qemu_printf("SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
+ s->spurious_vec,
+ s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
+ s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
+ s->spurious_vec & APIC_VECTOR_MASK);
+
+ dump_apic_icr(s, &cpu->env);
+
+ qemu_printf("ESR\t 0x%08x\n", s->esr);
+
+ dump_apic_interrupt("ISR", s->isr, s->tmr);
+ dump_apic_interrupt("IRR", s->irr, s->tmr);
+
+ qemu_printf("\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
+ s->arb_id, s->tpr, s->dest_mode, s->log_dest);
+ if (s->dest_mode == 0) {
+ qemu_printf("(cluster %u: id %u)",
+ s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
+ s->log_dest & APIC_LOGDEST_XAPIC_ID);
+ }
+ qemu_printf(" PPR 0x%02x\n", apic_get_ppr(s));
+}
+#else
+void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
+{
+}
+#endif /* !CONFIG_USER_ONLY */
+
+#define DUMP_CODE_BYTES_TOTAL 50
+#define DUMP_CODE_BYTES_BACKWARD 20
+
+void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+ int eflags, i, nb;
+ char cc_op_name[32];
+ static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
+
+ eflags = cpu_compute_eflags(env);
+#ifdef TARGET_X86_64
+ if (env->hflags & HF_CS64_MASK) {
+ qemu_fprintf(f, "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
+ "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
+ "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
+ "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
+ "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
+ env->regs[R_EAX],
+ env->regs[R_EBX],
+ env->regs[R_ECX],
+ env->regs[R_EDX],
+ env->regs[R_ESI],
+ env->regs[R_EDI],
+ env->regs[R_EBP],
+ env->regs[R_ESP],
+ env->regs[8],
+ env->regs[9],
+ env->regs[10],
+ env->regs[11],
+ env->regs[12],
+ env->regs[13],
+ env->regs[14],
+ env->regs[15],
+ env->eip, eflags,
+ eflags & DF_MASK ? 'D' : '-',
+ eflags & CC_O ? 'O' : '-',
+ eflags & CC_S ? 'S' : '-',
+ eflags & CC_Z ? 'Z' : '-',
+ eflags & CC_A ? 'A' : '-',
+ eflags & CC_P ? 'P' : '-',
+ eflags & CC_C ? 'C' : '-',
+ env->hflags & HF_CPL_MASK,
+ (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
+ (env->a20_mask >> 20) & 1,
+ (env->hflags >> HF_SMM_SHIFT) & 1,
+ cs->halted);
+ } else
+#endif
+ {
+ qemu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
+ "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
+ "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
+ (uint32_t)env->regs[R_EAX],
+ (uint32_t)env->regs[R_EBX],
+ (uint32_t)env->regs[R_ECX],
+ (uint32_t)env->regs[R_EDX],
+ (uint32_t)env->regs[R_ESI],
+ (uint32_t)env->regs[R_EDI],
+ (uint32_t)env->regs[R_EBP],
+ (uint32_t)env->regs[R_ESP],
+ (uint32_t)env->eip, eflags,
+ eflags & DF_MASK ? 'D' : '-',
+ eflags & CC_O ? 'O' : '-',
+ eflags & CC_S ? 'S' : '-',
+ eflags & CC_Z ? 'Z' : '-',
+ eflags & CC_A ? 'A' : '-',
+ eflags & CC_P ? 'P' : '-',
+ eflags & CC_C ? 'C' : '-',
+ env->hflags & HF_CPL_MASK,
+ (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
+ (env->a20_mask >> 20) & 1,
+ (env->hflags >> HF_SMM_SHIFT) & 1,
+ cs->halted);
+ }
+
+ for(i = 0; i < 6; i++) {
+ cpu_x86_dump_seg_cache(env, f, seg_name[i], &env->segs[i]);
+ }
+ cpu_x86_dump_seg_cache(env, f, "LDT", &env->ldt);
+ cpu_x86_dump_seg_cache(env, f, "TR", &env->tr);
+
+#ifdef TARGET_X86_64
+ if (env->hflags & HF_LMA_MASK) {
+ qemu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
+ env->gdt.base, env->gdt.limit);
+ qemu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
+ env->idt.base, env->idt.limit);
+ qemu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
+ (uint32_t)env->cr[0],
+ env->cr[2],
+ env->cr[3],
+ (uint32_t)env->cr[4]);
+ for(i = 0; i < 4; i++)
+ qemu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
+ qemu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
+ env->dr[6], env->dr[7]);
+ } else
+#endif
+ {
+ qemu_fprintf(f, "GDT= %08x %08x\n",
+ (uint32_t)env->gdt.base, env->gdt.limit);
+ qemu_fprintf(f, "IDT= %08x %08x\n",
+ (uint32_t)env->idt.base, env->idt.limit);
+ qemu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
+ (uint32_t)env->cr[0],
+ (uint32_t)env->cr[2],
+ (uint32_t)env->cr[3],
+ (uint32_t)env->cr[4]);
+ for(i = 0; i < 4; i++) {
+ qemu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
+ }
+ qemu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
+ env->dr[6], env->dr[7]);
+ }
+ if (flags & CPU_DUMP_CCOP) {
+ if ((unsigned)env->cc_op < CC_OP_NB)
+ snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
+ else
+ snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
+#ifdef TARGET_X86_64
+ if (env->hflags & HF_CS64_MASK) {
+ qemu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
+ env->cc_src, env->cc_dst,
+ cc_op_name);
+ } else
+#endif
+ {
+ qemu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
+ (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
+ cc_op_name);
+ }
+ }
+ qemu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
+ if (flags & CPU_DUMP_FPU) {
+ int fptag;
+ fptag = 0;
+ for(i = 0; i < 8; i++) {
+ fptag |= ((!env->fptags[i]) << i);
+ }
+ update_mxcsr_from_sse_status(env);
+ qemu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
+ env->fpuc,
+ (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
+ env->fpstt,
+ fptag,
+ env->mxcsr);
+ for(i=0;i<8;i++) {
+ CPU_LDoubleU u;
+ u.d = env->fpregs[i].d;
+ qemu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
+ i, u.l.lower, u.l.upper);
+ if ((i & 1) == 1)
+ qemu_fprintf(f, "\n");
+ else
+ qemu_fprintf(f, " ");
+ }
+ if (env->hflags & HF_CS64_MASK)
+ nb = 16;
+ else
+ nb = 8;
+ for(i=0;i<nb;i++) {
+ qemu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
+ i,
+ env->xmm_regs[i].ZMM_L(3),
+ env->xmm_regs[i].ZMM_L(2),
+ env->xmm_regs[i].ZMM_L(1),
+ env->xmm_regs[i].ZMM_L(0));
+ if ((i & 1) == 1)
+ qemu_fprintf(f, "\n");
+ else
+ qemu_fprintf(f, " ");
+ }
+ }
+ if (flags & CPU_DUMP_CODE) {
+ target_ulong base = env->segs[R_CS].base + env->eip;
+ target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
+ uint8_t code;
+ char codestr[3];
+
+ qemu_fprintf(f, "Code=");
+ for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
+ if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
+ snprintf(codestr, sizeof(codestr), "%02x", code);
+ } else {
+ snprintf(codestr, sizeof(codestr), "??");
+ }
+ qemu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
+ i == offs ? "<" : "", codestr, i == offs ? ">" : "");
+ }
+ qemu_fprintf(f, "\n");
+ }
+}
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index 9ecda75aec..d6ed45c5d7 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -2232,6 +2232,7 @@ void enable_compat_apic_id_mode(void);
#define APIC_DEFAULT_ADDRESS 0xfee00000
#define APIC_SPACE_SIZE 0x100000
+/* cpu-dump.c */
void x86_cpu_dump_local_apic_state(CPUState *cs, int flags);
/* cpu.c */
diff --git a/target/i386/helper.c b/target/i386/helper.c
index a1b3367ab2..6e7e0f507c 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -21,8 +21,6 @@
#include "qapi/qapi-events-run-state.h"
#include "cpu.h"
#include "exec/exec-all.h"
-#include "qemu/qemu-print.h"
-#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
#include "kvm/kvm_i386.h"
#ifndef CONFIG_USER_ONLY
@@ -88,518 +86,6 @@ int cpu_x86_support_mca_broadcast(CPUX86State *env)
return 0;
}
-/***********************************************************/
-/* x86 debug */
-
-static const char *cc_op_str[CC_OP_NB] = {
- "DYNAMIC",
- "EFLAGS",
-
- "MULB",
- "MULW",
- "MULL",
- "MULQ",
-
- "ADDB",
- "ADDW",
- "ADDL",
- "ADDQ",
-
- "ADCB",
- "ADCW",
- "ADCL",
- "ADCQ",
-
- "SUBB",
- "SUBW",
- "SUBL",
- "SUBQ",
-
- "SBBB",
- "SBBW",
- "SBBL",
- "SBBQ",
-
- "LOGICB",
- "LOGICW",
- "LOGICL",
- "LOGICQ",
-
- "INCB",
- "INCW",
- "INCL",
- "INCQ",
-
- "DECB",
- "DECW",
- "DECL",
- "DECQ",
-
- "SHLB",
- "SHLW",
- "SHLL",
- "SHLQ",
-
- "SARB",
- "SARW",
- "SARL",
- "SARQ",
-
- "BMILGB",
- "BMILGW",
- "BMILGL",
- "BMILGQ",
-
- "ADCX",
- "ADOX",
- "ADCOX",
-
- "CLR",
-};
-
-static void
-cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f,
- const char *name, struct SegmentCache *sc)
-{
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK) {
- qemu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name,
- sc->selector, sc->base, sc->limit,
- sc->flags & 0x00ffff00);
- } else
-#endif
- {
- qemu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector,
- (uint32_t)sc->base, sc->limit,
- sc->flags & 0x00ffff00);
- }
-
- if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK))
- goto done;
-
- qemu_fprintf(f, " DPL=%d ",
- (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT);
- if (sc->flags & DESC_S_MASK) {
- if (sc->flags & DESC_CS_MASK) {
- qemu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" :
- ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16"));
- qemu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-',
- (sc->flags & DESC_R_MASK) ? 'R' : '-');
- } else {
- qemu_fprintf(f, (sc->flags & DESC_B_MASK
- || env->hflags & HF_LMA_MASK)
- ? "DS " : "DS16");
- qemu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-',
- (sc->flags & DESC_W_MASK) ? 'W' : '-');
- }
- qemu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-');
- } else {
- static const char *sys_type_name[2][16] = {
- { /* 32 bit mode */
- "Reserved", "TSS16-avl", "LDT", "TSS16-busy",
- "CallGate16", "TaskGate", "IntGate16", "TrapGate16",
- "Reserved", "TSS32-avl", "Reserved", "TSS32-busy",
- "CallGate32", "Reserved", "IntGate32", "TrapGate32"
- },
- { /* 64 bit mode */
- "<hiword>", "Reserved", "LDT", "Reserved", "Reserved",
- "Reserved", "Reserved", "Reserved", "Reserved",
- "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64",
- "Reserved", "IntGate64", "TrapGate64"
- }
- };
- qemu_fprintf(f, "%s",
- sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0]
- [(sc->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT]);
- }
-done:
- qemu_fprintf(f, "\n");
-}
-
-#ifndef CONFIG_USER_ONLY
-
-/* ARRAY_SIZE check is not required because
- * DeliveryMode(dm) has a size of 3 bit.
- */
-static inline const char *dm2str(uint32_t dm)
-{
- static const char *str[] = {
- "Fixed",
- "...",
- "SMI",
- "...",
- "NMI",
- "INIT",
- "...",
- "ExtINT"
- };
- return str[dm];
-}
-
-static void dump_apic_lvt(const char *name, uint32_t lvt, bool is_timer)
-{
- uint32_t dm = (lvt & APIC_LVT_DELIV_MOD) >> APIC_LVT_DELIV_MOD_SHIFT;
- qemu_printf("%s\t 0x%08x %s %-5s %-6s %-7s %-12s %-6s",
- name, lvt,
- lvt & APIC_LVT_INT_POLARITY ? "active-lo" : "active-hi",
- lvt & APIC_LVT_LEVEL_TRIGGER ? "level" : "edge",
- lvt & APIC_LVT_MASKED ? "masked" : "",
- lvt & APIC_LVT_DELIV_STS ? "pending" : "",
- !is_timer ?
- "" : lvt & APIC_LVT_TIMER_PERIODIC ?
- "periodic" : lvt & APIC_LVT_TIMER_TSCDEADLINE ?
- "tsc-deadline" : "one-shot",
- dm2str(dm));
- if (dm != APIC_DM_NMI) {
- qemu_printf(" (vec %u)\n", lvt & APIC_VECTOR_MASK);
- } else {
- qemu_printf("\n");
- }
-}
-
-/* ARRAY_SIZE check is not required because
- * destination shorthand has a size of 2 bit.
- */
-static inline const char *shorthand2str(uint32_t shorthand)
-{
- const char *str[] = {
- "no-shorthand", "self", "all-self", "all"
- };
- return str[shorthand];
-}
-
-static inline uint8_t divider_conf(uint32_t divide_conf)
-{
- uint8_t divide_val = ((divide_conf & 0x8) >> 1) | (divide_conf & 0x3);
-
- return divide_val == 7 ? 1 : 2 << divide_val;
-}
-
-static inline void mask2str(char *str, uint32_t val, uint8_t size)
-{
- while (size--) {
- *str++ = (val >> size) & 1 ? '1' : '0';
- }
- *str = 0;
-}
-
-#define MAX_LOGICAL_APIC_ID_MASK_SIZE 16
-
-static void dump_apic_icr(APICCommonState *s, CPUX86State *env)
-{
- uint32_t icr = s->icr[0], icr2 = s->icr[1];
- uint8_t dest_shorthand = \
- (icr & APIC_ICR_DEST_SHORT) >> APIC_ICR_DEST_SHORT_SHIFT;
- bool logical_mod = icr & APIC_ICR_DEST_MOD;
- char apic_id_str[MAX_LOGICAL_APIC_ID_MASK_SIZE + 1];
- uint32_t dest_field;
- bool x2apic;
-
- qemu_printf("ICR\t 0x%08x %s %s %s %s\n",
- icr,
- logical_mod ? "logical" : "physical",
- icr & APIC_ICR_TRIGGER_MOD ? "level" : "edge",
- icr & APIC_ICR_LEVEL ? "assert" : "de-assert",
- shorthand2str(dest_shorthand));
-
- qemu_printf("ICR2\t 0x%08x", icr2);
- if (dest_shorthand != 0) {
- qemu_printf("\n");
- return;
- }
- x2apic = env->features[FEAT_1_ECX] & CPUID_EXT_X2APIC;
- dest_field = x2apic ? icr2 : icr2 >> APIC_ICR_DEST_SHIFT;
-
- if (!logical_mod) {
- if (x2apic) {
- qemu_printf(" cpu %u (X2APIC ID)\n", dest_field);
- } else {
- qemu_printf(" cpu %u (APIC ID)\n",
- dest_field & APIC_LOGDEST_XAPIC_ID);
- }
- return;
- }
-
- if (s->dest_mode == 0xf) { /* flat mode */
- mask2str(apic_id_str, icr2 >> APIC_ICR_DEST_SHIFT, 8);
- qemu_printf(" mask %s (APIC ID)\n", apic_id_str);
- } else if (s->dest_mode == 0) { /* cluster mode */
- if (x2apic) {
- mask2str(apic_id_str, dest_field & APIC_LOGDEST_X2APIC_ID, 16);
- qemu_printf(" cluster %u mask %s (X2APIC ID)\n",
- dest_field >> APIC_LOGDEST_X2APIC_SHIFT, apic_id_str);
- } else {
- mask2str(apic_id_str, dest_field & APIC_LOGDEST_XAPIC_ID, 4);
- qemu_printf(" cluster %u mask %s (APIC ID)\n",
- dest_field >> APIC_LOGDEST_XAPIC_SHIFT, apic_id_str);
- }
- }
-}
-
-static void dump_apic_interrupt(const char *name, uint32_t *ireg_tab,
- uint32_t *tmr_tab)
-{
- int i, empty = true;
-
- qemu_printf("%s\t ", name);
- for (i = 0; i < 256; i++) {
- if (apic_get_bit(ireg_tab, i)) {
- qemu_printf("%u%s ", i,
- apic_get_bit(tmr_tab, i) ? "(level)" : "");
- empty = false;
- }
- }
- qemu_printf("%s\n", empty ? "(none)" : "");
-}
-
-void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
-{
- X86CPU *cpu = X86_CPU(cs);
- APICCommonState *s = APIC_COMMON(cpu->apic_state);
- if (!s) {
- qemu_printf("local apic state not available\n");
- return;
- }
- uint32_t *lvt = s->lvt;
-
- qemu_printf("dumping local APIC state for CPU %-2u\n\n",
- CPU(cpu)->cpu_index);
- dump_apic_lvt("LVT0", lvt[APIC_LVT_LINT0], false);
- dump_apic_lvt("LVT1", lvt[APIC_LVT_LINT1], false);
- dump_apic_lvt("LVTPC", lvt[APIC_LVT_PERFORM], false);
- dump_apic_lvt("LVTERR", lvt[APIC_LVT_ERROR], false);
- dump_apic_lvt("LVTTHMR", lvt[APIC_LVT_THERMAL], false);
- dump_apic_lvt("LVTT", lvt[APIC_LVT_TIMER], true);
-
- qemu_printf("Timer\t DCR=0x%x (divide by %u) initial_count = %u"
- " current_count = %u\n",
- s->divide_conf & APIC_DCR_MASK,
- divider_conf(s->divide_conf),
- s->initial_count, apic_get_current_count(s));
-
- qemu_printf("SPIV\t 0x%08x APIC %s, focus=%s, spurious vec %u\n",
- s->spurious_vec,
- s->spurious_vec & APIC_SPURIO_ENABLED ? "enabled" : "disabled",
- s->spurious_vec & APIC_SPURIO_FOCUS ? "on" : "off",
- s->spurious_vec & APIC_VECTOR_MASK);
-
- dump_apic_icr(s, &cpu->env);
-
- qemu_printf("ESR\t 0x%08x\n", s->esr);
-
- dump_apic_interrupt("ISR", s->isr, s->tmr);
- dump_apic_interrupt("IRR", s->irr, s->tmr);
-
- qemu_printf("\nAPR 0x%02x TPR 0x%02x DFR 0x%02x LDR 0x%02x",
- s->arb_id, s->tpr, s->dest_mode, s->log_dest);
- if (s->dest_mode == 0) {
- qemu_printf("(cluster %u: id %u)",
- s->log_dest >> APIC_LOGDEST_XAPIC_SHIFT,
- s->log_dest & APIC_LOGDEST_XAPIC_ID);
- }
- qemu_printf(" PPR 0x%02x\n", apic_get_ppr(s));
-}
-#else
-void x86_cpu_dump_local_apic_state(CPUState *cs, int flags)
-{
-}
-#endif /* !CONFIG_USER_ONLY */
-
-#define DUMP_CODE_BYTES_TOTAL 50
-#define DUMP_CODE_BYTES_BACKWARD 20
-
-void x86_cpu_dump_state(CPUState *cs, FILE *f, int flags)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
- int eflags, i, nb;
- char cc_op_name[32];
- static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };
-
- eflags = cpu_compute_eflags(env);
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK) {
- qemu_fprintf(f, "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"
- "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"
- "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"
- "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"
- "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
- env->regs[R_EAX],
- env->regs[R_EBX],
- env->regs[R_ECX],
- env->regs[R_EDX],
- env->regs[R_ESI],
- env->regs[R_EDI],
- env->regs[R_EBP],
- env->regs[R_ESP],
- env->regs[8],
- env->regs[9],
- env->regs[10],
- env->regs[11],
- env->regs[12],
- env->regs[13],
- env->regs[14],
- env->regs[15],
- env->eip, eflags,
- eflags & DF_MASK ? 'D' : '-',
- eflags & CC_O ? 'O' : '-',
- eflags & CC_S ? 'S' : '-',
- eflags & CC_Z ? 'Z' : '-',
- eflags & CC_A ? 'A' : '-',
- eflags & CC_P ? 'P' : '-',
- eflags & CC_C ? 'C' : '-',
- env->hflags & HF_CPL_MASK,
- (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
- (env->a20_mask >> 20) & 1,
- (env->hflags >> HF_SMM_SHIFT) & 1,
- cs->halted);
- } else
-#endif
- {
- qemu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
- "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
- "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",
- (uint32_t)env->regs[R_EAX],
- (uint32_t)env->regs[R_EBX],
- (uint32_t)env->regs[R_ECX],
- (uint32_t)env->regs[R_EDX],
- (uint32_t)env->regs[R_ESI],
- (uint32_t)env->regs[R_EDI],
- (uint32_t)env->regs[R_EBP],
- (uint32_t)env->regs[R_ESP],
- (uint32_t)env->eip, eflags,
- eflags & DF_MASK ? 'D' : '-',
- eflags & CC_O ? 'O' : '-',
- eflags & CC_S ? 'S' : '-',
- eflags & CC_Z ? 'Z' : '-',
- eflags & CC_A ? 'A' : '-',
- eflags & CC_P ? 'P' : '-',
- eflags & CC_C ? 'C' : '-',
- env->hflags & HF_CPL_MASK,
- (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,
- (env->a20_mask >> 20) & 1,
- (env->hflags >> HF_SMM_SHIFT) & 1,
- cs->halted);
- }
-
- for(i = 0; i < 6; i++) {
- cpu_x86_dump_seg_cache(env, f, seg_name[i], &env->segs[i]);
- }
- cpu_x86_dump_seg_cache(env, f, "LDT", &env->ldt);
- cpu_x86_dump_seg_cache(env, f, "TR", &env->tr);
-
-#ifdef TARGET_X86_64
- if (env->hflags & HF_LMA_MASK) {
- qemu_fprintf(f, "GDT= %016" PRIx64 " %08x\n",
- env->gdt.base, env->gdt.limit);
- qemu_fprintf(f, "IDT= %016" PRIx64 " %08x\n",
- env->idt.base, env->idt.limit);
- qemu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",
- (uint32_t)env->cr[0],
- env->cr[2],
- env->cr[3],
- (uint32_t)env->cr[4]);
- for(i = 0; i < 4; i++)
- qemu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);
- qemu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",
- env->dr[6], env->dr[7]);
- } else
-#endif
- {
- qemu_fprintf(f, "GDT= %08x %08x\n",
- (uint32_t)env->gdt.base, env->gdt.limit);
- qemu_fprintf(f, "IDT= %08x %08x\n",
- (uint32_t)env->idt.base, env->idt.limit);
- qemu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",
- (uint32_t)env->cr[0],
- (uint32_t)env->cr[2],
- (uint32_t)env->cr[3],
- (uint32_t)env->cr[4]);
- for(i = 0; i < 4; i++) {
- qemu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
- }
- qemu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
- env->dr[6], env->dr[7]);
- }
- if (flags & CPU_DUMP_CCOP) {
- if ((unsigned)env->cc_op < CC_OP_NB)
- snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);
- else
- snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);
-#ifdef TARGET_X86_64
- if (env->hflags & HF_CS64_MASK) {
- qemu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",
- env->cc_src, env->cc_dst,
- cc_op_name);
- } else
-#endif
- {
- qemu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",
- (uint32_t)env->cc_src, (uint32_t)env->cc_dst,
- cc_op_name);
- }
- }
- qemu_fprintf(f, "EFER=%016" PRIx64 "\n", env->efer);
- if (flags & CPU_DUMP_FPU) {
- int fptag;
- fptag = 0;
- for(i = 0; i < 8; i++) {
- fptag |= ((!env->fptags[i]) << i);
- }
- update_mxcsr_from_sse_status(env);
- qemu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",
- env->fpuc,
- (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,
- env->fpstt,
- fptag,
- env->mxcsr);
- for(i=0;i<8;i++) {
- CPU_LDoubleU u;
- u.d = env->fpregs[i].d;
- qemu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",
- i, u.l.lower, u.l.upper);
- if ((i & 1) == 1)
- qemu_fprintf(f, "\n");
- else
- qemu_fprintf(f, " ");
- }
- if (env->hflags & HF_CS64_MASK)
- nb = 16;
- else
- nb = 8;
- for(i=0;i<nb;i++) {
- qemu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",
- i,
- env->xmm_regs[i].ZMM_L(3),
- env->xmm_regs[i].ZMM_L(2),
- env->xmm_regs[i].ZMM_L(1),
- env->xmm_regs[i].ZMM_L(0));
- if ((i & 1) == 1)
- qemu_fprintf(f, "\n");
- else
- qemu_fprintf(f, " ");
- }
- }
- if (flags & CPU_DUMP_CODE) {
- target_ulong base = env->segs[R_CS].base + env->eip;
- target_ulong offs = MIN(env->eip, DUMP_CODE_BYTES_BACKWARD);
- uint8_t code;
- char codestr[3];
-
- qemu_fprintf(f, "Code=");
- for (i = 0; i < DUMP_CODE_BYTES_TOTAL; i++) {
- if (cpu_memory_rw_debug(cs, base - offs + i, &code, 1, 0) == 0) {
- snprintf(codestr, sizeof(codestr), "%02x", code);
- } else {
- snprintf(codestr, sizeof(codestr), "??");
- }
- qemu_fprintf(f, "%s%s%s%s", i > 0 ? " " : "",
- i == offs ? "<" : "", codestr, i == offs ? ">" : "");
- }
- qemu_fprintf(f, "\n");
- }
-}
-
/***********************************************************/
/* x86 mmu */
/* XXX: add PGE support */
diff --git a/target/i386/meson.build b/target/i386/meson.build
index 750471c9f3..c4bf20b319 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -4,6 +4,7 @@ i386_ss.add(files(
'gdbstub.c',
'helper.c',
'xsave_helper.c',
+ 'cpu-dump.c',
))
i386_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-stub.c'))
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 10/27] i386: move TCG cpu class initialization out of helper.c
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (8 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 09/27] i386: move cpu dump out of helper.c into cpu-dump.c Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 11/27] tcg: cpu_exec_{enter,exit} helpers Claudio Fontana
` (17 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
target/i386/cpu.c | 33 ++++------
target/i386/cpu.h | 97 ++---------------------------
target/i386/helper-tcg.h | 112 ++++++++++++++++++++++++++++++++++
target/i386/helper.c | 23 -------
target/i386/meson.build | 1 +
target/i386/tcg-cpu.c | 71 +++++++++++++++++++++
target/i386/tcg-cpu.h | 15 +++++
target/i386/tcg/bpt_helper.c | 1 +
target/i386/tcg/cc_helper.c | 1 +
target/i386/tcg/excp_helper.c | 1 +
target/i386/tcg/fpu_helper.c | 33 +++++-----
target/i386/tcg/int_helper.c | 1 +
target/i386/tcg/mem_helper.c | 1 +
target/i386/tcg/misc_helper.c | 1 +
target/i386/tcg/mpx_helper.c | 1 +
target/i386/tcg/seg_helper.c | 1 +
target/i386/tcg/smm_helper.c | 2 +
target/i386/tcg/svm_helper.c | 1 +
target/i386/tcg/translate.c | 1 +
19 files changed, 244 insertions(+), 153 deletions(-)
create mode 100644 target/i386/helper-tcg.h
create mode 100644 target/i386/tcg-cpu.c
create mode 100644 target/i386/tcg-cpu.h
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index b9bd249c8f..3462d0143f 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -24,6 +24,8 @@
#include "qemu/qemu-print.h"
#include "cpu.h"
+#include "tcg-cpu.h"
+#include "helper-tcg.h"
#include "exec/exec-all.h"
#include "sysemu/kvm.h"
#include "sysemu/reset.h"
@@ -1495,7 +1497,8 @@ static inline uint64_t x86_cpu_xsave_components(X86CPU *cpu)
cpu->env.features[FEAT_XSAVE_COMP_LO];
}
-const char *get_register_name_32(unsigned int reg)
+/* Return name of 32-bit register, from a R_* constant */
+static const char *get_register_name_32(unsigned int reg)
{
if (reg >= CPU_NB_REGS32) {
return NULL;
@@ -7012,13 +7015,6 @@ static void x86_cpu_set_pc(CPUState *cs, vaddr value)
cpu->env.eip = value;
}
-static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
-{
- X86CPU *cpu = X86_CPU(cs);
-
- cpu->env.eip = tb->pc - tb->cs_base;
-}
-
int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request)
{
X86CPU *cpu = X86_CPU(cs);
@@ -7252,17 +7248,18 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->class_by_name = x86_cpu_class_by_name;
cc->parse_features = x86_cpu_parse_featurestr;
cc->has_work = x86_cpu_has_work;
+
#ifdef CONFIG_TCG
- cc->do_interrupt = x86_cpu_do_interrupt;
- cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
-#endif
+ tcg_cpu_common_class_init(cc);
+#endif /* CONFIG_TCG */
+
cc->dump_state = x86_cpu_dump_state;
cc->set_pc = x86_cpu_set_pc;
- cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
cc->gdb_read_register = x86_cpu_gdb_read_register;
cc->gdb_write_register = x86_cpu_gdb_write_register;
cc->get_arch_id = x86_cpu_get_arch_id;
cc->get_paging_enabled = x86_cpu_get_paging_enabled;
+
#ifndef CONFIG_USER_ONLY
cc->asidx_from_attrs = x86_asidx_from_attrs;
cc->get_memory_mapping = x86_cpu_get_memory_mapping;
@@ -7273,7 +7270,8 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->write_elf32_note = x86_cpu_write_elf32_note;
cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote;
cc->vmsd = &vmstate_x86_cpu;
-#endif
+#endif /* !CONFIG_USER_ONLY */
+
cc->gdb_arch_name = x86_gdb_arch_name;
#ifdef TARGET_X86_64
cc->gdb_core_xml_file = "i386-64bit.xml";
@@ -7281,15 +7279,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
#else
cc->gdb_core_xml_file = "i386-32bit.xml";
cc->gdb_num_core_regs = 50;
-#endif
-#if defined(CONFIG_TCG) && !defined(CONFIG_USER_ONLY)
- cc->debug_excp_handler = breakpoint_handler;
-#endif
- cc->cpu_exec_enter = x86_cpu_exec_enter;
- cc->cpu_exec_exit = x86_cpu_exec_exit;
-#ifdef CONFIG_TCG
- cc->tcg_initialize = tcg_x86_init;
- cc->tlb_fill = x86_cpu_tlb_fill;
#endif
cc->disas_set_info = x86_disas_set_info;
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index d6ed45c5d7..a0d64613dc 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -31,9 +31,6 @@
#define KVM_HAVE_MCE_INJECTION 1
-/* Maximum instruction code size */
-#define TARGET_MAX_INSN_SIZE 16
-
/* support for self modifying code even if the modified instruction is
close to the modifying instruction */
#define TARGET_HAS_PRECISE_SMC
@@ -1037,6 +1034,12 @@ typedef uint64_t FeatureWordArray[FEATURE_WORDS];
* using this information. Condition codes are not generated if they
* are only needed for conditional branches.
*/
+
+#define CC_DST (env->cc_dst)
+#define CC_SRC (env->cc_src)
+#define CC_SRC2 (env->cc_src2)
+#define CC_OP (env->cc_op)
+
typedef enum {
CC_OP_DYNAMIC, /* must use dynamic code to get cc_op */
CC_OP_EFLAGS, /* all cc are explicitly computed, CC_SRC = flags */
@@ -1765,12 +1768,6 @@ struct X86CPU {
extern VMStateDescription vmstate_x86_cpu;
#endif
-/**
- * x86_cpu_do_interrupt:
- * @cpu: vCPU the interrupt is to be handled by.
- */
-void x86_cpu_do_interrupt(CPUState *cpu);
-bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
int x86_cpu_pending_interrupt(CPUState *cs, int interrupt_request);
int x86_cpu_write_elf64_note(WriteCoreDumpFunction f, CPUState *cpu,
@@ -1793,9 +1790,6 @@ hwaddr x86_cpu_get_phys_page_attrs_debug(CPUState *cpu, vaddr addr,
int x86_cpu_gdb_read_register(CPUState *cpu, GByteArray *buf, int reg);
int x86_cpu_gdb_write_register(CPUState *cpu, uint8_t *buf, int reg);
-void x86_cpu_exec_enter(CPUState *cpu);
-void x86_cpu_exec_exit(CPUState *cpu);
-
void x86_cpu_list(void);
int cpu_x86_support_mca_broadcast(CPUX86State *env);
@@ -1920,9 +1914,6 @@ void host_cpuid(uint32_t function, uint32_t count,
void host_vendor_fms(char *vendor, int *family, int *model, int *stepping);
/* helper.c */
-bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
void x86_cpu_set_a20(X86CPU *cpu, int a20_state);
#ifndef CONFIG_USER_ONLY
@@ -1947,8 +1938,6 @@ void x86_stl_phys(CPUState *cs, hwaddr addr, uint32_t val);
void x86_stq_phys(CPUState *cs, hwaddr addr, uint64_t val);
#endif
-void breakpoint_handler(CPUState *cs);
-
/* will be suppressed */
void cpu_x86_update_cr0(CPUX86State *env, uint32_t new_cr0);
void cpu_x86_update_cr3(CPUX86State *env, target_ulong new_cr3);
@@ -1958,16 +1947,6 @@ void cpu_x86_update_dr7(CPUX86State *env, uint32_t new_dr7);
/* hw/pc.c */
uint64_t cpu_get_tsc(CPUX86State *env);
-/* XXX: This value should match the one returned by CPUID
- * and in exec.c */
-# if defined(TARGET_X86_64)
-# define TCG_PHYS_ADDR_BITS 40
-# else
-# define TCG_PHYS_ADDR_BITS 36
-# endif
-
-#define PHYS_ADDR_MASK MAKE_64BIT_MASK(0, TCG_PHYS_ADDR_BITS)
-
#define X86_CPU_TYPE_SUFFIX "-" TYPE_X86_CPU
#define X86_CPU_TYPE_NAME(name) (name X86_CPU_TYPE_SUFFIX)
#define CPU_RESOLVING_TYPE TYPE_X86_CPU
@@ -1999,30 +1978,6 @@ static inline int cpu_mmu_index_kernel(CPUX86State *env)
? MMU_KNOSMAP_IDX : MMU_KSMAP_IDX;
}
-#define CC_DST (env->cc_dst)
-#define CC_SRC (env->cc_src)
-#define CC_SRC2 (env->cc_src2)
-#define CC_OP (env->cc_op)
-
-/* n must be a constant to be efficient */
-static inline target_long lshift(target_long x, int n)
-{
- if (n >= 0) {
- return x << n;
- } else {
- return x >> (-n);
- }
-}
-
-/* float macros */
-#define FT0 (env->ft0)
-#define ST0 (env->fpregs[env->fpstt].d)
-#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
-#define ST1 ST(1)
-
-/* translate.c */
-void tcg_x86_init(void);
-
typedef CPUX86State CPUArchState;
typedef X86CPU ArchCPU;
@@ -2052,19 +2007,6 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
uint64_t status, uint64_t mcg_status, uint64_t addr,
uint64_t misc, int flags);
-/* excp_helper.c */
-void QEMU_NORETURN raise_exception(CPUX86State *env, int exception_index);
-void QEMU_NORETURN raise_exception_ra(CPUX86State *env, int exception_index,
- uintptr_t retaddr);
-void QEMU_NORETURN raise_exception_err(CPUX86State *env, int exception_index,
- int error_code);
-void QEMU_NORETURN raise_exception_err_ra(CPUX86State *env, int exception_index,
- int error_code, uintptr_t retaddr);
-void QEMU_NORETURN raise_interrupt(CPUX86State *nenv, int intno, int is_int,
- int error_code, int next_eip_addend);
-
-/* cc_helper.c */
-extern const uint8_t parity_table[256];
uint32_t cpu_cc_compute_all(CPUX86State *env1, int op);
static inline uint32_t cpu_compute_eflags(CPUX86State *env)
@@ -2076,18 +2018,6 @@ static inline uint32_t cpu_compute_eflags(CPUX86State *env)
return eflags;
}
-/* NOTE: the translator must set DisasContext.cc_op to CC_OP_EFLAGS
- * after generating a call to a helper that uses this.
- */
-static inline void cpu_load_eflags(CPUX86State *env, int eflags,
- int update_mask)
-{
- CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- CC_OP = CC_OP_EFLAGS;
- env->df = 1 - (2 * ((eflags >> 10) & 1));
- env->eflags = (env->eflags & ~update_mask) |
- (eflags & update_mask) | 0x2;
-}
/* load efer and update the corresponding hflags. XXX: do consistency
checks with cpuid bits? */
@@ -2176,16 +2106,6 @@ void helper_lock_init(void);
/* svm_helper.c */
void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
uint64_t param, uintptr_t retaddr);
-void QEMU_NORETURN cpu_vmexit(CPUX86State *nenv, uint32_t exit_code,
- uint64_t exit_info_1, uintptr_t retaddr);
-void do_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1);
-
-/* seg_helper.c */
-void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
-
-/* smm_helper.c */
-void do_smm_enter(X86CPU *cpu);
-
/* apic.c */
void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
@@ -2224,11 +2144,6 @@ typedef int X86CPUVersion;
*/
void x86_cpu_set_default_version(X86CPUVersion version);
-/* Return name of 32-bit register, from a R_* constant */
-const char *get_register_name_32(unsigned int reg);
-
-void enable_compat_apic_id_mode(void);
-
#define APIC_DEFAULT_ADDRESS 0xfee00000
#define APIC_SPACE_SIZE 0x100000
diff --git a/target/i386/helper-tcg.h b/target/i386/helper-tcg.h
new file mode 100644
index 0000000000..57b4391a7d
--- /dev/null
+++ b/target/i386/helper-tcg.h
@@ -0,0 +1,112 @@
+/*
+ * TCG specific prototypes for helpers
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef I386_HELPER_TCG_H
+#define I386_HELPER_TCG_H
+
+#include "exec/exec-all.h"
+
+/* Maximum instruction code size */
+#define TARGET_MAX_INSN_SIZE 16
+
+/*
+ * XXX: This value should match the one returned by CPUID
+ * and in exec.c
+ */
+# if defined(TARGET_X86_64)
+# define TCG_PHYS_ADDR_BITS 40
+# else
+# define TCG_PHYS_ADDR_BITS 36
+# endif
+
+#define PHYS_ADDR_MASK MAKE_64BIT_MASK(0, TCG_PHYS_ADDR_BITS)
+
+/**
+ * x86_cpu_do_interrupt:
+ * @cpu: vCPU the interrupt is to be handled by.
+ */
+void x86_cpu_do_interrupt(CPUState *cpu);
+bool x86_cpu_exec_interrupt(CPUState *cpu, int int_req);
+
+/* helper.c */
+bool x86_cpu_tlb_fill(CPUState *cs, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
+
+void breakpoint_handler(CPUState *cs);
+
+/* n must be a constant to be efficient */
+static inline target_long lshift(target_long x, int n)
+{
+ if (n >= 0) {
+ return x << n;
+ } else {
+ return x >> (-n);
+ }
+}
+
+/* float macros */
+#define FT0 (env->ft0)
+#define ST0 (env->fpregs[env->fpstt].d)
+#define ST(n) (env->fpregs[(env->fpstt + (n)) & 7].d)
+#define ST1 ST(1)
+
+/* translate.c */
+void tcg_x86_init(void);
+
+/* excp_helper.c */
+void QEMU_NORETURN raise_exception(CPUX86State *env, int exception_index);
+void QEMU_NORETURN raise_exception_ra(CPUX86State *env, int exception_index,
+ uintptr_t retaddr);
+void QEMU_NORETURN raise_exception_err(CPUX86State *env, int exception_index,
+ int error_code);
+void QEMU_NORETURN raise_exception_err_ra(CPUX86State *env, int exception_index,
+ int error_code, uintptr_t retaddr);
+void QEMU_NORETURN raise_interrupt(CPUX86State *nenv, int intno, int is_int,
+ int error_code, int next_eip_addend);
+
+/* cc_helper.c */
+extern const uint8_t parity_table[256];
+
+/*
+ * NOTE: the translator must set DisasContext.cc_op to CC_OP_EFLAGS
+ * after generating a call to a helper that uses this.
+ */
+static inline void cpu_load_eflags(CPUX86State *env, int eflags,
+ int update_mask)
+{
+ CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ CC_OP = CC_OP_EFLAGS;
+ env->df = 1 - (2 * ((eflags >> 10) & 1));
+ env->eflags = (env->eflags & ~update_mask) |
+ (eflags & update_mask) | 0x2;
+}
+
+/* svm_helper.c */
+void QEMU_NORETURN cpu_vmexit(CPUX86State *nenv, uint32_t exit_code,
+ uint64_t exit_info_1, uintptr_t retaddr);
+void do_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1);
+
+/* seg_helper.c */
+void do_interrupt_x86_hardirq(CPUX86State *env, int intno, int is_hw);
+
+/* smm_helper.c */
+void do_smm_enter(X86CPU *cpu);
+
+#endif /* I386_HELPER_TCG_H */
diff --git a/target/i386/helper.c b/target/i386/helper.c
index 6e7e0f507c..6bb0c53182 100644
--- a/target/i386/helper.c
+++ b/target/i386/helper.c
@@ -24,10 +24,8 @@
#include "sysemu/runstate.h"
#include "kvm/kvm_i386.h"
#ifndef CONFIG_USER_ONLY
-#include "sysemu/tcg.h"
#include "sysemu/hw_accel.h"
#include "monitor/monitor.h"
-#include "hw/i386/apic_internal.h"
#endif
void cpu_sync_bndcs_hflags(CPUX86State *env)
@@ -572,27 +570,6 @@ void do_cpu_sipi(X86CPU *cpu)
}
#endif
-/* Frob eflags into and out of the CPU temporary format. */
-
-void x86_cpu_exec_enter(CPUState *cs)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
-
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- env->df = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-}
-
-void x86_cpu_exec_exit(CPUState *cs)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
-
- env->eflags = cpu_compute_eflags(env);
-}
-
#ifndef CONFIG_USER_ONLY
uint8_t x86_ldub_phys(CPUState *cs, hwaddr addr)
{
diff --git a/target/i386/meson.build b/target/i386/meson.build
index c4bf20b319..9c20208e5a 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -6,6 +6,7 @@ i386_ss.add(files(
'xsave_helper.c',
'cpu-dump.c',
))
+i386_ss.add(when: 'CONFIG_TCG', if_true: files('tcg-cpu.c'))
i386_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-stub.c'))
i386_softmmu_ss = ss.source_set()
diff --git a/target/i386/tcg-cpu.c b/target/i386/tcg-cpu.c
new file mode 100644
index 0000000000..628dd29fe7
--- /dev/null
+++ b/target/i386/tcg-cpu.c
@@ -0,0 +1,71 @@
+/*
+ * i386 TCG cpu class initialization
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "tcg-cpu.h"
+#include "exec/exec-all.h"
+#include "sysemu/runstate.h"
+#include "helper-tcg.h"
+
+#if !defined(CONFIG_USER_ONLY)
+#include "hw/i386/apic.h"
+#endif
+
+/* Frob eflags into and out of the CPU temporary format. */
+
+static void x86_cpu_exec_enter(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ env->df = 1 - (2 * ((env->eflags >> 10) & 1));
+ CC_OP = CC_OP_EFLAGS;
+ env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+}
+
+static void x86_cpu_exec_exit(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ env->eflags = cpu_compute_eflags(env);
+}
+
+static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ cpu->env.eip = tb->pc - tb->cs_base;
+}
+
+void tcg_cpu_common_class_init(CPUClass *cc)
+{
+ cc->do_interrupt = x86_cpu_do_interrupt;
+ cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
+ cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
+ cc->cpu_exec_enter = x86_cpu_exec_enter;
+ cc->cpu_exec_exit = x86_cpu_exec_exit;
+ cc->tcg_initialize = tcg_x86_init;
+ cc->tlb_fill = x86_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
+ cc->debug_excp_handler = breakpoint_handler;
+#endif
+}
diff --git a/target/i386/tcg-cpu.h b/target/i386/tcg-cpu.h
new file mode 100644
index 0000000000..81f02e562e
--- /dev/null
+++ b/target/i386/tcg-cpu.h
@@ -0,0 +1,15 @@
+/*
+ * i386 TCG CPU class initialization
+ *
+ * Copyright 2020 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_CPU_H
+#define TCG_CPU_H
+
+void tcg_cpu_common_class_init(CPUClass *cc);
+
+#endif /* TCG_CPU_H */
diff --git a/target/i386/tcg/bpt_helper.c b/target/i386/tcg/bpt_helper.c
index e6cc2921e2..979230ac12 100644
--- a/target/i386/tcg/bpt_helper.c
+++ b/target/i386/tcg/bpt_helper.c
@@ -21,6 +21,7 @@
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
+#include "helper-tcg.h"
#ifndef CONFIG_USER_ONLY
diff --git a/target/i386/tcg/cc_helper.c b/target/i386/tcg/cc_helper.c
index 924dd3cd57..cc7ea9e8b9 100644
--- a/target/i386/tcg/cc_helper.c
+++ b/target/i386/tcg/cc_helper.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "cpu.h"
#include "exec/helper-proto.h"
+#include "helper-tcg.h"
const uint8_t parity_table[256] = {
CC_P, 0, 0, CC_P, 0, CC_P, CC_P, 0,
diff --git a/target/i386/tcg/excp_helper.c b/target/i386/tcg/excp_helper.c
index 191471749f..a0f44431fe 100644
--- a/target/i386/tcg/excp_helper.c
+++ b/target/i386/tcg/excp_helper.c
@@ -23,6 +23,7 @@
#include "qemu/log.h"
#include "sysemu/runstate.h"
#include "exec/helper-proto.h"
+#include "helper-tcg.h"
void helper_raise_interrupt(CPUX86State *env, int intno, int next_eip_addend)
{
diff --git a/target/i386/tcg/fpu_helper.c b/target/i386/tcg/fpu_helper.c
index 03b35443a6..13f31b6ac7 100644
--- a/target/i386/tcg/fpu_helper.c
+++ b/target/i386/tcg/fpu_helper.c
@@ -26,6 +26,7 @@
#include "exec/cpu_ldst.h"
#include "fpu/softfloat.h"
#include "fpu/softfloat-macros.h"
+#include "helper-tcg.h"
#ifdef CONFIG_SOFTMMU
#include "hw/irq.h"
@@ -2986,23 +2987,21 @@ void update_mxcsr_status(CPUX86State *env)
void update_mxcsr_from_sse_status(CPUX86State *env)
{
- if (tcg_enabled()) {
- uint8_t flags = get_float_exception_flags(&env->sse_status);
- /*
- * The MXCSR denormal flag has opposite semantics to
- * float_flag_input_denormal (the softfloat code sets that flag
- * only when flushing input denormals to zero, but SSE sets it
- * only when not flushing them to zero), so is not converted
- * here.
- */
- env->mxcsr |= ((flags & float_flag_invalid ? FPUS_IE : 0) |
- (flags & float_flag_divbyzero ? FPUS_ZE : 0) |
- (flags & float_flag_overflow ? FPUS_OE : 0) |
- (flags & float_flag_underflow ? FPUS_UE : 0) |
- (flags & float_flag_inexact ? FPUS_PE : 0) |
- (flags & float_flag_output_denormal ? FPUS_UE | FPUS_PE :
- 0));
- }
+ uint8_t flags = get_float_exception_flags(&env->sse_status);
+ /*
+ * The MXCSR denormal flag has opposite semantics to
+ * float_flag_input_denormal (the softfloat code sets that flag
+ * only when flushing input denormals to zero, but SSE sets it
+ * only when not flushing them to zero), so is not converted
+ * here.
+ */
+ env->mxcsr |= ((flags & float_flag_invalid ? FPUS_IE : 0) |
+ (flags & float_flag_divbyzero ? FPUS_ZE : 0) |
+ (flags & float_flag_overflow ? FPUS_OE : 0) |
+ (flags & float_flag_underflow ? FPUS_UE : 0) |
+ (flags & float_flag_inexact ? FPUS_PE : 0) |
+ (flags & float_flag_output_denormal ? FPUS_UE | FPUS_PE :
+ 0));
}
void helper_update_mxcsr(CPUX86State *env)
diff --git a/target/i386/tcg/int_helper.c b/target/i386/tcg/int_helper.c
index 4f89436b53..87fa7280ee 100644
--- a/target/i386/tcg/int_helper.c
+++ b/target/i386/tcg/int_helper.c
@@ -24,6 +24,7 @@
#include "exec/helper-proto.h"
#include "qapi/error.h"
#include "qemu/guest-random.h"
+#include "helper-tcg.h"
//#define DEBUG_MULDIV
diff --git a/target/i386/tcg/mem_helper.c b/target/i386/tcg/mem_helper.c
index 21ca3e3e88..e5cd2de1bf 100644
--- a/target/i386/tcg/mem_helper.c
+++ b/target/i386/tcg/mem_helper.c
@@ -25,6 +25,7 @@
#include "qemu/int128.h"
#include "qemu/atomic128.h"
#include "tcg/tcg.h"
+#include "helper-tcg.h"
void helper_cmpxchg8b_unlocked(CPUX86State *env, target_ulong a0)
{
diff --git a/target/i386/tcg/misc_helper.c b/target/i386/tcg/misc_helper.c
index ae259d9145..c99370e5e3 100644
--- a/target/i386/tcg/misc_helper.c
+++ b/target/i386/tcg/misc_helper.c
@@ -24,6 +24,7 @@
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "exec/address-spaces.h"
+#include "helper-tcg.h"
void helper_outb(CPUX86State *env, uint32_t port, uint32_t data)
{
diff --git a/target/i386/tcg/mpx_helper.c b/target/i386/tcg/mpx_helper.c
index fd966174b4..22423eedcd 100644
--- a/target/i386/tcg/mpx_helper.c
+++ b/target/i386/tcg/mpx_helper.c
@@ -22,6 +22,7 @@
#include "exec/helper-proto.h"
#include "exec/cpu_ldst.h"
#include "exec/exec-all.h"
+#include "helper-tcg.h"
void helper_bndck(CPUX86State *env, uint32_t fail)
diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c
index 09b6554660..ed3e04a187 100644
--- a/target/i386/tcg/seg_helper.c
+++ b/target/i386/tcg/seg_helper.c
@@ -25,6 +25,7 @@
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
#include "exec/log.h"
+#include "helper-tcg.h"
//#define DEBUG_PCALL
diff --git a/target/i386/tcg/smm_helper.c b/target/i386/tcg/smm_helper.c
index d20e8edfdf..62d027abd3 100644
--- a/target/i386/tcg/smm_helper.c
+++ b/target/i386/tcg/smm_helper.c
@@ -22,6 +22,8 @@
#include "cpu.h"
#include "exec/helper-proto.h"
#include "exec/log.h"
+#include "helper-tcg.h"
+
/* SMM support */
diff --git a/target/i386/tcg/svm_helper.c b/target/i386/tcg/svm_helper.c
index 38931586e5..097bb9b83d 100644
--- a/target/i386/tcg/svm_helper.c
+++ b/target/i386/tcg/svm_helper.c
@@ -22,6 +22,7 @@
#include "exec/helper-proto.h"
#include "exec/exec-all.h"
#include "exec/cpu_ldst.h"
+#include "helper-tcg.h"
/* Secure Virtual Machine helpers */
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index 4c57307e42..5988ea0289 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -28,6 +28,7 @@
#include "exec/helper-proto.h"
#include "exec/helper-gen.h"
+#include "helper-tcg.h"
#include "trace-tcg.h"
#include "exec/log.h"
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 11/27] tcg: cpu_exec_{enter,exit} helpers
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (9 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 10/27] i386: move TCG cpu class initialization out of helper.c Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 12/27] tcg: make CPUClass.cpu_exec_* optional Claudio Fontana
` (16 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
Move invocation of CPUClass.cpu_exec_*() to separate helpers,
to make it easier to refactor that code later.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
accel/tcg/cpu-exec.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 58aea605d8..8d31145ad2 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -236,9 +236,22 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
}
#endif
+static void cpu_exec_enter(CPUState *cpu)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ cc->cpu_exec_enter(cpu);
+}
+
+static void cpu_exec_exit(CPUState *cpu)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ cc->cpu_exec_exit(cpu);
+}
+
void cpu_exec_step_atomic(CPUState *cpu)
{
- CPUClass *cc = CPU_GET_CLASS(cpu);
TranslationBlock *tb;
target_ulong cs_base, pc;
uint32_t flags;
@@ -257,11 +270,11 @@ void cpu_exec_step_atomic(CPUState *cpu)
/* Since we got here, we know that parallel_cpus must be true. */
parallel_cpus = false;
- cc->cpu_exec_enter(cpu);
+ cpu_exec_enter(cpu);
/* execute the generated code */
trace_exec_tb(tb, pc);
cpu_tb_exec(cpu, tb);
- cc->cpu_exec_exit(cpu);
+ cpu_exec_exit(cpu);
} else {
/*
* The mmap_lock is dropped by tb_gen_code if it runs out of
@@ -713,7 +726,7 @@ int cpu_exec(CPUState *cpu)
rcu_read_lock();
- cc->cpu_exec_enter(cpu);
+ cpu_exec_enter(cpu);
/* Calculate difference between guest clock and host clock.
* This delay includes the delay of the last cycle, so
@@ -775,7 +788,7 @@ int cpu_exec(CPUState *cpu)
}
}
- cc->cpu_exec_exit(cpu);
+ cpu_exec_exit(cpu);
rcu_read_unlock();
return ret;
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 12/27] tcg: make CPUClass.cpu_exec_* optional
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (10 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 11/27] tcg: cpu_exec_{enter,exit} helpers Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:36 ` Philippe Mathieu-Daudé
2020-12-05 16:15 ` [RFC v8 13/27] tcg: Make CPUClass.debug_excp_handler optional Claudio Fontana
` (15 subsequent siblings)
27 siblings, 1 reply; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
This will let us simplify the code that initializes CPU class
methods, when we move cpu_exec_*() to a separate struct.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
accel/tcg/cpu-exec.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 8d31145ad2..890b88861a 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -240,14 +240,18 @@ static void cpu_exec_enter(CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
- cc->cpu_exec_enter(cpu);
+ if (cc->cpu_exec_enter) {
+ cc->cpu_exec_enter(cpu);
+ }
}
static void cpu_exec_exit(CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
- cc->cpu_exec_exit(cpu);
+ if (cc->cpu_exec_exit) {
+ cc->cpu_exec_exit(cpu);
+ }
}
void cpu_exec_step_atomic(CPUState *cpu)
@@ -619,7 +623,8 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
True when it is, and we should restart on a new TB,
and via longjmp via cpu_loop_exit. */
else {
- if (cc->cpu_exec_interrupt(cpu, interrupt_request)) {
+ if (cc->cpu_exec_interrupt &&
+ cc->cpu_exec_interrupt(cpu, interrupt_request)) {
if (need_replay_interrupt(interrupt_request)) {
replay_interrupt();
}
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC v8 12/27] tcg: make CPUClass.cpu_exec_* optional
2020-12-05 16:15 ` [RFC v8 12/27] tcg: make CPUClass.cpu_exec_* optional Claudio Fontana
@ 2020-12-05 16:36 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 34+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-05 16:36 UTC (permalink / raw)
To: Claudio Fontana, Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota
On 12/5/20 5:15 PM, Claudio Fontana wrote:
> From: Eduardo Habkost <ehabkost@redhat.com>
>
> This will let us simplify the code that initializes CPU class
> methods, when we move cpu_exec_*() to a separate struct.
[newline]
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Claudio Fontana <cfontana@suse.de>
> ---
> accel/tcg/cpu-exec.c | 11 ++++++++---
> 1 file changed, 8 insertions(+), 3 deletions(-)
^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC v8 13/27] tcg: Make CPUClass.debug_excp_handler optional
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (11 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 12/27] tcg: make CPUClass.cpu_exec_* optional Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:36 ` Philippe Mathieu-Daudé
2020-12-05 16:15 ` [RFC v8 14/27] cpu: Remove unnecessary noop methods Claudio Fontana
` (14 subsequent siblings)
27 siblings, 1 reply; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
accel/tcg/cpu-exec.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 890b88861a..64cba89356 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -482,7 +482,9 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
}
}
- cc->debug_excp_handler(cpu);
+ if (cc->debug_excp_handler) {
+ cc->debug_excp_handler(cpu);
+ }
}
static inline bool cpu_handle_exception(CPUState *cpu, int *ret)
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC v8 13/27] tcg: Make CPUClass.debug_excp_handler optional
2020-12-05 16:15 ` [RFC v8 13/27] tcg: Make CPUClass.debug_excp_handler optional Claudio Fontana
@ 2020-12-05 16:36 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 34+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-05 16:36 UTC (permalink / raw)
To: Claudio Fontana, Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota
On 12/5/20 5:15 PM, Claudio Fontana wrote:
> From: Eduardo Habkost <ehabkost@redhat.com>
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Claudio Fontana <cfontana@suse.de>
> ---
> accel/tcg/cpu-exec.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC v8 14/27] cpu: Remove unnecessary noop methods
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (12 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 13/27] tcg: Make CPUClass.debug_excp_handler optional Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:37 ` Philippe Mathieu-Daudé
2020-12-05 16:15 ` [RFC v8 15/27] cpu: Introduce TCGCpuOperations struct Claudio Fontana
` (13 subsequent siblings)
27 siblings, 1 reply; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
hw/core/cpu.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/hw/core/cpu.c b/hw/core/cpu.c
index 576fa1d7ba..994a12cb35 100644
--- a/hw/core/cpu.c
+++ b/hw/core/cpu.c
@@ -199,15 +199,6 @@ static bool cpu_common_virtio_is_big_endian(CPUState *cpu)
return target_words_bigendian();
}
-static void cpu_common_noop(CPUState *cpu)
-{
-}
-
-static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
-{
- return false;
-}
-
#if !defined(CONFIG_USER_ONLY)
GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
{
@@ -410,11 +401,7 @@ static void cpu_class_init(ObjectClass *klass, void *data)
k->gdb_read_register = cpu_common_gdb_read_register;
k->gdb_write_register = cpu_common_gdb_write_register;
k->virtio_is_big_endian = cpu_common_virtio_is_big_endian;
- k->debug_excp_handler = cpu_common_noop;
k->debug_check_watchpoint = cpu_common_debug_check_watchpoint;
- k->cpu_exec_enter = cpu_common_noop;
- k->cpu_exec_exit = cpu_common_noop;
- k->cpu_exec_interrupt = cpu_common_exec_interrupt;
k->adjust_watchpoint_address = cpu_adjust_watchpoint_address;
set_bit(DEVICE_CATEGORY_CPU, dc->categories);
dc->realize = cpu_common_realizefn;
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC v8 14/27] cpu: Remove unnecessary noop methods
2020-12-05 16:15 ` [RFC v8 14/27] cpu: Remove unnecessary noop methods Claudio Fontana
@ 2020-12-05 16:37 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 34+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-05 16:37 UTC (permalink / raw)
To: Claudio Fontana, Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota
On 12/5/20 5:15 PM, Claudio Fontana wrote:
> From: Eduardo Habkost <ehabkost@redhat.com>
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> Signed-off-by: Claudio Fontana <cfontana@suse.de>
> ---
> hw/core/cpu.c | 13 -------------
> 1 file changed, 13 deletions(-)
>
> diff --git a/hw/core/cpu.c b/hw/core/cpu.c
> index 576fa1d7ba..994a12cb35 100644
> --- a/hw/core/cpu.c
> +++ b/hw/core/cpu.c
> @@ -199,15 +199,6 @@ static bool cpu_common_virtio_is_big_endian(CPUState *cpu)
> return target_words_bigendian();
> }
>
> -static void cpu_common_noop(CPUState *cpu)
> -{
> -}
> -
> -static bool cpu_common_exec_interrupt(CPUState *cpu, int int_req)
> -{
> - return false;
> -}
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC v8 15/27] cpu: Introduce TCGCpuOperations struct
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (13 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 14/27] cpu: Remove unnecessary noop methods Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:33 ` Philippe Mathieu-Daudé
2020-12-05 16:15 ` [RFC v8 16/27] accel/tcg: split TCG-only code from cpu_exec_realizefn Claudio Fontana
` (12 subsequent siblings)
27 siblings, 1 reply; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
The TCG-specific CPU methods will be moved to a separate struct,
to make it easier to move accel-specific code outside generic CPU
code in the future. Start by moving tcg_initialize().
The new CPUClass.tcg_opts field may eventually become a pointer,
but keep it an embedded struct for now, to make code conversion
easier.
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
[claudio: make the tcg code build for CONFIG_TCG only]
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
MAINTAINERS | 1 +
cpu.c | 6 +++++-
include/hw/core/cpu.h | 9 ++++++++-
include/hw/core/tcg-cpu-ops.h | 25 +++++++++++++++++++++++++
target/alpha/cpu.c | 2 +-
target/arm/cpu.c | 2 +-
target/avr/cpu.c | 2 +-
target/cris/cpu.c | 12 ++++++------
target/hppa/cpu.c | 2 +-
target/i386/tcg-cpu.c | 2 +-
target/lm32/cpu.c | 2 +-
target/m68k/cpu.c | 2 +-
target/microblaze/cpu.c | 2 +-
target/mips/cpu.c | 2 +-
target/moxie/cpu.c | 2 +-
target/nios2/cpu.c | 2 +-
target/openrisc/cpu.c | 2 +-
target/ppc/translate_init.c.inc | 2 +-
target/riscv/cpu.c | 2 +-
target/rx/cpu.c | 2 +-
target/s390x/cpu.c | 2 +-
target/sh4/cpu.c | 2 +-
target/sparc/cpu.c | 2 +-
target/tilegx/cpu.c | 2 +-
target/tricore/cpu.c | 2 +-
target/unicore32/cpu.c | 2 +-
target/xtensa/cpu.c | 2 +-
27 files changed, 67 insertions(+), 30 deletions(-)
create mode 100644 include/hw/core/tcg-cpu-ops.h
diff --git a/MAINTAINERS b/MAINTAINERS
index f53f2678d8..d876f504a6 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1535,6 +1535,7 @@ F: qapi/machine.json
F: qapi/machine-target.json
F: include/hw/boards.h
F: include/hw/core/cpu.h
+F: include/hw/core/tcg-cpu-ops.h
F: include/hw/cpu/cluster.h
F: include/sysemu/numa.h
T: git https://github.com/ehabkost/qemu.git machine-next
diff --git a/cpu.c b/cpu.c
index 0be5dcb6f3..27ad096cc4 100644
--- a/cpu.c
+++ b/cpu.c
@@ -174,14 +174,18 @@ void cpu_exec_initfn(CPUState *cpu)
void cpu_exec_realizefn(CPUState *cpu, Error **errp)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
+#ifdef CONFIG_TCG
static bool tcg_target_initialized;
+#endif /* CONFIG_TCG */
cpu_list_add(cpu);
+#ifdef CONFIG_TCG
if (tcg_enabled() && !tcg_target_initialized) {
tcg_target_initialized = true;
- cc->tcg_initialize();
+ cc->tcg_ops.initialize();
}
+#endif /* CONFIG_TCG */
tlb_init(cpu);
qemu_plugin_vcpu_init_hook(cpu);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 3d92c967ff..c93b08a0fb 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -76,6 +76,10 @@ typedef struct CPUWatchpoint CPUWatchpoint;
struct TranslationBlock;
+#ifdef CONFIG_TCG
+#include "tcg-cpu-ops.h"
+#endif /* CONFIG_TCG */
+
/**
* CPUClass:
* @class_by_name: Callback to map -cpu command line model name to an
@@ -221,12 +225,15 @@ struct CPUClass {
void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
- void (*tcg_initialize)(void);
const char *deprecation_note;
/* Keep non-pointer data at the end to minimize holes. */
int gdb_num_core_regs;
bool gdb_stop_before_watchpoint;
+
+#ifdef CONFIG_TCG
+ TcgCpuOperations tcg_ops;
+#endif /* CONFIG_TCG */
};
/*
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
new file mode 100644
index 0000000000..4475ef0996
--- /dev/null
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -0,0 +1,25 @@
+/*
+ * TCG-Specific operations that are not meaningful for hardware accelerators
+ *
+ * Copyright 2020 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_CPU_OPS_H
+#define TCG_CPU_OPS_H
+
+/**
+ * struct TcgCpuOperations: TCG operations specific to a CPU class
+ */
+typedef struct TcgCpuOperations {
+ /**
+ * @initialize: Initalize TCG state
+ *
+ * Called when the first CPU is realized.
+ */
+ void (*initialize)(void);
+} TcgCpuOperations;
+
+#endif /* TCG_CPU_OPS_H */
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index b3fd6643e8..d66f0351a9 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -231,7 +231,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
dc->vmsd = &vmstate_alpha_cpu;
#endif
cc->disas_set_info = alpha_cpu_disas_set_info;
- cc->tcg_initialize = alpha_translate_init;
+ cc->tcg_ops.initialize = alpha_translate_init;
cc->gdb_num_core_regs = 67;
}
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 07492e9f9a..1fa9382a7c 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2261,7 +2261,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_stop_before_watchpoint = true;
cc->disas_set_info = arm_disas_set_info;
#ifdef CONFIG_TCG
- cc->tcg_initialize = arm_translate_init;
+ cc->tcg_ops.initialize = arm_translate_init;
cc->tlb_fill = arm_cpu_tlb_fill;
cc->debug_excp_handler = arm_debug_excp_handler;
cc->debug_check_watchpoint = arm_debug_check_watchpoint;
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 5d9c4ad5bf..94306a2aa0 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -206,7 +206,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
cc->tlb_fill = avr_cpu_tlb_fill;
cc->vmsd = &vms_avr_cpu;
cc->disas_set_info = avr_cpu_disas_set_info;
- cc->tcg_initialize = avr_cpu_tcg_init;
+ cc->tcg_ops.initialize = avr_cpu_tcg_init;
cc->synchronize_from_tb = avr_cpu_synchronize_from_tb;
cc->gdb_read_register = avr_cpu_gdb_read_register;
cc->gdb_write_register = avr_cpu_gdb_write_register;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index cff6b9eabf..4328f8e6c9 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -201,7 +201,7 @@ static void crisv8_cpu_class_init(ObjectClass *oc, void *data)
ccc->vr = 8;
cc->do_interrupt = crisv10_cpu_do_interrupt;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
- cc->tcg_initialize = cris_initialize_crisv10_tcg;
+ cc->tcg_ops.initialize = cris_initialize_crisv10_tcg;
}
static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
@@ -212,7 +212,7 @@ static void crisv9_cpu_class_init(ObjectClass *oc, void *data)
ccc->vr = 9;
cc->do_interrupt = crisv10_cpu_do_interrupt;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
- cc->tcg_initialize = cris_initialize_crisv10_tcg;
+ cc->tcg_ops.initialize = cris_initialize_crisv10_tcg;
}
static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
@@ -223,7 +223,7 @@ static void crisv10_cpu_class_init(ObjectClass *oc, void *data)
ccc->vr = 10;
cc->do_interrupt = crisv10_cpu_do_interrupt;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
- cc->tcg_initialize = cris_initialize_crisv10_tcg;
+ cc->tcg_ops.initialize = cris_initialize_crisv10_tcg;
}
static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
@@ -234,7 +234,7 @@ static void crisv11_cpu_class_init(ObjectClass *oc, void *data)
ccc->vr = 11;
cc->do_interrupt = crisv10_cpu_do_interrupt;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
- cc->tcg_initialize = cris_initialize_crisv10_tcg;
+ cc->tcg_ops.initialize = cris_initialize_crisv10_tcg;
}
static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
@@ -245,7 +245,7 @@ static void crisv17_cpu_class_init(ObjectClass *oc, void *data)
ccc->vr = 17;
cc->do_interrupt = crisv10_cpu_do_interrupt;
cc->gdb_read_register = crisv10_cpu_gdb_read_register;
- cc->tcg_initialize = cris_initialize_crisv10_tcg;
+ cc->tcg_ops.initialize = cris_initialize_crisv10_tcg;
}
static void crisv32_cpu_class_init(ObjectClass *oc, void *data)
@@ -284,7 +284,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_stop_before_watchpoint = true;
cc->disas_set_info = cris_disas_set_info;
- cc->tcg_initialize = cris_initialize_tcg;
+ cc->tcg_ops.initialize = cris_initialize_tcg;
}
#define DEFINE_CRIS_CPU_TYPE(cpu_model, initfn) \
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 71b6aca45d..4c778966c2 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -153,7 +153,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->do_unaligned_access = hppa_cpu_do_unaligned_access;
cc->disas_set_info = hppa_cpu_disas_set_info;
- cc->tcg_initialize = hppa_translate_init;
+ cc->tcg_ops.initialize = hppa_translate_init;
cc->gdb_num_core_regs = 128;
}
diff --git a/target/i386/tcg-cpu.c b/target/i386/tcg-cpu.c
index 628dd29fe7..1f2a3e881a 100644
--- a/target/i386/tcg-cpu.c
+++ b/target/i386/tcg-cpu.c
@@ -63,7 +63,7 @@ void tcg_cpu_common_class_init(CPUClass *cc)
cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
cc->cpu_exec_enter = x86_cpu_exec_enter;
cc->cpu_exec_exit = x86_cpu_exec_exit;
- cc->tcg_initialize = tcg_x86_init;
+ cc->tcg_ops.initialize = tcg_x86_init;
cc->tlb_fill = x86_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->debug_excp_handler = breakpoint_handler;
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index c50ad5fa15..ef795b81a4 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -237,7 +237,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_stop_before_watchpoint = true;
cc->debug_excp_handler = lm32_debug_excp_handler;
cc->disas_set_info = lm32_cpu_disas_set_info;
- cc->tcg_initialize = lm32_translate_init;
+ cc->tcg_ops.initialize = lm32_translate_init;
}
#define DEFINE_LM32_CPU_TYPE(cpu_model, initfn) \
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index 72c545149e..b66d86c353 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -289,7 +289,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
#endif
cc->disas_set_info = m68k_cpu_disas_set_info;
- cc->tcg_initialize = m68k_tcg_init;
+ cc->tcg_ops.initialize = m68k_tcg_init;
cc->gdb_num_core_regs = 18;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 9b2482159d..bc10518fa3 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -335,7 +335,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_num_core_regs = 32 + 27;
cc->disas_set_info = mb_disas_set_info;
- cc->tcg_initialize = mb_tcg_init;
+ cc->tcg_ops.initialize = mb_tcg_init;
}
static const TypeInfo mb_cpu_type_info = {
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 76d50b00b4..bc48573763 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -249,7 +249,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
#endif
cc->disas_set_info = mips_cpu_disas_set_info;
#ifdef CONFIG_TCG
- cc->tcg_initialize = mips_tcg_init;
+ cc->tcg_ops.initialize = mips_tcg_init;
cc->tlb_fill = mips_cpu_tlb_fill;
#endif
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
index 6e0443ccb7..224cfc8361 100644
--- a/target/moxie/cpu.c
+++ b/target/moxie/cpu.c
@@ -116,7 +116,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
cc->vmsd = &vmstate_moxie_cpu;
#endif
cc->disas_set_info = moxie_cpu_disas_set_info;
- cc->tcg_initialize = moxie_translate_init;
+ cc->tcg_ops.initialize = moxie_translate_init;
}
static void moxielite_initfn(Object *obj)
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 8f7011fcb9..29c9c6f634 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -205,7 +205,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_read_register = nios2_cpu_gdb_read_register;
cc->gdb_write_register = nios2_cpu_gdb_write_register;
cc->gdb_num_core_regs = 49;
- cc->tcg_initialize = nios2_tcg_init;
+ cc->tcg_ops.initialize = nios2_tcg_init;
}
static const TypeInfo nios2_cpu_type_info = {
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index 5528c0918f..e442f4f97c 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -166,7 +166,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
dc->vmsd = &vmstate_openrisc_cpu;
#endif
cc->gdb_num_core_regs = 32 + 3;
- cc->tcg_initialize = openrisc_translate_init;
+ cc->tcg_ops.initialize = openrisc_translate_init;
cc->disas_set_info = openrisc_disas_set_info;
}
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index 78cc8f043b..9a6932b774 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -10945,7 +10945,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
cc->virtio_is_big_endian = ppc_cpu_is_big_endian;
#endif
#ifdef CONFIG_TCG
- cc->tcg_initialize = ppc_translate_init;
+ cc->tcg_ops.initialize = ppc_translate_init;
cc->tlb_fill = ppc_cpu_tlb_fill;
#endif
#ifndef CONFIG_USER_ONLY
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 6a0264fc6b..a52e0ce466 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -562,7 +562,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
cc->vmsd = &vmstate_riscv_cpu;
#endif
#ifdef CONFIG_TCG
- cc->tcg_initialize = riscv_translate_init;
+ cc->tcg_ops.initialize = riscv_translate_init;
cc->tlb_fill = riscv_cpu_tlb_fill;
#endif
device_class_set_props(dc, riscv_cpu_properties);
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 23ee17a701..a701a09b11 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -194,7 +194,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
cc->gdb_write_register = rx_cpu_gdb_write_register;
cc->get_phys_page_debug = rx_cpu_get_phys_page_debug;
cc->disas_set_info = rx_cpu_disas_set_info;
- cc->tcg_initialize = rx_translate_init;
+ cc->tcg_ops.initialize = rx_translate_init;
cc->tlb_fill = rx_cpu_tlb_fill;
cc->gdb_num_core_regs = 26;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 7b66718c44..697b94ff7b 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -512,7 +512,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->disas_set_info = s390_cpu_disas_set_info;
#ifdef CONFIG_TCG
- cc->tcg_initialize = s390x_translate_init;
+ cc->tcg_ops.initialize = s390x_translate_init;
cc->tlb_fill = s390_cpu_tlb_fill;
#endif
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 3c68021c56..bdc5c9d90b 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -231,7 +231,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
#endif
cc->disas_set_info = superh_cpu_disas_set_info;
- cc->tcg_initialize = sh4_translate_init;
+ cc->tcg_ops.initialize = sh4_translate_init;
cc->gdb_num_core_regs = 59;
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 701e794eac..07e48b86d1 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -879,7 +879,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
cc->vmsd = &vmstate_sparc_cpu;
#endif
cc->disas_set_info = cpu_sparc_disas_set_info;
- cc->tcg_initialize = sparc_tcg_init;
+ cc->tcg_ops.initialize = sparc_tcg_init;
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
cc->gdb_num_core_regs = 86;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index 1fee87c094..cd24d0eb9d 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -153,7 +153,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = tilegx_cpu_set_pc;
cc->tlb_fill = tilegx_cpu_tlb_fill;
cc->gdb_num_core_regs = 0;
- cc->tcg_initialize = tilegx_tcg_init;
+ cc->tcg_ops.initialize = tilegx_tcg_init;
}
static const TypeInfo tilegx_cpu_type_info = {
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index 2f2e5b029f..78b2925955 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -164,7 +164,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
cc->set_pc = tricore_cpu_set_pc;
cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
cc->get_phys_page_debug = tricore_cpu_get_phys_page_debug;
- cc->tcg_initialize = tricore_tcg_init;
+ cc->tcg_ops.initialize = tricore_tcg_init;
cc->tlb_fill = tricore_cpu_tlb_fill;
}
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index b27fb9689f..226bf4226e 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -137,7 +137,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = uc32_cpu_set_pc;
cc->tlb_fill = uc32_cpu_tlb_fill;
cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
- cc->tcg_initialize = uc32_translate_init;
+ cc->tcg_ops.initialize = uc32_translate_init;
dc->vmsd = &vmstate_uc32_cpu;
}
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 88a32268a1..5a6f5bf88b 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -209,7 +209,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->debug_excp_handler = xtensa_breakpoint_handler;
cc->disas_set_info = xtensa_cpu_disas_set_info;
- cc->tcg_initialize = xtensa_translate_init;
+ cc->tcg_ops.initialize = xtensa_translate_init;
dc->vmsd = &vmstate_xtensa_cpu;
}
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC v8 15/27] cpu: Introduce TCGCpuOperations struct
2020-12-05 16:15 ` [RFC v8 15/27] cpu: Introduce TCGCpuOperations struct Claudio Fontana
@ 2020-12-05 16:33 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 34+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-05 16:33 UTC (permalink / raw)
To: Claudio Fontana, Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota
On 12/5/20 5:15 PM, Claudio Fontana wrote:
> From: Eduardo Habkost <ehabkost@redhat.com>
>
> The TCG-specific CPU methods will be moved to a separate struct,
> to make it easier to move accel-specific code outside generic CPU
> code in the future. Start by moving tcg_initialize().
>
> The new CPUClass.tcg_opts field may eventually become a pointer,
> but keep it an embedded struct for now, to make code conversion
> easier.
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
>
> [claudio: make the tcg code build for CONFIG_TCG only]
>
> Signed-off-by: Claudio Fontana <cfontana@suse.de>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
> MAINTAINERS | 1 +
> cpu.c | 6 +++++-
> include/hw/core/cpu.h | 9 ++++++++-
> include/hw/core/tcg-cpu-ops.h | 25 +++++++++++++++++++++++++
> target/alpha/cpu.c | 2 +-
> target/arm/cpu.c | 2 +-
> target/avr/cpu.c | 2 +-
> target/cris/cpu.c | 12 ++++++------
> target/hppa/cpu.c | 2 +-
> target/i386/tcg-cpu.c | 2 +-
> target/lm32/cpu.c | 2 +-
> target/m68k/cpu.c | 2 +-
> target/microblaze/cpu.c | 2 +-
> target/mips/cpu.c | 2 +-
> target/moxie/cpu.c | 2 +-
> target/nios2/cpu.c | 2 +-
> target/openrisc/cpu.c | 2 +-
> target/ppc/translate_init.c.inc | 2 +-
> target/riscv/cpu.c | 2 +-
> target/rx/cpu.c | 2 +-
> target/s390x/cpu.c | 2 +-
> target/sh4/cpu.c | 2 +-
> target/sparc/cpu.c | 2 +-
> target/tilegx/cpu.c | 2 +-
> target/tricore/cpu.c | 2 +-
> target/unicore32/cpu.c | 2 +-
> target/xtensa/cpu.c | 2 +-
> 27 files changed, 67 insertions(+), 30 deletions(-)
> create mode 100644 include/hw/core/tcg-cpu-ops.h
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index f53f2678d8..d876f504a6 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1535,6 +1535,7 @@ F: qapi/machine.json
> F: qapi/machine-target.json
> F: include/hw/boards.h
> F: include/hw/core/cpu.h
> +F: include/hw/core/tcg-cpu-ops.h
> F: include/hw/cpu/cluster.h
> F: include/sysemu/numa.h
> T: git https://github.com/ehabkost/qemu.git machine-next
> diff --git a/cpu.c b/cpu.c
> index 0be5dcb6f3..27ad096cc4 100644
> --- a/cpu.c
> +++ b/cpu.c
> @@ -174,14 +174,18 @@ void cpu_exec_initfn(CPUState *cpu)
> void cpu_exec_realizefn(CPUState *cpu, Error **errp)
> {
> CPUClass *cc = CPU_GET_CLASS(cpu);
> +#ifdef CONFIG_TCG
> static bool tcg_target_initialized;
> +#endif /* CONFIG_TCG */
Maybe worth extract as tcg_target_initialized() method.
>
> cpu_list_add(cpu);
>
> +#ifdef CONFIG_TCG
> if (tcg_enabled() && !tcg_target_initialized) {
> tcg_target_initialized = true;
> - cc->tcg_initialize();
> + cc->tcg_ops.initialize();
> }
> +#endif /* CONFIG_TCG */
> tlb_init(cpu);
[...]
^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC v8 16/27] accel/tcg: split TCG-only code from cpu_exec_realizefn
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (14 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 15/27] cpu: Introduce TCGCpuOperations struct Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 17/27] cpu: Move synchronize_from_tb() to tcg_ops Claudio Fontana
` (11 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
move away TCG-only code, make it compile only on TCG.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
accel/tcg/cpu-exec.c | 28 +++++++++++++++++
cpu.c | 70 ++++++++++++++++++++-----------------------
hw/core/cpu.c | 6 +++-
include/hw/core/cpu.h | 8 +++++
4 files changed, 74 insertions(+), 38 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 64cba89356..436dfbf155 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -801,6 +801,34 @@ int cpu_exec(CPUState *cpu)
return ret;
}
+void tcg_exec_realizefn(CPUState *cpu, Error **errp)
+{
+ static bool tcg_target_initialized;
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (!tcg_target_initialized) {
+ tcg_target_initialized = true;
+ cc->tcg_ops.initialize();
+ }
+ tlb_init(cpu);
+ qemu_plugin_vcpu_init_hook(cpu);
+
+#ifndef CONFIG_USER_ONLY
+ tcg_iommu_init_notifier_list(cpu);
+#endif /* !CONFIG_USER_ONLY */
+}
+
+/* undo the initializations in reverse order */
+void tcg_exec_unrealizefn(CPUState *cpu)
+{
+#ifndef CONFIG_USER_ONLY
+ tcg_iommu_free_notifier_list(cpu);
+#endif /* !CONFIG_USER_ONLY */
+
+ qemu_plugin_vcpu_exit_hook(cpu);
+ tlb_destroy(cpu);
+}
+
#ifndef CONFIG_USER_ONLY
void dump_drift_info(void)
diff --git a/cpu.c b/cpu.c
index 27ad096cc4..5cc8f181be 100644
--- a/cpu.c
+++ b/cpu.c
@@ -124,13 +124,35 @@ const VMStateDescription vmstate_cpu_common = {
};
#endif
+void cpu_exec_realizefn(CPUState *cpu, Error **errp)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ cpu_list_add(cpu);
+
+#ifdef CONFIG_TCG
+ /* NB: errp parameter is unused currently */
+ if (tcg_enabled()) {
+ tcg_exec_realizefn(cpu, errp);
+ }
+#endif /* CONFIG_TCG */
+
+#ifdef CONFIG_USER_ONLY
+ assert(cc->vmsd == NULL);
+#else
+ if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
+ vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
+ }
+ if (cc->vmsd != NULL) {
+ vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
+ }
+#endif /* CONFIG_USER_ONLY */
+}
+
void cpu_exec_unrealizefn(CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
- tlb_destroy(cpu);
- cpu_list_remove(cpu);
-
#ifdef CONFIG_USER_ONLY
assert(cc->vmsd == NULL);
#else
@@ -140,8 +162,15 @@ void cpu_exec_unrealizefn(CPUState *cpu)
if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
vmstate_unregister(NULL, &vmstate_cpu_common, cpu);
}
- tcg_iommu_free_notifier_list(cpu);
#endif
+#ifdef CONFIG_TCG
+ /* NB: errp parameter is unused currently */
+ if (tcg_enabled()) {
+ tcg_exec_unrealizefn(cpu);
+ }
+#endif /* CONFIG_TCG */
+
+ cpu_list_remove(cpu);
}
Property cpu_common_props[] = {
@@ -171,39 +200,6 @@ void cpu_exec_initfn(CPUState *cpu)
#endif
}
-void cpu_exec_realizefn(CPUState *cpu, Error **errp)
-{
- CPUClass *cc = CPU_GET_CLASS(cpu);
-#ifdef CONFIG_TCG
- static bool tcg_target_initialized;
-#endif /* CONFIG_TCG */
-
- cpu_list_add(cpu);
-
-#ifdef CONFIG_TCG
- if (tcg_enabled() && !tcg_target_initialized) {
- tcg_target_initialized = true;
- cc->tcg_ops.initialize();
- }
-#endif /* CONFIG_TCG */
- tlb_init(cpu);
-
- qemu_plugin_vcpu_init_hook(cpu);
-
-#ifdef CONFIG_USER_ONLY
- assert(cc->vmsd == NULL);
-#else /* !CONFIG_USER_ONLY */
- if (qdev_get_vmsd(DEVICE(cpu)) == NULL) {
- vmstate_register(NULL, cpu->cpu_index, &vmstate_cpu_common, cpu);
- }
- if (cc->vmsd != NULL) {
- vmstate_register(NULL, cpu->cpu_index, cc->vmsd, cpu);
- }
-
- tcg_iommu_init_notifier_list(cpu);
-#endif
-}
-
const char *parse_cpu_option(const char *cpu_option)
{
ObjectClass *oc;
diff --git a/hw/core/cpu.c b/hw/core/cpu.c
index 994a12cb35..1f04aab16b 100644
--- a/hw/core/cpu.c
+++ b/hw/core/cpu.c
@@ -199,6 +199,10 @@ static bool cpu_common_virtio_is_big_endian(CPUState *cpu)
return target_words_bigendian();
}
+/*
+ * XXX the following #if is always true because this is a common_ss
+ * module, so target CONFIG_* is never defined.
+ */
#if !defined(CONFIG_USER_ONLY)
GuestPanicInformation *cpu_get_crash_info(CPUState *cpu)
{
@@ -340,9 +344,9 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
static void cpu_common_unrealizefn(DeviceState *dev)
{
CPUState *cpu = CPU(dev);
+
/* NOTE: latest generic point before the cpu is fully unrealized */
trace_fini_vcpu(cpu);
- qemu_plugin_vcpu_exit_hook(cpu);
cpu_exec_unrealizefn(cpu);
}
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index c93b08a0fb..ea648d52ad 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -1119,10 +1119,18 @@ AddressSpace *cpu_get_address_space(CPUState *cpu, int asidx);
void QEMU_NORETURN cpu_abort(CPUState *cpu, const char *fmt, ...)
GCC_FMT_ATTR(2, 3);
extern Property cpu_common_props[];
+
+/* $(top_srcdir)/cpu.c */
void cpu_exec_initfn(CPUState *cpu);
void cpu_exec_realizefn(CPUState *cpu, Error **errp);
void cpu_exec_unrealizefn(CPUState *cpu);
+#ifdef CONFIG_TCG
+/* accel/tcg/cpu-exec.c */
+void tcg_exec_realizefn(CPUState *cpu, Error **errp);
+void tcg_exec_unrealizefn(CPUState *cpu);
+#endif /* CONFIG_TCG */
+
/**
* target_words_bigendian:
* Returns true if the (default) endianness of the target is big endian,
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 17/27] cpu: Move synchronize_from_tb() to tcg_ops
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (15 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 16/27] accel/tcg: split TCG-only code from cpu_exec_realizefn Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 18/27] cpu: Move cpu_exec_* " Claudio Fontana
` (10 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
[claudio: wrapped in CONFIG_TCG]
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
accel/tcg/cpu-exec.c | 4 ++--
include/hw/core/cpu.h | 8 --------
include/hw/core/tcg-cpu-ops.h | 14 +++++++++++---
target/arm/cpu.c | 2 +-
target/avr/cpu.c | 2 +-
target/hppa/cpu.c | 2 +-
target/i386/tcg-cpu.c | 2 +-
target/microblaze/cpu.c | 2 +-
target/mips/cpu.c | 2 +-
target/riscv/cpu.c | 2 +-
target/rx/cpu.c | 2 +-
target/sh4/cpu.c | 2 +-
target/sparc/cpu.c | 2 +-
target/tricore/cpu.c | 2 +-
14 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 436dfbf155..776415d47e 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -192,8 +192,8 @@ static inline tcg_target_ulong cpu_tb_exec(CPUState *cpu, TranslationBlock *itb)
TARGET_FMT_lx "] %s\n",
last_tb->tc.ptr, last_tb->pc,
lookup_symbol(last_tb->pc));
- if (cc->synchronize_from_tb) {
- cc->synchronize_from_tb(cpu, last_tb);
+ if (cc->tcg_ops.synchronize_from_tb) {
+ cc->tcg_ops.synchronize_from_tb(cpu, last_tb);
} else {
assert(cc->set_pc);
cc->set_pc(cpu, last_tb->pc);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index ea648d52ad..83007d262c 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -110,13 +110,6 @@ struct TranslationBlock;
* If the target behaviour here is anything other than "set
* the PC register to the value passed in" then the target must
* also implement the synchronize_from_tb hook.
- * @synchronize_from_tb: Callback for synchronizing state from a TCG
- * #TranslationBlock. This is called when we abandon execution
- * of a TB before starting it, and must set all parts of the CPU
- * state which the previous TB in the chain may not have updated.
- * This always includes at least the program counter; some targets
- * will need to do more. If this hook is not implemented then the
- * default is to call @set_pc(tb->pc).
* @tlb_fill: Callback for handling a softmmu tlb miss or user-only
* address fault. For system mode, if the access is valid, call
* tlb_set_page and return true; if the access is invalid, and
@@ -193,7 +186,6 @@ struct CPUClass {
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
Error **errp);
void (*set_pc)(CPUState *cpu, vaddr value);
- void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 4475ef0996..109291ac52 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -10,9 +10,6 @@
#ifndef TCG_CPU_OPS_H
#define TCG_CPU_OPS_H
-/**
- * struct TcgCpuOperations: TCG operations specific to a CPU class
- */
typedef struct TcgCpuOperations {
/**
* @initialize: Initalize TCG state
@@ -20,6 +17,17 @@ typedef struct TcgCpuOperations {
* Called when the first CPU is realized.
*/
void (*initialize)(void);
+ /**
+ * @synchronize_from_tb: Synchronize state from a TCG #TranslationBlock
+ *
+ * This is called when we abandon execution of a TB before
+ * starting it, and must set all parts of the CPU state which
+ * the previous TB in the chain may not have updated. This
+ * will need to do more. If this hook is not implemented then
+ * the default is to call
+ * @set_pc(tb->pc).
+ */
+ void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
} TcgCpuOperations;
#endif /* TCG_CPU_OPS_H */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 1fa9382a7c..2f9e27c248 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2242,7 +2242,6 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
cc->dump_state = arm_cpu_dump_state;
cc->set_pc = arm_cpu_set_pc;
- cc->synchronize_from_tb = arm_cpu_synchronize_from_tb;
cc->gdb_read_register = arm_cpu_gdb_read_register;
cc->gdb_write_register = arm_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
@@ -2262,6 +2261,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->disas_set_info = arm_disas_set_info;
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = arm_translate_init;
+ cc->tcg_ops.synchronize_from_tb = arm_cpu_synchronize_from_tb;
cc->tlb_fill = arm_cpu_tlb_fill;
cc->debug_excp_handler = arm_debug_excp_handler;
cc->debug_check_watchpoint = arm_debug_check_watchpoint;
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 94306a2aa0..f753c15768 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -207,7 +207,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
cc->vmsd = &vms_avr_cpu;
cc->disas_set_info = avr_cpu_disas_set_info;
cc->tcg_ops.initialize = avr_cpu_tcg_init;
- cc->synchronize_from_tb = avr_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = avr_cpu_synchronize_from_tb;
cc->gdb_read_register = avr_cpu_gdb_read_register;
cc->gdb_write_register = avr_cpu_gdb_write_register;
cc->gdb_num_core_regs = 35;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 4c778966c2..12a09e93ae 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -143,7 +143,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
cc->dump_state = hppa_cpu_dump_state;
cc->set_pc = hppa_cpu_set_pc;
- cc->synchronize_from_tb = hppa_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = hppa_cpu_synchronize_from_tb;
cc->gdb_read_register = hppa_cpu_gdb_read_register;
cc->gdb_write_register = hppa_cpu_gdb_write_register;
cc->tlb_fill = hppa_cpu_tlb_fill;
diff --git a/target/i386/tcg-cpu.c b/target/i386/tcg-cpu.c
index 1f2a3e881a..d1414e2970 100644
--- a/target/i386/tcg-cpu.c
+++ b/target/i386/tcg-cpu.c
@@ -60,7 +60,7 @@ void tcg_cpu_common_class_init(CPUClass *cc)
{
cc->do_interrupt = x86_cpu_do_interrupt;
cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
- cc->synchronize_from_tb = x86_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = x86_cpu_synchronize_from_tb;
cc->cpu_exec_enter = x86_cpu_exec_enter;
cc->cpu_exec_exit = x86_cpu_exec_exit;
cc->tcg_ops.initialize = tcg_x86_init;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index bc10518fa3..97d94d9c27 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -322,7 +322,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
cc->dump_state = mb_cpu_dump_state;
cc->set_pc = mb_cpu_set_pc;
- cc->synchronize_from_tb = mb_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = mb_cpu_synchronize_from_tb;
cc->gdb_read_register = mb_cpu_gdb_read_register;
cc->gdb_write_register = mb_cpu_gdb_write_register;
cc->tlb_fill = mb_cpu_tlb_fill;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index bc48573763..71c488f3dd 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -238,7 +238,6 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
cc->dump_state = mips_cpu_dump_state;
cc->set_pc = mips_cpu_set_pc;
- cc->synchronize_from_tb = mips_cpu_synchronize_from_tb;
cc->gdb_read_register = mips_cpu_gdb_read_register;
cc->gdb_write_register = mips_cpu_gdb_write_register;
#ifndef CONFIG_USER_ONLY
@@ -250,6 +249,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
cc->disas_set_info = mips_cpu_disas_set_info;
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = mips_tcg_init;
+ cc->tcg_ops.synchronize_from_tb = mips_cpu_synchronize_from_tb;
cc->tlb_fill = mips_cpu_tlb_fill;
#endif
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index a52e0ce466..de44e323ae 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -543,7 +543,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
cc->dump_state = riscv_cpu_dump_state;
cc->set_pc = riscv_cpu_set_pc;
- cc->synchronize_from_tb = riscv_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = riscv_cpu_synchronize_from_tb;
cc->gdb_read_register = riscv_cpu_gdb_read_register;
cc->gdb_write_register = riscv_cpu_gdb_write_register;
cc->gdb_num_core_regs = 33;
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index a701a09b11..d03c4e0b05 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -189,7 +189,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
cc->dump_state = rx_cpu_dump_state;
cc->set_pc = rx_cpu_set_pc;
- cc->synchronize_from_tb = rx_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = rx_cpu_synchronize_from_tb;
cc->gdb_read_register = rx_cpu_gdb_read_register;
cc->gdb_write_register = rx_cpu_gdb_write_register;
cc->get_phys_page_debug = rx_cpu_get_phys_page_debug;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index bdc5c9d90b..a33025b5c8 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -222,7 +222,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
cc->dump_state = superh_cpu_dump_state;
cc->set_pc = superh_cpu_set_pc;
- cc->synchronize_from_tb = superh_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = superh_cpu_synchronize_from_tb;
cc->gdb_read_register = superh_cpu_gdb_read_register;
cc->gdb_write_register = superh_cpu_gdb_write_register;
cc->tlb_fill = superh_cpu_tlb_fill;
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 07e48b86d1..baf6c5b587 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -868,7 +868,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
#endif
cc->set_pc = sparc_cpu_set_pc;
- cc->synchronize_from_tb = sparc_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = sparc_cpu_synchronize_from_tb;
cc->gdb_read_register = sparc_cpu_gdb_read_register;
cc->gdb_write_register = sparc_cpu_gdb_write_register;
cc->tlb_fill = sparc_cpu_tlb_fill;
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index 78b2925955..5edf96c600 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -162,7 +162,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
cc->dump_state = tricore_cpu_dump_state;
cc->set_pc = tricore_cpu_set_pc;
- cc->synchronize_from_tb = tricore_cpu_synchronize_from_tb;
+ cc->tcg_ops.synchronize_from_tb = tricore_cpu_synchronize_from_tb;
cc->get_phys_page_debug = tricore_cpu_get_phys_page_debug;
cc->tcg_ops.initialize = tricore_tcg_init;
cc->tlb_fill = tricore_cpu_tlb_fill;
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 18/27] cpu: Move cpu_exec_* to tcg_ops
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (16 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 17/27] cpu: Move synchronize_from_tb() to tcg_ops Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:34 ` Philippe Mathieu-Daudé
2020-12-05 16:15 ` [RFC v8 19/27] cpu: Move tlb_fill " Claudio Fontana
` (9 subsequent siblings)
27 siblings, 1 reply; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
[claudio: wrapped in CONFIG_TCG]
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
accel/tcg/cpu-exec.c | 12 ++++++------
include/hw/core/cpu.h | 6 ------
include/hw/core/tcg-cpu-ops.h | 9 +++++++++
target/alpha/cpu.c | 3 ++-
target/arm/cpu.c | 2 +-
target/arm/cpu64.c | 5 ++++-
target/arm/cpu_tcg.c | 5 ++++-
target/avr/cpu.c | 2 +-
target/cris/cpu.c | 2 +-
target/hppa/cpu.c | 2 +-
target/i386/tcg-cpu.c | 6 +++---
target/lm32/cpu.c | 2 +-
target/m68k/cpu.c | 2 +-
target/microblaze/cpu.c | 2 +-
target/mips/cpu.c | 2 +-
target/nios2/cpu.c | 2 +-
target/openrisc/cpu.c | 2 +-
target/ppc/translate_init.c.inc | 10 +++++-----
target/riscv/cpu.c | 2 +-
target/rx/cpu.c | 2 +-
target/s390x/cpu.c | 2 +-
target/sh4/cpu.c | 2 +-
target/sparc/cpu.c | 2 +-
target/tilegx/cpu.c | 2 +-
target/unicore32/cpu.c | 2 +-
target/xtensa/cpu.c | 2 +-
26 files changed, 51 insertions(+), 41 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index 776415d47e..edb349835e 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -240,8 +240,8 @@ static void cpu_exec_enter(CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
- if (cc->cpu_exec_enter) {
- cc->cpu_exec_enter(cpu);
+ if (cc->tcg_ops.cpu_exec_enter) {
+ cc->tcg_ops.cpu_exec_enter(cpu);
}
}
@@ -249,8 +249,8 @@ static void cpu_exec_exit(CPUState *cpu)
{
CPUClass *cc = CPU_GET_CLASS(cpu);
- if (cc->cpu_exec_exit) {
- cc->cpu_exec_exit(cpu);
+ if (cc->tcg_ops.cpu_exec_exit) {
+ cc->tcg_ops.cpu_exec_exit(cpu);
}
}
@@ -625,8 +625,8 @@ static inline bool cpu_handle_interrupt(CPUState *cpu,
True when it is, and we should restart on a new TB,
and via longjmp via cpu_loop_exit. */
else {
- if (cc->cpu_exec_interrupt &&
- cc->cpu_exec_interrupt(cpu, interrupt_request)) {
+ if (cc->tcg_ops.cpu_exec_interrupt &&
+ cc->tcg_ops.cpu_exec_interrupt(cpu, interrupt_request)) {
if (need_replay_interrupt(interrupt_request)) {
replay_interrupt();
}
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 83007d262c..52142e9094 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -146,9 +146,6 @@ struct TranslationBlock;
* @gdb_get_dynamic_xml: Callback to return dynamically generated XML for the
* gdb stub. Returns a pointer to the XML contents for the specified XML file
* or NULL if the CPU doesn't have a dynamically generated content for it.
- * @cpu_exec_enter: Callback for cpu_exec preparation.
- * @cpu_exec_exit: Callback for cpu_exec cleanup.
- * @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec.
* @disas_set_info: Setup architecture specific components of disassembly info
* @adjust_watchpoint_address: Perform a target-specific adjustment to an
* address before attempting to match it against watchpoints.
@@ -211,9 +208,6 @@ struct CPUClass {
const char *gdb_core_xml_file;
gchar * (*gdb_arch_name)(CPUState *cpu);
const char * (*gdb_get_dynamic_xml)(CPUState *cpu, const char *xmlname);
- void (*cpu_exec_enter)(CPUState *cpu);
- void (*cpu_exec_exit)(CPUState *cpu);
- bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
void (*disas_set_info)(CPUState *cpu, disassemble_info *info);
vaddr (*adjust_watchpoint_address)(CPUState *cpu, vaddr addr, int len);
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 109291ac52..e12f32919b 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -10,6 +10,9 @@
#ifndef TCG_CPU_OPS_H
#define TCG_CPU_OPS_H
+/**
+ * struct TcgCpuOperations: TCG operations specific to a CPU class
+ */
typedef struct TcgCpuOperations {
/**
* @initialize: Initalize TCG state
@@ -28,6 +31,12 @@ typedef struct TcgCpuOperations {
* @set_pc(tb->pc).
*/
void (*synchronize_from_tb)(CPUState *cpu, struct TranslationBlock *tb);
+ /** @cpu_exec_enter: Callback for cpu_exec preparation */
+ void (*cpu_exec_enter)(CPUState *cpu);
+ /** @cpu_exec_exit: Callback for cpu_exec cleanup */
+ void (*cpu_exec_exit)(CPUState *cpu);
+ /** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
+ bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
} TcgCpuOperations;
#endif /* TCG_CPU_OPS_H */
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index d66f0351a9..4f206c154d 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -218,7 +218,6 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = alpha_cpu_class_by_name;
cc->has_work = alpha_cpu_has_work;
cc->do_interrupt = alpha_cpu_do_interrupt;
- cc->cpu_exec_interrupt = alpha_cpu_exec_interrupt;
cc->dump_state = alpha_cpu_dump_state;
cc->set_pc = alpha_cpu_set_pc;
cc->gdb_read_register = alpha_cpu_gdb_read_register;
@@ -234,6 +233,8 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.initialize = alpha_translate_init;
cc->gdb_num_core_regs = 67;
+
+ cc->tcg_ops.cpu_exec_interrupt = alpha_cpu_exec_interrupt;
}
#define DEFINE_ALPHA_CPU_TYPE(base_type, cpu_model, initfn) \
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 2f9e27c248..470b7b48c3 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2239,7 +2239,6 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = arm_cpu_class_by_name;
cc->has_work = arm_cpu_has_work;
- cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
cc->dump_state = arm_cpu_dump_state;
cc->set_pc = arm_cpu_set_pc;
cc->gdb_read_register = arm_cpu_gdb_read_register;
@@ -2261,6 +2260,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->disas_set_info = arm_disas_set_info;
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = arm_translate_init;
+ cc->tcg_ops.cpu_exec_interrupt = arm_cpu_exec_interrupt;
cc->tcg_ops.synchronize_from_tb = arm_cpu_synchronize_from_tb;
cc->tlb_fill = arm_cpu_tlb_fill;
cc->debug_excp_handler = arm_debug_excp_handler;
diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
index 649213082f..ebc53c8bdc 100644
--- a/target/arm/cpu64.c
+++ b/target/arm/cpu64.c
@@ -784,7 +784,10 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
{
CPUClass *cc = CPU_CLASS(oc);
- cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
+#ifdef CONFIG_TCG
+ cc->tcg_ops.cpu_exec_interrupt = arm_cpu_exec_interrupt;
+#endif /* CONFIG_TCG */
+
cc->gdb_read_register = aarch64_cpu_gdb_read_register;
cc->gdb_write_register = aarch64_cpu_gdb_write_register;
cc->gdb_num_core_regs = 34;
diff --git a/target/arm/cpu_tcg.c b/target/arm/cpu_tcg.c
index 0013e25412..a6538d3a96 100644
--- a/target/arm/cpu_tcg.c
+++ b/target/arm/cpu_tcg.c
@@ -628,7 +628,10 @@ static void arm_v7m_class_init(ObjectClass *oc, void *data)
cc->do_interrupt = arm_v7m_cpu_do_interrupt;
#endif
- cc->cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
+#ifdef CONFIG_TCG
+ cc->tcg_ops.cpu_exec_interrupt = arm_v7m_cpu_exec_interrupt;
+#endif /* CONFIG_TCG */
+
cc->gdb_core_xml_file = "arm-m-profile.xml";
}
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index f753c15768..277b00dbfc 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -198,7 +198,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
cc->has_work = avr_cpu_has_work;
cc->do_interrupt = avr_cpu_do_interrupt;
- cc->cpu_exec_interrupt = avr_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = avr_cpu_exec_interrupt;
cc->dump_state = avr_cpu_dump_state;
cc->set_pc = avr_cpu_set_pc;
cc->memory_rw_debug = avr_cpu_memory_rw_debug;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 4328f8e6c9..7489fc20c8 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -269,7 +269,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = cris_cpu_class_by_name;
cc->has_work = cris_cpu_has_work;
cc->do_interrupt = cris_cpu_do_interrupt;
- cc->cpu_exec_interrupt = cris_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = cris_cpu_exec_interrupt;
cc->dump_state = cris_cpu_dump_state;
cc->set_pc = cris_cpu_set_pc;
cc->gdb_read_register = cris_cpu_gdb_read_register;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 12a09e93ae..61444753f2 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -140,7 +140,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = hppa_cpu_class_by_name;
cc->has_work = hppa_cpu_has_work;
cc->do_interrupt = hppa_cpu_do_interrupt;
- cc->cpu_exec_interrupt = hppa_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = hppa_cpu_exec_interrupt;
cc->dump_state = hppa_cpu_dump_state;
cc->set_pc = hppa_cpu_set_pc;
cc->tcg_ops.synchronize_from_tb = hppa_cpu_synchronize_from_tb;
diff --git a/target/i386/tcg-cpu.c b/target/i386/tcg-cpu.c
index d1414e2970..5e0f2a2fae 100644
--- a/target/i386/tcg-cpu.c
+++ b/target/i386/tcg-cpu.c
@@ -59,10 +59,10 @@ static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
void tcg_cpu_common_class_init(CPUClass *cc)
{
cc->do_interrupt = x86_cpu_do_interrupt;
- cc->cpu_exec_interrupt = x86_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = x86_cpu_exec_interrupt;
cc->tcg_ops.synchronize_from_tb = x86_cpu_synchronize_from_tb;
- cc->cpu_exec_enter = x86_cpu_exec_enter;
- cc->cpu_exec_exit = x86_cpu_exec_exit;
+ cc->tcg_ops.cpu_exec_enter = x86_cpu_exec_enter;
+ cc->tcg_ops.cpu_exec_exit = x86_cpu_exec_exit;
cc->tcg_ops.initialize = tcg_x86_init;
cc->tlb_fill = x86_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index ef795b81a4..eea2d3e515 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -223,7 +223,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = lm32_cpu_class_by_name;
cc->has_work = lm32_cpu_has_work;
cc->do_interrupt = lm32_cpu_do_interrupt;
- cc->cpu_exec_interrupt = lm32_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = lm32_cpu_exec_interrupt;
cc->dump_state = lm32_cpu_dump_state;
cc->set_pc = lm32_cpu_set_pc;
cc->gdb_read_register = lm32_cpu_gdb_read_register;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index b66d86c353..c0fa517fc3 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -278,7 +278,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
cc->class_by_name = m68k_cpu_class_by_name;
cc->has_work = m68k_cpu_has_work;
cc->do_interrupt = m68k_cpu_do_interrupt;
- cc->cpu_exec_interrupt = m68k_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = m68k_cpu_exec_interrupt;
cc->dump_state = m68k_cpu_dump_state;
cc->set_pc = m68k_cpu_set_pc;
cc->gdb_read_register = m68k_cpu_gdb_read_register;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 97d94d9c27..833d7f2d59 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -319,7 +319,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
cc->has_work = mb_cpu_has_work;
cc->do_interrupt = mb_cpu_do_interrupt;
cc->do_unaligned_access = mb_cpu_do_unaligned_access;
- cc->cpu_exec_interrupt = mb_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = mb_cpu_exec_interrupt;
cc->dump_state = mb_cpu_dump_state;
cc->set_pc = mb_cpu_set_pc;
cc->tcg_ops.synchronize_from_tb = mb_cpu_synchronize_from_tb;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 71c488f3dd..344ee402fc 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -235,7 +235,6 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
cc->class_by_name = mips_cpu_class_by_name;
cc->has_work = mips_cpu_has_work;
cc->do_interrupt = mips_cpu_do_interrupt;
- cc->cpu_exec_interrupt = mips_cpu_exec_interrupt;
cc->dump_state = mips_cpu_dump_state;
cc->set_pc = mips_cpu_set_pc;
cc->gdb_read_register = mips_cpu_gdb_read_register;
@@ -249,6 +248,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
cc->disas_set_info = mips_cpu_disas_set_info;
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = mips_tcg_init;
+ cc->tcg_ops.cpu_exec_interrupt = mips_cpu_exec_interrupt;
cc->tcg_ops.synchronize_from_tb = mips_cpu_synchronize_from_tb;
cc->tlb_fill = mips_cpu_tlb_fill;
#endif
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 29c9c6f634..9eeb01fb5b 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -193,7 +193,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = nios2_cpu_class_by_name;
cc->has_work = nios2_cpu_has_work;
cc->do_interrupt = nios2_cpu_do_interrupt;
- cc->cpu_exec_interrupt = nios2_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = nios2_cpu_exec_interrupt;
cc->dump_state = nios2_cpu_dump_state;
cc->set_pc = nios2_cpu_set_pc;
cc->disas_set_info = nios2_cpu_disas_set_info;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index e442f4f97c..df8a41f956 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -155,7 +155,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = openrisc_cpu_class_by_name;
cc->has_work = openrisc_cpu_has_work;
cc->do_interrupt = openrisc_cpu_do_interrupt;
- cc->cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = openrisc_cpu_exec_interrupt;
cc->dump_state = openrisc_cpu_dump_state;
cc->set_pc = openrisc_cpu_set_pc;
cc->gdb_read_register = openrisc_cpu_gdb_read_register;
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index 9a6932b774..e0edbac999 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -10909,7 +10909,6 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
cc->parse_features = ppc_cpu_parse_featurestr;
cc->has_work = ppc_cpu_has_work;
cc->do_interrupt = ppc_cpu_do_interrupt;
- cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt;
cc->dump_state = ppc_cpu_dump_state;
cc->dump_statistics = ppc_cpu_dump_statistics;
cc->set_pc = ppc_cpu_set_pc;
@@ -10946,12 +10945,13 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
#endif
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = ppc_translate_init;
+ cc->tcg_ops.cpu_exec_interrupt = ppc_cpu_exec_interrupt;
cc->tlb_fill = ppc_cpu_tlb_fill;
-#endif
#ifndef CONFIG_USER_ONLY
- cc->cpu_exec_enter = ppc_cpu_exec_enter;
- cc->cpu_exec_exit = ppc_cpu_exec_exit;
-#endif
+ cc->tcg_ops.cpu_exec_enter = ppc_cpu_exec_enter;
+ cc->tcg_ops.cpu_exec_exit = ppc_cpu_exec_exit;
+#endif /* !CONFIG_USER_ONLY */
+#endif /* CONFIG_TCG */
cc->disas_set_info = ppc_disas_set_info;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index de44e323ae..97dbe1a08c 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -540,7 +540,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
cc->class_by_name = riscv_cpu_class_by_name;
cc->has_work = riscv_cpu_has_work;
cc->do_interrupt = riscv_cpu_do_interrupt;
- cc->cpu_exec_interrupt = riscv_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = riscv_cpu_exec_interrupt;
cc->dump_state = riscv_cpu_dump_state;
cc->set_pc = riscv_cpu_set_pc;
cc->tcg_ops.synchronize_from_tb = riscv_cpu_synchronize_from_tb;
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index d03c4e0b05..3ba93590d2 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -186,7 +186,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
cc->class_by_name = rx_cpu_class_by_name;
cc->has_work = rx_cpu_has_work;
cc->do_interrupt = rx_cpu_do_interrupt;
- cc->cpu_exec_interrupt = rx_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = rx_cpu_exec_interrupt;
cc->dump_state = rx_cpu_dump_state;
cc->set_pc = rx_cpu_set_pc;
cc->tcg_ops.synchronize_from_tb = rx_cpu_synchronize_from_tb;
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 697b94ff7b..add2f4b21f 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -505,7 +505,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->get_crash_info = s390_cpu_get_crash_info;
cc->write_elf64_note = s390_cpu_write_elf64_note;
#ifdef CONFIG_TCG
- cc->cpu_exec_interrupt = s390_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = s390_cpu_exec_interrupt;
cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
#endif
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index a33025b5c8..0574194cd0 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -219,7 +219,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = superh_cpu_class_by_name;
cc->has_work = superh_cpu_has_work;
cc->do_interrupt = superh_cpu_do_interrupt;
- cc->cpu_exec_interrupt = superh_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = superh_cpu_exec_interrupt;
cc->dump_state = superh_cpu_dump_state;
cc->set_pc = superh_cpu_set_pc;
cc->tcg_ops.synchronize_from_tb = superh_cpu_synchronize_from_tb;
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index baf6c5b587..c559f15e14 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -862,7 +862,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
cc->parse_features = sparc_cpu_parse_features;
cc->has_work = sparc_cpu_has_work;
cc->do_interrupt = sparc_cpu_do_interrupt;
- cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = sparc_cpu_exec_interrupt;
cc->dump_state = sparc_cpu_dump_state;
#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
cc->memory_rw_debug = sparc_cpu_memory_rw_debug;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index cd24d0eb9d..4c6176d26e 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -148,7 +148,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = tilegx_cpu_class_by_name;
cc->has_work = tilegx_cpu_has_work;
cc->do_interrupt = tilegx_cpu_do_interrupt;
- cc->cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
cc->dump_state = tilegx_cpu_dump_state;
cc->set_pc = tilegx_cpu_set_pc;
cc->tlb_fill = tilegx_cpu_tlb_fill;
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 226bf4226e..84c3419989 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -132,7 +132,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = uc32_cpu_class_by_name;
cc->has_work = uc32_cpu_has_work;
cc->do_interrupt = uc32_cpu_do_interrupt;
- cc->cpu_exec_interrupt = uc32_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = uc32_cpu_exec_interrupt;
cc->dump_state = uc32_cpu_dump_state;
cc->set_pc = uc32_cpu_set_pc;
cc->tlb_fill = uc32_cpu_tlb_fill;
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 5a6f5bf88b..42a5e4ebe8 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -195,7 +195,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
cc->class_by_name = xtensa_cpu_class_by_name;
cc->has_work = xtensa_cpu_has_work;
cc->do_interrupt = xtensa_cpu_do_interrupt;
- cc->cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = xtensa_cpu_exec_interrupt;
cc->dump_state = xtensa_cpu_dump_state;
cc->set_pc = xtensa_cpu_set_pc;
cc->gdb_read_register = xtensa_cpu_gdb_read_register;
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC v8 18/27] cpu: Move cpu_exec_* to tcg_ops
2020-12-05 16:15 ` [RFC v8 18/27] cpu: Move cpu_exec_* " Claudio Fontana
@ 2020-12-05 16:34 ` Philippe Mathieu-Daudé
0 siblings, 0 replies; 34+ messages in thread
From: Philippe Mathieu-Daudé @ 2020-12-05 16:34 UTC (permalink / raw)
To: Claudio Fontana, Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota
On 12/5/20 5:15 PM, Claudio Fontana wrote:
> From: Eduardo Habkost <ehabkost@redhat.com>
>
> Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
> [claudio: wrapped in CONFIG_TCG]
> Signed-off-by: Claudio Fontana <cfontana@suse.de>
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> ---
> accel/tcg/cpu-exec.c | 12 ++++++------
> include/hw/core/cpu.h | 6 ------
> include/hw/core/tcg-cpu-ops.h | 9 +++++++++
> target/alpha/cpu.c | 3 ++-
> target/arm/cpu.c | 2 +-
> target/arm/cpu64.c | 5 ++++-
> target/arm/cpu_tcg.c | 5 ++++-
> target/avr/cpu.c | 2 +-
> target/cris/cpu.c | 2 +-
> target/hppa/cpu.c | 2 +-
> target/i386/tcg-cpu.c | 6 +++---
> target/lm32/cpu.c | 2 +-
> target/m68k/cpu.c | 2 +-
> target/microblaze/cpu.c | 2 +-
> target/mips/cpu.c | 2 +-
> target/nios2/cpu.c | 2 +-
> target/openrisc/cpu.c | 2 +-
> target/ppc/translate_init.c.inc | 10 +++++-----
> target/riscv/cpu.c | 2 +-
> target/rx/cpu.c | 2 +-
> target/s390x/cpu.c | 2 +-
> target/sh4/cpu.c | 2 +-
> target/sparc/cpu.c | 2 +-
> target/tilegx/cpu.c | 2 +-
> target/unicore32/cpu.c | 2 +-
> target/xtensa/cpu.c | 2 +-
> 26 files changed, 51 insertions(+), 41 deletions(-)
...
> diff --git a/target/arm/cpu.c b/target/arm/cpu.c
> index 2f9e27c248..470b7b48c3 100644
> --- a/target/arm/cpu.c
> +++ b/target/arm/cpu.c
> @@ -2239,7 +2239,6 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
>
> cc->class_by_name = arm_cpu_class_by_name;
> cc->has_work = arm_cpu_has_work;
> - cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
> cc->dump_state = arm_cpu_dump_state;
> cc->set_pc = arm_cpu_set_pc;
> cc->gdb_read_register = arm_cpu_gdb_read_register;
> @@ -2261,6 +2260,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
> cc->disas_set_info = arm_disas_set_info;
> #ifdef CONFIG_TCG
> cc->tcg_ops.initialize = arm_translate_init;
> + cc->tcg_ops.cpu_exec_interrupt = arm_cpu_exec_interrupt;
> cc->tcg_ops.synchronize_from_tb = arm_cpu_synchronize_from_tb;
> cc->tlb_fill = arm_cpu_tlb_fill;
> cc->debug_excp_handler = arm_debug_excp_handler;
> diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c
> index 649213082f..ebc53c8bdc 100644
> --- a/target/arm/cpu64.c
> +++ b/target/arm/cpu64.c
> @@ -784,7 +784,10 @@ static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
> {
> CPUClass *cc = CPU_CLASS(oc);
>
> - cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
> +#ifdef CONFIG_TCG
> + cc->tcg_ops.cpu_exec_interrupt = arm_cpu_exec_interrupt;
> +#endif /* CONFIG_TCG */
Thanks.
^ permalink raw reply [flat|nested] 34+ messages in thread
* [RFC v8 19/27] cpu: Move tlb_fill to tcg_ops
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (17 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 18/27] cpu: Move cpu_exec_* " Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 20/27] cpu: Move debug_excp_handler " Claudio Fontana
` (8 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
[claudio: wrapped in CONFIG_TCG]
Signed-off-by: Claudio Fontana <cfontana@suse.de>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
---
accel/tcg/cputlb.c | 6 +++---
accel/tcg/user-exec.c | 6 +++---
include/hw/core/cpu.h | 9 ---------
include/hw/core/tcg-cpu-ops.h | 12 ++++++++++++
target/alpha/cpu.c | 2 +-
target/arm/cpu.c | 2 +-
target/avr/cpu.c | 2 +-
target/cris/cpu.c | 2 +-
target/hppa/cpu.c | 2 +-
target/i386/tcg-cpu.c | 2 +-
target/lm32/cpu.c | 2 +-
target/m68k/cpu.c | 2 +-
target/microblaze/cpu.c | 2 +-
target/mips/cpu.c | 2 +-
target/moxie/cpu.c | 2 +-
target/nios2/cpu.c | 2 +-
target/openrisc/cpu.c | 2 +-
target/ppc/translate_init.c.inc | 2 +-
target/riscv/cpu.c | 2 +-
target/rx/cpu.c | 2 +-
target/s390x/cpu.c | 2 +-
target/sh4/cpu.c | 2 +-
target/sparc/cpu.c | 2 +-
target/tilegx/cpu.c | 2 +-
target/tricore/cpu.c | 2 +-
target/unicore32/cpu.c | 2 +-
target/xtensa/cpu.c | 2 +-
27 files changed, 41 insertions(+), 38 deletions(-)
diff --git a/accel/tcg/cputlb.c b/accel/tcg/cputlb.c
index 42ab79c1a5..2dc71b5528 100644
--- a/accel/tcg/cputlb.c
+++ b/accel/tcg/cputlb.c
@@ -1286,7 +1286,7 @@ static void tlb_fill(CPUState *cpu, target_ulong addr, int size,
* This is not a probe, so only valid return is success; failure
* should result in exception + longjmp to the cpu loop.
*/
- ok = cc->tlb_fill(cpu, addr, size, access_type, mmu_idx, false, retaddr);
+ ok = cc->tcg_ops.tlb_fill(cpu, addr, size, access_type, mmu_idx, false, retaddr);
assert(ok);
}
@@ -1557,8 +1557,8 @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
CPUState *cs = env_cpu(env);
CPUClass *cc = CPU_GET_CLASS(cs);
- if (!cc->tlb_fill(cs, addr, fault_size, access_type,
- mmu_idx, nonfault, retaddr)) {
+ if (!cc->tcg_ops.tlb_fill(cs, addr, fault_size, access_type,
+ mmu_idx, nonfault, retaddr)) {
/* Non-faulting page table read failed. */
*phost = NULL;
return TLB_INVALID_MASK;
diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c
index 4ebe25461a..7f53992251 100644
--- a/accel/tcg/user-exec.c
+++ b/accel/tcg/user-exec.c
@@ -186,7 +186,7 @@ static inline int handle_cpu_signal(uintptr_t pc, siginfo_t *info,
clear_helper_retaddr();
cc = CPU_GET_CLASS(cpu);
- cc->tlb_fill(cpu, address, 0, access_type, MMU_USER_IDX, false, pc);
+ cc->tcg_ops.tlb_fill(cpu, address, 0, access_type, MMU_USER_IDX, false, pc);
g_assert_not_reached();
}
@@ -216,8 +216,8 @@ static int probe_access_internal(CPUArchState *env, target_ulong addr,
} else {
CPUState *cpu = env_cpu(env);
CPUClass *cc = CPU_GET_CLASS(cpu);
- cc->tlb_fill(cpu, addr, fault_size, access_type,
- MMU_USER_IDX, false, ra);
+ cc->tcg_ops.tlb_fill(cpu, addr, fault_size, access_type,
+ MMU_USER_IDX, false, ra);
g_assert_not_reached();
}
}
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index 52142e9094..c82ef261c6 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -110,12 +110,6 @@ struct TranslationBlock;
* If the target behaviour here is anything other than "set
* the PC register to the value passed in" then the target must
* also implement the synchronize_from_tb hook.
- * @tlb_fill: Callback for handling a softmmu tlb miss or user-only
- * address fault. For system mode, if the access is valid, call
- * tlb_set_page and return true; if the access is invalid, and
- * probe is true, return false; otherwise raise an exception and
- * do not return. For user-only mode, always raise an exception
- * and do not return.
* @get_phys_page_debug: Callback for obtaining a physical address.
* @get_phys_page_attrs_debug: Callback for obtaining a physical address and the
* associated memory transaction attributes to use for the access.
@@ -183,9 +177,6 @@ struct CPUClass {
void (*get_memory_mapping)(CPUState *cpu, MemoryMappingList *list,
Error **errp);
void (*set_pc)(CPUState *cpu, vaddr value);
- bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
- MMUAccessType access_type, int mmu_idx,
- bool probe, uintptr_t retaddr);
hwaddr (*get_phys_page_debug)(CPUState *cpu, vaddr addr);
hwaddr (*get_phys_page_attrs_debug)(CPUState *cpu, vaddr addr,
MemTxAttrs *attrs);
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index e12f32919b..2ea94acca0 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -37,6 +37,18 @@ typedef struct TcgCpuOperations {
void (*cpu_exec_exit)(CPUState *cpu);
/** @cpu_exec_interrupt: Callback for processing interrupts in cpu_exec */
bool (*cpu_exec_interrupt)(CPUState *cpu, int interrupt_request);
+ /**
+ * @tlb_fill: Handle a softmmu tlb miss or user-only address fault
+ *
+ * For system mode, if the access is valid, call tlb_set_page
+ * and return true; if the access is invalid, and probe is
+ * true, return false; otherwise raise an exception and do
+ * not return. For user-only mode, always raise an exception
+ * and do not return.
+ */
+ bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
+ MMUAccessType access_type, int mmu_idx,
+ bool probe, uintptr_t retaddr);
} TcgCpuOperations;
#endif /* TCG_CPU_OPS_H */
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 4f206c154d..0369d5a99c 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -222,7 +222,7 @@ static void alpha_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = alpha_cpu_set_pc;
cc->gdb_read_register = alpha_cpu_gdb_read_register;
cc->gdb_write_register = alpha_cpu_gdb_write_register;
- cc->tlb_fill = alpha_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = alpha_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->do_transaction_failed = alpha_cpu_do_transaction_failed;
cc->do_unaligned_access = alpha_cpu_do_unaligned_access;
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 470b7b48c3..0dac097367 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2262,7 +2262,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.initialize = arm_translate_init;
cc->tcg_ops.cpu_exec_interrupt = arm_cpu_exec_interrupt;
cc->tcg_ops.synchronize_from_tb = arm_cpu_synchronize_from_tb;
- cc->tlb_fill = arm_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = arm_cpu_tlb_fill;
cc->debug_excp_handler = arm_debug_excp_handler;
cc->debug_check_watchpoint = arm_debug_check_watchpoint;
cc->do_unaligned_access = arm_cpu_do_unaligned_access;
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 277b00dbfc..699055de7c 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -203,7 +203,7 @@ static void avr_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = avr_cpu_set_pc;
cc->memory_rw_debug = avr_cpu_memory_rw_debug;
cc->get_phys_page_debug = avr_cpu_get_phys_page_debug;
- cc->tlb_fill = avr_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = avr_cpu_tlb_fill;
cc->vmsd = &vms_avr_cpu;
cc->disas_set_info = avr_cpu_disas_set_info;
cc->tcg_ops.initialize = avr_cpu_tcg_init;
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 7489fc20c8..9222717f3e 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -274,7 +274,7 @@ static void cris_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = cris_cpu_set_pc;
cc->gdb_read_register = cris_cpu_gdb_read_register;
cc->gdb_write_register = cris_cpu_gdb_write_register;
- cc->tlb_fill = cris_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = cris_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->get_phys_page_debug = cris_cpu_get_phys_page_debug;
dc->vmsd = &vmstate_cris_cpu;
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index 61444753f2..e2d79f954e 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -146,7 +146,7 @@ static void hppa_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.synchronize_from_tb = hppa_cpu_synchronize_from_tb;
cc->gdb_read_register = hppa_cpu_gdb_read_register;
cc->gdb_write_register = hppa_cpu_gdb_write_register;
- cc->tlb_fill = hppa_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = hppa_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->get_phys_page_debug = hppa_cpu_get_phys_page_debug;
dc->vmsd = &vmstate_hppa_cpu;
diff --git a/target/i386/tcg-cpu.c b/target/i386/tcg-cpu.c
index 5e0f2a2fae..8606dd6a3e 100644
--- a/target/i386/tcg-cpu.c
+++ b/target/i386/tcg-cpu.c
@@ -64,7 +64,7 @@ void tcg_cpu_common_class_init(CPUClass *cc)
cc->tcg_ops.cpu_exec_enter = x86_cpu_exec_enter;
cc->tcg_ops.cpu_exec_exit = x86_cpu_exec_exit;
cc->tcg_ops.initialize = tcg_x86_init;
- cc->tlb_fill = x86_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = x86_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->debug_excp_handler = breakpoint_handler;
#endif
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index eea2d3e515..76dc728858 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -228,7 +228,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = lm32_cpu_set_pc;
cc->gdb_read_register = lm32_cpu_gdb_read_register;
cc->gdb_write_register = lm32_cpu_gdb_write_register;
- cc->tlb_fill = lm32_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = lm32_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->get_phys_page_debug = lm32_cpu_get_phys_page_debug;
cc->vmsd = &vmstate_lm32_cpu;
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index c0fa517fc3..bc109faa21 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -283,7 +283,7 @@ static void m68k_cpu_class_init(ObjectClass *c, void *data)
cc->set_pc = m68k_cpu_set_pc;
cc->gdb_read_register = m68k_cpu_gdb_read_register;
cc->gdb_write_register = m68k_cpu_gdb_write_register;
- cc->tlb_fill = m68k_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = m68k_cpu_tlb_fill;
#if defined(CONFIG_SOFTMMU)
cc->do_transaction_failed = m68k_cpu_transaction_failed;
cc->get_phys_page_debug = m68k_cpu_get_phys_page_debug;
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 833d7f2d59..6e660a27b8 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -325,7 +325,7 @@ static void mb_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.synchronize_from_tb = mb_cpu_synchronize_from_tb;
cc->gdb_read_register = mb_cpu_gdb_read_register;
cc->gdb_write_register = mb_cpu_gdb_write_register;
- cc->tlb_fill = mb_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = mb_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->do_transaction_failed = mb_cpu_transaction_failed;
cc->get_phys_page_debug = mb_cpu_get_phys_page_debug;
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 344ee402fc..1f7573d319 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -250,7 +250,7 @@ static void mips_cpu_class_init(ObjectClass *c, void *data)
cc->tcg_ops.initialize = mips_tcg_init;
cc->tcg_ops.cpu_exec_interrupt = mips_cpu_exec_interrupt;
cc->tcg_ops.synchronize_from_tb = mips_cpu_synchronize_from_tb;
- cc->tlb_fill = mips_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = mips_cpu_tlb_fill;
#endif
cc->gdb_num_core_regs = 73;
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
index 224cfc8361..1177d092c1 100644
--- a/target/moxie/cpu.c
+++ b/target/moxie/cpu.c
@@ -110,7 +110,7 @@ static void moxie_cpu_class_init(ObjectClass *oc, void *data)
cc->do_interrupt = moxie_cpu_do_interrupt;
cc->dump_state = moxie_cpu_dump_state;
cc->set_pc = moxie_cpu_set_pc;
- cc->tlb_fill = moxie_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = moxie_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
cc->vmsd = &vmstate_moxie_cpu;
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index 9eeb01fb5b..a96b74b00c 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -197,7 +197,7 @@ static void nios2_cpu_class_init(ObjectClass *oc, void *data)
cc->dump_state = nios2_cpu_dump_state;
cc->set_pc = nios2_cpu_set_pc;
cc->disas_set_info = nios2_cpu_disas_set_info;
- cc->tlb_fill = nios2_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = nios2_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->do_unaligned_access = nios2_cpu_do_unaligned_access;
cc->get_phys_page_debug = nios2_cpu_get_phys_page_debug;
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index df8a41f956..e6d1c9764b 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -160,7 +160,7 @@ static void openrisc_cpu_class_init(ObjectClass *oc, void *data)
cc->set_pc = openrisc_cpu_set_pc;
cc->gdb_read_register = openrisc_cpu_gdb_read_register;
cc->gdb_write_register = openrisc_cpu_gdb_write_register;
- cc->tlb_fill = openrisc_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = openrisc_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->get_phys_page_debug = openrisc_cpu_get_phys_page_debug;
dc->vmsd = &vmstate_openrisc_cpu;
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index e0edbac999..e83000b2fb 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -10946,7 +10946,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = ppc_translate_init;
cc->tcg_ops.cpu_exec_interrupt = ppc_cpu_exec_interrupt;
- cc->tlb_fill = ppc_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = ppc_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->tcg_ops.cpu_exec_enter = ppc_cpu_exec_enter;
cc->tcg_ops.cpu_exec_exit = ppc_cpu_exec_exit;
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 97dbe1a08c..022b4271d4 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -563,7 +563,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
#endif
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = riscv_translate_init;
- cc->tlb_fill = riscv_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = riscv_cpu_tlb_fill;
#endif
device_class_set_props(dc, riscv_cpu_properties);
}
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index 3ba93590d2..c815533223 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -195,7 +195,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
cc->get_phys_page_debug = rx_cpu_get_phys_page_debug;
cc->disas_set_info = rx_cpu_disas_set_info;
cc->tcg_ops.initialize = rx_translate_init;
- cc->tlb_fill = rx_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = rx_cpu_tlb_fill;
cc->gdb_num_core_regs = 26;
cc->gdb_core_xml_file = "rx-core.xml";
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index add2f4b21f..6cd2b30192 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -513,7 +513,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->disas_set_info = s390_cpu_disas_set_info;
#ifdef CONFIG_TCG
cc->tcg_ops.initialize = s390x_translate_init;
- cc->tlb_fill = s390_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = s390_cpu_tlb_fill;
#endif
cc->gdb_num_core_regs = S390_NUM_CORE_REGS;
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 0574194cd0..7a9019edec 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -225,7 +225,7 @@ static void superh_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.synchronize_from_tb = superh_cpu_synchronize_from_tb;
cc->gdb_read_register = superh_cpu_gdb_read_register;
cc->gdb_write_register = superh_cpu_gdb_write_register;
- cc->tlb_fill = superh_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = superh_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->do_unaligned_access = superh_cpu_do_unaligned_access;
cc->get_phys_page_debug = superh_cpu_get_phys_page_debug;
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index c559f15e14..760e0ea92c 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -871,7 +871,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.synchronize_from_tb = sparc_cpu_synchronize_from_tb;
cc->gdb_read_register = sparc_cpu_gdb_read_register;
cc->gdb_write_register = sparc_cpu_gdb_write_register;
- cc->tlb_fill = sparc_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = sparc_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->do_transaction_failed = sparc_cpu_do_transaction_failed;
cc->do_unaligned_access = sparc_cpu_do_unaligned_access;
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index 4c6176d26e..75b3a4bae3 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -151,7 +151,7 @@ static void tilegx_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.cpu_exec_interrupt = tilegx_cpu_exec_interrupt;
cc->dump_state = tilegx_cpu_dump_state;
cc->set_pc = tilegx_cpu_set_pc;
- cc->tlb_fill = tilegx_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = tilegx_cpu_tlb_fill;
cc->gdb_num_core_regs = 0;
cc->tcg_ops.initialize = tilegx_tcg_init;
}
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index 5edf96c600..89a14f81d7 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -165,7 +165,7 @@ static void tricore_cpu_class_init(ObjectClass *c, void *data)
cc->tcg_ops.synchronize_from_tb = tricore_cpu_synchronize_from_tb;
cc->get_phys_page_debug = tricore_cpu_get_phys_page_debug;
cc->tcg_ops.initialize = tricore_tcg_init;
- cc->tlb_fill = tricore_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = tricore_cpu_tlb_fill;
}
#define DEFINE_TRICORE_CPU_TYPE(cpu_model, initfn) \
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index 84c3419989..a57d315d2f 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -135,7 +135,7 @@ static void uc32_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.cpu_exec_interrupt = uc32_cpu_exec_interrupt;
cc->dump_state = uc32_cpu_dump_state;
cc->set_pc = uc32_cpu_set_pc;
- cc->tlb_fill = uc32_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = uc32_cpu_tlb_fill;
cc->get_phys_page_debug = uc32_cpu_get_phys_page_debug;
cc->tcg_ops.initialize = uc32_translate_init;
dc->vmsd = &vmstate_uc32_cpu;
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index 42a5e4ebe8..e764dbeb73 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -201,7 +201,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
cc->gdb_read_register = xtensa_cpu_gdb_read_register;
cc->gdb_write_register = xtensa_cpu_gdb_write_register;
cc->gdb_stop_before_watchpoint = true;
- cc->tlb_fill = xtensa_cpu_tlb_fill;
+ cc->tcg_ops.tlb_fill = xtensa_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
cc->do_unaligned_access = xtensa_cpu_do_unaligned_access;
cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 20/27] cpu: Move debug_excp_handler to tcg_ops
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (18 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 19/27] cpu: Move tlb_fill " Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 21/27] accel: extend AccelState and AccelClass to user-mode Claudio Fontana
` (7 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Claudio Fontana
From: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
accel/tcg/cpu-exec.c | 4 ++--
include/hw/core/cpu.h | 2 --
include/hw/core/tcg-cpu-ops.h | 2 ++
target/arm/cpu.c | 2 +-
target/i386/tcg-cpu.c | 2 +-
target/lm32/cpu.c | 2 +-
target/s390x/cpu.c | 2 +-
target/xtensa/cpu.c | 2 +-
8 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/accel/tcg/cpu-exec.c b/accel/tcg/cpu-exec.c
index edb349835e..343ae427a0 100644
--- a/accel/tcg/cpu-exec.c
+++ b/accel/tcg/cpu-exec.c
@@ -482,8 +482,8 @@ static inline void cpu_handle_debug_exception(CPUState *cpu)
}
}
- if (cc->debug_excp_handler) {
- cc->debug_excp_handler(cpu);
+ if (cc->tcg_ops.debug_excp_handler) {
+ cc->tcg_ops.debug_excp_handler(cpu);
}
}
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index c82ef261c6..f438abb785 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -121,7 +121,6 @@ struct TranslationBlock;
* @gdb_write_register: Callback for letting GDB write a register.
* @debug_check_watchpoint: Callback: return true if the architectural
* watchpoint whose address has matched should really fire.
- * @debug_excp_handler: Callback for handling debug exceptions.
* @write_elf64_note: Callback for writing a CPU-specific ELF note to a
* 64-bit VM coredump.
* @write_elf32_qemunote: Callback for writing a CPU- and QEMU-specific ELF
@@ -184,7 +183,6 @@ struct CPUClass {
int (*gdb_read_register)(CPUState *cpu, GByteArray *buf, int reg);
int (*gdb_write_register)(CPUState *cpu, uint8_t *buf, int reg);
bool (*debug_check_watchpoint)(CPUState *cpu, CPUWatchpoint *wp);
- void (*debug_excp_handler)(CPUState *cpu);
int (*write_elf64_note)(WriteCoreDumpFunction f, CPUState *cpu,
int cpuid, void *opaque);
diff --git a/include/hw/core/tcg-cpu-ops.h b/include/hw/core/tcg-cpu-ops.h
index 2ea94acca0..dbbc64418c 100644
--- a/include/hw/core/tcg-cpu-ops.h
+++ b/include/hw/core/tcg-cpu-ops.h
@@ -49,6 +49,8 @@ typedef struct TcgCpuOperations {
bool (*tlb_fill)(CPUState *cpu, vaddr address, int size,
MMUAccessType access_type, int mmu_idx,
bool probe, uintptr_t retaddr);
+ /** @debug_excp_handler: Callback for handling debug exceptions */
+ void (*debug_excp_handler)(CPUState *cpu);
} TcgCpuOperations;
#endif /* TCG_CPU_OPS_H */
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 0dac097367..20cbfaea51 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -2263,7 +2263,7 @@ static void arm_cpu_class_init(ObjectClass *oc, void *data)
cc->tcg_ops.cpu_exec_interrupt = arm_cpu_exec_interrupt;
cc->tcg_ops.synchronize_from_tb = arm_cpu_synchronize_from_tb;
cc->tcg_ops.tlb_fill = arm_cpu_tlb_fill;
- cc->debug_excp_handler = arm_debug_excp_handler;
+ cc->tcg_ops.debug_excp_handler = arm_debug_excp_handler;
cc->debug_check_watchpoint = arm_debug_check_watchpoint;
cc->do_unaligned_access = arm_cpu_do_unaligned_access;
#if !defined(CONFIG_USER_ONLY)
diff --git a/target/i386/tcg-cpu.c b/target/i386/tcg-cpu.c
index 8606dd6a3e..38ed8bf6d3 100644
--- a/target/i386/tcg-cpu.c
+++ b/target/i386/tcg-cpu.c
@@ -66,6 +66,6 @@ void tcg_cpu_common_class_init(CPUClass *cc)
cc->tcg_ops.initialize = tcg_x86_init;
cc->tcg_ops.tlb_fill = x86_cpu_tlb_fill;
#ifndef CONFIG_USER_ONLY
- cc->debug_excp_handler = breakpoint_handler;
+ cc->tcg_ops.debug_excp_handler = breakpoint_handler;
#endif
}
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index 76dc728858..bbe1405e32 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -235,7 +235,7 @@ static void lm32_cpu_class_init(ObjectClass *oc, void *data)
#endif
cc->gdb_num_core_regs = 32 + 7;
cc->gdb_stop_before_watchpoint = true;
- cc->debug_excp_handler = lm32_debug_excp_handler;
+ cc->tcg_ops.debug_excp_handler = lm32_debug_excp_handler;
cc->disas_set_info = lm32_cpu_disas_set_info;
cc->tcg_ops.initialize = lm32_translate_init;
}
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 6cd2b30192..04856076b3 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -506,7 +506,7 @@ static void s390_cpu_class_init(ObjectClass *oc, void *data)
cc->write_elf64_note = s390_cpu_write_elf64_note;
#ifdef CONFIG_TCG
cc->tcg_ops.cpu_exec_interrupt = s390_cpu_exec_interrupt;
- cc->debug_excp_handler = s390x_cpu_debug_excp_handler;
+ cc->tcg_ops.debug_excp_handler = s390x_cpu_debug_excp_handler;
cc->do_unaligned_access = s390x_cpu_do_unaligned_access;
#endif
#endif
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index e764dbeb73..b6f13ceb32 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -207,7 +207,7 @@ static void xtensa_cpu_class_init(ObjectClass *oc, void *data)
cc->get_phys_page_debug = xtensa_cpu_get_phys_page_debug;
cc->do_transaction_failed = xtensa_cpu_do_transaction_failed;
#endif
- cc->debug_excp_handler = xtensa_breakpoint_handler;
+ cc->tcg_ops.debug_excp_handler = xtensa_breakpoint_handler;
cc->disas_set_info = xtensa_cpu_disas_set_info;
cc->tcg_ops.initialize = xtensa_translate_init;
dc->vmsd = &vmstate_xtensa_cpu;
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 21/27] accel: extend AccelState and AccelClass to user-mode
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (19 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 20/27] cpu: Move debug_excp_handler " Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 22/27] accel: replace struct CpusAccel with AccelOpsClass Claudio Fontana
` (6 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
MAINTAINERS | 2 +-
accel/accel-common.c | 50 ++++++++++++++++++++++++++++++
accel/{accel.c => accel-softmmu.c} | 27 ++--------------
accel/accel-user.c | 24 ++++++++++++++
accel/meson.build | 4 ++-
accel/qtest/qtest.c | 2 +-
accel/tcg/meson.build | 2 +-
accel/tcg/tcg-all.c | 13 ++++++--
accel/xen/xen-all.c | 2 +-
bsd-user/main.c | 6 +++-
include/hw/boards.h | 2 +-
include/{sysemu => qemu}/accel.h | 14 +++++----
include/sysemu/hvf.h | 2 +-
include/sysemu/kvm.h | 2 +-
include/sysemu/kvm_int.h | 2 +-
linux-user/main.c | 6 +++-
softmmu/memory.c | 2 +-
softmmu/qtest.c | 2 +-
softmmu/vl.c | 2 +-
target/i386/hax/hax-all.c | 2 +-
target/i386/hvf/hvf-i386.h | 2 +-
target/i386/hvf/hvf.c | 2 +-
target/i386/hvf/x86_task.c | 2 +-
target/i386/whpx/whpx-all.c | 2 +-
24 files changed, 124 insertions(+), 52 deletions(-)
create mode 100644 accel/accel-common.c
rename accel/{accel.c => accel-softmmu.c} (75%)
create mode 100644 accel/accel-user.c
rename include/{sysemu => qemu}/accel.h (95%)
diff --git a/MAINTAINERS b/MAINTAINERS
index d876f504a6..6235dd3a9f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -434,7 +434,7 @@ Overall
M: Richard Henderson <richard.henderson@linaro.org>
R: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
-F: include/sysemu/accel.h
+F: include/qemu/accel.h
F: accel/accel.c
F: accel/Makefile.objs
F: accel/stubs/Makefile.objs
diff --git a/accel/accel-common.c b/accel/accel-common.c
new file mode 100644
index 0000000000..ddec8cb5ae
--- /dev/null
+++ b/accel/accel-common.c
@@ -0,0 +1,50 @@
+/*
+ * QEMU accel class, components common to system emulation and user mode
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2014 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/accel.h"
+
+static const TypeInfo accel_type = {
+ .name = TYPE_ACCEL,
+ .parent = TYPE_OBJECT,
+ .class_size = sizeof(AccelClass),
+ .instance_size = sizeof(AccelState),
+};
+
+/* Lookup AccelClass from opt_name. Returns NULL if not found */
+AccelClass *accel_find(const char *opt_name)
+{
+ char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
+ AccelClass *ac = ACCEL_CLASS(object_class_by_name(class_name));
+ g_free(class_name);
+ return ac;
+}
+
+static void register_accel_types(void)
+{
+ type_register_static(&accel_type);
+}
+
+type_init(register_accel_types);
diff --git a/accel/accel.c b/accel/accel-softmmu.c
similarity index 75%
rename from accel/accel.c
rename to accel/accel-softmmu.c
index cb555e3b06..f89da8f9d1 100644
--- a/accel/accel.c
+++ b/accel/accel-softmmu.c
@@ -1,5 +1,5 @@
/*
- * QEMU System Emulator, accelerator interfaces
+ * QEMU accel class, system emulation components
*
* Copyright (c) 2003-2008 Fabrice Bellard
* Copyright (c) 2014 Red Hat Inc.
@@ -24,28 +24,12 @@
*/
#include "qemu/osdep.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "hw/boards.h"
#include "sysemu/arch_init.h"
#include "sysemu/sysemu.h"
#include "qom/object.h"
-static const TypeInfo accel_type = {
- .name = TYPE_ACCEL,
- .parent = TYPE_OBJECT,
- .class_size = sizeof(AccelClass),
- .instance_size = sizeof(AccelState),
-};
-
-/* Lookup AccelClass from opt_name. Returns NULL if not found */
-AccelClass *accel_find(const char *opt_name)
-{
- char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
- AccelClass *ac = ACCEL_CLASS(object_class_by_name(class_name));
- g_free(class_name);
- return ac;
-}
-
int accel_init_machine(AccelState *accel, MachineState *ms)
{
AccelClass *acc = ACCEL_GET_CLASS(accel);
@@ -76,10 +60,3 @@ void accel_setup_post(MachineState *ms)
acc->setup_post(ms, accel);
}
}
-
-static void register_accel_types(void)
-{
- type_register_static(&accel_type);
-}
-
-type_init(register_accel_types);
diff --git a/accel/accel-user.c b/accel/accel-user.c
new file mode 100644
index 0000000000..26bdda6236
--- /dev/null
+++ b/accel/accel-user.c
@@ -0,0 +1,24 @@
+/*
+ * QEMU accel class, user-mode components
+ *
+ * Copyright 2020 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.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/accel.h"
+
+AccelState *current_accel(void)
+{
+ static AccelState *accel;
+
+ if (!accel) {
+ AccelClass *ac = accel_find("tcg");
+
+ g_assert(ac != NULL);
+ accel = ACCEL(object_new_with_class(OBJECT_CLASS(ac)));
+ }
+ return accel;
+}
diff --git a/accel/meson.build b/accel/meson.build
index b26cca227a..b44ba30c86 100644
--- a/accel/meson.build
+++ b/accel/meson.build
@@ -1,4 +1,6 @@
-softmmu_ss.add(files('accel.c'))
+specific_ss.add(files('accel-common.c'))
+softmmu_ss.add(files('accel-softmmu.c'))
+user_ss.add(files('accel-user.c'))
subdir('qtest')
subdir('kvm')
diff --git a/accel/qtest/qtest.c b/accel/qtest/qtest.c
index b282cea5cf..b4e731cb2b 100644
--- a/accel/qtest/qtest.c
+++ b/accel/qtest/qtest.c
@@ -17,7 +17,7 @@
#include "qemu/module.h"
#include "qemu/option.h"
#include "qemu/config-file.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "sysemu/qtest.h"
#include "sysemu/cpus.h"
#include "sysemu/cpu-timers.h"
diff --git a/accel/tcg/meson.build b/accel/tcg/meson.build
index f39aab0a0c..424d9bb1fc 100644
--- a/accel/tcg/meson.build
+++ b/accel/tcg/meson.build
@@ -1,5 +1,6 @@
tcg_ss = ss.source_set()
tcg_ss.add(files(
+ 'tcg-all.c',
'cpu-exec-common.c',
'cpu-exec.c',
'tcg-runtime-gvec.c',
@@ -13,7 +14,6 @@ tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c'), libdl])
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files(
- 'tcg-all.c',
'cputlb.c',
'tcg-cpus.c',
'tcg-cpus-mttcg.c',
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 1ac0b76515..7125d0cc29 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -30,9 +30,12 @@
#include "tcg/tcg.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
-#include "hw/boards.h"
+#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;
@@ -106,8 +109,12 @@ static int tcg_init(MachineState *ms)
mttcg_enabled = s->mttcg_enabled;
/*
- * Initialize TCG regions
+ * Initialize TCG regions only for softmmu.
+ *
+ * This needs to be done later for user mode, because the prologue
+ * generation needs to be delayed so that GUEST_BASE is already set.
*/
+#ifndef CONFIG_USER_ONLY
tcg_region_init();
if (mttcg_enabled) {
@@ -117,6 +124,8 @@ static int tcg_init(MachineState *ms)
} 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 878a4089d9..594aaf6b49 100644
--- a/accel/xen/xen-all.c
+++ b/accel/xen/xen-all.c
@@ -15,7 +15,7 @@
#include "hw/xen/xen-legacy-backend.h"
#include "hw/xen/xen_pt.h"
#include "chardev/char.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "sysemu/cpus.h"
#include "sysemu/xen.h"
#include "sysemu/runstate.h"
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0a918e8f74..ff295bcb29 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/units.h"
+#include "qemu/accel.h"
#include "sysemu/tcg.h"
#include "qemu-version.h"
#include <machine/trap.h>
@@ -908,8 +909,11 @@ int main(int argc, char **argv)
}
/* init tcg before creating CPUs and to get qemu_host_page_size */
- tcg_exec_init(0);
+ {
+ AccelClass *ac = ACCEL_GET_CLASS(current_accel());
+ ac->init_machine(NULL);
+ }
cpu_type = parse_cpu_option(cpu_model);
cpu = cpu_create(cpu_type);
env = cpu->env_ptr;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index a49e3a6b44..b754504afe 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -6,7 +6,7 @@
#include "exec/memory.h"
#include "sysemu/hostmem.h"
#include "sysemu/blockdev.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "qapi/qapi-types-machine.h"
#include "qemu/module.h"
#include "qom/object.h"
diff --git a/include/sysemu/accel.h b/include/qemu/accel.h
similarity index 95%
rename from include/sysemu/accel.h
rename to include/qemu/accel.h
index e08b8ab8fa..fac4a18703 100644
--- a/include/sysemu/accel.h
+++ b/include/qemu/accel.h
@@ -20,8 +20,8 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
-#ifndef HW_ACCEL_H
-#define HW_ACCEL_H
+#ifndef QEMU_ACCEL_H
+#define QEMU_ACCEL_H
#include "qom/object.h"
#include "exec/hwaddr.h"
@@ -37,8 +37,8 @@ typedef struct AccelClass {
/*< public >*/
const char *name;
-#ifndef CONFIG_USER_ONLY
int (*init_machine)(MachineState *ms);
+#ifndef CONFIG_USER_ONLY
void (*setup_post)(MachineState *ms, AccelState *accel);
bool (*has_memory)(MachineState *ms, AddressSpace *as,
hwaddr start_addr, hwaddr size);
@@ -67,11 +67,13 @@ typedef struct AccelClass {
OBJECT_GET_CLASS(AccelClass, (obj), TYPE_ACCEL)
AccelClass *accel_find(const char *opt_name);
+AccelState *current_accel(void);
+
+#ifndef CONFIG_USER_ONLY
int accel_init_machine(AccelState *accel, MachineState *ms);
/* Called just before os_setup_post (ie just before drop OS privs) */
void accel_setup_post(MachineState *ms);
+#endif /* !CONFIG_USER_ONLY */
-AccelState *current_accel(void);
-
-#endif
+#endif /* QEMU_ACCEL_H */
diff --git a/include/sysemu/hvf.h b/include/sysemu/hvf.h
index f893768df9..c98636bc81 100644
--- a/include/sysemu/hvf.h
+++ b/include/sysemu/hvf.h
@@ -13,7 +13,7 @@
#ifndef HVF_H
#define HVF_H
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "qom/object.h"
#ifdef CONFIG_HVF
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index bb5d5cf497..739682f3c3 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -17,7 +17,7 @@
#include "qemu/queue.h"
#include "hw/core/cpu.h"
#include "exec/memattrs.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "qom/object.h"
#ifdef NEED_CPU_H
diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h
index 65740806da..ccb8869f01 100644
--- a/include/sysemu/kvm_int.h
+++ b/include/sysemu/kvm_int.h
@@ -10,7 +10,7 @@
#define QEMU_KVM_INT_H
#include "exec/memory.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "sysemu/kvm.h"
typedef struct KVMSlot
diff --git a/linux-user/main.c b/linux-user/main.c
index 24d1eb73ad..5c059a8445 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/units.h"
+#include "qemu/accel.h"
#include "sysemu/tcg.h"
#include "qemu-version.h"
#include <sys/syscall.h>
@@ -703,8 +704,11 @@ int main(int argc, char **argv, char **envp)
cpu_type = parse_cpu_option(cpu_model);
/* init tcg before creating CPUs and to get qemu_host_page_size */
- tcg_exec_init(0);
+ {
+ AccelClass *ac = ACCEL_GET_CLASS(current_accel());
+ ac->init_machine(NULL);
+ }
cpu = cpu_create(cpu_type);
env = cpu->env_ptr;
cpu_reset(cpu);
diff --git a/softmmu/memory.c b/softmmu/memory.c
index 11ca94d037..9484ae9503 100644
--- a/softmmu/memory.c
+++ b/softmmu/memory.c
@@ -32,7 +32,7 @@
#include "sysemu/kvm.h"
#include "sysemu/runstate.h"
#include "sysemu/tcg.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "hw/boards.h"
#include "migration/vmstate.h"
diff --git a/softmmu/qtest.c b/softmmu/qtest.c
index 7965dc9a16..130c366615 100644
--- a/softmmu/qtest.c
+++ b/softmmu/qtest.c
@@ -20,7 +20,7 @@
#include "exec/ioport.h"
#include "exec/memory.h"
#include "hw/irq.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "sysemu/cpu-timers.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
diff --git a/softmmu/vl.c b/softmmu/vl.c
index e6e0ad5a92..bc20c526d2 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -40,7 +40,7 @@
#include "qemu/error-report.h"
#include "qemu/sockets.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "hw/usb.h"
#include "hw/isa/isa.h"
#include "hw/scsi/scsi.h"
diff --git a/target/i386/hax/hax-all.c b/target/i386/hax/hax-all.c
index fecfe8cd6e..d7f4bb44a7 100644
--- a/target/i386/hax/hax-all.c
+++ b/target/i386/hax/hax-all.c
@@ -28,7 +28,7 @@
#include "exec/address-spaces.h"
#include "qemu-common.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "hw/boards.h"
diff --git a/target/i386/hvf/hvf-i386.h b/target/i386/hvf/hvf-i386.h
index e0edffd077..50b914fd67 100644
--- a/target/i386/hvf/hvf-i386.h
+++ b/target/i386/hvf/hvf-i386.h
@@ -16,7 +16,7 @@
#ifndef HVF_I386_H
#define HVF_I386_H
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "sysemu/hvf.h"
#include "cpu.h"
#include "x86.h"
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index ed9356565c..ffc9efa40f 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -69,7 +69,7 @@
#include "exec/address-spaces.h"
#include "hw/i386/apic_internal.h"
#include "qemu/main-loop.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "target/i386/cpu.h"
#include "hvf-cpus.h"
diff --git a/target/i386/hvf/x86_task.c b/target/i386/hvf/x86_task.c
index 6f04478b3a..d66dfd7669 100644
--- a/target/i386/hvf/x86_task.c
+++ b/target/i386/hvf/x86_task.c
@@ -28,7 +28,7 @@
#include "hw/i386/apic_internal.h"
#include "qemu/main-loop.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "target/i386/cpu.h"
// TODO: taskswitch handling
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index f4f3e33eac..ee6b606194 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -13,7 +13,7 @@
#include "exec/address-spaces.h"
#include "exec/ioport.h"
#include "qemu-common.h"
-#include "sysemu/accel.h"
+#include "qemu/accel.h"
#include "sysemu/whpx.h"
#include "sysemu/cpus.h"
#include "sysemu/runstate.h"
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 22/27] accel: replace struct CpusAccel with AccelOpsClass
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (20 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 21/27] accel: extend AccelState and AccelClass to user-mode Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 23/27] accel: introduce AccelCPUClass extending CPUClass Claudio Fontana
` (5 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
centralize the registration of the cpus.c module
accelerator operations in accel/accel-softmmu.c
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
MAINTAINERS | 3 ++-
accel/accel-common.c | 11 +++++++++
accel/accel-softmmu.c | 43 +++++++++++++++++++++++++++++++---
accel/accel-softmmu.h | 15 ++++++++++++
accel/kvm/kvm-all.c | 2 --
accel/kvm/kvm-cpus.c | 26 ++++++++++++++++-----
accel/kvm/kvm-cpus.h | 2 --
accel/qtest/qtest.c | 23 +++++++++++++-----
accel/tcg/tcg-all.c | 12 ----------
accel/tcg/tcg-cpus-icount.c | 11 +--------
accel/tcg/tcg-cpus-icount.h | 2 ++
accel/tcg/tcg-cpus-mttcg.c | 12 +++-------
accel/tcg/tcg-cpus-mttcg.h | 19 +++++++++++++++
accel/tcg/tcg-cpus-rr.c | 7 ------
accel/tcg/tcg-cpus.c | 43 ++++++++++++++++++++++++++++++++++
accel/tcg/tcg-cpus.h | 4 ----
accel/xen/xen-all.c | 22 ++++++++++++------
bsd-user/main.c | 3 ++-
include/qemu/accel.h | 2 ++
include/sysemu/accel-ops.h | 45 ++++++++++++++++++++++++++++++++++++
include/sysemu/cpus.h | 26 ++++-----------------
linux-user/main.c | 1 +
softmmu/cpus.c | 12 +++++-----
softmmu/vl.c | 6 +++--
target/i386/hax/hax-all.c | 3 ---
target/i386/hax/hax-cpus.c | 29 +++++++++++++++++------
target/i386/hax/hax-cpus.h | 2 --
target/i386/hvf/hvf-cpus.c | 27 +++++++++++++++++-----
target/i386/hvf/hvf-cpus.h | 2 --
target/i386/hvf/hvf.c | 1 -
target/i386/whpx/whpx-all.c | 2 --
target/i386/whpx/whpx-cpus.c | 29 +++++++++++++++++------
target/i386/whpx/whpx-cpus.h | 2 --
33 files changed, 318 insertions(+), 131 deletions(-)
create mode 100644 accel/accel-softmmu.h
create mode 100644 accel/tcg/tcg-cpus-mttcg.h
create mode 100644 include/sysemu/accel-ops.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 6235dd3a9f..8f0e773a47 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -435,7 +435,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
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..2d15d3f2f4 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,40 @@ 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..2877b5c234
--- /dev/null
+++ b/accel/accel-softmmu.h
@@ -0,0 +1,15 @@
+/*
+ * QEMU System Emulation accel internal functions
+ *
+ * Copyright 2020 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-all.c b/accel/kvm/kvm-all.c
index baaa54249d..18be3cd113 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2253,8 +2253,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.c b/accel/kvm/kvm-cpus.c
index d809b1e74c..fc9dda46ae 100644
--- a/accel/kvm/kvm-cpus.c
+++ b/accel/kvm/kvm-cpus.c
@@ -74,11 +74,25 @@ 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_cpus_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_cpus_type_info = {
+ .name = ACCEL_OPS_NAME("kvm"),
+
+ .parent = TYPE_ACCEL_OPS,
+ .class_init = kvm_cpus_class_init,
+ .abstract = true,
+};
+static void kvm_cpus_register_types(void)
+{
+ type_register_static(&kvm_cpus_type_info);
+}
+type_init(kvm_cpus_register_types);
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/qtest/qtest.c b/accel/qtest/qtest.c
index b4e731cb2b..68d86de30f 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_cpus_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_cpus_type_info = {
+ .name = ACCEL_OPS_NAME("qtest"),
+
+ .parent = TYPE_ACCEL_OPS,
+ .class_init = qtest_cpus_class_init,
+ .abstract = true,
+};
+
static void qtest_type_init(void)
{
type_register_static(&qtest_accel_type);
+ type_register_static(&qtest_cpus_type_info);
}
type_init(qtest_type_init);
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 7125d0cc29..f0d97b4b21 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;
@@ -116,14 +112,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/tcg/tcg-cpus-icount.c b/accel/tcg/tcg-cpus-icount.c
index 9f45432275..5445b4d545 100644
--- a/accel/tcg/tcg-cpus-icount.c
+++ b/accel/tcg/tcg-cpus-icount.c
@@ -125,7 +125,7 @@ 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;
@@ -136,12 +136,3 @@ static void icount_handle_interrupt(CPUState *cpu, int mask)
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-cpus-icount.h
index b695939dfa..d884aa2aaa 100644
--- a/accel/tcg/tcg-cpus-icount.h
+++ b/accel/tcg/tcg-cpus-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-cpus-mttcg.c
index 9c3767d260..dabf5ed42e 100644
--- a/accel/tcg/tcg-cpus-mttcg.c
+++ b/accel/tcg/tcg-cpus-mttcg.c
@@ -33,6 +33,7 @@
#include "hw/boards.h"
#include "tcg-cpus.h"
+#include "tcg-cpus-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-cpus-mttcg.h b/accel/tcg/tcg-cpus-mttcg.h
new file mode 100644
index 0000000000..0af91dd3b3
--- /dev/null
+++ b/accel/tcg/tcg-cpus-mttcg.h
@@ -0,0 +1,19 @@
+/*
+ * QEMU TCG Multi Threaded vCPUs implementation
+ *
+ * Copyright 2020 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-cpus-rr.c
index 0181d2e4eb..802c57bb60 100644
--- a/accel/tcg/tcg-cpus-rr.c
+++ b/accel/tcg/tcg-cpus-rr.c
@@ -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.c b/accel/tcg/tcg-cpus.c
index e335f9f155..38a58ab271 100644
--- a/accel/tcg/tcg-cpus.c
+++ b/accel/tcg/tcg-cpus.c
@@ -35,6 +35,9 @@
#include "hw/boards.h"
#include "tcg-cpus.h"
+#include "tcg-cpus-mttcg.h"
+#include "tcg-cpus-rr.h"
+#include "tcg-cpus-icount.h"
/* common functionality among all TCG variants */
@@ -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_cpus_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_cpus_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_cpus_handle_interrupt;
+ }
+}
+
+static void tcg_cpus_class_init(ObjectClass *oc, void *data)
+{
+ AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
+
+ ops->ops_init = tcg_cpus_ops_init;
+};
+static const TypeInfo tcg_cpus_type_info = {
+ .name = ACCEL_OPS_NAME("tcg"),
+
+ .parent = TYPE_ACCEL_OPS,
+ .class_init = tcg_cpus_class_init,
+ .abstract = true,
+};
+static void tcg_cpus_register_types(void)
+{
+ type_register_static(&tcg_cpus_type_info);
+}
+type_init(tcg_cpus_register_types);
diff --git a/accel/tcg/tcg-cpus.h b/accel/tcg/tcg-cpus.h
index d6893a32f8..923cbace12 100644
--- a/accel/tcg/tcg-cpus.h
+++ b/accel/tcg/tcg-cpus.h
@@ -14,10 +14,6 @@
#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);
diff --git a/accel/xen/xen-all.c b/accel/xen/xen-all.c
index 594aaf6b49..cd5aa2b96e 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_cpus_class_init(ObjectClass *oc, void *data)
+{
+ AccelOpsClass *ops = ACCEL_OPS_CLASS(oc);
+
+ ops->create_vcpu_thread = dummy_start_vcpu_thread;
+};
+static const TypeInfo xen_cpus_type_info = {
+ .name = ACCEL_OPS_NAME("xen"),
+
+ .parent = TYPE_ACCEL_OPS,
+ .class_init = xen_cpus_class_init,
+ .abstract = true,
+};
+
static void xen_type_init(void)
{
type_register_static(&xen_accel_type);
+ type_register_static(&xen_cpus_type_info);
}
type_init(xen_type_init);
diff --git a/bsd-user/main.c b/bsd-user/main.c
index ff295bcb29..a68ce5f446 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -908,13 +908,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)
diff --git a/include/qemu/accel.h b/include/qemu/accel.h
index fac4a18703..b9d6d69eb8 100644
--- a/include/qemu/accel.h
+++ b/include/qemu/accel.h
@@ -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);
diff --git a/include/sysemu/accel-ops.h b/include/sysemu/accel-ops.h
new file mode 100644
index 0000000000..6102d2f80d
--- /dev/null
+++ b/include/sysemu/accel-ops.h
@@ -0,0 +1,45 @@
+/*
+ * Accelerator OPS, used for cpus.c module
+ *
+ * Copyright 2020 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 */
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index e8156728c6..2cd74392e0 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -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 */
diff --git a/linux-user/main.c b/linux-user/main.c
index 5c059a8445..e28d016c6f 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -708,6 +708,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;
diff --git a/softmmu/cpus.c b/softmmu/cpus.c
index e46ac68ad0..659617e7ef 100644
--- a/softmmu/cpus.c
+++ b/softmmu/cpus.c
@@ -127,7 +127,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)
{
@@ -593,11 +593,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)
@@ -617,7 +617,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);
diff --git a/softmmu/vl.c b/softmmu/vl.c
index bc20c526d2..b97708300e 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -2558,7 +2558,7 @@ static bool object_create_initial(const char *type, QemuOpts *opts)
}
/* Memory allocation by backends needs to be done
- * after configure_accelerator() (due to the tcg_enabled()
+ * after do_configure_accelerator() (due to the tcg_enabled()
* checks at memory_region_init_*()).
*
* Also, allocation of large amounts of memory may delay
@@ -4186,7 +4186,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().
*/
if (!qtest_enabled() && machine_class->deprecation_reason) {
@@ -4321,6 +4321,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));
if (current_machine->ram_memdev_id) {
Object *backend;
diff --git a/target/i386/hax/hax-all.c b/target/i386/hax/hax-all.c
index d7f4bb44a7..ec3c426223 100644
--- a/target/i386/hax/hax-all.c
+++ b/target/i386/hax/hax-all.c
@@ -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;
}
diff --git a/target/i386/hax/hax-cpus.c b/target/i386/hax/hax-cpus.c
index f72c85bd49..2f8424388d 100644
--- a/target/i386/hax/hax-cpus.c
+++ b/target/i386/hax/hax-cpus.c
@@ -74,12 +74,27 @@ 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_cpus_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_cpus_type_info = {
+ .name = ACCEL_OPS_NAME("hax"),
+
+ .parent = TYPE_ACCEL_OPS,
+ .class_init = hax_cpus_class_init,
+ .abstract = true,
};
+static void hax_cpus_register_types(void)
+{
+ type_register_static(&hax_cpus_type_info);
+}
+type_init(hax_cpus_register_types);
diff --git a/target/i386/hax/hax-cpus.h b/target/i386/hax/hax-cpus.h
index ee8ab7a631..c7698519cd 100644
--- a/target/i386/hax/hax-cpus.h
+++ b/target/i386/hax/hax-cpus.h
@@ -12,8 +12,6 @@
#include "sysemu/cpus.h"
-extern const CpusAccel hax_cpus;
-
#include "hax-interface.h"
#include "hax-i386.h"
diff --git a/target/i386/hvf/hvf-cpus.c b/target/i386/hvf/hvf-cpus.c
index 817b3d7452..dd022a84c4 100644
--- a/target/i386/hvf/hvf-cpus.c
+++ b/target/i386/hvf/hvf-cpus.c
@@ -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_cpus_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_cpus_type_info = {
+ .name = ACCEL_OPS_NAME("hvf"),
+
+ .parent = TYPE_ACCEL_OPS,
+ .class_init = hvf_cpus_class_init,
+ .abstract = true,
};
+static void hvf_cpus_register_types(void)
+{
+ type_register_static(&hvf_cpus_type_info);
+}
+type_init(hvf_cpus_register_types);
diff --git a/target/i386/hvf/hvf-cpus.h b/target/i386/hvf/hvf-cpus.h
index ced31b82c0..8f992da168 100644
--- a/target/i386/hvf/hvf-cpus.h
+++ b/target/i386/hvf/hvf-cpus.h
@@ -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 *);
diff --git a/target/i386/hvf/hvf.c b/target/i386/hvf/hvf.c
index ffc9efa40f..bd94bb5243 100644
--- a/target/i386/hvf/hvf.c
+++ b/target/i386/hvf/hvf.c
@@ -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;
}
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index ee6b606194..90adae9af7 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -1642,8 +1642,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;
diff --git a/target/i386/whpx/whpx-cpus.c b/target/i386/whpx/whpx-cpus.c
index d9bd5a2d36..8e82974de7 100644
--- a/target/i386/whpx/whpx-cpus.c
+++ b/target/i386/whpx/whpx-cpus.c
@@ -85,12 +85,27 @@ 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_cpus_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_cpus_type_info = {
+ .name = ACCEL_OPS_NAME("whpx"),
+
+ .parent = TYPE_ACCEL_OPS,
+ .class_init = whpx_cpus_class_init,
+ .abstract = true,
};
+static void whpx_cpus_register_types(void)
+{
+ type_register_static(&whpx_cpus_type_info);
+}
+type_init(whpx_cpus_register_types);
diff --git a/target/i386/whpx/whpx-cpus.h b/target/i386/whpx/whpx-cpus.h
index bdb367d1d0..2dee6d61ea 100644
--- a/target/i386/whpx/whpx-cpus.h
+++ b/target/i386/whpx/whpx-cpus.h
@@ -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);
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 23/27] accel: introduce AccelCPUClass extending CPUClass
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (21 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 22/27] accel: replace struct CpusAccel with AccelOpsClass Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 24/27] i386: split cpu accelerators from cpu.c, using AccelCPUClass Claudio Fontana
` (4 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
add a new optional interface to CPUClass,
which allows accelerators to extend the CPUClass
with additional accelerator-specific initializations.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
MAINTAINERS | 1 +
accel/accel-common.c | 44 +++++++++++++++++++++++++++++++++++++
include/hw/core/accel-cpu.h | 25 +++++++++++++++++++++
include/hw/core/cpu.h | 13 +++++++++++
4 files changed, 83 insertions(+)
create mode 100644 include/hw/core/accel-cpu.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 8f0e773a47..f084d73f6b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -436,6 +436,7 @@ R: Paolo Bonzini <pbonzini@redhat.com>
S: Maintained
F: include/qemu/accel.h
F: include/sysemu/accel-ops.h
+F: include/hw/core/accel-cpu.h
F: accel/accel-*.c
F: accel/Makefile.objs
F: accel/stubs/Makefile.objs
diff --git a/accel/accel-common.c b/accel/accel-common.c
index 6b59873419..ef73c761fc 100644
--- a/accel/accel-common.c
+++ b/accel/accel-common.c
@@ -26,6 +26,9 @@
#include "qemu/osdep.h"
#include "qemu/accel.h"
+#include "cpu.h"
+#include "hw/core/accel-cpu.h"
+
#ifndef CONFIG_USER_ONLY
#include "accel-softmmu.h"
#endif /* !CONFIG_USER_ONLY */
@@ -46,16 +49,57 @@ AccelClass *accel_find(const char *opt_name)
return ac;
}
+static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque)
+{
+ CPUClass *cc = CPU_CLASS(klass);
+ AccelCPUClass *accel_cpu_interface = opaque;
+
+ cc->accel_cpu_interface = accel_cpu_interface;
+ if (accel_cpu_interface->cpu_class_init) {
+ accel_cpu_interface->cpu_class_init(cc);
+ }
+}
+
+/* initialize the arch-specific accel CpuClass interfaces */
+static void accel_init_cpu_interfaces(AccelClass *ac)
+{
+ const char *ac_name; /* AccelClass name */
+ char *acc_name; /* AccelCPUClass name */
+ ObjectClass *acc; /* AccelCPUClass */
+
+ ac_name = object_class_get_name(OBJECT_CLASS(ac));
+ g_assert(ac_name != NULL);
+
+ acc_name = g_strdup_printf("%s-%s", ac_name, CPU_RESOLVING_TYPE);
+ acc = object_class_by_name(acc_name);
+ g_free(acc_name);
+
+ if (acc) {
+ object_class_foreach(accel_init_cpu_int_aux,
+ CPU_RESOLVING_TYPE, false, acc);
+ }
+}
+
void accel_init_interfaces(AccelClass *ac)
{
#ifndef CONFIG_USER_ONLY
accel_init_ops_interfaces(ac);
#endif /* !CONFIG_USER_ONLY */
+
+ accel_init_cpu_interfaces(ac);
}
+static const TypeInfo accel_cpu_type = {
+ .name = TYPE_ACCEL_CPU,
+ .parent = TYPE_OBJECT,
+ .abstract = true,
+ .class_size = sizeof(AccelCPUClass),
+};
+
static void register_accel_types(void)
{
type_register_static(&accel_type);
+ type_register_static(&accel_cpu_type);
}
type_init(register_accel_types);
diff --git a/include/hw/core/accel-cpu.h b/include/hw/core/accel-cpu.h
new file mode 100644
index 0000000000..dce08a9100
--- /dev/null
+++ b/include/hw/core/accel-cpu.h
@@ -0,0 +1,25 @@
+/*
+ * Accelerator interface, specializes CPUClass
+ *
+ * Copyright 2020 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_CPU_H
+#define ACCEL_CPU_H
+
+/*
+ * these defines cannot be in cpu.h, because we are using
+ * CPU_RESOLVING_TYPE here.
+ * Use this header to define your accelerator-specific
+ * cpu-specific accelerator interfaces.
+ */
+
+#define TYPE_ACCEL_CPU "accel-" CPU_RESOLVING_TYPE
+#define ACCEL_CPU_NAME(name) (name "-" TYPE_ACCEL_CPU)
+typedef struct AccelCPUClass AccelCPUClass;
+DECLARE_CLASS_CHECKERS(AccelCPUClass, ACCEL_CPU, TYPE_ACCEL_CPU)
+
+#endif /* ACCEL_CPU_H */
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index f438abb785..fee3a68194 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -76,6 +76,17 @@ typedef struct CPUWatchpoint CPUWatchpoint;
struct TranslationBlock;
+/* see also accel-cpu.h */
+typedef struct AccelCPUClass {
+ /*< private >*/
+ ObjectClass parent_class;
+ /*< public >*/
+
+ void (*cpu_class_init)(CPUClass *cc);
+ void (*cpu_instance_init)(CPUState *cpu);
+ void (*cpu_realizefn)(CPUState *cpu, Error **errp);
+} AccelCPUClass;
+
#ifdef CONFIG_TCG
#include "tcg-cpu-ops.h"
#endif /* CONFIG_TCG */
@@ -209,6 +220,8 @@ struct CPUClass {
#ifdef CONFIG_TCG
TcgCpuOperations tcg_ops;
#endif /* CONFIG_TCG */
+
+ AccelCPUClass *accel_cpu_interface;
};
/*
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 24/27] i386: split cpu accelerators from cpu.c, using AccelCPUClass
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (22 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 23/27] accel: introduce AccelCPUClass extending CPUClass Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 25/27] cpu: call AccelCPUClass::cpu_realizefn in cpu_exec_realizefn Claudio Fontana
` (3 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
i386 is the first user of AccelCPUClass, allowing to split
cpu.c into:
cpu.c cpuid and common x86 cpu functionality
host-cpu.c host x86 cpu functions and "host" cpu type
kvm/cpu.c KVM x86 AccelCPUClass
hvf/cpu.c HVF x86 AccelCPUClass
tcg/cpu.c TCG x86 AccelCPUClass
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
MAINTAINERS | 2 +-
hw/i386/pc_piix.c | 1 +
target/i386/cpu.c | 386 ++++--------------------------------
target/i386/cpu.h | 20 +-
target/i386/host-cpu.c | 198 ++++++++++++++++++
target/i386/host-cpu.h | 19 ++
target/i386/hvf/cpu.c | 65 ++++++
target/i386/hvf/meson.build | 1 +
target/i386/kvm/cpu.c | 148 ++++++++++++++
target/i386/kvm/kvm-cpu.h | 41 ++++
target/i386/kvm/kvm.c | 3 +-
target/i386/kvm/meson.build | 7 +-
target/i386/meson.build | 8 +-
target/i386/tcg-cpu.c | 71 -------
target/i386/tcg-cpu.h | 15 --
target/i386/tcg/cpu.c | 173 ++++++++++++++++
target/i386/tcg/meson.build | 3 +-
17 files changed, 711 insertions(+), 450 deletions(-)
create mode 100644 target/i386/host-cpu.c
create mode 100644 target/i386/host-cpu.h
create mode 100644 target/i386/hvf/cpu.c
create mode 100644 target/i386/kvm/cpu.c
create mode 100644 target/i386/kvm/kvm-cpu.h
delete mode 100644 target/i386/tcg-cpu.c
delete mode 100644 target/i386/tcg-cpu.h
create mode 100644 target/i386/tcg/cpu.c
diff --git a/MAINTAINERS b/MAINTAINERS
index f084d73f6b..4f3f1e8b18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -337,7 +337,7 @@ M: Paolo Bonzini <pbonzini@redhat.com>
M: Richard Henderson <richard.henderson@linaro.org>
M: Eduardo Habkost <ehabkost@redhat.com>
S: Maintained
-F: target/i386/
+F: target/i386/tcg/
F: tests/tcg/i386/
F: tests/tcg/x86_64/
F: hw/i386/
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 13d1628f13..d3f013f3a1 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -64,6 +64,7 @@
#include "hw/hyperv/vmbus-bridge.h"
#include "hw/mem/nvdimm.h"
#include "hw/i386/acpi-build.h"
+#include "kvm/kvm-cpu.h"
#define MAX_IDE_BUS 2
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 3462d0143f..27fba3b003 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -22,37 +22,24 @@
#include "qemu/cutils.h"
#include "qemu/bitops.h"
#include "qemu/qemu-print.h"
-
#include "cpu.h"
-#include "tcg-cpu.h"
#include "helper-tcg.h"
#include "exec/exec-all.h"
#include "sysemu/kvm.h"
#include "sysemu/reset.h"
#include "sysemu/hvf.h"
-#include "sysemu/cpus.h"
+#include "hw/core/accel-cpu.h"
#include "sysemu/xen.h"
#include "kvm/kvm_i386.h"
#include "sev_i386.h"
-
-#include "qemu/error-report.h"
#include "qemu/module.h"
-#include "qemu/option.h"
-#include "qemu/config-file.h"
-#include "qapi/error.h"
#include "qapi/qapi-visit-machine.h"
#include "qapi/qapi-visit-run-state.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qerror.h"
-#include "qapi/visitor.h"
#include "qom/qom-qobject.h"
-#include "sysemu/arch_init.h"
#include "qapi/qapi-commands-machine-target.h"
-
#include "standard-headers/asm-x86/kvm_para.h"
-
-#include "sysemu/sysemu.h"
-#include "sysemu/tcg.h"
#include "hw/qdev-properties.h"
#include "hw/i386/topology.h"
#ifndef CONFIG_USER_ONLY
@@ -594,8 +581,8 @@ static CPUCacheInfo legacy_l3_cache = {
#define INTEL_PT_CYCLE_BITMAP 0x1fff /* Support 0,2^(0~11) */
#define INTEL_PT_PSB_BITMAP (0x003f << 16) /* Support 2K,4K,8K,16K,32K,64K */
-static void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
- uint32_t vendor2, uint32_t vendor3)
+void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
+ uint32_t vendor2, uint32_t vendor3)
{
int i;
for (i = 0; i < 4; i++) {
@@ -1563,25 +1550,6 @@ void host_cpuid(uint32_t function, uint32_t count,
*edx = vec[3];
}
-void host_vendor_fms(char *vendor, int *family, int *model, int *stepping)
-{
- uint32_t eax, ebx, ecx, edx;
-
- host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
- x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
-
- host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
- if (family) {
- *family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
- }
- if (model) {
- *model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
- }
- if (stepping) {
- *stepping = eax & 0x0F;
- }
-}
-
/* CPU class name definitions: */
/* Return type name for a given CPU model name
@@ -1606,10 +1574,6 @@ static char *x86_cpu_class_get_model_name(X86CPUClass *cc)
strlen(class_name) - strlen(X86_CPU_TYPE_SUFFIX));
}
-typedef struct PropValue {
- const char *prop, *value;
-} PropValue;
-
typedef struct X86CPUVersionDefinition {
X86CPUVersion version;
const char *alias;
@@ -4106,31 +4070,6 @@ static X86CPUDefinition builtin_x86_defs[] = {
},
};
-/* KVM-specific features that are automatically added/removed
- * from all CPU models when KVM is enabled.
- */
-static PropValue kvm_default_props[] = {
- { "kvmclock", "on" },
- { "kvm-nopiodelay", "on" },
- { "kvm-asyncpf", "on" },
- { "kvm-steal-time", "on" },
- { "kvm-pv-eoi", "on" },
- { "kvmclock-stable-bit", "on" },
- { "x2apic", "on" },
- { "acpi", "off" },
- { "monitor", "off" },
- { "svm", "off" },
- { NULL, NULL },
-};
-
-/* TCG-specific defaults that override all CPU models when using TCG
- */
-static PropValue tcg_default_props[] = {
- { "vme", "off" },
- { NULL, NULL },
-};
-
-
/*
* We resolve CPU model aliases using -v1 when using "-machine
* none", but this is just for compatibility while libvirt isn't
@@ -4172,61 +4111,6 @@ static X86CPUVersion x86_cpu_model_resolve_version(const X86CPUModel *model)
return v;
}
-void x86_cpu_change_kvm_default(const char *prop, const char *value)
-{
- PropValue *pv;
- for (pv = kvm_default_props; pv->prop; pv++) {
- if (!strcmp(pv->prop, prop)) {
- pv->value = value;
- break;
- }
- }
-
- /* It is valid to call this function only for properties that
- * are already present in the kvm_default_props table.
- */
- assert(pv->prop);
-}
-
-static bool lmce_supported(void)
-{
- uint64_t mce_cap = 0;
-
-#ifdef CONFIG_KVM
- if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0) {
- return false;
- }
-#endif
-
- return !!(mce_cap & MCG_LMCE_P);
-}
-
-#define CPUID_MODEL_ID_SZ 48
-
-/**
- * cpu_x86_fill_model_id:
- * Get CPUID model ID string from host CPU.
- *
- * @str should have at least CPUID_MODEL_ID_SZ bytes
- *
- * The function does NOT add a null terminator to the string
- * automatically.
- */
-static int cpu_x86_fill_model_id(char *str)
-{
- uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
- int i;
-
- for (i = 0; i < 3; i++) {
- host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
- memcpy(str + i * 16 + 0, &eax, 4);
- memcpy(str + i * 16 + 4, &ebx, 4);
- memcpy(str + i * 16 + 8, &ecx, 4);
- memcpy(str + i * 16 + 12, &edx, 4);
- }
- return 0;
-}
-
static Property max_x86_cpu_properties[] = {
DEFINE_PROP_BOOL("migratable", X86CPU, migratable, true),
DEFINE_PROP_BOOL("host-cache-info", X86CPU, cache_info_passthrough, false),
@@ -4249,61 +4133,25 @@ static void max_x86_cpu_class_init(ObjectClass *oc, void *data)
static void max_x86_cpu_initfn(Object *obj)
{
X86CPU *cpu = X86_CPU(obj);
- CPUX86State *env = &cpu->env;
- KVMState *s = kvm_state;
/* We can't fill the features array here because we don't know yet if
* "migratable" is true or false.
*/
cpu->max_features = true;
-
- if (accel_uses_host_cpuid()) {
- char vendor[CPUID_VENDOR_SZ + 1] = { 0 };
- char model_id[CPUID_MODEL_ID_SZ + 1] = { 0 };
- int family, model, stepping;
-
- host_vendor_fms(vendor, &family, &model, &stepping);
- cpu_x86_fill_model_id(model_id);
-
- object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort);
- object_property_set_int(OBJECT(cpu), "family", family, &error_abort);
- object_property_set_int(OBJECT(cpu), "model", model, &error_abort);
- object_property_set_int(OBJECT(cpu), "stepping", stepping,
- &error_abort);
- object_property_set_str(OBJECT(cpu), "model-id", model_id,
- &error_abort);
-
- if (kvm_enabled()) {
- env->cpuid_min_level =
- kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
- env->cpuid_min_xlevel =
- kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
- env->cpuid_min_xlevel2 =
- kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
- } else {
- env->cpuid_min_level =
- hvf_get_supported_cpuid(0x0, 0, R_EAX);
- env->cpuid_min_xlevel =
- hvf_get_supported_cpuid(0x80000000, 0, R_EAX);
- env->cpuid_min_xlevel2 =
- hvf_get_supported_cpuid(0xC0000000, 0, R_EAX);
- }
-
- if (lmce_supported()) {
- object_property_set_bool(OBJECT(cpu), "lmce", true, &error_abort);
- }
- } else {
- object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD,
- &error_abort);
- object_property_set_int(OBJECT(cpu), "family", 6, &error_abort);
- object_property_set_int(OBJECT(cpu), "model", 6, &error_abort);
- object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort);
- object_property_set_str(OBJECT(cpu), "model-id",
- "QEMU TCG CPU version " QEMU_HW_VERSION,
- &error_abort);
- }
-
object_property_set_bool(OBJECT(cpu), "pmu", true, &error_abort);
+
+ /*
+ * these defaults are used for TCG and all other accelerators
+ * besides KVM and HVF, which overwrite these values
+ */
+ object_property_set_str(OBJECT(cpu), "vendor", CPUID_VENDOR_AMD,
+ &error_abort);
+ object_property_set_int(OBJECT(cpu), "family", 6, &error_abort);
+ object_property_set_int(OBJECT(cpu), "model", 6, &error_abort);
+ object_property_set_int(OBJECT(cpu), "stepping", 3, &error_abort);
+ object_property_set_str(OBJECT(cpu), "model-id",
+ "QEMU TCG CPU version " QEMU_HW_VERSION,
+ &error_abort);
}
static const TypeInfo max_x86_cpu_type_info = {
@@ -4313,31 +4161,6 @@ static const TypeInfo max_x86_cpu_type_info = {
.class_init = max_x86_cpu_class_init,
};
-#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
-static void host_x86_cpu_class_init(ObjectClass *oc, void *data)
-{
- X86CPUClass *xcc = X86_CPU_CLASS(oc);
-
- xcc->host_cpuid_required = true;
- xcc->ordering = 8;
-
-#if defined(CONFIG_KVM)
- xcc->model_description =
- "KVM processor with all supported host features ";
-#elif defined(CONFIG_HVF)
- xcc->model_description =
- "HVF processor with all supported host features ";
-#endif
-}
-
-static const TypeInfo host_x86_cpu_type_info = {
- .name = X86_CPU_TYPE_NAME("host"),
- .parent = X86_CPU_TYPE_NAME("max"),
- .class_init = host_x86_cpu_class_init,
-};
-
-#endif
-
static char *feature_word_description(FeatureWordInfo *f, uint32_t bit)
{
assert(f->type == CPUID_FEATURE_WORD || f->type == MSR_FEATURE_WORD);
@@ -5063,7 +4886,7 @@ static uint64_t x86_cpu_get_supported_feature_word(FeatureWord w,
return r;
}
-static void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
+void x86_cpu_apply_props(X86CPU *cpu, PropValue *props)
{
PropValue *pv;
for (pv = props; pv->prop; pv++) {
@@ -5110,8 +4933,6 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
{
X86CPUDefinition *def = model->cpudef;
CPUX86State *env = &cpu->env;
- const char *vendor;
- char host_vendor[CPUID_VENDOR_SZ + 1];
FeatureWord w;
/*NOTE: any property set by this function should be returned by
@@ -5138,18 +4959,6 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
/* legacy-cache defaults to 'off' if CPU model provides cache info */
cpu->legacy_cache = !def->cache_info;
- /* Special cases not set in the X86CPUDefinition structs: */
- /* TODO: in-kernel irqchip for hvf */
- if (kvm_enabled()) {
- if (!kvm_irqchip_in_kernel()) {
- x86_cpu_change_kvm_default("x2apic", "off");
- }
-
- x86_cpu_apply_props(cpu, kvm_default_props);
- } else if (tcg_enabled()) {
- x86_cpu_apply_props(cpu, tcg_default_props);
- }
-
env->features[FEAT_1_ECX] |= CPUID_EXT_HYPERVISOR;
/* sysenter isn't supported in compatibility mode on AMD,
@@ -5159,15 +4968,12 @@ static void x86_cpu_load_model(X86CPU *cpu, X86CPUModel *model)
* KVM's sysenter/syscall emulation in compatibility mode and
* when doing cross vendor migration
*/
- vendor = def->vendor;
- if (accel_uses_host_cpuid()) {
- uint32_t ebx = 0, ecx = 0, edx = 0;
- host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
- x86_cpu_vendor_words2str(host_vendor, ebx, edx, ecx);
- vendor = host_vendor;
- }
- object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort);
+ /*
+ * vendor property is set here but then overloaded with the
+ * host cpu vendor for KVM and HVF.
+ */
+ object_property_set_str(OBJECT(cpu), "vendor", def->vendor, &error_abort);
x86_cpu_apply_version_props(cpu, model);
@@ -6192,53 +5998,12 @@ static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
apic_mmio_map_once = true;
}
}
-
-static void x86_cpu_machine_done(Notifier *n, void *unused)
-{
- X86CPU *cpu = container_of(n, X86CPU, machine_done);
- MemoryRegion *smram =
- (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
-
- if (smram) {
- cpu->smram = g_new(MemoryRegion, 1);
- memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
- smram, 0, 4 * GiB);
- memory_region_set_enabled(cpu->smram, true);
- memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->smram, 1);
- }
-}
#else
static void x86_cpu_apic_realize(X86CPU *cpu, Error **errp)
{
}
#endif
-/* Note: Only safe for use on x86(-64) hosts */
-static uint32_t x86_host_phys_bits(void)
-{
- uint32_t eax;
- uint32_t host_phys_bits;
-
- host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL);
- if (eax >= 0x80000008) {
- host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL);
- /* Note: According to AMD doc 25481 rev 2.34 they have a field
- * at 23:16 that can specify a maximum physical address bits for
- * the guest that can override this value; but I've not seen
- * anything with that set.
- */
- host_phys_bits = eax & 0xff;
- } else {
- /* It's an odd 64 bit machine that doesn't have the leaf for
- * physical address bits; fall back to 36 that's most older
- * Intel.
- */
- host_phys_bits = 36;
- }
-
- return host_phys_bits;
-}
-
static void x86_cpu_adjust_level(X86CPU *cpu, uint32_t *min, uint32_t value)
{
if (*min < value) {
@@ -6515,33 +6280,22 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
+ CPUClass *cc = CPU_GET_CLASS(cs);
X86CPU *cpu = X86_CPU(dev);
X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
CPUX86State *env = &cpu->env;
Error *local_err = NULL;
static bool ht_warned;
- if (xcc->host_cpuid_required) {
- if (!accel_uses_host_cpuid()) {
- g_autofree char *name = x86_cpu_class_get_model_name(xcc);
- error_setg(&local_err, "CPU model '%s' requires KVM", name);
- goto out;
- }
+ /* The accelerator realizefn needs to be called first. */
+ if (cc->accel_cpu_interface) {
+ cc->accel_cpu_interface->cpu_realizefn(cs, errp);
}
- if (cpu->max_features && accel_uses_host_cpuid()) {
- if (enable_cpu_pm) {
- host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
- &cpu->mwait.ecx, &cpu->mwait.edx);
- env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
- if (kvm_enabled() && kvm_has_waitpkg()) {
- env->features[FEAT_7_0_ECX] |= CPUID_7_0_ECX_WAITPKG;
- }
- }
- if (kvm_enabled() && cpu->ucode_rev == 0) {
- cpu->ucode_rev = kvm_arch_get_supported_msr_feature(kvm_state,
- MSR_IA32_UCODE_REV);
- }
+ if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
+ g_autofree char *name = x86_cpu_class_get_model_name(xcc);
+ error_setg(&local_err, "CPU model '%s' requires KVM or HVF", name);
+ goto out;
}
if (cpu->ucode_rev == 0) {
@@ -6593,39 +6347,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
* consumer AMD devices but nothing else.
*/
if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
- if (accel_uses_host_cpuid()) {
- uint32_t host_phys_bits = x86_host_phys_bits();
- static bool warned;
-
- /* Print a warning if the user set it to a value that's not the
- * host value.
- */
- if (cpu->phys_bits != host_phys_bits && cpu->phys_bits != 0 &&
- !warned) {
- warn_report("Host physical bits (%u)"
- " does not match phys-bits property (%u)",
- host_phys_bits, cpu->phys_bits);
- warned = true;
- }
-
- if (cpu->host_phys_bits) {
- /* The user asked for us to use the host physical bits */
- cpu->phys_bits = host_phys_bits;
- if (cpu->host_phys_bits_limit &&
- cpu->phys_bits > cpu->host_phys_bits_limit) {
- cpu->phys_bits = cpu->host_phys_bits_limit;
- }
- }
-
- if (cpu->phys_bits &&
- (cpu->phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
- cpu->phys_bits < 32)) {
- error_setg(errp, "phys-bits should be between 32 and %u "
- " (but is %u)",
- TARGET_PHYS_ADDR_SPACE_BITS, cpu->phys_bits);
- return;
- }
- } else {
+ if (!accel_uses_host_cpuid()) {
if (cpu->phys_bits && cpu->phys_bits != TCG_PHYS_ADDR_BITS) {
error_setg(errp, "TCG only supports phys-bits=%u",
TCG_PHYS_ADDR_BITS);
@@ -6633,8 +6355,8 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
}
}
/* 0 means it was not explicitly set by the user (or by machine
- * compat_props or by the host code above). In this case, the default
- * is the value used by TCG (40).
+ * compat_props or by the host code in host-cpu.c).
+ * In this case, the default is the value used by TCG (40).
*/
if (cpu->phys_bits == 0) {
cpu->phys_bits = TCG_PHYS_ADDR_BITS;
@@ -6704,33 +6426,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
mce_init(cpu);
-#ifndef CONFIG_USER_ONLY
- if (tcg_enabled()) {
- cpu->cpu_as_mem = g_new(MemoryRegion, 1);
- cpu->cpu_as_root = g_new(MemoryRegion, 1);
-
- /* Outer container... */
- memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
- memory_region_set_enabled(cpu->cpu_as_root, true);
-
- /* ... with two regions inside: normal system memory with low
- * priority, and...
- */
- memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
- get_system_memory(), 0, ~0ull);
- memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
- memory_region_set_enabled(cpu->cpu_as_mem, true);
-
- cs->num_ases = 2;
- cpu_address_space_init(cs, 0, "cpu-memory", cs->memory);
- cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root);
-
- /* ... SMRAM with higher priority, linked from /machine/smram. */
- cpu->machine_done.notify = x86_cpu_machine_done;
- qemu_add_machine_init_done_notifier(&cpu->machine_done);
- }
-#endif
-
qemu_init_vcpu(cs);
/*
@@ -6936,6 +6631,8 @@ static void x86_cpu_initfn(Object *obj)
{
X86CPU *cpu = X86_CPU(obj);
X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
+ CPUClass *cc = CPU_CLASS(xcc);
+
CPUX86State *env = &cpu->env;
FeatureWord w;
@@ -6992,6 +6689,11 @@ static void x86_cpu_initfn(Object *obj)
if (xcc->model) {
x86_cpu_load_model(cpu, xcc->model);
}
+
+ /* if required, do the accelerator-specific cpu initialization */
+ if (cc->accel_cpu_interface) {
+ cc->accel_cpu_interface->cpu_instance_init(CPU(obj));
+ }
}
static int64_t x86_cpu_get_arch_id(CPUState *cs)
@@ -7248,11 +6950,6 @@ static void x86_cpu_common_class_init(ObjectClass *oc, void *data)
cc->class_by_name = x86_cpu_class_by_name;
cc->parse_features = x86_cpu_parse_featurestr;
cc->has_work = x86_cpu_has_work;
-
-#ifdef CONFIG_TCG
- tcg_cpu_common_class_init(cc);
-#endif /* CONFIG_TCG */
-
cc->dump_state = x86_cpu_dump_state;
cc->set_pc = x86_cpu_set_pc;
cc->gdb_read_register = x86_cpu_gdb_read_register;
@@ -7357,9 +7054,6 @@ static void x86_cpu_register_types(void)
}
type_register_static(&max_x86_cpu_type_info);
type_register_static(&x86_base_cpu_type_info);
-#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
- type_register_static(&host_x86_cpu_type_info);
-#endif
}
type_init(x86_cpu_register_types)
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index a0d64613dc..b3e39fc631 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -1905,13 +1905,20 @@ int cpu_x86_signal_handler(int host_signum, void *pinfo,
void *puc);
/* cpu.c */
+void x86_cpu_vendor_words2str(char *dst, uint32_t vendor1,
+ uint32_t vendor2, uint32_t vendor3);
+typedef struct PropValue {
+ const char *prop, *value;
+} PropValue;
+void x86_cpu_apply_props(X86CPU *cpu, PropValue *props);
+
+/* cpu.c other functions (cpuid) */
void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
uint32_t *eax, uint32_t *ebx,
uint32_t *ecx, uint32_t *edx);
void cpu_clear_apic_feature(CPUX86State *env);
void host_cpuid(uint32_t function, uint32_t count,
uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx);
-void host_vendor_fms(char *vendor, int *family, int *model, int *stepping);
/* helper.c */
void x86_cpu_set_a20(X86CPU *cpu, int a20_state);
@@ -2111,17 +2118,6 @@ void cpu_report_tpr_access(CPUX86State *env, TPRAccess access);
void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
TPRAccess access);
-
-/* Change the value of a KVM-specific default
- *
- * If value is NULL, no default will be set and the original
- * value from the CPU model table will be kept.
- *
- * It is valid to call this function only for properties that
- * are already present in the kvm_default_props table.
- */
-void x86_cpu_change_kvm_default(const char *prop, const char *value);
-
/* Special values for X86CPUVersion: */
/* Resolve to latest CPU version */
diff --git a/target/i386/host-cpu.c b/target/i386/host-cpu.c
new file mode 100644
index 0000000000..3ce2bc9a84
--- /dev/null
+++ b/target/i386/host-cpu.c
@@ -0,0 +1,198 @@
+/*
+ * x86 host CPU functions, and "host" cpu type initialization
+ *
+ * Copyright 2020 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.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "host-cpu.h"
+#include "qapi/error.h"
+#include "sysemu/sysemu.h"
+
+/* Note: Only safe for use on x86(-64) hosts */
+static uint32_t host_cpu_phys_bits(void)
+{
+ uint32_t eax;
+ uint32_t host_phys_bits;
+
+ host_cpuid(0x80000000, 0, &eax, NULL, NULL, NULL);
+ if (eax >= 0x80000008) {
+ host_cpuid(0x80000008, 0, &eax, NULL, NULL, NULL);
+ /*
+ * Note: According to AMD doc 25481 rev 2.34 they have a field
+ * at 23:16 that can specify a maximum physical address bits for
+ * the guest that can override this value; but I've not seen
+ * anything with that set.
+ */
+ host_phys_bits = eax & 0xff;
+ } else {
+ /*
+ * It's an odd 64 bit machine that doesn't have the leaf for
+ * physical address bits; fall back to 36 that's most older
+ * Intel.
+ */
+ host_phys_bits = 36;
+ }
+
+ return host_phys_bits;
+}
+
+static void host_cpu_enable_cpu_pm(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+
+ host_cpuid(5, 0, &cpu->mwait.eax, &cpu->mwait.ebx,
+ &cpu->mwait.ecx, &cpu->mwait.edx);
+ env->features[FEAT_1_ECX] |= CPUID_EXT_MONITOR;
+}
+
+static uint32_t host_cpu_adjust_phys_bits(X86CPU *cpu, Error **errp)
+{
+ uint32_t host_phys_bits = host_cpu_phys_bits();
+ uint32_t phys_bits = cpu->phys_bits;
+ static bool warned;
+
+ /*
+ * Print a warning if the user set it to a value that's not the
+ * host value.
+ */
+ if (phys_bits != host_phys_bits && phys_bits != 0 &&
+ !warned) {
+ warn_report("Host physical bits (%u)"
+ " does not match phys-bits property (%u)",
+ host_phys_bits, phys_bits);
+ warned = true;
+ }
+
+ if (cpu->host_phys_bits) {
+ /* The user asked for us to use the host physical bits */
+ phys_bits = host_phys_bits;
+ if (cpu->host_phys_bits_limit &&
+ phys_bits > cpu->host_phys_bits_limit) {
+ phys_bits = cpu->host_phys_bits_limit;
+ }
+ }
+
+ if (phys_bits &&
+ (phys_bits > TARGET_PHYS_ADDR_SPACE_BITS ||
+ phys_bits < 32)) {
+ error_setg(errp, "phys-bits should be between 32 and %u "
+ " (but is %u)",
+ TARGET_PHYS_ADDR_SPACE_BITS, phys_bits);
+ }
+
+ return phys_bits;
+}
+
+void host_cpu_realizefn(CPUState *cs, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ if (cpu->max_features && enable_cpu_pm) {
+ host_cpu_enable_cpu_pm(cpu);
+ }
+ if (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) {
+ cpu->phys_bits = host_cpu_adjust_phys_bits(cpu, errp);
+ }
+}
+
+#define CPUID_MODEL_ID_SZ 48
+/**
+ * cpu_x86_fill_model_id:
+ * Get CPUID model ID string from host CPU.
+ *
+ * @str should have at least CPUID_MODEL_ID_SZ bytes
+ *
+ * The function does NOT add a null terminator to the string
+ * automatically.
+ */
+static int host_cpu_fill_model_id(char *str)
+{
+ uint32_t eax = 0, ebx = 0, ecx = 0, edx = 0;
+ int i;
+
+ for (i = 0; i < 3; i++) {
+ host_cpuid(0x80000002 + i, 0, &eax, &ebx, &ecx, &edx);
+ memcpy(str + i * 16 + 0, &eax, 4);
+ memcpy(str + i * 16 + 4, &ebx, 4);
+ memcpy(str + i * 16 + 8, &ecx, 4);
+ memcpy(str + i * 16 + 12, &edx, 4);
+ }
+ return 0;
+}
+
+void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepping)
+{
+ uint32_t eax, ebx, ecx, edx;
+
+ host_cpuid(0x0, 0, &eax, &ebx, &ecx, &edx);
+ x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
+
+ host_cpuid(0x1, 0, &eax, &ebx, &ecx, &edx);
+ if (family) {
+ *family = ((eax >> 8) & 0x0F) + ((eax >> 20) & 0xFF);
+ }
+ if (model) {
+ *model = ((eax >> 4) & 0x0F) | ((eax & 0xF0000) >> 12);
+ }
+ if (stepping) {
+ *stepping = eax & 0x0F;
+ }
+}
+
+void host_cpu_instance_init(X86CPU *cpu)
+{
+ uint32_t ebx = 0, ecx = 0, edx = 0;
+ char vendor[CPUID_VENDOR_SZ + 1];
+
+ host_cpuid(0, 0, NULL, &ebx, &ecx, &edx);
+ x86_cpu_vendor_words2str(vendor, ebx, edx, ecx);
+
+ object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort);
+}
+
+void host_cpu_max_instance_init(X86CPU *cpu)
+{
+ char vendor[CPUID_VENDOR_SZ + 1] = { 0 };
+ char model_id[CPUID_MODEL_ID_SZ + 1] = { 0 };
+ int family, model, stepping;
+
+ host_cpu_vendor_fms(vendor, &family, &model, &stepping);
+ host_cpu_fill_model_id(model_id);
+
+ object_property_set_str(OBJECT(cpu), "vendor", vendor, &error_abort);
+ object_property_set_int(OBJECT(cpu), "family", family, &error_abort);
+ object_property_set_int(OBJECT(cpu), "model", model, &error_abort);
+ object_property_set_int(OBJECT(cpu), "stepping", stepping,
+ &error_abort);
+ object_property_set_str(OBJECT(cpu), "model-id", model_id,
+ &error_abort);
+}
+
+static void host_cpu_class_init(ObjectClass *oc, void *data)
+{
+ X86CPUClass *xcc = X86_CPU_CLASS(oc);
+
+ xcc->host_cpuid_required = true;
+ xcc->ordering = 8;
+ xcc->model_description =
+ g_strdup_printf("processor with all supported host features ");
+}
+
+static const TypeInfo host_cpu_type_info = {
+ .name = X86_CPU_TYPE_NAME("host"),
+ .parent = X86_CPU_TYPE_NAME("max"),
+ .class_init = host_cpu_class_init,
+};
+
+static void host_cpu_type_init(void)
+{
+ type_register_static(&host_cpu_type_info);
+}
+
+type_init(host_cpu_type_init);
diff --git a/target/i386/host-cpu.h b/target/i386/host-cpu.h
new file mode 100644
index 0000000000..d1f2644422
--- /dev/null
+++ b/target/i386/host-cpu.h
@@ -0,0 +1,19 @@
+/*
+ * x86 host CPU type initialization and host CPU functions
+ *
+ * Copyright 2020 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 HOST_CPU_H
+#define HOST_CPU_H
+
+void host_cpu_instance_init(X86CPU *cpu);
+void host_cpu_max_instance_init(X86CPU *cpu);
+void host_cpu_realizefn(CPUState *cs, Error **errp);
+
+void host_cpu_vendor_fms(char *vendor, int *family, int *model, int *stepping);
+
+#endif /* HOST_CPU_H */
diff --git a/target/i386/hvf/cpu.c b/target/i386/hvf/cpu.c
new file mode 100644
index 0000000000..d6579571f1
--- /dev/null
+++ b/target/i386/hvf/cpu.c
@@ -0,0 +1,65 @@
+/*
+ * x86 HVF CPU type initialization
+ *
+ * Copyright 2020 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.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "host-cpu.h"
+#include "qapi/error.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+#include "sysemu/hvf.h"
+#include "hw/core/accel-cpu.h"
+
+static void hvf_cpu_max_instance_init(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+
+ host_cpu_max_instance_init(cpu);
+
+ env->cpuid_min_level =
+ hvf_get_supported_cpuid(0x0, 0, R_EAX);
+ env->cpuid_min_xlevel =
+ hvf_get_supported_cpuid(0x80000000, 0, R_EAX);
+ env->cpuid_min_xlevel2 =
+ hvf_get_supported_cpuid(0xC0000000, 0, R_EAX);
+}
+
+static void hvf_cpu_instance_init(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ host_cpu_instance_init(cpu);
+
+ /* Special cases not set in the X86CPUDefinition structs: */
+ /* TODO: in-kernel irqchip for hvf */
+
+ if (cpu->max_features) {
+ hvf_cpu_max_instance_init(cpu);
+ }
+}
+
+static void hvf_cpu_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+ acc->cpu_realizefn = host_cpu_realizefn;
+ acc->cpu_instance_init = hvf_cpu_instance_init;
+};
+static const TypeInfo hvf_cpu_accel_type_info = {
+ .name = ACCEL_CPU_NAME("hvf"),
+
+ .parent = TYPE_ACCEL_CPU,
+ .class_init = hvf_cpu_accel_class_init,
+ .abstract = true,
+};
+static void hvf_cpu_accel_register_types(void)
+{
+ type_register_static(&hvf_cpu_accel_type_info);
+}
+type_init(hvf_cpu_accel_register_types);
diff --git a/target/i386/hvf/meson.build b/target/i386/hvf/meson.build
index 409c9a3f14..a7fba5724c 100644
--- a/target/i386/hvf/meson.build
+++ b/target/i386/hvf/meson.build
@@ -10,4 +10,5 @@ i386_softmmu_ss.add(when: [hvf, 'CONFIG_HVF'], if_true: files(
'x86_mmu.c',
'x86_task.c',
'x86hvf.c',
+ 'cpu.c',
))
diff --git a/target/i386/kvm/cpu.c b/target/i386/kvm/cpu.c
new file mode 100644
index 0000000000..adc5120cf6
--- /dev/null
+++ b/target/i386/kvm/cpu.c
@@ -0,0 +1,148 @@
+/*
+ * x86 KVM CPU type initialization
+ *
+ * Copyright 2020 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.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "host-cpu.h"
+#include "kvm-cpu.h"
+#include "qapi/error.h"
+#include "sysemu/sysemu.h"
+#include "hw/boards.h"
+
+#include "kvm_i386.h"
+#include "hw/core/accel-cpu.h"
+
+static void kvm_cpu_realizefn(CPUState *cs, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ /*
+ * The realize order is important, since x86_cpu_realize() checks if
+ * nothing else has been set by the user (or by accelerators) in
+ * cpu->ucode_rev and cpu->phys_bits.
+ *
+ * realize order:
+ * kvm_cpu -> host_cpu -> x86_cpu
+ */
+ if (cpu->max_features) {
+ if (enable_cpu_pm && kvm_has_waitpkg()) {
+ env->features[FEAT_7_0_ECX] |= CPUID_7_0_ECX_WAITPKG;
+ }
+ if (cpu->ucode_rev == 0) {
+ cpu->ucode_rev =
+ kvm_arch_get_supported_msr_feature(kvm_state,
+ MSR_IA32_UCODE_REV);
+ }
+ }
+ host_cpu_realizefn(cs, errp);
+}
+
+/*
+ * KVM-specific features that are automatically added/removed
+ * from all CPU models when KVM is enabled.
+ */
+static PropValue kvm_default_props[] = {
+ { "kvmclock", "on" },
+ { "kvm-nopiodelay", "on" },
+ { "kvm-asyncpf", "on" },
+ { "kvm-steal-time", "on" },
+ { "kvm-pv-eoi", "on" },
+ { "kvmclock-stable-bit", "on" },
+ { "x2apic", "on" },
+ { "acpi", "off" },
+ { "monitor", "off" },
+ { "svm", "off" },
+ { NULL, NULL },
+};
+
+void x86_cpu_change_kvm_default(const char *prop, const char *value)
+{
+ PropValue *pv;
+ for (pv = kvm_default_props; pv->prop; pv++) {
+ if (!strcmp(pv->prop, prop)) {
+ pv->value = value;
+ break;
+ }
+ }
+
+ /*
+ * It is valid to call this function only for properties that
+ * are already present in the kvm_default_props table.
+ */
+ assert(pv->prop);
+}
+
+static bool lmce_supported(void)
+{
+ uint64_t mce_cap = 0;
+
+ if (kvm_ioctl(kvm_state, KVM_X86_GET_MCE_CAP_SUPPORTED, &mce_cap) < 0) {
+ return false;
+ }
+ return !!(mce_cap & MCG_LMCE_P);
+}
+
+static void kvm_cpu_max_instance_init(X86CPU *cpu)
+{
+ CPUX86State *env = &cpu->env;
+ KVMState *s = kvm_state;
+
+ host_cpu_max_instance_init(cpu);
+
+ if (lmce_supported()) {
+ object_property_set_bool(OBJECT(cpu), "lmce", true, &error_abort);
+ }
+
+ env->cpuid_min_level =
+ kvm_arch_get_supported_cpuid(s, 0x0, 0, R_EAX);
+ env->cpuid_min_xlevel =
+ kvm_arch_get_supported_cpuid(s, 0x80000000, 0, R_EAX);
+ env->cpuid_min_xlevel2 =
+ kvm_arch_get_supported_cpuid(s, 0xC0000000, 0, R_EAX);
+}
+
+static void kvm_cpu_instance_init(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ host_cpu_instance_init(cpu);
+
+ if (!kvm_irqchip_in_kernel()) {
+ x86_cpu_change_kvm_default("x2apic", "off");
+ }
+
+ /* Special cases not set in the X86CPUDefinition structs: */
+
+ x86_cpu_apply_props(cpu, kvm_default_props);
+
+ if (cpu->max_features) {
+ kvm_cpu_max_instance_init(cpu);
+ }
+}
+
+static void kvm_cpu_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+ acc->cpu_realizefn = kvm_cpu_realizefn;
+ acc->cpu_instance_init = kvm_cpu_instance_init;
+}
+static const TypeInfo kvm_cpu_accel_type_info = {
+ .name = ACCEL_CPU_NAME("kvm"),
+
+ .parent = TYPE_ACCEL_CPU,
+ .class_init = kvm_cpu_accel_class_init,
+ .abstract = true,
+};
+static void kvm_cpu_accel_register_types(void)
+{
+ type_register_static(&kvm_cpu_accel_type_info);
+}
+type_init(kvm_cpu_accel_register_types);
diff --git a/target/i386/kvm/kvm-cpu.h b/target/i386/kvm/kvm-cpu.h
new file mode 100644
index 0000000000..e858ca21e5
--- /dev/null
+++ b/target/i386/kvm/kvm-cpu.h
@@ -0,0 +1,41 @@
+/*
+ * i386 KVM CPU type and functions
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef KVM_CPU_H
+#define KVM_CPU_H
+
+#ifdef CONFIG_KVM
+/*
+ * Change the value of a KVM-specific default
+ *
+ * If value is NULL, no default will be set and the original
+ * value from the CPU model table will be kept.
+ *
+ * It is valid to call this function only for properties that
+ * are already present in the kvm_default_props table.
+ */
+void x86_cpu_change_kvm_default(const char *prop, const char *value);
+
+#else /* !CONFIG_KVM */
+
+#define x86_cpu_change_kvm_default(a, b)
+
+#endif /* CONFIG_KVM */
+
+#endif /* KVM_CPU_H */
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index a2934dda02..35c86fdba6 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -22,6 +22,7 @@
#include "standard-headers/asm-x86/kvm_para.h"
#include "cpu.h"
+#include "host-cpu.h"
#include "sysemu/sysemu.h"
#include "sysemu/hw_accel.h"
#include "sysemu/kvm_int.h"
@@ -285,7 +286,7 @@ static bool host_tsx_broken(void)
int family, model, stepping;\
char vendor[CPUID_VENDOR_SZ + 1];
- host_vendor_fms(vendor, &family, &model, &stepping);
+ host_cpu_vendor_fms(vendor, &family, &model, &stepping);
/* Check if we are running on a Haswell host known to have broken TSX */
return !strcmp(vendor, CPUID_VENDOR_INTEL) &&
diff --git a/target/i386/kvm/meson.build b/target/i386/kvm/meson.build
index 1d66559187..0bc3724eb3 100644
--- a/target/i386/kvm/meson.build
+++ b/target/i386/kvm/meson.build
@@ -1,3 +1,8 @@
i386_ss.add(when: 'CONFIG_KVM', if_false: files('kvm-stub.c'))
-i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files('kvm.c'))
+
+i386_softmmu_ss.add(when: 'CONFIG_KVM', if_true: files(
+ 'kvm.c',
+ 'cpu.c',
+))
+
i386_softmmu_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c'), if_false: files('hyperv-stub.c'))
diff --git a/target/i386/meson.build b/target/i386/meson.build
index 9c20208e5a..4e6e915e7f 100644
--- a/target/i386/meson.build
+++ b/target/i386/meson.build
@@ -6,8 +6,12 @@ i386_ss.add(files(
'xsave_helper.c',
'cpu-dump.c',
))
-i386_ss.add(when: 'CONFIG_TCG', if_true: files('tcg-cpu.c'))
-i386_ss.add(when: 'CONFIG_SEV', if_true: files('sev.c'), if_false: files('sev-stub.c'))
+
+i386_ss.add(when: 'CONFIG_SEV', if_true: files('host-cpu.c', 'sev.c'), if_false: files('sev-stub.c'))
+
+# x86 cpu type
+i386_ss.add(when: 'CONFIG_KVM', if_true: files('host-cpu.c'))
+i386_ss.add(when: 'CONFIG_HVF', if_true: files('host-cpu.c'))
i386_softmmu_ss = ss.source_set()
i386_softmmu_ss.add(files(
diff --git a/target/i386/tcg-cpu.c b/target/i386/tcg-cpu.c
deleted file mode 100644
index 38ed8bf6d3..0000000000
--- a/target/i386/tcg-cpu.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * i386 TCG cpu class initialization
- *
- * Copyright (c) 2003 Fabrice Bellard
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "qemu/osdep.h"
-#include "cpu.h"
-#include "tcg-cpu.h"
-#include "exec/exec-all.h"
-#include "sysemu/runstate.h"
-#include "helper-tcg.h"
-
-#if !defined(CONFIG_USER_ONLY)
-#include "hw/i386/apic.h"
-#endif
-
-/* Frob eflags into and out of the CPU temporary format. */
-
-static void x86_cpu_exec_enter(CPUState *cs)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
-
- CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
- env->df = 1 - (2 * ((env->eflags >> 10) & 1));
- CC_OP = CC_OP_EFLAGS;
- env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
-}
-
-static void x86_cpu_exec_exit(CPUState *cs)
-{
- X86CPU *cpu = X86_CPU(cs);
- CPUX86State *env = &cpu->env;
-
- env->eflags = cpu_compute_eflags(env);
-}
-
-static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
-{
- X86CPU *cpu = X86_CPU(cs);
-
- cpu->env.eip = tb->pc - tb->cs_base;
-}
-
-void tcg_cpu_common_class_init(CPUClass *cc)
-{
- cc->do_interrupt = x86_cpu_do_interrupt;
- cc->tcg_ops.cpu_exec_interrupt = x86_cpu_exec_interrupt;
- cc->tcg_ops.synchronize_from_tb = x86_cpu_synchronize_from_tb;
- cc->tcg_ops.cpu_exec_enter = x86_cpu_exec_enter;
- cc->tcg_ops.cpu_exec_exit = x86_cpu_exec_exit;
- cc->tcg_ops.initialize = tcg_x86_init;
- cc->tcg_ops.tlb_fill = x86_cpu_tlb_fill;
-#ifndef CONFIG_USER_ONLY
- cc->tcg_ops.debug_excp_handler = breakpoint_handler;
-#endif
-}
diff --git a/target/i386/tcg-cpu.h b/target/i386/tcg-cpu.h
deleted file mode 100644
index 81f02e562e..0000000000
--- a/target/i386/tcg-cpu.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * i386 TCG CPU class initialization
- *
- * Copyright 2020 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_CPU_H
-#define TCG_CPU_H
-
-void tcg_cpu_common_class_init(CPUClass *cc);
-
-#endif /* TCG_CPU_H */
diff --git a/target/i386/tcg/cpu.c b/target/i386/tcg/cpu.c
new file mode 100644
index 0000000000..e9c8b20f0e
--- /dev/null
+++ b/target/i386/tcg/cpu.c
@@ -0,0 +1,173 @@
+/*
+ * i386 TCG cpu class initialization
+ *
+ * Copyright (c) 2003 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "cpu.h"
+#include "helper-tcg.h"
+#include "qemu/accel.h"
+#include "hw/core/accel-cpu.h"
+
+#ifndef CONFIG_USER_ONLY
+#include "sysemu/sysemu.h"
+#include "qemu/units.h"
+#include "exec/address-spaces.h"
+#endif
+
+/* Frob eflags into and out of the CPU temporary format. */
+
+static void x86_cpu_exec_enter(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ CC_SRC = env->eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+ env->df = 1 - (2 * ((env->eflags >> 10) & 1));
+ CC_OP = CC_OP_EFLAGS;
+ env->eflags &= ~(DF_MASK | CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);
+}
+
+static void x86_cpu_exec_exit(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ CPUX86State *env = &cpu->env;
+
+ env->eflags = cpu_compute_eflags(env);
+}
+
+static void x86_cpu_synchronize_from_tb(CPUState *cs, TranslationBlock *tb)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ cpu->env.eip = tb->pc - tb->cs_base;
+}
+
+#ifndef CONFIG_USER_ONLY
+
+static void x86_cpu_machine_done(Notifier *n, void *unused)
+{
+ X86CPU *cpu = container_of(n, X86CPU, machine_done);
+ MemoryRegion *smram =
+ (MemoryRegion *) object_resolve_path("/machine/smram", NULL);
+
+ if (smram) {
+ cpu->smram = g_new(MemoryRegion, 1);
+ memory_region_init_alias(cpu->smram, OBJECT(cpu), "smram",
+ smram, 0, 4 * GiB);
+ memory_region_set_enabled(cpu->smram, true);
+ memory_region_add_subregion_overlap(cpu->cpu_as_root, 0,
+ cpu->smram, 1);
+ }
+}
+
+static void tcg_cpu_realizefn(CPUState *cs, Error **errp)
+{
+ X86CPU *cpu = X86_CPU(cs);
+
+ /*
+ * The realize order is important, since x86_cpu_realize() checks if
+ * nothing else has been set by the user (or by accelerators) in
+ * cpu->ucode_rev and cpu->phys_bits, and the memory regions
+ * initialized here are needed for the vcpu initialization.
+ *
+ * realize order:
+ * tcg_cpu -> host_cpu -> x86_cpu
+ */
+ cpu->cpu_as_mem = g_new(MemoryRegion, 1);
+ cpu->cpu_as_root = g_new(MemoryRegion, 1);
+
+ /* Outer container... */
+ memory_region_init(cpu->cpu_as_root, OBJECT(cpu), "memory", ~0ull);
+ memory_region_set_enabled(cpu->cpu_as_root, true);
+
+ /*
+ * ... with two regions inside: normal system memory with low
+ * priority, and...
+ */
+ memory_region_init_alias(cpu->cpu_as_mem, OBJECT(cpu), "memory",
+ get_system_memory(), 0, ~0ull);
+ memory_region_add_subregion_overlap(cpu->cpu_as_root, 0, cpu->cpu_as_mem, 0);
+ memory_region_set_enabled(cpu->cpu_as_mem, true);
+
+ cs->num_ases = 2;
+ cpu_address_space_init(cs, 0, "cpu-memory", cs->memory);
+ cpu_address_space_init(cs, 1, "cpu-smm", cpu->cpu_as_root);
+
+ /* ... SMRAM with higher priority, linked from /machine/smram. */
+ cpu->machine_done.notify = x86_cpu_machine_done;
+ qemu_add_machine_init_done_notifier(&cpu->machine_done);
+}
+
+#else /* CONFIG_USER_ONLY */
+
+static void tcg_cpu_realizefn(CPUState *cs, Error **errp)
+{
+}
+
+#endif /* !CONFIG_USER_ONLY */
+
+
+static void tcg_cpu_class_init(CPUClass *cc)
+{
+ cc->do_interrupt = x86_cpu_do_interrupt;
+ cc->tcg_ops.cpu_exec_interrupt = x86_cpu_exec_interrupt;
+ cc->tcg_ops.synchronize_from_tb = x86_cpu_synchronize_from_tb;
+ cc->tcg_ops.cpu_exec_enter = x86_cpu_exec_enter;
+ cc->tcg_ops.cpu_exec_exit = x86_cpu_exec_exit;
+ cc->tcg_ops.initialize = tcg_x86_init;
+ cc->tcg_ops.tlb_fill = x86_cpu_tlb_fill;
+#ifndef CONFIG_USER_ONLY
+ cc->tcg_ops.debug_excp_handler = breakpoint_handler;
+#endif /* !CONFIG_USER_ONLY */
+}
+
+/*
+ * TCG-specific defaults that override all CPU models when using TCG
+ */
+static PropValue tcg_default_props[] = {
+ { "vme", "off" },
+ { NULL, NULL },
+};
+
+static void tcg_cpu_instance_init(CPUState *cs)
+{
+ X86CPU *cpu = X86_CPU(cs);
+ /* Special cases not set in the X86CPUDefinition structs: */
+ x86_cpu_apply_props(cpu, tcg_default_props);
+}
+
+static void tcg_cpu_accel_class_init(ObjectClass *oc, void *data)
+{
+ AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
+
+ acc->cpu_realizefn = tcg_cpu_realizefn;
+ acc->cpu_class_init = tcg_cpu_class_init;
+ acc->cpu_instance_init = tcg_cpu_instance_init;
+}
+static const TypeInfo tcg_cpu_accel_type_info = {
+ .name = ACCEL_CPU_NAME("tcg"),
+
+ .parent = TYPE_ACCEL_CPU,
+ .class_init = tcg_cpu_accel_class_init,
+ .abstract = true,
+};
+static void tcg_cpu_accel_register_types(void)
+{
+ type_register_static(&tcg_cpu_accel_type_info);
+}
+type_init(tcg_cpu_accel_register_types);
diff --git a/target/i386/tcg/meson.build b/target/i386/tcg/meson.build
index 02794226c2..9e439df9c7 100644
--- a/target/i386/tcg/meson.build
+++ b/target/i386/tcg/meson.build
@@ -10,4 +10,5 @@ i386_ss.add(when: 'CONFIG_TCG', if_true: files(
'seg_helper.c',
'smm_helper.c',
'svm_helper.c',
- 'translate.c'), if_false: files('tcg-stub.c'))
+ 'translate.c',
+ 'cpu.c'), if_false: files('tcg-stub.c'))
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 25/27] cpu: call AccelCPUClass::cpu_realizefn in cpu_exec_realizefn
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (23 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 24/27] i386: split cpu accelerators from cpu.c, using AccelCPUClass Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 26/27] hw/core/cpu: call qemu_init_vcpu in cpu_common_realizefn Claudio Fontana
` (2 subsequent siblings)
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
move the call to the accel_cpu_interface method to the general
cpu_exec_realizefn from target/i386, so it does not need to be
called for every target explicitly as we enable more targets.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
cpu.c | 5 +++++
target/i386/cpu.c | 15 ++++-----------
2 files changed, 9 insertions(+), 11 deletions(-)
diff --git a/cpu.c b/cpu.c
index 5cc8f181be..a59a909cfe 100644
--- a/cpu.c
+++ b/cpu.c
@@ -130,6 +130,11 @@ void cpu_exec_realizefn(CPUState *cpu, Error **errp)
cpu_list_add(cpu);
+ if (cc->accel_cpu_interface) {
+ /* NB: errp parameter is unused currently */
+ cc->accel_cpu_interface->cpu_realizefn(cpu, errp);
+ }
+
#ifdef CONFIG_TCG
/* NB: errp parameter is unused currently */
if (tcg_enabled()) {
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 27fba3b003..25998c0122 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6280,16 +6280,16 @@ static void x86_cpu_filter_features(X86CPU *cpu, bool verbose)
static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
- CPUClass *cc = CPU_GET_CLASS(cs);
X86CPU *cpu = X86_CPU(dev);
X86CPUClass *xcc = X86_CPU_GET_CLASS(dev);
CPUX86State *env = &cpu->env;
Error *local_err = NULL;
static bool ht_warned;
- /* The accelerator realizefn needs to be called first. */
- if (cc->accel_cpu_interface) {
- cc->accel_cpu_interface->cpu_realizefn(cs, errp);
+ cpu_exec_realizefn(cs, &local_err);
+ if (local_err != NULL) {
+ error_propagate(errp, local_err);
+ return;
}
if (xcc->host_cpuid_required && !accel_uses_host_cpuid()) {
@@ -6405,13 +6405,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
env->cache_info_amd.l3_cache = &legacy_l3_cache;
}
-
- cpu_exec_realizefn(cs, &local_err);
- if (local_err != NULL) {
- error_propagate(errp, local_err);
- return;
- }
-
#ifndef CONFIG_USER_ONLY
MachineState *ms = MACHINE(qdev_get_machine());
qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 26/27] hw/core/cpu: call qemu_init_vcpu in cpu_common_realizefn
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (24 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 25/27] cpu: call AccelCPUClass::cpu_realizefn in cpu_exec_realizefn Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:15 ` [RFC v8 27/27] cpu: introduce cpu_accel_instance_init Claudio Fontana
2020-12-05 16:17 ` [RFC v8 00/22] i386 cleanup Claudio Fontana
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
move the call to qemu_init_vcpu inside cpu_common_realizefn,
so it does not need to be done explicitly in each target cpu.
This makes it a little bit better, but still the way realize
is done continues to be bad; ideally the cpu_list_add would
be done in common_cpu, and in this case we could avoid even
more additional calls in target/xxx/cpu.c,
but this cannot happen because target cpu code, plugins, etc
now all rely on cpu->index, since no particular order was
defined previously, so we are stuck with the freak call order
for the target cpu realizefn.
After this patch the target/xxx/cpu.c realizefn body is now:
void mycpu_realizefn(DeviceState *dev, Error **errp)
{
/* ... */
cpu_exec_realizefn(CPU_STATE(dev), errp);
/* ... anything that needs done pre-qemu_vcpu_init */
xcc->parent_realize(dev, errp); /* does qemu_vcpu_init */
/* ... anything that needs to be done after qemu_vcpu_init */
}
Note: better do some testing for all targets for this.
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
hw/core/cpu.c | 2 ++
target/alpha/cpu.c | 5 +----
target/arm/cpu.c | 4 +---
target/avr/cpu.c | 3 +--
target/cris/cpu.c | 2 --
target/hppa/cpu.c | 1 -
target/i386/cpu.c | 5 +----
target/lm32/cpu.c | 3 ---
target/m68k/cpu.c | 2 --
target/microblaze/cpu.c | 9 +++------
target/mips/cpu.c | 2 --
target/moxie/cpu.c | 4 +---
target/nios2/cpu.c | 4 +---
target/openrisc/cpu.c | 4 +---
target/ppc/translate_init.c.inc | 5 ++---
target/riscv/cpu.c | 8 +++-----
target/rx/cpu.c | 8 +++-----
target/s390x/cpu.c | 3 +--
target/sh4/cpu.c | 2 --
target/sparc/cpu.c | 4 +---
target/tilegx/cpu.c | 2 --
target/tricore/cpu.c | 2 --
target/unicore32/cpu.c | 6 +-----
target/xtensa/cpu.c | 2 --
24 files changed, 23 insertions(+), 69 deletions(-)
diff --git a/hw/core/cpu.c b/hw/core/cpu.c
index 1f04aab16b..f41c009e6c 100644
--- a/hw/core/cpu.c
+++ b/hw/core/cpu.c
@@ -318,6 +318,8 @@ static void cpu_common_realizefn(DeviceState *dev, Error **errp)
CPUState *cpu = CPU(dev);
Object *machine = qdev_get_machine();
+ qemu_init_vcpu(cpu);
+
/* qdev_get_machine() can return something that's not TYPE_MACHINE
* if this is one of the user-only emulators; in that case there's
* no need to check the ignore_memory_transaction_failures board flag.
diff --git a/target/alpha/cpu.c b/target/alpha/cpu.c
index 0369d5a99c..9bec7dcd6b 100644
--- a/target/alpha/cpu.c
+++ b/target/alpha/cpu.c
@@ -56,18 +56,15 @@ static void alpha_cpu_disas_set_info(CPUState *cpu, disassemble_info *info)
static void alpha_cpu_realizefn(DeviceState *dev, Error **errp)
{
- CPUState *cs = CPU(dev);
AlphaCPUClass *acc = ALPHA_CPU_GET_CLASS(dev);
Error *local_err = NULL;
- cpu_exec_realizefn(cs, &local_err);
+ cpu_exec_realizefn(CPU(dev), &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
}
- qemu_init_vcpu(cs);
-
acc->parent_realize(dev, errp);
}
diff --git a/target/arm/cpu.c b/target/arm/cpu.c
index 20cbfaea51..128a8f3e28 100644
--- a/target/arm/cpu.c
+++ b/target/arm/cpu.c
@@ -1857,10 +1857,8 @@ static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
}
}
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
acc->parent_realize(dev, errp);
+ cpu_reset(cs);
}
static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
diff --git a/target/avr/cpu.c b/target/avr/cpu.c
index 699055de7c..d2b10b99d9 100644
--- a/target/avr/cpu.c
+++ b/target/avr/cpu.c
@@ -97,10 +97,9 @@ static void avr_cpu_realizefn(DeviceState *dev, Error **errp)
error_propagate(errp, local_err);
return;
}
- qemu_init_vcpu(cs);
- cpu_reset(cs);
mcc->parent_realize(dev, errp);
+ cpu_reset(cs);
}
static void avr_cpu_set_int(void *opaque, int irq, int level)
diff --git a/target/cris/cpu.c b/target/cris/cpu.c
index 9222717f3e..8402141184 100644
--- a/target/cris/cpu.c
+++ b/target/cris/cpu.c
@@ -135,8 +135,6 @@ static void cris_cpu_realizefn(DeviceState *dev, Error **errp)
}
cpu_reset(cs);
- qemu_init_vcpu(cs);
-
ccc->parent_realize(dev, errp);
}
diff --git a/target/hppa/cpu.c b/target/hppa/cpu.c
index e2d79f954e..472c03e36b 100644
--- a/target/hppa/cpu.c
+++ b/target/hppa/cpu.c
@@ -99,7 +99,6 @@ static void hppa_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
- qemu_init_vcpu(cs);
acc->parent_realize(dev, errp);
#ifndef CONFIG_USER_ONLY
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 25998c0122..aabb8edfe0 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -6419,8 +6419,7 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
mce_init(cpu);
- qemu_init_vcpu(cs);
-
+ xcc->parent_realize(dev, &local_err);
/*
* Most Intel and certain AMD CPUs support hyperthreading. Even though QEMU
* fixes this issue by adjusting CPUID_0000_0001_EBX and CPUID_8000_0008_ECX
@@ -6447,8 +6446,6 @@ static void x86_cpu_realizefn(DeviceState *dev, Error **errp)
}
cpu_reset(cs);
- xcc->parent_realize(dev, &local_err);
-
out:
if (local_err != NULL) {
error_propagate(errp, local_err);
diff --git a/target/lm32/cpu.c b/target/lm32/cpu.c
index bbe1405e32..72d1a51d62 100644
--- a/target/lm32/cpu.c
+++ b/target/lm32/cpu.c
@@ -133,9 +133,6 @@ static void lm32_cpu_realizefn(DeviceState *dev, Error **errp)
}
cpu_reset(cs);
-
- qemu_init_vcpu(cs);
-
lcc->parent_realize(dev, errp);
}
diff --git a/target/m68k/cpu.c b/target/m68k/cpu.c
index bc109faa21..f8ea599c1c 100644
--- a/target/m68k/cpu.c
+++ b/target/m68k/cpu.c
@@ -248,8 +248,6 @@ static void m68k_cpu_realizefn(DeviceState *dev, Error **errp)
m68k_cpu_init_gdb(cpu);
cpu_reset(cs);
- qemu_init_vcpu(cs);
-
mcc->parent_realize(dev, errp);
}
diff --git a/target/microblaze/cpu.c b/target/microblaze/cpu.c
index 6e660a27b8..42cfc214ff 100644
--- a/target/microblaze/cpu.c
+++ b/target/microblaze/cpu.c
@@ -145,15 +145,14 @@ static void mb_disas_set_info(CPUState *cpu, disassemble_info *info)
static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
{
- CPUState *cs = CPU(dev);
MicroBlazeCPUClass *mcc = MICROBLAZE_CPU_GET_CLASS(dev);
- MicroBlazeCPU *cpu = MICROBLAZE_CPU(cs);
+ MicroBlazeCPU *cpu = MICROBLAZE_CPU(dev);
uint8_t version_code = 0;
const char *version;
int i = 0;
Error *local_err = NULL;
- cpu_exec_realizefn(cs, &local_err);
+ cpu_exec_realizefn(CPU(dev), &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
@@ -165,7 +164,7 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
- qemu_init_vcpu(cs);
+ mcc->parent_realize(dev, errp);
version = cpu->cfg.version ? cpu->cfg.version : DEFAULT_CPU_VERSION;
for (i = 0; mb_cpu_lookup[i].name && version; i++) {
@@ -231,8 +230,6 @@ static void mb_cpu_realizefn(DeviceState *dev, Error **errp)
cpu->cfg.mmu_tlb_access = 3;
cpu->cfg.mmu_zones = 16;
cpu->cfg.addr_mask = MAKE_64BIT_MASK(0, cpu->cfg.addr_size);
-
- mcc->parent_realize(dev, errp);
}
static void mb_cpu_initfn(Object *obj)
diff --git a/target/mips/cpu.c b/target/mips/cpu.c
index 1f7573d319..3a457f723b 100644
--- a/target/mips/cpu.c
+++ b/target/mips/cpu.c
@@ -182,8 +182,6 @@ static void mips_cpu_realizefn(DeviceState *dev, Error **errp)
cpu_mips_realize_env(&cpu->env);
cpu_reset(cs);
- qemu_init_vcpu(cs);
-
mcc->parent_realize(dev, errp);
}
diff --git a/target/moxie/cpu.c b/target/moxie/cpu.c
index 1177d092c1..c9a593ecd0 100644
--- a/target/moxie/cpu.c
+++ b/target/moxie/cpu.c
@@ -66,10 +66,8 @@ static void moxie_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
mcc->parent_realize(dev, errp);
+ cpu_reset(cs);
}
static void moxie_cpu_initfn(Object *obj)
diff --git a/target/nios2/cpu.c b/target/nios2/cpu.c
index a96b74b00c..77928ab61a 100644
--- a/target/nios2/cpu.c
+++ b/target/nios2/cpu.c
@@ -92,10 +92,8 @@ static void nios2_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
ncc->parent_realize(dev, errp);
+ cpu_reset(cs);
}
static bool nios2_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
diff --git a/target/openrisc/cpu.c b/target/openrisc/cpu.c
index e6d1c9764b..79485285da 100644
--- a/target/openrisc/cpu.c
+++ b/target/openrisc/cpu.c
@@ -77,10 +77,8 @@ static void openrisc_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
occ->parent_realize(dev, errp);
+ cpu_reset(cs);
}
static void openrisc_cpu_initfn(Object *obj)
diff --git a/target/ppc/translate_init.c.inc b/target/ppc/translate_init.c.inc
index e83000b2fb..3155c2cedc 100644
--- a/target/ppc/translate_init.c.inc
+++ b/target/ppc/translate_init.c.inc
@@ -10093,7 +10093,7 @@ static int ppc_fixup_cpu(PowerPCCPU *cpu)
return 0;
}
-static void ppc_cpu_realize(DeviceState *dev, Error **errp)
+static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
PowerPCCPU *cpu = POWERPC_CPU(dev);
@@ -10143,7 +10143,6 @@ static void ppc_cpu_realize(DeviceState *dev, Error **errp)
gdb_register_coprocessor(cs, gdb_get_spr_reg, gdb_set_spr_reg,
pcc->gdb_num_sprs, "power-spr.xml", 0);
#endif
- qemu_init_vcpu(cs);
pcc->parent_realize(dev, errp);
@@ -10894,7 +10893,7 @@ static void ppc_cpu_class_init(ObjectClass *oc, void *data)
CPUClass *cc = CPU_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
- device_class_set_parent_realize(dc, ppc_cpu_realize,
+ device_class_set_parent_realize(dc, ppc_cpu_realizefn,
&pcc->parent_realize);
device_class_set_parent_unrealize(dc, ppc_cpu_unrealize,
&pcc->parent_unrealize);
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 022b4271d4..77a1dbcb88 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -341,7 +341,7 @@ static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
#endif
}
-static void riscv_cpu_realize(DeviceState *dev, Error **errp)
+static void riscv_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
RISCVCPU *cpu = RISCV_CPU(dev);
@@ -486,10 +486,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
riscv_cpu_register_gdb_regs_for_features(cs);
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
mcc->parent_realize(dev, errp);
+ cpu_reset(cs);
}
static void riscv_cpu_init(Object *obj)
@@ -532,7 +530,7 @@ static void riscv_cpu_class_init(ObjectClass *c, void *data)
CPUClass *cc = CPU_CLASS(c);
DeviceClass *dc = DEVICE_CLASS(c);
- device_class_set_parent_realize(dc, riscv_cpu_realize,
+ device_class_set_parent_realize(dc, riscv_cpu_realizefn,
&mcc->parent_realize);
device_class_set_parent_reset(dc, riscv_cpu_reset, &mcc->parent_reset);
diff --git a/target/rx/cpu.c b/target/rx/cpu.c
index c815533223..07a76405cd 100644
--- a/target/rx/cpu.c
+++ b/target/rx/cpu.c
@@ -105,7 +105,7 @@ static ObjectClass *rx_cpu_class_by_name(const char *cpu_model)
return oc;
}
-static void rx_cpu_realize(DeviceState *dev, Error **errp)
+static void rx_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
RXCPUClass *rcc = RX_CPU_GET_CLASS(dev);
@@ -117,10 +117,8 @@ static void rx_cpu_realize(DeviceState *dev, Error **errp)
return;
}
- qemu_init_vcpu(cs);
- cpu_reset(cs);
-
rcc->parent_realize(dev, errp);
+ cpu_reset(cs);
}
static void rx_cpu_set_irq(void *opaque, int no, int request)
@@ -178,7 +176,7 @@ static void rx_cpu_class_init(ObjectClass *klass, void *data)
CPUClass *cc = CPU_CLASS(klass);
RXCPUClass *rcc = RX_CPU_CLASS(klass);
- device_class_set_parent_realize(dc, rx_cpu_realize,
+ device_class_set_parent_realize(dc, rx_cpu_realizefn,
&rcc->parent_realize);
device_class_set_parent_reset(dc, rx_cpu_reset,
&rcc->parent_reset);
diff --git a/target/s390x/cpu.c b/target/s390x/cpu.c
index 04856076b3..20b87693a1 100644
--- a/target/s390x/cpu.c
+++ b/target/s390x/cpu.c
@@ -232,8 +232,8 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
qemu_register_reset(s390_cpu_machine_reset_cb, cpu);
#endif
s390_cpu_gdb_init(cs);
- qemu_init_vcpu(cs);
+ scc->parent_realize(dev, &err);
/*
* KVM requires the initial CPU reset ioctl to be executed on the target
* CPU thread. CPU hotplug under single-threaded TCG will not work with
@@ -246,7 +246,6 @@ static void s390_cpu_realizefn(DeviceState *dev, Error **errp)
cpu_reset(cs);
}
- scc->parent_realize(dev, &err);
out:
error_propagate(errp, err);
}
diff --git a/target/sh4/cpu.c b/target/sh4/cpu.c
index 7a9019edec..50519e1a61 100644
--- a/target/sh4/cpu.c
+++ b/target/sh4/cpu.c
@@ -185,8 +185,6 @@ static void superh_cpu_realizefn(DeviceState *dev, Error **errp)
}
cpu_reset(cs);
- qemu_init_vcpu(cs);
-
scc->parent_realize(dev, errp);
}
diff --git a/target/sparc/cpu.c b/target/sparc/cpu.c
index 760e0ea92c..f3e628ada9 100644
--- a/target/sparc/cpu.c
+++ b/target/sparc/cpu.c
@@ -738,9 +738,9 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
{
CPUState *cs = CPU(dev);
SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(dev);
- Error *local_err = NULL;
SPARCCPU *cpu = SPARC_CPU(dev);
CPUSPARCState *env = &cpu->env;
+ Error *local_err = NULL;
#if defined(CONFIG_USER_ONLY)
if ((env->def.features & CPU_FEATURE_FLOAT)) {
@@ -768,8 +768,6 @@ static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
return;
}
- qemu_init_vcpu(cs);
-
scc->parent_realize(dev, errp);
}
diff --git a/target/tilegx/cpu.c b/target/tilegx/cpu.c
index 75b3a4bae3..d887eafe47 100644
--- a/target/tilegx/cpu.c
+++ b/target/tilegx/cpu.c
@@ -93,8 +93,6 @@ static void tilegx_cpu_realizefn(DeviceState *dev, Error **errp)
}
cpu_reset(cs);
- qemu_init_vcpu(cs);
-
tcc->parent_realize(dev, errp);
}
diff --git a/target/tricore/cpu.c b/target/tricore/cpu.c
index 89a14f81d7..ac57239f87 100644
--- a/target/tricore/cpu.c
+++ b/target/tricore/cpu.c
@@ -93,8 +93,6 @@ static void tricore_cpu_realizefn(DeviceState *dev, Error **errp)
set_feature(env, TRICORE_FEATURE_13);
}
cpu_reset(cs);
- qemu_init_vcpu(cs);
-
tcc->parent_realize(dev, errp);
}
diff --git a/target/unicore32/cpu.c b/target/unicore32/cpu.c
index a57d315d2f..007564bf59 100644
--- a/target/unicore32/cpu.c
+++ b/target/unicore32/cpu.c
@@ -84,18 +84,14 @@ static void uc32_any_cpu_initfn(Object *obj)
static void uc32_cpu_realizefn(DeviceState *dev, Error **errp)
{
- CPUState *cs = CPU(dev);
UniCore32CPUClass *ucc = UNICORE32_CPU_GET_CLASS(dev);
Error *local_err = NULL;
- cpu_exec_realizefn(cs, &local_err);
+ cpu_exec_realizefn(CPU(dev), &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
return;
}
-
- qemu_init_vcpu(cs);
-
ucc->parent_realize(dev, errp);
}
diff --git a/target/xtensa/cpu.c b/target/xtensa/cpu.c
index b6f13ceb32..94f02cc659 100644
--- a/target/xtensa/cpu.c
+++ b/target/xtensa/cpu.c
@@ -153,8 +153,6 @@ static void xtensa_cpu_realizefn(DeviceState *dev, Error **errp)
cs->gdb_num_regs = xcc->config->gdb_regmap.num_regs;
- qemu_init_vcpu(cs);
-
xcc->parent_realize(dev, errp);
}
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* [RFC v8 27/27] cpu: introduce cpu_accel_instance_init
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (25 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 26/27] hw/core/cpu: call qemu_init_vcpu in cpu_common_realizefn Claudio Fontana
@ 2020-12-05 16:15 ` Claudio Fontana
2020-12-05 16:17 ` [RFC v8 00/22] i386 cleanup Claudio Fontana
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:15 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Claudio Fontana, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota, Colin Xu
centralize the calls to cpu->accel_cpu_interface
Signed-off-by: Claudio Fontana <cfontana@suse.de>
---
hw/core/cpu.c | 9 +++++++++
include/hw/core/cpu.h | 6 ++++++
target/i386/cpu.c | 9 ++-------
3 files changed, 17 insertions(+), 7 deletions(-)
diff --git a/hw/core/cpu.c b/hw/core/cpu.c
index f41c009e6c..873cf5e4ef 100644
--- a/hw/core/cpu.c
+++ b/hw/core/cpu.c
@@ -242,6 +242,15 @@ void cpu_reset(CPUState *cpu)
trace_guest_cpu_reset(cpu);
}
+void cpu_accel_instance_init(CPUState *cpu)
+{
+ CPUClass *cc = CPU_GET_CLASS(cpu);
+
+ if (cc->accel_cpu_interface) {
+ cc->accel_cpu_interface->cpu_instance_init(cpu);
+ }
+}
+
static void cpu_common_reset(DeviceState *dev)
{
CPUState *cpu = CPU(dev);
diff --git a/include/hw/core/cpu.h b/include/hw/core/cpu.h
index fee3a68194..0a09f0dd8b 100644
--- a/include/hw/core/cpu.h
+++ b/include/hw/core/cpu.h
@@ -677,6 +677,12 @@ void cpu_list_remove(CPUState *cpu);
*/
void cpu_reset(CPUState *cpu);
+/**
+ * cpu_accel_instance_init:
+ * @cpu: The CPU that needs to do accel-specific object initializations.
+ */
+void cpu_accel_instance_init(CPUState *cpu);
+
/**
* cpu_class_by_name:
* @typename: The CPU base type.
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index aabb8edfe0..e2f16a1f37 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -28,7 +28,6 @@
#include "sysemu/kvm.h"
#include "sysemu/reset.h"
#include "sysemu/hvf.h"
-#include "hw/core/accel-cpu.h"
#include "sysemu/xen.h"
#include "kvm/kvm_i386.h"
#include "sev_i386.h"
@@ -6621,8 +6620,6 @@ static void x86_cpu_initfn(Object *obj)
{
X86CPU *cpu = X86_CPU(obj);
X86CPUClass *xcc = X86_CPU_GET_CLASS(obj);
- CPUClass *cc = CPU_CLASS(xcc);
-
CPUX86State *env = &cpu->env;
FeatureWord w;
@@ -6680,10 +6677,8 @@ static void x86_cpu_initfn(Object *obj)
x86_cpu_load_model(cpu, xcc->model);
}
- /* if required, do the accelerator-specific cpu initialization */
- if (cc->accel_cpu_interface) {
- cc->accel_cpu_interface->cpu_instance_init(CPU(obj));
- }
+ /* if required, do accelerator-specific cpu initializations */
+ cpu_accel_instance_init(CPU(obj));
}
static int64_t x86_cpu_get_arch_id(CPUState *cs)
--
2.26.2
^ permalink raw reply related [flat|nested] 34+ messages in thread
* Re: [RFC v8 00/22] i386 cleanup
2020-12-05 16:14 [RFC v8 00/22] i386 cleanup Claudio Fontana
` (26 preceding siblings ...)
2020-12-05 16:15 ` [RFC v8 27/27] cpu: introduce cpu_accel_instance_init Claudio Fontana
@ 2020-12-05 16:17 ` Claudio Fontana
27 siblings, 0 replies; 34+ messages in thread
From: Claudio Fontana @ 2020-12-05 16:17 UTC (permalink / raw)
To: Paolo Bonzini, Thomas Huth, Richard Henderson,
Stefano Stabellini, Wenchao Wang, Roman Bolshakov,
Sunil Muthuswamy, Philippe Mathieu-Daudé
Cc: Laurent Vivier, Eduardo Habkost, Paul Durrant, Jason Wang,
Marcelo Tosatti, qemu-devel, Peter Xu, Dario Faggioli,
Cameron Esfahani, haxm-team, Colin Xu, Anthony Perard,
Bruce Rogers, Olaf Hering, Emilio G . Cota
Sorry, new script.
this is of course "v8" of the i386 cleanup:
v7 -> v8: add missing CONFIG_TCGs, fix bugs
* add the prerequisite patches for "3 tcg" at the beginning of the
series for convenience (already reviewed, queued by RH).
* add CONFIG_TCG to TCGCpuOperations and tcg_ops variable use
* reduce the scope of the realizefn refactoring, do not
introduce a separate cpu_accel_realize, and instead use the
existing cpu_exec_realizefn, there is not enough benefit
to introduce a new function.
* fix bugs in user mode due to attempt to move the tcg_region_init()
early, so it could be done just once in tcg_init() for both
softmmu and user mode. Unfortunately it needs to remain deferred
for user mode, as it needs to be done after prologue init and
after the GUEST_BASE has been set.
On 12/5/20 5:14 PM, Claudio Fontana wrote:
> *** BLURB HERE ***
>
> Hi all, this is v7 of the i386 cleanup,
> with the most interesting patches at the end.
>
> v6 -> v7: integrate TCGCpuOperations, refactored cpu_exec_realizefn
>
> * integrate TCGCpuOperations (Eduardo)
>
> Taken some refactoring from Eduardo for Tcg-only operations on
> CPUClass.
>
> * refactored cpu_exec_realizefn
>
> The other main change is a refactoring of cpu_exec_realizefn,
> directly linked to the effort of making many cpu_exec operations
> TCG-only (Eduardo series above):
>
> cpu_exec_realizefn is actually a TCG-only thing, with the
> exception of a couple things that can be done in base cpu code.
>
> This changes all targets realizefn, so I guess I have to Cc:
> the Multiverse? (Universe was already CCed for all accelerators).
>
>
> v5 -> v6: remove MODULE_INIT_ACCEL_CPU
>
>
> instead, use a call to accel_init_interfaces().
>
> * The class lookups are now general and performed in accel/
>
> new AccelCPUClass for new archs are supported as new
> ones appear in the class hierarchy, no need for stubs.
>
> * Split the code a bit better
>
>
> v4 -> v5: centralized and simplified initializations
>
> I put in Cc: Emilio G. Cota, specifically because in patch 8
> I (re)moved for user-mode the call to tcg_regions_init().
>
> The call happens now inside the tcg AccelClass machine_init,
> (so earlier). This seems to work fine, but thought to get the
> author opinion on this.
>
> Rebased on "tcg-cpus: split into 3 tcg variants" series
> (queued by Richard), to avoid some code churn:
>
>
> https://lists.gnu.org/archive/html/qemu-devel/2020-10/msg04356.html
>
>
> * Extended AccelClass to user-mode.
>
> user-mode now does not call tcg_exec_init directly,
> instead it uses the tcg accel class, and its init_machine method.
>
> Since user-mode does not define or use a machine state,
> the machine is just passed as NULL.
>
> The immediate advantage is that now we can call current_accel()
> from both user mode and softmmu, so we can work out the correct
> class to use for accelerator initializations.
>
> * QOMification of CpusAccelOps
>
> simple QOMification of CpusAccelOps abstract class.
>
> * Centralized all accel_cpu_init, so only one per cpu-arch,
> plus one for all accels will remain.
>
> So we can expect accel_cpu_init() to be limited to:
>
> softmmu/cpus.c - initializes the chosen softmmu accel ops for the cpus module.
> target/ARCH/cpu.c - initializes the chosen arch-specific cpu accelerator.
>
> These changes are meant to address concerns/issues (Paolo):
>
> 1) the use of if (tcg_enabled()) and similar in the module_init call path
>
> 2) the excessive number of accel_cpu_init() to hunt down in the codebase.
>
>
> * Fixed wrong use of host_cpu_class_init (Eduardo)
>
>
> v3 -> v4: QOMification of X86CPUAccelClass
>
>
> In this version I basically QOMified X86CPUAccel, taking the
> suggestions from Eduardo as the starting point,
> but stopping just short of making it an actual QOM interface,
> using a plain abstract class, and then subclasses for the
> actual objects.
>
> Initialization is still using the existing qemu initialization
> framework (module_call_init), which is I still think is better
> than the alternatives proposed, in the current state.
>
> Possibly some improvements could be developed in the future here.
> In this case, effort should be put in keeping things extendible,
> in order not to be blocked once accelerators also become modules.
>
> Motivation and higher level steps:
>
> https://lists.gnu.org/archive/html/qemu-devel/2020-05/msg04628.html
>
> Looking forward to your comments on this proposal,
>
> Ciao,
>
> Claudio
>
>
> Claudio Fontana (18):
> accel/tcg: split CpusAccel into three TCG variants
> accel/tcg: split tcg_start_vcpu_thread
> accel/tcg: rename tcg-cpus functions to match module name
> i386: move kvm accel files into kvm/
> i386: move whpx accel files into whpx/
> i386: move hax accel files into hax/
> i386: hvf: remove stale MAINTAINERS entry for old hvf stubs
> i386: move TCG accel files into tcg/
> i386: move cpu dump out of helper.c into cpu-dump.c
> i386: move TCG cpu class initialization out of helper.c
> accel/tcg: split TCG-only code from cpu_exec_realizefn
> accel: extend AccelState and AccelClass to user-mode
> accel: replace struct CpusAccel with AccelOpsClass
> accel: introduce AccelCPUClass extending CPUClass
> i386: split cpu accelerators from cpu.c, using AccelCPUClass
> cpu: call AccelCPUClass::cpu_realizefn in cpu_exec_realizefn
> hw/core/cpu: call qemu_init_vcpu in cpu_common_realizefn
> cpu: introduce cpu_accel_instance_init
>
> Eduardo Habkost (9):
> tcg: cpu_exec_{enter,exit} helpers
> tcg: make CPUClass.cpu_exec_* optional
> tcg: Make CPUClass.debug_excp_handler optional
> cpu: Remove unnecessary noop methods
> cpu: Introduce TCGCpuOperations struct
> cpu: Move synchronize_from_tb() to tcg_ops
> cpu: Move cpu_exec_* to tcg_ops
> cpu: Move tlb_fill to tcg_ops
> cpu: Move debug_excp_handler to tcg_ops
>
> MAINTAINERS | 19 +-
> accel/accel-common.c | 105 +++++
> accel/{accel.c => accel-softmmu.c} | 60 +--
> accel/accel-softmmu.h | 15 +
> accel/accel-user.c | 24 ++
> accel/kvm/kvm-all.c | 2 -
> accel/kvm/kvm-cpus.c | 26 +-
> accel/kvm/kvm-cpus.h | 2 -
> accel/meson.build | 4 +-
> accel/qtest/qtest.c | 25 +-
> accel/tcg/cpu-exec.c | 66 +++-
> accel/tcg/cputlb.c | 6 +-
> accel/tcg/meson.build | 9 +-
> accel/tcg/tcg-all.c | 14 +-
> accel/tcg/tcg-cpus-icount.c | 138 +++++++
> accel/tcg/tcg-cpus-icount.h | 19 +
> accel/tcg/tcg-cpus-mttcg.c | 134 +++++++
> accel/tcg/tcg-cpus-mttcg.h | 19 +
> accel/tcg/tcg-cpus-rr.c | 298 ++++++++++++++
> accel/tcg/tcg-cpus-rr.h | 21 +
> accel/tcg/tcg-cpus.c | 539 +++-----------------------
> accel/tcg/tcg-cpus.h | 8 +-
> accel/tcg/user-exec.c | 6 +-
> accel/xen/xen-all.c | 24 +-
> bsd-user/main.c | 11 +-
> cpu.c | 71 ++--
> hw/core/cpu.c | 30 +-
> hw/i386/fw_cfg.c | 2 +-
> hw/i386/intel_iommu.c | 2 +-
> hw/i386/kvm/apic.c | 2 +-
> hw/i386/kvm/clock.c | 2 +-
> hw/i386/microvm.c | 2 +-
> hw/i386/pc.c | 2 +-
> hw/i386/pc_piix.c | 1 +
> hw/i386/x86.c | 2 +-
> include/hw/boards.h | 2 +-
> include/hw/core/accel-cpu.h | 25 ++
> include/hw/core/cpu.h | 61 +--
> include/hw/core/tcg-cpu-ops.h | 56 +++
> include/{sysemu => qemu}/accel.h | 16 +-
> include/sysemu/accel-ops.h | 45 +++
> include/sysemu/cpus.h | 26 +-
> include/sysemu/hvf.h | 2 +-
> include/sysemu/kvm.h | 2 +-
> include/sysemu/kvm_int.h | 2 +-
> linux-user/main.c | 7 +-
> meson.build | 1 +
> softmmu/cpus.c | 12 +-
> softmmu/icount.c | 2 +-
> softmmu/memory.c | 2 +-
> softmmu/qtest.c | 2 +-
> softmmu/vl.c | 8 +-
> target/alpha/cpu.c | 12 +-
> target/arm/cpu.c | 14 +-
> target/arm/cpu64.c | 5 +-
> target/arm/cpu_tcg.c | 5 +-
> target/avr/cpu.c | 11 +-
> target/cris/cpu.c | 18 +-
> target/hppa/cpu.c | 9 +-
> target/i386/cpu-dump.c | 537 +++++++++++++++++++++++++
> target/i386/cpu.c | 418 ++------------------
> target/i386/cpu.h | 120 +-----
> target/i386/{ => hax}/hax-all.c | 5 +-
> target/i386/{ => hax}/hax-cpus.c | 29 +-
> target/i386/{ => hax}/hax-cpus.h | 2 -
> target/i386/{ => hax}/hax-i386.h | 6 +-
> target/i386/{ => hax}/hax-interface.h | 0
> target/i386/{ => hax}/hax-mem.c | 0
> target/i386/{ => hax}/hax-posix.c | 0
> target/i386/{ => hax}/hax-posix.h | 0
> target/i386/{ => hax}/hax-windows.c | 0
> target/i386/{ => hax}/hax-windows.h | 0
> target/i386/hax/meson.build | 7 +
> target/i386/helper-tcg.h | 112 ++++++
> target/i386/helper.c | 539 +-------------------------
> target/i386/host-cpu.c | 198 ++++++++++
> target/i386/host-cpu.h | 19 +
> target/i386/hvf/cpu.c | 65 ++++
> target/i386/hvf/hvf-cpus.c | 27 +-
> target/i386/hvf/hvf-cpus.h | 2 -
> target/i386/hvf/hvf-i386.h | 2 +-
> target/i386/hvf/hvf.c | 3 +-
> target/i386/hvf/meson.build | 1 +
> target/i386/hvf/x86_task.c | 2 +-
> target/i386/kvm/cpu.c | 148 +++++++
> target/i386/{ => kvm}/hyperv-proto.h | 0
> target/i386/{ => kvm}/hyperv-stub.c | 0
> target/i386/{ => kvm}/hyperv.c | 0
> target/i386/{ => kvm}/hyperv.h | 0
> target/i386/kvm/kvm-cpu.h | 41 ++
> target/i386/{ => kvm}/kvm-stub.c | 0
> target/i386/{ => kvm}/kvm.c | 3 +-
> target/i386/{ => kvm}/kvm_i386.h | 0
> target/i386/kvm/meson.build | 8 +
> target/i386/kvm/trace-events | 7 +
> target/i386/kvm/trace.h | 1 +
> target/i386/machine.c | 4 +-
> target/i386/meson.build | 39 +-
> target/i386/{ => tcg}/bpt_helper.c | 1 +
> target/i386/{ => tcg}/cc_helper.c | 1 +
> target/i386/tcg/cpu.c | 173 +++++++++
> target/i386/{ => tcg}/excp_helper.c | 1 +
> target/i386/{ => tcg}/fpu_helper.c | 33 +-
> target/i386/{ => tcg}/int_helper.c | 1 +
> target/i386/{ => tcg}/mem_helper.c | 1 +
> target/i386/tcg/meson.build | 14 +
> target/i386/{ => tcg}/misc_helper.c | 1 +
> target/i386/{ => tcg}/mpx_helper.c | 1 +
> target/i386/{ => tcg}/seg_helper.c | 1 +
> target/i386/{ => tcg}/smm_helper.c | 2 +
> target/i386/{ => tcg}/svm_helper.c | 1 +
> target/i386/{ => tcg}/tcg-stub.c | 0
> target/i386/{ => tcg}/translate.c | 1 +
> target/i386/trace-events | 6 -
> target/i386/whpx/meson.build | 4 +
> target/i386/{ => whpx}/whp-dispatch.h | 0
> target/i386/{ => whpx}/whpx-all.c | 4 +-
> target/i386/{ => whpx}/whpx-cpus.c | 29 +-
> target/i386/{ => whpx}/whpx-cpus.h | 2 -
> target/lm32/cpu.c | 11 +-
> target/m68k/cpu.c | 8 +-
> target/microblaze/cpu.c | 17 +-
> target/mips/cpu.c | 10 +-
> target/moxie/cpu.c | 8 +-
> target/nios2/cpu.c | 10 +-
> target/openrisc/cpu.c | 10 +-
> target/ppc/translate_init.c.inc | 19 +-
> target/riscv/cpu.c | 16 +-
> target/rx/cpu.c | 16 +-
> target/s390x/cpu.c | 11 +-
> target/sh4/cpu.c | 10 +-
> target/sparc/cpu.c | 12 +-
> target/tilegx/cpu.c | 8 +-
> target/tricore/cpu.c | 8 +-
> target/unicore32/cpu.c | 12 +-
> target/xtensa/cpu.c | 10 +-
> 136 files changed, 2909 insertions(+), 1964 deletions(-)
> create mode 100644 accel/accel-common.c
> rename accel/{accel.c => accel-softmmu.c} (64%)
> create mode 100644 accel/accel-softmmu.h
> create mode 100644 accel/accel-user.c
> create mode 100644 accel/tcg/tcg-cpus-icount.c
> create mode 100644 accel/tcg/tcg-cpus-icount.h
> create mode 100644 accel/tcg/tcg-cpus-mttcg.c
> create mode 100644 accel/tcg/tcg-cpus-mttcg.h
> create mode 100644 accel/tcg/tcg-cpus-rr.c
> create mode 100644 accel/tcg/tcg-cpus-rr.h
> create mode 100644 include/hw/core/accel-cpu.h
> create mode 100644 include/hw/core/tcg-cpu-ops.h
> rename include/{sysemu => qemu}/accel.h (94%)
> create mode 100644 include/sysemu/accel-ops.h
> create mode 100644 target/i386/cpu-dump.c
> rename target/i386/{ => hax}/hax-all.c (99%)
> rename target/i386/{ => hax}/hax-cpus.c (71%)
> rename target/i386/{ => hax}/hax-cpus.h (95%)
> rename target/i386/{ => hax}/hax-i386.h (95%)
> rename target/i386/{ => hax}/hax-interface.h (100%)
> rename target/i386/{ => hax}/hax-mem.c (100%)
> rename target/i386/{ => hax}/hax-posix.c (100%)
> rename target/i386/{ => hax}/hax-posix.h (100%)
> rename target/i386/{ => hax}/hax-windows.c (100%)
> rename target/i386/{ => hax}/hax-windows.h (100%)
> create mode 100644 target/i386/hax/meson.build
> create mode 100644 target/i386/helper-tcg.h
> create mode 100644 target/i386/host-cpu.c
> create mode 100644 target/i386/host-cpu.h
> create mode 100644 target/i386/hvf/cpu.c
> create mode 100644 target/i386/kvm/cpu.c
> rename target/i386/{ => kvm}/hyperv-proto.h (100%)
> rename target/i386/{ => kvm}/hyperv-stub.c (100%)
> rename target/i386/{ => kvm}/hyperv.c (100%)
> rename target/i386/{ => kvm}/hyperv.h (100%)
> create mode 100644 target/i386/kvm/kvm-cpu.h
> rename target/i386/{ => kvm}/kvm-stub.c (100%)
> rename target/i386/{ => kvm}/kvm.c (99%)
> rename target/i386/{ => kvm}/kvm_i386.h (100%)
> create mode 100644 target/i386/kvm/meson.build
> create mode 100644 target/i386/kvm/trace-events
> create mode 100644 target/i386/kvm/trace.h
> rename target/i386/{ => tcg}/bpt_helper.c (99%)
> rename target/i386/{ => tcg}/cc_helper.c (99%)
> create mode 100644 target/i386/tcg/cpu.c
> rename target/i386/{ => tcg}/excp_helper.c (99%)
> rename target/i386/{ => tcg}/fpu_helper.c (99%)
> rename target/i386/{ => tcg}/int_helper.c (99%)
> rename target/i386/{ => tcg}/mem_helper.c (99%)
> create mode 100644 target/i386/tcg/meson.build
> rename target/i386/{ => tcg}/misc_helper.c (99%)
> rename target/i386/{ => tcg}/mpx_helper.c (99%)
> rename target/i386/{ => tcg}/seg_helper.c (99%)
> rename target/i386/{ => tcg}/smm_helper.c (99%)
> rename target/i386/{ => tcg}/svm_helper.c (99%)
> rename target/i386/{ => tcg}/tcg-stub.c (100%)
> rename target/i386/{ => tcg}/translate.c (99%)
> create mode 100644 target/i386/whpx/meson.build
> rename target/i386/{ => whpx}/whp-dispatch.h (100%)
> rename target/i386/{ => whpx}/whpx-all.c (99%)
> rename target/i386/{ => whpx}/whpx-cpus.c (73%)
> rename target/i386/{ => whpx}/whpx-cpus.h (96%)
>
^ permalink raw reply [flat|nested] 34+ messages in thread