Add '-accel <mode>' and 'no-accel' options.
This patch adds two new options to better control CPU emulation
acceleration (i.e. KVM and HAX). More specifically:
'-no-accel' can be used to disable acceleration if available.
'-accel off' does the same.
'-accel on' forces to run with acceleration, or refuses to start
the emulator.
'-accel auto' probes the system for a working accelerator and uses
it when possible (i.e. when emulating x86 or x86_64 images only).
Also print some information with -verbose or -debug-init.
Note: This adds QEMU-independent probing code for KVM and HAX
under android/emulation/ (C++), as well as some glue to
use it from C under android/cpu_accelerator.[hc].
Note: HAX is no longer enabled by default when reaching the QEMU
main function.
Change-Id: Ic91db7a3b213d69296c50fec35cd29a32a8e5779
diff --git a/android/main.c b/android/main.c
index 0662bfe..c0ac767 100644
--- a/android/main.c
+++ b/android/main.c
@@ -36,6 +36,7 @@
#include "android/utils/debug.h"
#include "android/config-file.h"
#include "android/config/config.h"
+#include "android/cpu_accelerator.h"
#include "android/user-config.h"
#include "android/utils/bufprint.h"
@@ -1202,6 +1203,91 @@
args[n++] = "socket,vlan=1,mcast=230.0.0.10:1234";
}
+ /* Handle CPU acceleration options. */
+ if (opts->no_accel) {
+ if (opts->accel) {
+ if (strcmp(opts->accel, "off") != 0) {
+ derror("You cannot use -no-accel and '-accel %s' at the same time",
+ opts->accel);
+ exit(1);
+ }
+ } else {
+ AFREE(opts->accel);
+ opts->accel = ASTRDUP("off");
+ }
+ }
+
+ enum {
+ ACCEL_OFF = 0,
+ ACCEL_ON = 1,
+ ACCEL_AUTO = 2,
+ } accel_mode = ACCEL_AUTO;
+
+ if (opts->accel) {
+ if (!strcmp(opts->accel, "off")) {
+ accel_mode = ACCEL_OFF;
+ } else if (!strcmp(opts->accel, "on")) {
+ accel_mode = ACCEL_ON;
+ } else if (!strcmp(opts->accel, "auto")) {
+ accel_mode = ACCEL_AUTO;
+ } else {
+ derror("Invalid '-accel %s' parameter, valid values are: on off auto\n",
+ opts->accel);
+ exit(1);
+ }
+ }
+
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+ char* accel_status = NULL;
+ bool accel_ok = android_hasCpuAcceleration(&accel_status);
+
+#ifdef __linux__
+ static const char kEnableAccelerator[] = "-enable-kvm";
+ static const char kDisableAccelerator[] = "-disable-kvm";
+#else
+ static const char kEnableAccelerator[] = "-enable-hax";
+ static const char kDisableAccelerator[] = "-disable-hax";
+#endif
+
+ // Dump CPU acceleration status.
+ if (VERBOSE_CHECK(init)) {
+ const char* accel_str = "DISABLED";
+ if (accel_ok) {
+ if (accel_mode == ACCEL_OFF) {
+ accel_str = "working, but disabled by user";
+ } else {
+ accel_str = "working";
+ }
+ }
+ dprint("CPU Acceleration: %s", accel_str);
+ dprint("CPU Acceleration status: %s", accel_status);
+ }
+
+ // CPU acceleration only works for x86 and x86_64 system images.
+ if (accel_mode == ACCEL_OFF && accel_ok) {
+ args[n++] = ASTRDUP(kDisableAccelerator);
+ } else if (accel_mode == ACCEL_ON) {
+ if (!accel_ok) {
+ derror("CPU acceleration not supported on this machine!");
+ derror("Reason: %s", accel_status);
+ exit(1);
+ }
+ args[n++] = ASTRDUP(kEnableAccelerator);
+ } else {
+ args[n++] = accel_ok ? ASTRDUP(kEnableAccelerator)
+ : ASTRDUP(kDisableAccelerator);
+ }
+
+ AFREE(accel_status);
+#else
+ (void)accel_mode;
+
+ if (VERBOSE_CHECK(init)) {
+ dwarning("CPU acceleration only works with x86/x86_64 "
+ "system images.");
+ }
+#endif
+
/* Setup screen emulation */
if (opts->screen) {
if (strcmp(opts->screen, "touch") &&