aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-03-09 18:53:55 +0000
committerPeter Maydell <peter.maydell@linaro.org>2017-03-09 18:53:55 +0000
commit95b0eca46e03ffa0b20d29d1b3127c291accea39 (patch)
treee1ebe9e961a096afa89cbbe976acf678c009aed1
parentdd4d2578215cd380f40a38028a9904e15b135ef3 (diff)
parent68bf93ce9dc5c84c45a827ce2bd6eab768524e79 (diff)
Merge remote-tracking branch 'remotes/stsquad/tags/pull-mttcg-fixups-090317-1' into staging
Fix-ups for MTTCG regressions for 2.9 This is the same as v3 posted a few days ago except with a few extra Reviewed-by tags added. # gpg: Signature made Thu 09 Mar 2017 10:45:18 GMT # gpg: using RSA key 0xFBD0DB095A9E2A44 # gpg: Good signature from "Alex Bennée (Master Work Key) <alex.bennee@linaro.org>" # Primary key fingerprint: 6685 AE99 E751 67BC AFC8 DF35 FBD0 DB09 5A9E 2A44 * remotes/stsquad/tags/pull-mttcg-fixups-090317-1: hw/intc/arm_gic: modernise the DPRINTF target/arm/helper: make it clear the EC field is also in hex target-i386: defer VMEXIT to do_interrupt target/mips: hold BQL for timer interrupts translate-all: exit cpu_restore_state early if translating target/xtensa: hold BQL for interrupt processing s390x/misc_helper.c: wrap IO instructions in BQL sparc/sparc64: grab BQL before calling cpu_check_irqs cpus.c: add additional error_report when !TARGET_SUPPORT_MTTCG target/i386/cpu.h: declare TCG_GUEST_DEFAULT_MO vl/cpus: be smarter with icount and MTTCG Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--cpus.c11
-rw-r--r--hw/intc/arm_gic.c13
-rw-r--r--hw/sparc/sun4m.c3
-rw-r--r--hw/sparc64/sparc64.c3
-rw-r--r--target/arm/helper.c2
-rw-r--r--target/i386/cpu.h5
-rw-r--r--target/i386/seg_helper.c20
-rw-r--r--target/i386/svm_helper.c22
-rw-r--r--target/mips/op_helper.c21
-rw-r--r--target/s390x/misc_helper.c21
-rw-r--r--target/sparc/int64_helper.c3
-rw-r--r--target/sparc/win_helper.c13
-rw-r--r--target/xtensa/helper.c1
-rw-r--r--target/xtensa/op_helper.c7
-rw-r--r--translate-all.c13
-rw-r--r--vl.c7
16 files changed, 130 insertions, 35 deletions
diff --git a/cpus.c b/cpus.c
index c857ad2957..69e21858b8 100644
--- a/cpus.c
+++ b/cpus.c
@@ -181,10 +181,7 @@ static bool check_tcg_memory_orders_compatible(void)
static bool default_mttcg_enabled(void)
{
- QemuOpts *icount_opts = qemu_find_opts_singleton("icount");
- const char *rr = qemu_opt_get(icount_opts, "rr");
-
- if (rr || TCG_OVERSIZED_GUEST) {
+ if (use_icount || TCG_OVERSIZED_GUEST) {
return false;
} else {
#ifdef TARGET_SUPPORTS_MTTCG
@@ -202,7 +199,13 @@ void qemu_tcg_configure(QemuOpts *opts, Error **errp)
if (strcmp(t, "multi") == 0) {
if (TCG_OVERSIZED_GUEST) {
error_setg(errp, "No MTTCG when guest word size > hosts");
+ } else if (use_icount) {
+ error_setg(errp, "No MTTCG when icount is enabled");
} else {
+#ifndef TARGET_SUPPORT_MTTCG
+ error_report("Guest not yet converted to MTTCG - "
+ "you may get unexpected results");
+#endif
if (!check_tcg_memory_orders_compatible()) {
error_report("Guest expects a stronger memory ordering "
"than the host provides");
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index 8e5a9d8a3e..b305d9032a 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -26,15 +26,20 @@
#include "qemu/log.h"
#include "trace.h"
-//#define DEBUG_GIC
+/* #define DEBUG_GIC */
#ifdef DEBUG_GIC
-#define DPRINTF(fmt, ...) \
-do { fprintf(stderr, "arm_gic: " fmt , ## __VA_ARGS__); } while (0)
+#define DEBUG_GIC_GATE 1
#else
-#define DPRINTF(fmt, ...) do {} while(0)
+#define DEBUG_GIC_GATE 0
#endif
+#define DPRINTF(fmt, ...) do { \
+ if (DEBUG_GIC_GATE) { \
+ fprintf(stderr, "%s: " fmt, __func__, ## __VA_ARGS__); \
+ } \
+ } while (0)
+
static const uint8_t gic_id_11mpcore[] = {
0x00, 0x00, 0x00, 0x00, 0x90, 0x13, 0x04, 0x00, 0x0d, 0xf0, 0x05, 0xb1
};
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 61416a6426..873cd7df9a 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -142,6 +142,9 @@ void cpu_check_irqs(CPUSPARCState *env)
{
CPUState *cs;
+ /* We should be holding the BQL before we mess with IRQs */
+ g_assert(qemu_mutex_iothread_locked());
+
if (env->pil_in && (env->interrupt_index == 0 ||
(env->interrupt_index & ~15) == TT_EXTINT)) {
unsigned int i;
diff --git a/hw/sparc64/sparc64.c b/hw/sparc64/sparc64.c
index b3d219c769..4e4fdab065 100644
--- a/hw/sparc64/sparc64.c
+++ b/hw/sparc64/sparc64.c
@@ -55,6 +55,9 @@ void cpu_check_irqs(CPUSPARCState *env)
uint32_t pil = env->pil_in |
(env->softint & ~(SOFTINT_TIMER | SOFTINT_STIMER));
+ /* We should be holding the BQL before we mess with IRQs */
+ g_assert(qemu_mutex_iothread_locked());
+
/* TT_IVEC has a higher priority (16) than TT_EXTINT (31..17) */
if (env->ivec_status & 0x20) {
return;
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 3f4211b572..76b608f0ba 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -6857,7 +6857,7 @@ void arm_cpu_do_interrupt(CPUState *cs)
new_el);
if (qemu_loglevel_mask(CPU_LOG_INT)
&& !excp_is_internal(cs->exception_index)) {
- qemu_log_mask(CPU_LOG_INT, "...with ESR %x/0x%" PRIx32 "\n",
+ qemu_log_mask(CPU_LOG_INT, "...with ESR 0x%x/0x%" PRIx32 "\n",
env->exception.syndrome >> ARM_EL_EC_SHIFT,
env->exception.syndrome);
}
diff --git a/target/i386/cpu.h b/target/i386/cpu.h
index ac2ad6d443..406cb24301 100644
--- a/target/i386/cpu.h
+++ b/target/i386/cpu.h
@@ -30,6 +30,9 @@
#define TARGET_LONG_BITS 32
#endif
+/* The x86 has a strong memory model with some store-after-load re-ordering */
+#define TCG_GUEST_DEFAULT_MO (TCG_MO_ALL & ~TCG_MO_ST_LD)
+
/* Maximum instruction code size */
#define TARGET_MAX_INSN_SIZE 16
@@ -694,6 +697,7 @@ typedef uint32_t FeatureWordArray[FEATURE_WORDS];
#define EXCP_SYSCALL 0x100 /* only happens in user only emulation
for syscall instruction */
+#define EXCP_VMEXIT 0x100
/* i386-specific interrupt pending bits. */
#define CPU_INTERRUPT_POLL CPU_INTERRUPT_TGT_EXT_1
@@ -1629,6 +1633,7 @@ void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
uint64_t param, uintptr_t retaddr);
void 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);
diff --git a/target/i386/seg_helper.c b/target/i386/seg_helper.c
index 5c845dc25c..0374031ea2 100644
--- a/target/i386/seg_helper.c
+++ b/target/i386/seg_helper.c
@@ -1297,15 +1297,17 @@ void x86_cpu_do_interrupt(CPUState *cs)
/* successfully delivered */
env->old_exception = -1;
#else
- /* simulate a real cpu exception. On i386, it can
- trigger new exceptions, but we do not handle
- double or triple faults yet. */
- do_interrupt_all(cpu, cs->exception_index,
- env->exception_is_int,
- env->error_code,
- env->exception_next_eip, 0);
- /* successfully delivered */
- env->old_exception = -1;
+ if (cs->exception_index >= EXCP_VMEXIT) {
+ assert(env->old_exception == -1);
+ do_vmexit(env, cs->exception_index - EXCP_VMEXIT, env->error_code);
+ } else {
+ do_interrupt_all(cpu, cs->exception_index,
+ env->exception_is_int,
+ env->error_code,
+ env->exception_next_eip, 0);
+ /* successfully delivered */
+ env->old_exception = -1;
+ }
#endif
}
diff --git a/target/i386/svm_helper.c b/target/i386/svm_helper.c
index 78d8df4af6..59e8b5091c 100644
--- a/target/i386/svm_helper.c
+++ b/target/i386/svm_helper.c
@@ -580,12 +580,10 @@ void helper_svm_check_io(CPUX86State *env, uint32_t port, uint32_t param,
}
}
-/* Note: currently only 32 bits of exit_code are used */
void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
uintptr_t retaddr)
{
CPUState *cs = CPU(x86_env_get_cpu(env));
- uint32_t int_ctl;
if (retaddr) {
cpu_restore_state(cs, retaddr);
@@ -598,6 +596,19 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
control.exit_info_2)),
env->eip);
+ cs->exception_index = EXCP_VMEXIT + exit_code;
+ env->error_code = exit_info_1;
+
+ /* remove any pending exception */
+ env->old_exception = -1;
+ cpu_loop_exit(cs);
+}
+
+void do_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1)
+{
+ CPUState *cs = CPU(x86_env_get_cpu(env));
+ uint32_t int_ctl;
+
if (env->hflags & HF_INHIBIT_IRQ_MASK) {
x86_stl_phys(cs,
env->vm_vmcb + offsetof(struct vmcb, control.int_state),
@@ -759,13 +770,6 @@ void cpu_vmexit(CPUX86State *env, uint32_t exit_code, uint64_t exit_info_1,
/* If the host's rIP reloaded by #VMEXIT is outside the limit of the
host's code segment or non-canonical (in the case of long mode), a
#GP fault is delivered inside the host. */
-
- /* remove any pending exception */
- cs->exception_index = -1;
- env->error_code = 0;
- env->old_exception = -1;
-
- cpu_loop_exit(cs);
}
#endif
diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c
index b683fcb025..e5f3ea4042 100644
--- a/target/mips/op_helper.c
+++ b/target/mips/op_helper.c
@@ -17,6 +17,7 @@
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
#include "cpu.h"
#include "qemu/host-utils.h"
#include "exec/helper-proto.h"
@@ -827,7 +828,11 @@ target_ulong helper_mftc0_tcschefback(CPUMIPSState *env)
target_ulong helper_mfc0_count(CPUMIPSState *env)
{
- return (int32_t)cpu_mips_get_count(env);
+ int32_t count;
+ qemu_mutex_lock_iothread();
+ count = (int32_t) cpu_mips_get_count(env);
+ qemu_mutex_unlock_iothread();
+ return count;
}
target_ulong helper_mftc0_entryhi(CPUMIPSState *env)
@@ -1375,7 +1380,9 @@ void helper_mtc0_hwrena(CPUMIPSState *env, target_ulong arg1)
void helper_mtc0_count(CPUMIPSState *env, target_ulong arg1)
{
+ qemu_mutex_lock_iothread();
cpu_mips_store_count(env, arg1);
+ qemu_mutex_unlock_iothread();
}
void helper_mtc0_entryhi(CPUMIPSState *env, target_ulong arg1)
@@ -1424,7 +1431,9 @@ void helper_mttc0_entryhi(CPUMIPSState *env, target_ulong arg1)
void helper_mtc0_compare(CPUMIPSState *env, target_ulong arg1)
{
+ qemu_mutex_lock_iothread();
cpu_mips_store_compare(env, arg1);
+ qemu_mutex_unlock_iothread();
}
void helper_mtc0_status(CPUMIPSState *env, target_ulong arg1)
@@ -1475,7 +1484,9 @@ void helper_mtc0_srsctl(CPUMIPSState *env, target_ulong arg1)
void helper_mtc0_cause(CPUMIPSState *env, target_ulong arg1)
{
+ qemu_mutex_lock_iothread();
cpu_mips_store_cause(env, arg1);
+ qemu_mutex_unlock_iothread();
}
void helper_mttc0_cause(CPUMIPSState *env, target_ulong arg1)
@@ -2296,12 +2307,16 @@ target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)
target_ulong helper_rdhwr_cc(CPUMIPSState *env)
{
+ int32_t count;
check_hwrena(env, 2, GETPC());
#ifdef CONFIG_USER_ONLY
- return env->CP0_Count;
+ count = env->CP0_Count;
#else
- return (int32_t)cpu_mips_get_count(env);
+ qemu_mutex_lock_iothread();
+ count = (int32_t)cpu_mips_get_count(env);
+ qemu_mutex_unlock_iothread();
#endif
+ return count;
}
target_ulong helper_rdhwr_ccres(CPUMIPSState *env)
diff --git a/target/s390x/misc_helper.c b/target/s390x/misc_helper.c
index 3cb942e8bb..93b0e61366 100644
--- a/target/s390x/misc_helper.c
+++ b/target/s390x/misc_helper.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
#include "cpu.h"
#include "exec/memory.h"
#include "qemu/host-utils.h"
@@ -551,61 +552,81 @@ uint32_t HELPER(sigp)(CPUS390XState *env, uint64_t order_code, uint32_t r1,
void HELPER(xsch)(CPUS390XState *env, uint64_t r1)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_xsch(cpu, r1);
+ qemu_mutex_unlock_iothread();
}
void HELPER(csch)(CPUS390XState *env, uint64_t r1)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_csch(cpu, r1);
+ qemu_mutex_unlock_iothread();
}
void HELPER(hsch)(CPUS390XState *env, uint64_t r1)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_hsch(cpu, r1);
+ qemu_mutex_unlock_iothread();
}
void HELPER(msch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_msch(cpu, r1, inst >> 16);
+ qemu_mutex_unlock_iothread();
}
void HELPER(rchp)(CPUS390XState *env, uint64_t r1)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_rchp(cpu, r1);
+ qemu_mutex_unlock_iothread();
}
void HELPER(rsch)(CPUS390XState *env, uint64_t r1)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_rsch(cpu, r1);
+ qemu_mutex_unlock_iothread();
}
void HELPER(ssch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_ssch(cpu, r1, inst >> 16);
+ qemu_mutex_unlock_iothread();
}
void HELPER(stsch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_stsch(cpu, r1, inst >> 16);
+ qemu_mutex_unlock_iothread();
}
void HELPER(tsch)(CPUS390XState *env, uint64_t r1, uint64_t inst)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_tsch(cpu, r1, inst >> 16);
+ qemu_mutex_unlock_iothread();
}
void HELPER(chsc)(CPUS390XState *env, uint64_t inst)
{
S390CPU *cpu = s390_env_get_cpu(env);
+ qemu_mutex_lock_iothread();
ioinst_handle_chsc(cpu, inst >> 16);
+ qemu_mutex_unlock_iothread();
}
#endif
diff --git a/target/sparc/int64_helper.c b/target/sparc/int64_helper.c
index 605747c93c..f942973c22 100644
--- a/target/sparc/int64_helper.c
+++ b/target/sparc/int64_helper.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
#include "cpu.h"
#include "exec/helper-proto.h"
#include "exec/log.h"
@@ -208,7 +209,9 @@ static bool do_modify_softint(CPUSPARCState *env, uint32_t value)
env->softint = value;
#if !defined(CONFIG_USER_ONLY)
if (cpu_interrupts_enabled(env)) {
+ qemu_mutex_lock_iothread();
cpu_check_irqs(env);
+ qemu_mutex_unlock_iothread();
}
#endif
return true;
diff --git a/target/sparc/win_helper.c b/target/sparc/win_helper.c
index 71b3dd37e8..154279ecda 100644
--- a/target/sparc/win_helper.c
+++ b/target/sparc/win_helper.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
#include "cpu.h"
#include "exec/exec-all.h"
#include "exec/helper-proto.h"
@@ -82,6 +83,7 @@ void cpu_put_psr_raw(CPUSPARCState *env, target_ulong val)
#endif
}
+/* Called with BQL held */
void cpu_put_psr(CPUSPARCState *env, target_ulong val)
{
cpu_put_psr_raw(env, val);
@@ -153,7 +155,10 @@ void helper_wrpsr(CPUSPARCState *env, target_ulong new_psr)
if ((new_psr & PSR_CWP) >= env->nwindows) {
cpu_raise_exception_ra(env, TT_ILL_INSN, GETPC());
} else {
+ /* cpu_put_psr may trigger interrupts, hence BQL */
+ qemu_mutex_lock_iothread();
cpu_put_psr(env, new_psr);
+ qemu_mutex_unlock_iothread();
}
}
@@ -368,7 +373,9 @@ void helper_wrpstate(CPUSPARCState *env, target_ulong new_state)
#if !defined(CONFIG_USER_ONLY)
if (cpu_interrupts_enabled(env)) {
+ qemu_mutex_lock_iothread();
cpu_check_irqs(env);
+ qemu_mutex_unlock_iothread();
}
#endif
}
@@ -381,7 +388,9 @@ void helper_wrpil(CPUSPARCState *env, target_ulong new_pil)
env->psrpil = new_pil;
if (cpu_interrupts_enabled(env)) {
+ qemu_mutex_lock_iothread();
cpu_check_irqs(env);
+ qemu_mutex_unlock_iothread();
}
#endif
}
@@ -408,7 +417,9 @@ void helper_done(CPUSPARCState *env)
#if !defined(CONFIG_USER_ONLY)
if (cpu_interrupts_enabled(env)) {
+ qemu_mutex_lock_iothread();
cpu_check_irqs(env);
+ qemu_mutex_unlock_iothread();
}
#endif
}
@@ -435,7 +446,9 @@ void helper_retry(CPUSPARCState *env)
#if !defined(CONFIG_USER_ONLY)
if (cpu_interrupts_enabled(env)) {
+ qemu_mutex_lock_iothread();
cpu_check_irqs(env);
+ qemu_mutex_unlock_iothread();
}
#endif
}
diff --git a/target/xtensa/helper.c b/target/xtensa/helper.c
index c67d715c4b..bcd0b7738d 100644
--- a/target/xtensa/helper.c
+++ b/target/xtensa/helper.c
@@ -217,6 +217,7 @@ static void handle_interrupt(CPUXtensaState *env)
}
}
+/* Called from cpu_handle_interrupt with BQL held */
void xtensa_cpu_do_interrupt(CPUState *cs)
{
XtensaCPU *cpu = XTENSA_CPU(cs);
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
index af2723445d..519fbeddd6 100644
--- a/target/xtensa/op_helper.c
+++ b/target/xtensa/op_helper.c
@@ -26,6 +26,7 @@
*/
#include "qemu/osdep.h"
+#include "qemu/main-loop.h"
#include "cpu.h"
#include "exec/helper-proto.h"
#include "qemu/host-utils.h"
@@ -381,7 +382,11 @@ void HELPER(waiti)(CPUXtensaState *env, uint32_t pc, uint32_t intlevel)
env->pc = pc;
env->sregs[PS] = (env->sregs[PS] & ~PS_INTLEVEL) |
(intlevel << PS_INTLEVEL_SHIFT);
+
+ qemu_mutex_lock_iothread();
check_interrupts(env);
+ qemu_mutex_unlock_iothread();
+
if (env->pending_irq_level) {
cpu_loop_exit(CPU(xtensa_env_get_cpu(env)));
return;
@@ -426,7 +431,9 @@ void HELPER(update_ccompare)(CPUXtensaState *env, uint32_t i)
void HELPER(check_interrupts)(CPUXtensaState *env)
{
+ qemu_mutex_lock_iothread();
check_interrupts(env);
+ qemu_mutex_unlock_iothread();
}
void HELPER(itlb_hit_test)(CPUXtensaState *env, uint32_t vaddr)
diff --git a/translate-all.c b/translate-all.c
index d42d003e67..34480aebba 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -333,6 +333,19 @@ bool cpu_restore_state(CPUState *cpu, uintptr_t retaddr)
TranslationBlock *tb;
bool r = false;
+ /* A retaddr of zero is invalid so we really shouldn't have ended
+ * up here. The target code has likely forgotten to check retaddr
+ * != 0 before attempting to restore state. We return early to
+ * avoid blowing up on a recursive tb_lock(). The target must have
+ * previously survived a failed cpu_restore_state because
+ * tb_find_pc(0) would have failed anyway. It still should be
+ * fixed though.
+ */
+
+ if (!retaddr) {
+ return r;
+ }
+
tb_lock();
tb = tb_find_pc(retaddr);
if (tb) {
diff --git a/vl.c b/vl.c
index 7f1644a2be..1a95500ac7 100644
--- a/vl.c
+++ b/vl.c
@@ -4055,8 +4055,6 @@ int main(int argc, char **argv, char **envp)
replay_configure(icount_opts);
- qemu_tcg_configure(accel_opts, &error_fatal);
-
machine_class = select_machine();
set_memory_options(&ram_slots, &maxram_size, machine_class);
@@ -4423,14 +4421,13 @@ int main(int argc, char **argv, char **envp)
if (!tcg_enabled()) {
error_report("-icount is not allowed with hardware virtualization");
exit(1);
- } else if (qemu_tcg_mttcg_enabled()) {
- error_report("-icount does not currently work with MTTCG");
- exit(1);
}
configure_icount(icount_opts, &error_abort);
qemu_opts_del(icount_opts);
}
+ qemu_tcg_configure(accel_opts, &error_fatal);
+
if (default_net) {
QemuOptsList *net = qemu_find_opts("net");
qemu_opts_set(net, NULL, "type", "nic", &error_abort);