aboutsummaryrefslogtreecommitdiff
path: root/accel/tcg/tcg-all.c
diff options
context:
space:
mode:
Diffstat (limited to 'accel/tcg/tcg-all.c')
-rw-r--r--accel/tcg/tcg-all.c98
1 files changed, 54 insertions, 44 deletions
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index c1a30b0..b0d4e3e 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -26,27 +26,30 @@
#include "qemu/osdep.h"
#include "system/tcg.h"
#include "exec/replay-core.h"
-#include "system/cpu-timers.h"
+#include "exec/icount.h"
#include "tcg/startup.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/accel.h"
#include "qemu/atomic.h"
+#include "qapi/qapi-types-common.h"
#include "qapi/qapi-builtin-visit.h"
#include "qemu/units.h"
#if defined(CONFIG_USER_ONLY)
#include "hw/qdev-core.h"
#else
#include "hw/boards.h"
+#include "system/tcg.h"
#endif
+#include "accel/tcg/cpu-ops.h"
#include "internal-common.h"
-#include "cpu-param.h"
+#include "cpu.h"
struct TCGState {
AccelState parent_obj;
- bool mttcg_enabled;
+ OnOffAuto mttcg_enabled;
bool one_insn_per_tb;
int splitwx_enabled;
unsigned long tb_size;
@@ -58,40 +61,18 @@ typedef struct TCGState TCGState;
DECLARE_INSTANCE_CHECKER(TCGState, TCG_STATE,
TYPE_TCG_ACCEL)
-/*
- * We default to false if we know other options have been enabled
- * which are currently incompatible with MTTCG. Otherwise when each
- * guest (target) has been updated to support:
- * - atomic instructions
- * - memory ordering primitives (barriers)
- * they can set the appropriate CONFIG flags in ${target}-softmmu.mak
- *
- * Once a guest architecture has been converted to the new primitives
- * there is one remaining limitation to check:
- * - The guest can't be oversized (e.g. 64 bit guest on 32 bit host)
- */
-
-static bool default_mttcg_enabled(void)
+#ifndef CONFIG_USER_ONLY
+bool qemu_tcg_mttcg_enabled(void)
{
- if (icount_enabled()) {
- return false;
- }
-#ifdef TARGET_SUPPORTS_MTTCG
-# ifndef TCG_GUEST_DEFAULT_MO
-# error "TARGET_SUPPORTS_MTTCG without TCG_GUEST_DEFAULT_MO"
-# endif
- return true;
-#else
- return false;
-#endif
+ TCGState *s = TCG_STATE(current_accel());
+ return s->mttcg_enabled == ON_OFF_AUTO_ON;
}
+#endif /* !CONFIG_USER_ONLY */
static void tcg_accel_instance_init(Object *obj)
{
TCGState *s = TCG_STATE(obj);
- s->mttcg_enabled = default_mttcg_enabled();
-
/* If debugging enabled, default "auto on", otherwise off. */
#if defined(CONFIG_DEBUG_TCG) && !defined(CONFIG_USER_ONLY)
s->splitwx_enabled = -1;
@@ -100,24 +81,57 @@ static void tcg_accel_instance_init(Object *obj)
#endif
}
-bool mttcg_enabled;
bool one_insn_per_tb;
static int tcg_init_machine(MachineState *ms)
{
TCGState *s = TCG_STATE(current_accel());
-#ifdef CONFIG_USER_ONLY
- unsigned max_cpus = 1;
-#else
- unsigned max_cpus = ms->smp.max_cpus;
+ unsigned max_threads = 1;
+
+#ifndef CONFIG_USER_ONLY
+ CPUClass *cc = CPU_CLASS(object_class_by_name(CPU_RESOLVING_TYPE));
+ bool mttcg_supported = cc->tcg_ops->mttcg_supported;
+
+ switch (s->mttcg_enabled) {
+ case ON_OFF_AUTO_AUTO:
+ /*
+ * We default to false if we know other options have been enabled
+ * which are currently incompatible with MTTCG. Otherwise when each
+ * guest (target) has been updated to support:
+ * - atomic instructions
+ * - memory ordering primitives (barriers)
+ * they can set the appropriate CONFIG flags in ${target}-softmmu.mak
+ *
+ * Once a guest architecture has been converted to the new primitives
+ * there is one remaining limitation to check:
+ * - The guest can't be oversized (e.g. 64 bit guest on 32 bit host)
+ */
+ if (mttcg_supported && !icount_enabled()) {
+ s->mttcg_enabled = ON_OFF_AUTO_ON;
+ max_threads = ms->smp.max_cpus;
+ } else {
+ s->mttcg_enabled = ON_OFF_AUTO_OFF;
+ }
+ break;
+ case ON_OFF_AUTO_ON:
+ if (!mttcg_supported) {
+ warn_report("Guest not yet converted to MTTCG - "
+ "you may get unexpected results");
+ }
+ max_threads = ms->smp.max_cpus;
+ break;
+ case ON_OFF_AUTO_OFF:
+ break;
+ default:
+ g_assert_not_reached();
+ }
#endif
tcg_allowed = true;
- mttcg_enabled = s->mttcg_enabled;
page_init();
tb_htable_init();
- tcg_init(s->tb_size * MiB, s->splitwx_enabled, max_cpus);
+ tcg_init(s->tb_size * MiB, s->splitwx_enabled, max_threads);
#if defined(CONFIG_SOFTMMU)
/*
@@ -138,7 +152,7 @@ static char *tcg_get_thread(Object *obj, Error **errp)
{
TCGState *s = TCG_STATE(obj);
- return g_strdup(s->mttcg_enabled ? "multi" : "single");
+ return g_strdup(s->mttcg_enabled == ON_OFF_AUTO_ON ? "multi" : "single");
}
static void tcg_set_thread(Object *obj, const char *value, Error **errp)
@@ -149,14 +163,10 @@ static void tcg_set_thread(Object *obj, const char *value, Error **errp)
if (icount_enabled()) {
error_setg(errp, "No MTTCG when icount is enabled");
} else {
-#ifndef TARGET_SUPPORTS_MTTCG
- warn_report("Guest not yet converted to MTTCG - "
- "you may get unexpected results");
-#endif
- s->mttcg_enabled = true;
+ s->mttcg_enabled = ON_OFF_AUTO_ON;
}
} else if (strcmp(value, "single") == 0) {
- s->mttcg_enabled = false;
+ s->mttcg_enabled = ON_OFF_AUTO_OFF;
} else {
error_setg(errp, "Invalid 'thread' setting %s", value);
}