Introduce -machine command option.
This option gives the ability to switch one "accelerator" like kvm, xen or the default one tcg. We can specify more than one accelerator by separate them by a colon. QEMU will try each one and use the first whose works. So, ./qemu -machine accel=xen:kvm:tcg which would try Xen support first, then KVM and finally TCG if none of the other works. By default, QEMU will use TCG. But we can specify another default in the global configuration file. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
85097db695
commit
303d4e865b
@ -709,6 +709,11 @@ int audio_available(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int tcg_available(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int kvm_available(void)
|
||||
{
|
||||
#ifdef CONFIG_KVM
|
||||
|
@ -27,6 +27,7 @@ void do_smbios_option(const char *optarg);
|
||||
void cpudef_init(void);
|
||||
int audio_available(void);
|
||||
void audio_init(qemu_irq *isa_pic, PCIBus *pci_bus);
|
||||
int tcg_available(void);
|
||||
int kvm_available(void);
|
||||
int xen_available(void);
|
||||
|
||||
|
@ -450,6 +450,19 @@ QemuOptsList qemu_option_rom_opts = {
|
||||
},
|
||||
};
|
||||
|
||||
static QemuOptsList qemu_machine_opts = {
|
||||
.name = "machine",
|
||||
.head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
|
||||
.desc = {
|
||||
{
|
||||
.name = "accel",
|
||||
.type = QEMU_OPT_STRING,
|
||||
.help = "accelerator list",
|
||||
},
|
||||
{ /* End of list */ }
|
||||
},
|
||||
};
|
||||
|
||||
static QemuOptsList *vm_config_groups[32] = {
|
||||
&qemu_drive_opts,
|
||||
&qemu_chardev_opts,
|
||||
@ -464,6 +477,7 @@ static QemuOptsList *vm_config_groups[32] = {
|
||||
&qemu_trace_opts,
|
||||
#endif
|
||||
&qemu_option_rom_opts,
|
||||
&qemu_machine_opts,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
@ -2030,6 +2030,16 @@ Enable KVM full virtualization support. This option is only available
|
||||
if KVM support is enabled when compiling.
|
||||
ETEXI
|
||||
|
||||
DEF("machine", HAS_ARG, QEMU_OPTION_machine, \
|
||||
"-machine accel=accel1[:accel2] use an accelerator (kvm,xen,tcg), default is tcg\n", QEMU_ARCH_ALL)
|
||||
STEXI
|
||||
@item -machine accel=@var{accels}
|
||||
@findex -machine
|
||||
This is use to enable an accelerator, in kvm,xen,tcg.
|
||||
By default, it use only tcg. If there a more than one accelerator
|
||||
specified, the next one is used if the first don't work.
|
||||
ETEXI
|
||||
|
||||
DEF("xen-domid", HAS_ARG, QEMU_OPTION_xen_domid,
|
||||
"-xen-domid id specify xen guest domain id\n", QEMU_ARCH_ALL)
|
||||
DEF("xen-create", 0, QEMU_OPTION_xen_create,
|
||||
|
102
vl.c
102
vl.c
@ -257,6 +257,7 @@ static NotifierList exit_notifiers =
|
||||
static NotifierList machine_init_done_notifiers =
|
||||
NOTIFIER_LIST_INITIALIZER(machine_init_done_notifiers);
|
||||
|
||||
static int tcg_allowed = 1;
|
||||
int kvm_allowed = 0;
|
||||
uint32_t xen_domid;
|
||||
enum xen_mode xen_mode = XEN_EMULATE;
|
||||
@ -1876,6 +1877,82 @@ static int debugcon_parse(const char *devname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tcg_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct {
|
||||
const char *opt_name;
|
||||
const char *name;
|
||||
int (*available)(void);
|
||||
int (*init)(void);
|
||||
int *allowed;
|
||||
} accel_list[] = {
|
||||
{ "tcg", "tcg", tcg_available, tcg_init, &tcg_allowed },
|
||||
{ "kvm", "KVM", kvm_available, kvm_init, &kvm_allowed },
|
||||
};
|
||||
|
||||
static int configure_accelerator(void)
|
||||
{
|
||||
const char *p = NULL;
|
||||
char buf[10];
|
||||
int i, ret;
|
||||
bool accel_initalised = 0;
|
||||
bool init_failed = 0;
|
||||
|
||||
QemuOptsList *list = qemu_find_opts("machine");
|
||||
if (!QTAILQ_EMPTY(&list->head)) {
|
||||
p = qemu_opt_get(QTAILQ_FIRST(&list->head), "accel");
|
||||
}
|
||||
|
||||
if (p == NULL) {
|
||||
/* Use the default "accelerator", tcg */
|
||||
p = "tcg";
|
||||
}
|
||||
|
||||
while (!accel_initalised && *p != '\0') {
|
||||
if (*p == ':') {
|
||||
p++;
|
||||
}
|
||||
p = get_opt_name(buf, sizeof (buf), p, ':');
|
||||
for (i = 0; i < ARRAY_SIZE(accel_list); i++) {
|
||||
if (strcmp(accel_list[i].opt_name, buf) == 0) {
|
||||
ret = accel_list[i].init();
|
||||
if (ret < 0) {
|
||||
init_failed = 1;
|
||||
if (!accel_list[i].available()) {
|
||||
printf("%s not supported for this target\n",
|
||||
accel_list[i].name);
|
||||
} else {
|
||||
fprintf(stderr, "failed to initialize %s: %s\n",
|
||||
accel_list[i].name,
|
||||
strerror(-ret));
|
||||
}
|
||||
} else {
|
||||
accel_initalised = 1;
|
||||
*(accel_list[i].allowed) = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == ARRAY_SIZE(accel_list)) {
|
||||
fprintf(stderr, "\"%s\" accelerator does not exist.\n", buf);
|
||||
}
|
||||
}
|
||||
|
||||
if (!accel_initalised) {
|
||||
fprintf(stderr, "No accelerator found!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (init_failed) {
|
||||
fprintf(stderr, "Back to %s accelerator.\n", accel_list[i].name);
|
||||
}
|
||||
|
||||
return !accel_initalised;
|
||||
}
|
||||
|
||||
void qemu_add_exit_notifier(Notifier *notify)
|
||||
{
|
||||
notifier_list_add(&exit_notifiers, notify);
|
||||
@ -2576,7 +2653,18 @@ int main(int argc, char **argv, char **envp)
|
||||
do_smbios_option(optarg);
|
||||
break;
|
||||
case QEMU_OPTION_enable_kvm:
|
||||
kvm_allowed = 1;
|
||||
olist = qemu_find_opts("machine");
|
||||
qemu_opts_reset(olist);
|
||||
qemu_opts_parse(olist, "accel=kvm", 0);
|
||||
break;
|
||||
case QEMU_OPTION_machine:
|
||||
olist = qemu_find_opts("machine");
|
||||
qemu_opts_reset(olist);
|
||||
opts = qemu_opts_parse(olist, optarg, 0);
|
||||
if (!opts) {
|
||||
fprintf(stderr, "parse error: %s\n", optarg);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
case QEMU_OPTION_usb:
|
||||
usb_enabled = 1;
|
||||
@ -2896,17 +2984,7 @@ int main(int argc, char **argv, char **envp)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (kvm_allowed) {
|
||||
int ret = kvm_init();
|
||||
if (ret < 0) {
|
||||
if (!kvm_available()) {
|
||||
printf("KVM not supported for this target\n");
|
||||
} else {
|
||||
fprintf(stderr, "failed to initialize KVM: %s\n", strerror(-ret));
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
configure_accelerator();
|
||||
|
||||
if (qemu_init_main_loop()) {
|
||||
fprintf(stderr, "qemu_init_main_loop failed\n");
|
||||
|
Loading…
Reference in New Issue
Block a user