All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/22] Refactor machine support
@ 2010-06-07 23:51 Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice Anthony Liguori
                   ` (22 more replies)
  0 siblings, 23 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Paul Brook

This series introduces a rather radical change in the way we deal with machine
definitions in QEMU.  Here are the features this series introduces:

 - Machines are definable via a -machine-def option or a [machine-def] config
   stanza
 - Parameters such as -kernel, -initrd, -append, -m, -acpi-enable, -enable-kvm,
   and potentially many more are now support via a config
 - It's possible to set a default block format (ide, scsi, virtio) for a machine
 - It's possible to make kvm enablement a property of a machine type.  The
   support modes are KVM enabled, TCG enabled, and KVM enabled with TCG
   fallback.
 - All properties of the default machine type are overridable via global config.
   IOW, you can make KVM enablement default without touching the source code.
   You can also increase the default ram size without touching any code.

Conceptually, it works by introducing a MachineCore concept.  A MachineCore is
a function that is able to create a machine based on a set of user specified
parameters.  These parameters may be high level properties (like ram size) or
qdev global properties (virtio-blk-pci.vectors).

A builtin Machine is an instance of a MachineCore that has a set of default
parameters set.

The concept of MachineCore is *not* a stop-gap measure for proper qdev
conversion.  Rather, the idea behind MachineCore is that it's a device tree
builder.

You certainly could still have a machine described purely by a device tree and
qdev properties but that's not enough to represent the UI that we currently
expose.  We need a way convert user visible operations like enable usb to
platform specific operations like add a PIIX3 USB hub.  This is what a
MachineCore does.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-08  7:51   ` Gerd Hoffmann
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 02/22] QemuOpts: make qemu_opts_validate() store the description list for later use Anthony Liguori
                   ` (21 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori, Gerd Hoffman

Right now, if you set a QemuOpts option in a section twice, when you get the
option you'll receive the value that was set the first time.  This is less than
ideal because if you're manipulating options in two places like a global config
followed by the command line, you really want the later to override the former.

This patch fixes this behavior.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu-option.c b/qemu-option.c
index acd74f9..e0cb91b 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -628,7 +628,7 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
     opt = qemu_mallocz(sizeof(*opt));
     opt->name = qemu_strdup(name);
     opt->opts = opts;
-    QTAILQ_INSERT_TAIL(&opts->head, opt, next);
+    QTAILQ_INSERT_HEAD(&opts->head, opt, next);
     if (desc[i].name != NULL) {
         opt->desc = desc+i;
     }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 02/22] QemuOpts: make qemu_opts_validate() store the description list for later use
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 03/22] QemuOpts: add function to set QemuOpts from defaults Anthony Liguori
                   ` (20 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori, Gerd Hoffman

Otherwise qemu_opt_set doesn't work as expected after a validate call

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu-option.c b/qemu-option.c
index e0cb91b..03b1ef7 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -525,6 +525,7 @@ struct QemuOpt {
 struct QemuOpts {
     char *id;
     QemuOptsList *list;
+    const QemuOptDesc *secondary_desc;
     Location loc;
     QTAILQ_HEAD(QemuOptHead, QemuOpt) head;
     QTAILQ_ENTRY(QemuOpts) next;
@@ -611,6 +612,10 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
     const QemuOptDesc *desc = opts->list->desc;
     int i;
 
+    if (desc[0].name == NULL && opts->secondary_desc) {
+        desc = opts->secondary_desc;
+    }
+
     for (i = 0; desc[i].name != NULL; i++) {
         if (strcmp(desc[i].name, name) == 0) {
             break;
@@ -927,6 +932,8 @@ int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc)
         }
     }
 
+    opts->secondary_desc = desc;
+
     return 0;
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 03/22] QemuOpts: add function to set QemuOpts from defaults
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 02/22] QemuOpts: make qemu_opts_validate() store the description list for later use Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 04/22] machine: package all init arguments into a QemuOpts (v2) Anthony Liguori
                   ` (19 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori, Gerd Hoffman

This lets us hard code a list of default QemuOpts values in a structured way.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu-option.c b/qemu-option.c
index 03b1ef7..b990cf5 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -954,3 +954,23 @@ int qemu_opts_foreach(QemuOptsList *list, qemu_opts_loopfunc func, void *opaque,
     loc_pop(&loc);
     return rc;
 }
+
+int qemu_opts_set_defaults(QemuOpts *opts, const QemuOptValue *defvals)
+{
+    int i;
+
+    for (i = 0; defvals[i].name; i++) {
+        int ret;
+
+        if (qemu_opt_get(opts, defvals[i].name)) {
+            continue;
+        }
+        
+        ret = qemu_opt_set(opts, defvals[i].name, defvals[i].value);
+        if (ret < 0) {
+            return ret;
+        }
+    }
+
+    return 0;
+}
diff --git a/qemu-option.h b/qemu-option.h
index 4823219..4a6717c 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -104,6 +104,11 @@ struct QemuOptsList {
     QemuOptDesc desc[];
 };
 
+typedef struct QemuOptValue {
+    const char *name;
+    const char *value;
+} QemuOptValue;
+
 const char *qemu_opt_get(QemuOpts *opts, const char *name);
 int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval);
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
@@ -113,6 +118,8 @@ typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, void *opaq
 int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
                      int abort_on_failure);
 
+int qemu_opts_set_defaults(QemuOpts *opts, const QemuOptValue *defvals);
+
 QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
 QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id, int fail_if_exists);
 int qemu_opts_set(QemuOptsList *list, const char *id,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 04/22] machine: package all init arguments into a QemuOpts (v2)
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (2 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 03/22] QemuOpts: add function to set QemuOpts from defaults Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 05/22] machine: pass all init options as a single QemuOpts Anthony Liguori
                   ` (18 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori, Gerd Hoffman

This patch creates a QemuOpts structure and stores all of the machine init
arguments in that structure.  It introduces a temporary list of QemuOptDescs
in vl.c such that the current common options can be validated.

The long term vision is that that list becomes a #define and that each machine
can optionally provide it's own QemuOptDescs list using the common options as
a base.  This enables per-machine options.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
--
v1 -> v2:
  - cpu_model -> cpu

diff --git a/hw/pc.c b/hw/pc.c
index 9b85c42..48b3730 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -534,6 +534,10 @@ static void load_linux(void *fw_cfg,
     FILE *f;
     char *vmode;
 
+    if (!kernel_cmdline) {
+        kernel_cmdline = "";
+    }
+
     /* Align to 16 bytes as a paranoia measure */
     cmdline_size = (strlen(kernel_cmdline)+16) & ~15;
 
diff --git a/qemu-config.c b/qemu-config.c
index 5a4e61b..3679a9f 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -336,6 +336,14 @@ QemuOptsList qemu_cpudef_opts = {
     },
 };
 
+QemuOptsList qemu_machine_opts = {
+    .name = "machine",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
+    .desc = {
+        { /* end of list */ }
+    },
+};        
+
 static QemuOptsList *vm_config_groups[] = {
     &qemu_drive_opts,
     &qemu_chardev_opts,
@@ -346,6 +354,7 @@ static QemuOptsList *vm_config_groups[] = {
     &qemu_global_opts,
     &qemu_mon_opts,
     &qemu_cpudef_opts,
+    &qemu_machine_opts,
     NULL,
 };
 
diff --git a/qemu-config.h b/qemu-config.h
index dca69d4..6f52188 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -14,6 +14,7 @@ extern QemuOptsList qemu_rtc_opts;
 extern QemuOptsList qemu_global_opts;
 extern QemuOptsList qemu_mon_opts;
 extern QemuOptsList qemu_cpudef_opts;
+extern QemuOptsList qemu_machine_opts;
 
 QemuOptsList *qemu_find_opts(const char *group);
 int qemu_set_option(const char *str);
diff --git a/vl.c b/vl.c
index 7121cd0..5349fd5 100644
--- a/vl.c
+++ b/vl.c
@@ -2550,6 +2550,35 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
     return popt;
 }
 
+/* TEMP: until we have proper -machine support */
+static QemuOptDesc common_machine_opts[] = {
+    {
+        .name = "ram_size",
+        .type = QEMU_OPT_SIZE,
+    },
+    {
+        .name = "kernel",
+        .type = QEMU_OPT_STRING,
+    },
+    {
+        .name = "cmdline",
+        .type = QEMU_OPT_STRING,
+    },
+    {
+        .name = "initrd",
+        .type = QEMU_OPT_STRING,
+    },
+    {
+        .name = "boot_device",
+        .type = QEMU_OPT_STRING,
+    },
+    {
+        .name = "cpu",
+        .type = QEMU_OPT_STRING,
+    },
+    { /* end of list */ },
+};
+
 int main(int argc, char **argv, char **envp)
 {
     const char *gdbstub_dev = NULL;
@@ -3718,8 +3747,42 @@ int main(int argc, char **argv, char **envp)
     }
     qemu_add_globals();
 
-    machine->init(ram_size, boot_devices,
-                  kernel_filename, kernel_cmdline, initrd_filename, cpu_model);
+    opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
+    if (kernel_filename) {
+        qemu_opt_set(opts, "kernel", kernel_filename);
+        if (kernel_cmdline) {
+            qemu_opt_set(opts, "cmdline", kernel_cmdline);
+        }
+        if (initrd_filename) {
+            qemu_opt_set(opts, "initrd", initrd_filename);
+        }
+    }
+
+    qemu_opt_set(opts, "boot_device", boot_devices);
+
+    if (cpu_model) {
+        qemu_opt_set(opts, "cpu", cpu_model);
+    }
+
+    if (ram_size) {
+        char buffer[64];
+        snprintf(buffer, sizeof(buffer),
+                 "%" PRId64, ram_size);
+        qemu_opt_set(opts, "ram_size", buffer);
+    }
+
+    if (qemu_opts_validate(opts, common_machine_opts) < 0) {
+        exit(1);
+    }
+    
+    machine->init(qemu_opt_get_size(opts, "ram_size"),
+                  qemu_opt_get(opts, "boot_device"),
+                  qemu_opt_get(opts, "kernel"),
+                  qemu_opt_get(opts, "cmdline"),
+                  qemu_opt_get(opts, "initrd"),
+                  qemu_opt_get(opts, "cpu"));
+
+    qemu_opts_del(opts);
 
     cpu_synchronize_all_post_init();
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 05/22] machine: pass all init options as a single QemuOpts
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (3 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 04/22] machine: package all init arguments into a QemuOpts (v2) Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-08  7:58   ` Gerd Hoffmann
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 06/22] Make -acpi-enable a machine specific option Anthony Liguori
                   ` (17 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

The current method of passing arguments to machine init functions is haphazard.
We pass some arguments as via the init function.  We pass a lot of other
arguments as global variables some that are supported by a lot of boards and
others that are only supported by one board.  It's very difficult to introduce
new parameters in the function signature because of the number of files that
have to be touched.  There is no central way to tie all of the machine options
into the configuration file.

This patch redefines the machine init signature to just take a QemuOpts.  It
also passes the machine as the first parameter to allow multiple boards to be
defined with one init function.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/an5206.c b/hw/an5206.c
index f584d88..0d6a6f0 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -29,11 +29,11 @@ void irq_info(Monitor *mon)
 
 /* Board init.  */
 
-static void an5206_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void an5206_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     int kernel_size;
     uint64_t elf_entry;
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 7d59c96..7999d47 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -264,11 +264,12 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 }
 
 static
-void axisdev88_init (ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+void axisdev88_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     DeviceState *dev;
     SysBusDevice *s;
diff --git a/hw/boards.h b/hw/boards.h
index 6f0f0d7..c3f4f68 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -5,14 +5,11 @@
 
 #include "qdev.h"
 
-typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
-                                 const char *boot_device,
-                                 const char *kernel_filename,
-                                 const char *kernel_cmdline,
-                                 const char *initrd_filename,
-                                 const char *cpu_model);
-
-typedef struct QEMUMachine {
+typedef struct QEMUMachine QEMUMachine;
+
+typedef void QEMUMachineInitFunc(QemuOpts *opts);
+
+struct QEMUMachine {
     const char *name;
     const char *alias;
     const char *desc;
@@ -29,7 +26,7 @@ typedef struct QEMUMachine {
     int is_default;
     GlobalProperty *compat_props;
     struct QEMUMachine *next;
-} QEMUMachine;
+};
 
 int qemu_register_machine(QEMUMachine *m);
 
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index 9c9e6ff..db94251 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -16,11 +16,11 @@
 
 /* Board init.  */
 
-static void dummy_m68k_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void dummy_m68k_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     int kernel_size;
     uint64_t elf_entry;
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index b88d00a..1cb6052 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -50,11 +50,12 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 }
 
 static
-void bareetraxfs_init (ram_addr_t ram_size,
-                       const char *boot_device,
-                       const char *kernel_filename, const char *kernel_cmdline,
-                       const char *initrd_filename, const char *cpu_model)
+void bareetraxfs_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     DeviceState *dev;
     SysBusDevice *s;
     CPUState *env;
diff --git a/hw/gumstix.c b/hw/gumstix.c
index b64e04e..6739332 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -41,10 +41,7 @@
 
 static const int sector_len = 128 * 1024;
 
-static void connex_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void connex_init(QemuOpts *opts)
 {
     PXA2xxState *cpu;
     DriveInfo *dinfo;
@@ -79,11 +76,9 @@ static void connex_init(ram_addr_t ram_size,
                     pxa2xx_gpio_in_get(cpu->gpio)[36]);
 }
 
-static void verdex_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void verdex_init(QemuOpts *opts)
 {
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     PXA2xxState *cpu;
     DriveInfo *dinfo;
     int be;
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index bee8298..36ebaf0 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -448,11 +448,13 @@ static struct arm_boot_info integrator_binfo = {
     .board_id = 0x113,
 };
 
-static void integratorcp_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void integratorcp_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     ram_addr_t ram_offset;
     qemu_irq pic[32];
diff --git a/hw/mainstone.c b/hw/mainstone.c
index 54bacfb..a7feacc 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -131,11 +131,13 @@ static void mainstone_common_init(ram_addr_t ram_size,
     arm_load_kernel(cpu->env, &mainstone_binfo);
 }
 
-static void mainstone_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void mainstone_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     mainstone_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, mainstone, 0x196);
 }
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 5b686c6..b6eb94d 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -195,11 +195,11 @@ static void mcf5208_sys_init(qemu_irq *pic)
     }
 }
 
-static void mcf5208evb_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void mcf5208evb_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     int kernel_size;
     uint64_t elf_entry;
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index ead3a00..1ba9475 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -300,20 +300,18 @@ void mips_jazz_init (ram_addr_t ram_size,
 }
 
 static
-void mips_magnum_init (ram_addr_t ram_size,
-                       const char *boot_device,
-                       const char *kernel_filename, const char *kernel_cmdline,
-                       const char *initrd_filename, const char *cpu_model)
+void mips_magnum_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     mips_jazz_init(ram_size, cpu_model, JAZZ_MAGNUM);
 }
 
 static
-void mips_pica61_init (ram_addr_t ram_size,
-                       const char *boot_device,
-                       const char *kernel_filename, const char *kernel_cmdline,
-                       const char *initrd_filename, const char *cpu_model)
+void mips_pica61_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     mips_jazz_init(ram_size, cpu_model, JAZZ_PICA61);
 }
 
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index a8f9d15..0ef0090 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -773,11 +773,13 @@ static void cpu_request_exit(void *opaque, int irq, int level)
 }
 
 static
-void mips_malta_init (ram_addr_t ram_size,
-                      const char *boot_device,
-                      const char *kernel_filename, const char *kernel_cmdline,
-                      const char *initrd_filename, const char *cpu_model)
+void mips_malta_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     char *filename;
     ram_addr_t ram_offset;
     ram_addr_t bios_offset;
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index a747de5..b5705e6 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -110,11 +110,13 @@ static void main_cpu_reset(void *opaque)
 }
 
 static void
-mips_mipssim_init (ram_addr_t ram_size,
-                   const char *boot_device,
-                   const char *kernel_filename, const char *kernel_cmdline,
-                   const char *initrd_filename, const char *cpu_model)
+mips_mipssim_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     char *filename;
     ram_addr_t ram_offset;
     ram_addr_t bios_offset;
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index f1fcfcd..853ea3b 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -155,11 +155,13 @@ static void main_cpu_reset(void *opaque)
 
 static const int sector_len = 32 * 1024;
 static
-void mips_r4k_init (ram_addr_t ram_size,
-                    const char *boot_device,
-                    const char *kernel_filename, const char *kernel_cmdline,
-                    const char *initrd_filename, const char *cpu_model)
+void mips_r4k_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     char *filename;
     ram_addr_t ram_offset;
     ram_addr_t bios_offset;
diff --git a/hw/musicpal.c b/hw/musicpal.c
index d44c5a0..95469d9 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1474,11 +1474,12 @@ static struct arm_boot_info musicpal_binfo = {
     .board_id = 0x20e,
 };
 
-static void musicpal_init(ram_addr_t ram_size,
-               const char *boot_device,
-               const char *kernel_filename, const char *kernel_cmdline,
-               const char *initrd_filename, const char *cpu_model)
+static void musicpal_init(QemuOpts *opts)
 {
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     qemu_irq *cpu_pic;
     qemu_irq pic[32];
diff --git a/hw/nseries.c b/hw/nseries.c
index 04a028d..13a370b 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1376,21 +1376,27 @@ static struct arm_boot_info n810_binfo = {
     .atag_board = n810_atag_setup,
 };
 
-static void n800_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void n800_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     return n8x0_init(ram_size, boot_device,
                     kernel_filename, kernel_cmdline, initrd_filename,
                     cpu_model, &n800_binfo, 800);
 }
 
-static void n810_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void n810_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     return n8x0_init(ram_size, boot_device,
                     kernel_filename, kernel_cmdline, initrd_filename,
                     cpu_model, &n810_binfo, 810);
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 2e9879f..46a8402 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -205,20 +205,26 @@ static void sx1_init(ram_addr_t ram_size,
     //~ qemu_console_resize(ds, 640, 480);
 }
 
-static void sx1_init_v1(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void sx1_init_v1(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sx1_init(ram_size, boot_device, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, 1);
 }
 
-static void sx1_init_v2(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void sx1_init_v2(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sx1_init(ram_size, boot_device, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, 2);
 }
diff --git a/hw/palm.c b/hw/palm.c
index 8db133d..6001f9b 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -193,11 +193,12 @@ static struct arm_boot_info palmte_binfo = {
     .board_id = 0x331,
 };
 
-static void palmte_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void palmte_init(QemuOpts *opts)
 {
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     struct omap_mpu_state_s *cpu;
     int flash_size = 0x00800000;
     int sdram_size = palmte_binfo.ram_size;
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 70f563a..c58cd42 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -161,25 +161,27 @@ static void pc_init1(ram_addr_t ram_size,
     }
 }
 
-static void pc_init_pci(ram_addr_t ram_size,
-                        const char *boot_device,
-                        const char *kernel_filename,
-                        const char *kernel_cmdline,
-                        const char *initrd_filename,
-                        const char *cpu_model)
+static void pc_init_pci(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     pc_init1(ram_size, boot_device,
              kernel_filename, kernel_cmdline,
              initrd_filename, cpu_model, 1);
 }
 
-static void pc_init_isa(ram_addr_t ram_size,
-                        const char *boot_device,
-                        const char *kernel_filename,
-                        const char *kernel_cmdline,
-                        const char *initrd_filename,
-                        const char *cpu_model)
+static void pc_init_isa(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     if (cpu_model == NULL)
         cpu_model = "486";
     pc_init1(ram_size, boot_device,
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 93344b1..5cc5787 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -110,12 +110,12 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 }
 
 static void
-petalogix_s3adsp1800_init(ram_addr_t ram_size,
-                          const char *boot_device,
-                          const char *kernel_filename,
-                          const char *kernel_cmdline,
-                          const char *initrd_filename, const char *cpu_model)
+petalogix_s3adsp1800_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     DeviceState *dev;
     CPUState *env;
     int kernel_size;
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 7c7075e..088cbad 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -168,13 +168,12 @@ static void ref405ep_fpga_init (uint32_t base)
     qemu_register_reset(&ref405ep_fpga_reset, fpga);
 }
 
-static void ref405ep_init (ram_addr_t ram_size,
-                           const char *boot_device,
-                           const char *kernel_filename,
-                           const char *kernel_cmdline,
-                           const char *initrd_filename,
-                           const char *cpu_model)
+static void ref405ep_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
     char *filename;
     ppc4xx_bd_info_t bd;
     CPUPPCState *env;
@@ -490,13 +489,11 @@ static void taihu_cpld_init (uint32_t base)
     qemu_register_reset(&taihu_cpld_reset, cpld);
 }
 
-static void taihu_405ep_init(ram_addr_t ram_size,
-                             const char *boot_device,
-                             const char *kernel_filename,
-                             const char *kernel_cmdline,
-                             const char *initrd_filename,
-                             const char *cpu_model)
+static void taihu_405ep_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
     char *filename;
     CPUPPCState *env;
     qemu_irq *pic;
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 6ca873e..ddbefb7 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -84,13 +84,13 @@ out:
     return ret;
 }
 
-static void bamboo_init(ram_addr_t ram_size,
-                        const char *boot_device,
-                        const char *kernel_filename,
-                        const char *kernel_cmdline,
-                        const char *initrd_filename,
-                        const char *cpu_model)
+static void bamboo_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     unsigned int pci_irq_nrs[4] = { 28, 27, 26, 25 };
     PCIBus *pcibus;
     CPUState *env;
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index d131aa5..1737cc4 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -121,13 +121,14 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
 }
 
 /* PowerPC Mac99 hardware initialisation */
-static void ppc_core99_init (ram_addr_t ram_size,
-                             const char *boot_device,
-                             const char *kernel_filename,
-                             const char *kernel_cmdline,
-                             const char *initrd_filename,
-                             const char *cpu_model)
+static void ppc_core99_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env = NULL, *envs[MAX_CPUS];
     char *filename;
     qemu_irq *pic, **openpic_irqs;
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 27ddc01..b1ce88d 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -128,13 +128,14 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr)
     return (addr & 0x0fffffff) + KERNEL_LOAD_ADDR;
 }
 
-static void ppc_heathrow_init (ram_addr_t ram_size,
-                               const char *boot_device,
-                               const char *kernel_filename,
-                               const char *kernel_cmdline,
-                               const char *initrd_filename,
-                               const char *cpu_model)
+static void ppc_heathrow_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env = NULL, *envs[MAX_CPUS];
     char *filename;
     qemu_irq *pic, **heathrow_irqs;
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 16c9950..090c8ac 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -557,13 +557,14 @@ static void cpu_request_exit(void *opaque, int irq, int level)
 }
 
 /* PowerPC PREP hardware initialisation */
-static void ppc_prep_init (ram_addr_t ram_size,
-                           const char *boot_device,
-                           const char *kernel_filename,
-                           const char *kernel_cmdline,
-                           const char *initrd_filename,
-                           const char *cpu_model)
+static void ppc_prep_init (QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env = NULL, *envs[MAX_CPUS];
     char *filename;
     nvram_t nvram;
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index 0901fa6..b110114 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -156,13 +156,12 @@ out:
     return ret;
 }
 
-static void mpc8544ds_init(ram_addr_t ram_size,
-                         const char *boot_device,
-                         const char *kernel_filename,
-                         const char *kernel_cmdline,
-                         const char *initrd_filename,
-                         const char *cpu_model)
+static void mpc8544ds_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
     PCIBus *pci_bus;
     CPUState *env;
     uint64_t elf_entry;
diff --git a/hw/r2d.c b/hw/r2d.c
index 38c4f6a..cf0fb89 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -220,11 +220,12 @@ static struct __attribute__((__packed__))
     char kernel_cmdline[256];
 } boot_params;
 
-static void r2d_init(ram_addr_t ram_size,
-              const char *boot_device,
-	      const char *kernel_filename, const char *kernel_cmdline,
-	      const char *initrd_filename, const char *cpu_model)
+static void r2d_init(QemuOpts *opts)
 {
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     struct SH7750State *s;
     ram_addr_t sdram_addr;
diff --git a/hw/realview.c b/hw/realview.c
index f786699..4364b7b 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -368,11 +368,14 @@ static void realview_init(ram_addr_t ram_size,
     arm_load_kernel(first_cpu, &realview_binfo);
 }
 
-static void realview_eb_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void realview_eb_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     if (!cpu_model) {
         cpu_model = "arm926";
     }
@@ -380,11 +383,14 @@ static void realview_eb_init(ram_addr_t ram_size,
                   initrd_filename, cpu_model, BOARD_EB);
 }
 
-static void realview_eb_mpcore_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void realview_eb_mpcore_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     if (!cpu_model) {
         cpu_model = "arm11mpcore";
     }
@@ -392,11 +398,14 @@ static void realview_eb_mpcore_init(ram_addr_t ram_size,
                   initrd_filename, cpu_model, BOARD_EB_MPCORE);
 }
 
-static void realview_pb_a8_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void realview_pb_a8_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     if (!cpu_model) {
         cpu_model = "cortex-a8";
     }
@@ -404,11 +413,14 @@ static void realview_pb_a8_init(ram_addr_t ram_size,
                   initrd_filename, cpu_model, BOARD_PB_A8);
 }
 
-static void realview_pbx_a9_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void realview_pbx_a9_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     if (!cpu_model) {
         cpu_model = "cortex-a9";
     }
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 898f442..70b88df 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -132,13 +132,14 @@ int s390_virtio_hypercall(CPUState *env)
 }
 
 /* PC hardware initialisation */
-static void s390_init(ram_addr_t ram_size,
-                      const char *boot_device,
-                      const char *kernel_filename,
-                      const char *kernel_cmdline,
-                      const char *initrd_filename,
-                      const char *cpu_model)
+static void s390_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env = NULL;
     ram_addr_t ram_addr;
     ram_addr_t kernel_size = 0;
diff --git a/hw/shix.c b/hw/shix.c
index 638bf16..da5716e 100644
--- a/hw/shix.c
+++ b/hw/shix.c
@@ -47,11 +47,9 @@ void pic_info(Monitor *mon)
     /* XXXXX */
 }
 
-static void shix_init(ram_addr_t ram_size,
-               const char *boot_device,
-	       const char *kernel_filename, const char *kernel_cmdline,
-	       const char *initrd_filename, const char *cpu_model)
+static void shix_init(QemuOpts *opts)
 {
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     int ret;
     CPUState *env;
     struct SH7750State *s;
diff --git a/hw/spitz.c b/hw/spitz.c
index 4f82e24..44cda95 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1001,38 +1001,46 @@ static void spitz_common_init(ram_addr_t ram_size,
     sl_bootparam_write(SL_PXA_PARAM_BASE);
 }
 
-static void spitz_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void spitz_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     spitz_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, spitz, 0x2c9);
 }
 
-static void borzoi_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void borzoi_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     spitz_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, borzoi, 0x33f);
 }
 
-static void akita_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void akita_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     spitz_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, akita, 0x2e8);
 }
 
-static void terrier_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void terrier_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     spitz_common_init(ram_size, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, terrier, 0x33f);
 }
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 5755f8a..42fb17b 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1412,19 +1412,17 @@ static void stellaris_init(const char *kernel_filename, const char *cpu_model,
 }
 
 /* FIXME: Figure out how to generate these from stellaris_boards.  */
-static void lm3s811evb_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void lm3s811evb_init(QemuOpts *opts)
 {
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     stellaris_init(kernel_filename, cpu_model, &stellaris_boards[0]);
 }
 
-static void lm3s6965evb_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void lm3s6965evb_init(QemuOpts *opts)
 {
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     stellaris_init(kernel_filename, cpu_model, &stellaris_boards[1]);
 }
 
diff --git a/hw/sun4m.c b/hw/sun4m.c
index e4ca8f3..5aa3de1 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -1199,92 +1199,118 @@ static const struct sun4m_hwdef sun4m_hwdefs[] = {
 };
 
 /* SPARCstation 5 hardware initialisation */
-static void ss5_init(ram_addr_t RAM_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void ss5_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCstation 10 hardware initialisation */
-static void ss10_init(ram_addr_t RAM_size,
-                      const char *boot_device,
-                      const char *kernel_filename, const char *kernel_cmdline,
-                      const char *initrd_filename, const char *cpu_model)
+static void ss10_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCserver 600MP hardware initialisation */
-static void ss600mp_init(ram_addr_t RAM_size,
-                         const char *boot_device,
-                         const char *kernel_filename,
-                         const char *kernel_cmdline,
-                         const char *initrd_filename, const char *cpu_model)
+static void ss600mp_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCstation 20 hardware initialisation */
-static void ss20_init(ram_addr_t RAM_size,
-                      const char *boot_device,
-                      const char *kernel_filename, const char *kernel_cmdline,
-                      const char *initrd_filename, const char *cpu_model)
+static void ss20_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCstation Voyager hardware initialisation */
-static void vger_init(ram_addr_t RAM_size,
-                      const char *boot_device,
-                      const char *kernel_filename, const char *kernel_cmdline,
-                      const char *initrd_filename, const char *cpu_model)
+static void vger_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCstation LX hardware initialisation */
-static void ss_lx_init(ram_addr_t RAM_size,
-                       const char *boot_device,
-                       const char *kernel_filename, const char *kernel_cmdline,
-                       const char *initrd_filename, const char *cpu_model)
+static void ss_lx_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCstation 4 hardware initialisation */
-static void ss4_init(ram_addr_t RAM_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void ss4_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCClassic hardware initialisation */
-static void scls_init(ram_addr_t RAM_size,
-                      const char *boot_device,
-                      const char *kernel_filename, const char *kernel_cmdline,
-                      const char *initrd_filename, const char *cpu_model)
+static void scls_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCbook hardware initialisation */
-static void sbook_init(ram_addr_t RAM_size,
-                       const char *boot_device,
-                       const char *kernel_filename, const char *kernel_cmdline,
-                       const char *initrd_filename, const char *cpu_model)
+static void sbook_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
@@ -1544,21 +1570,27 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
 }
 
 /* SPARCserver 1000 hardware initialisation */
-static void ss1000_init(ram_addr_t RAM_size,
-                        const char *boot_device,
-                        const char *kernel_filename, const char *kernel_cmdline,
-                        const char *initrd_filename, const char *cpu_model)
+static void ss1000_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
 
 /* SPARCcenter 2000 hardware initialisation */
-static void ss2000_init(ram_addr_t RAM_size,
-                        const char *boot_device,
-                        const char *kernel_filename, const char *kernel_cmdline,
-                        const char *initrd_filename, const char *cpu_model)
+static void ss2000_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
@@ -1734,11 +1766,14 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
 }
 
 /* SPARCstation 2 hardware initialisation */
-static void ss2_init(ram_addr_t RAM_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void ss2_init(QemuOpts *opts)
 {
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
                   kernel_cmdline, initrd_filename, cpu_model);
 }
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 40b5f1f..7abb027 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -881,31 +881,40 @@ static const struct hwdef hwdefs[] = {
 };
 
 /* Sun4u hardware initialisation */
-static void sun4u_init(ram_addr_t RAM_size,
-                       const char *boot_devices,
-                       const char *kernel_filename, const char *kernel_cmdline,
-                       const char *initrd_filename, const char *cpu_model)
-{
+static void sun4u_init(QemuOpts *opts)
+{
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_devices = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4uv_init(RAM_size, boot_devices, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]);
 }
 
 /* Sun4v hardware initialisation */
-static void sun4v_init(ram_addr_t RAM_size,
-                       const char *boot_devices,
-                       const char *kernel_filename, const char *kernel_cmdline,
-                       const char *initrd_filename, const char *cpu_model)
-{
+static void sun4v_init(QemuOpts *opts)
+{
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_devices = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4uv_init(RAM_size, boot_devices, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
 }
 
 /* Niagara hardware initialisation */
-static void niagara_init(ram_addr_t RAM_size,
-                         const char *boot_devices,
-                         const char *kernel_filename, const char *kernel_cmdline,
-                         const char *initrd_filename, const char *cpu_model)
-{
+static void niagara_init(QemuOpts *opts)
+{
+    ram_addr_t RAM_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_devices = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4uv_init(RAM_size, boot_devices, kernel_filename,
                 kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
 }
diff --git a/hw/syborg.c b/hw/syborg.c
index 2d08cb2..6b796ce 100644
--- a/hw/syborg.c
+++ b/hw/syborg.c
@@ -30,11 +30,13 @@
 
 static struct arm_boot_info syborg_binfo;
 
-static void syborg_init(ram_addr_t ram_size,
-                        const char *boot_device,
-                        const char *kernel_filename, const char *kernel_cmdline,
-                        const char *initrd_filename, const char *cpu_model)
+static void syborg_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     qemu_irq *cpu_pic;
     qemu_irq pic[64];
diff --git a/hw/tosa.c b/hw/tosa.c
index fbe8d8c..0a691e0 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -200,11 +200,12 @@ static struct arm_boot_info tosa_binfo = {
     .ram_size = 0x04000000,
 };
 
-static void tosa_init(ram_addr_t ram_size,
-                const char *boot_device,
-                const char *kernel_filename, const char *kernel_cmdline,
-                const char *initrd_filename, const char *cpu_model)
+static void tosa_init(QemuOpts *opts)
 {
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     PXA2xxState *cpu;
     TC6393xbState *tmio;
     ScoopInfo *scp0, *scp1;
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 391f5b8..59b66d7 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -289,22 +289,28 @@ static void versatile_init(ram_addr_t ram_size,
     arm_load_kernel(env, &versatile_binfo);
 }
 
-static void vpb_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void vpb_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     versatile_init(ram_size,
                    boot_device,
                    kernel_filename, kernel_cmdline,
                    initrd_filename, cpu_model, 0x183);
 }
 
-static void vab_init(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename, const char *kernel_cmdline,
-                     const char *initrd_filename, const char *cpu_model)
+static void vab_init(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     versatile_init(ram_size,
                    boot_device,
                    kernel_filename, kernel_cmdline,
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 586214d..58c68de 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -29,13 +29,13 @@
 #include "xen_backend.h"
 #include "xen_domainbuild.h"
 
-static void xen_init_pv(ram_addr_t ram_size,
-			const char *boot_device,
-			const char *kernel_filename,
-			const char *kernel_cmdline,
-			const char *initrd_filename,
-			const char *cpu_model)
+static void xen_init_pv(QemuOpts *opts)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     CPUState *env;
     DriveInfo *dinfo;
     int i;
diff --git a/vl.c b/vl.c
index 5349fd5..87009eb 100644
--- a/vl.c
+++ b/vl.c
@@ -3775,12 +3775,7 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
     
-    machine->init(qemu_opt_get_size(opts, "ram_size"),
-                  qemu_opt_get(opts, "boot_device"),
-                  qemu_opt_get(opts, "kernel"),
-                  qemu_opt_get(opts, "cmdline"),
-                  qemu_opt_get(opts, "initrd"),
-                  qemu_opt_get(opts, "cpu"));
+    machine->init(opts);
 
     qemu_opts_del(opts);
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 06/22] Make -acpi-enable a machine specific option
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (4 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 05/22] machine: pass all init options as a single QemuOpts Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 07/22] machine: introduce -machine option Anthony Liguori
                   ` (16 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index c3f4f68..728908b 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -25,6 +25,7 @@ struct QEMUMachine {
         no_sdcard:1;
     int is_default;
     GlobalProperty *compat_props;
+    QemuOptDesc *opts_desc;
     struct QEMUMachine *next;
 };
 
@@ -32,4 +33,29 @@ int qemu_register_machine(QEMUMachine *m);
 
 extern QEMUMachine *current_machine;
 
+#define COMMON_MACHINE_OPTS() 		\
+    {                                   \
+        .name = "ram_size",             \
+        .type = QEMU_OPT_SIZE,          \
+    },{                                 \
+        .name = "kernel",               \
+        .type = QEMU_OPT_STRING,        \
+    },                                  \
+    {                                   \
+        .name = "cmdline",              \
+        .type = QEMU_OPT_STRING,        \
+    },                                  \
+    {                                   \
+        .name = "initrd",               \
+        .type = QEMU_OPT_STRING,        \
+    },                                  \
+    {                                   \
+        .name = "boot_device",          \
+        .type = QEMU_OPT_STRING,        \
+    },                                  \
+    {                                   \
+        .name = "cpu",                  \
+        .type = QEMU_OPT_STRING,        \
+    }
+
 #endif
diff --git a/hw/pc.h b/hw/pc.h
index 0e52933..1ae61e0 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -110,7 +110,6 @@ typedef void (*cpu_set_smm_t)(int smm, void *arg);
 void cpu_smm_register(cpu_set_smm_t callback, void *arg);
 
 /* acpi.c */
-extern int acpi_enabled;
 extern char *acpi_tables;
 extern size_t acpi_tables_len;
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c58cd42..1830aca 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -40,14 +40,14 @@ static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
 static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
 /* PC hardware initialisation */
-static void pc_init1(ram_addr_t ram_size,
-                     const char *boot_device,
-                     const char *kernel_filename,
-                     const char *kernel_cmdline,
-                     const char *initrd_filename,
-                     const char *cpu_model,
-                     int pci_enabled)
+static void pc_init1(QemuOpts *opts, int pci_enabled)
 {
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
+    const char *boot_device = qemu_opt_get(opts, "boot_device");
+    const char *kernel_filename = qemu_opt_get(opts, "kernel");
+    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
+    const char *initrd_filename = qemu_opt_get(opts, "initrd");
+    const char *cpu_model = qemu_opt_get(opts, "cpu");
     int i;
     ram_addr_t below_4g_mem_size, above_4g_mem_size;
     PCIBus *pci_bus;
@@ -133,7 +133,7 @@ static void pc_init1(ram_addr_t ram_size,
         usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
     }
 
-    if (pci_enabled && acpi_enabled) {
+    if (pci_enabled && qemu_opt_get_bool(opts, "acpi", 1)) {
         uint8_t *eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
         i2c_bus *smbus;
 
@@ -163,32 +163,27 @@ static void pc_init1(ram_addr_t ram_size,
 
 static void pc_init_pci(QemuOpts *opts)
 {
-    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
-    const char *boot_device = qemu_opt_get(opts, "boot_device");
-    const char *kernel_filename = qemu_opt_get(opts, "kernel");
-    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
-    const char *initrd_filename = qemu_opt_get(opts, "initrd");
-    const char *cpu_model = qemu_opt_get(opts, "cpu");
-    pc_init1(ram_size, boot_device,
-             kernel_filename, kernel_cmdline,
-             initrd_filename, cpu_model, 1);
+    pc_init1(opts, 1);
 }
 
 static void pc_init_isa(QemuOpts *opts)
 {
-    ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
-    const char *boot_device = qemu_opt_get(opts, "boot_device");
-    const char *kernel_filename = qemu_opt_get(opts, "kernel");
-    const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
-    const char *initrd_filename = qemu_opt_get(opts, "initrd");
-    const char *cpu_model = qemu_opt_get(opts, "cpu");
-    if (cpu_model == NULL)
-        cpu_model = "486";
-    pc_init1(ram_size, boot_device,
-             kernel_filename, kernel_cmdline,
-             initrd_filename, cpu_model, 0);
+    if (!qemu_opt_get(opts, "cpu")) {
+        qemu_opt_set(opts, "cpu", "486");
+    }
+
+    pc_init1(opts, 0);
 }
 
+static QemuOptDesc pc_opts_desc[] = {
+    COMMON_MACHINE_OPTS(),
+    {
+        .name = "acpi",
+        .type = QEMU_OPT_BOOL,
+    },
+    { /* end of list */ },
+};
+
 static QEMUMachine pc_machine = {
     .name = "pc-0.13",
     .alias = "pc",
@@ -196,6 +191,7 @@ static QEMUMachine pc_machine = {
     .init = pc_init_pci,
     .max_cpus = 255,
     .is_default = 1,
+    .opts_desc = pc_opts_desc,
 };
 
 static QEMUMachine pc_machine_v0_12 = {
@@ -203,6 +199,7 @@ static QEMUMachine pc_machine_v0_12 = {
     .desc = "Standard PC",
     .init = pc_init_pci,
     .max_cpus = 255,
+    .opts_desc = pc_opts_desc,
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-serial-pci",
@@ -222,6 +219,7 @@ static QEMUMachine pc_machine_v0_11 = {
     .desc = "Standard PC, qemu 0.11",
     .init = pc_init_pci,
     .max_cpus = 255,
+    .opts_desc = pc_opts_desc,
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-blk-pci",
@@ -257,6 +255,7 @@ static QEMUMachine pc_machine_v0_10 = {
     .desc = "Standard PC, qemu 0.10",
     .init = pc_init_pci,
     .max_cpus = 255,
+    .opts_desc = pc_opts_desc,
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-blk-pci",
diff --git a/vl.c b/vl.c
index 87009eb..4fc4c20 100644
--- a/vl.c
+++ b/vl.c
@@ -209,7 +209,7 @@ int max_cpus = 0;
 int smp_cores = 1;
 int smp_threads = 1;
 const char *vnc_display;
-int acpi_enabled = 1;
+static int acpi_enabled = 1;
 int no_hpet = 0;
 int fd_bootchk = 1;
 int no_reboot = 0;
@@ -2550,32 +2550,8 @@ static const QEMUOption *lookup_opt(int argc, char **argv,
     return popt;
 }
 
-/* TEMP: until we have proper -machine support */
 static QemuOptDesc common_machine_opts[] = {
-    {
-        .name = "ram_size",
-        .type = QEMU_OPT_SIZE,
-    },
-    {
-        .name = "kernel",
-        .type = QEMU_OPT_STRING,
-    },
-    {
-        .name = "cmdline",
-        .type = QEMU_OPT_STRING,
-    },
-    {
-        .name = "initrd",
-        .type = QEMU_OPT_STRING,
-    },
-    {
-        .name = "boot_device",
-        .type = QEMU_OPT_STRING,
-    },
-    {
-        .name = "cpu",
-        .type = QEMU_OPT_STRING,
-    },
+    COMMON_MACHINE_OPTS(),
     { /* end of list */ },
 };
 
@@ -3771,8 +3747,18 @@ int main(int argc, char **argv, char **envp)
         qemu_opt_set(opts, "ram_size", buffer);
     }
 
-    if (qemu_opts_validate(opts, common_machine_opts) < 0) {
-        exit(1);
+    if (acpi_enabled == 0) {
+        qemu_opt_set(opts, "acpi", "off");
+    }
+
+    if (machine->opts_desc) {
+        if (qemu_opts_validate(opts, machine->opts_desc) < 0) {
+            exit(1);
+        }
+    } else {
+        if (qemu_opts_validate(opts, common_machine_opts) < 0) {
+            exit(1);
+        }
     }
     
     machine->init(opts);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 07/22] machine: introduce -machine option
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (5 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 06/22] Make -acpi-enable a machine specific option Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 08/22] machine: implement -kernel/-append/-initrd options in term of -machine Anthony Liguori
                   ` (15 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

This introduces a new -machine option that can be used to tweak machine specific
parameters.  One unusal feature of -machine is that there is only one machine
instance and all uses of -machine are combined together.  The last operation
to a parameter is given priority.

This let's a configuration file specify a set of default machine properties that
can then be overridden by a user.

This patch also makes -M a syntactic helper for -machine.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index 728908b..0092557 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -35,6 +35,10 @@ extern QEMUMachine *current_machine;
 
 #define COMMON_MACHINE_OPTS() 		\
     {                                   \
+        .name = "driver",               \
+        .type = QEMU_OPT_STRING,        \
+    },                                  \
+    {                                   \
         .name = "ram_size",             \
         .type = QEMU_OPT_SIZE,          \
     },{                                 \
diff --git a/qemu-config.c b/qemu-config.c
index 3679a9f..a0cb34f 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -338,6 +338,7 @@ QemuOptsList qemu_cpudef_opts = {
 
 QemuOptsList qemu_machine_opts = {
     .name = "machine",
+    .implied_opt_name = "driver",
     .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
     .desc = {
         { /* end of list */ }
diff --git a/qemu-option.c b/qemu-option.c
index b990cf5..61a2613 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -794,6 +794,27 @@ int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname
     return 0;
 }
 
+QemuOpts *qemu_opts_parsev(QemuOptsList *list, const char *params,
+                           va_list ap)
+{
+    char buffer[4096];
+    vsnprintf(buffer, sizeof(buffer), params, ap);
+    return qemu_opts_parse(list, buffer, 0);
+}
+
+QemuOpts *qemu_opts_parsef(QemuOptsList *list, const char *params,
+                           ...)
+{
+    va_list ap;
+    QemuOpts *opts;
+
+    va_start(ap, params);
+    opts = qemu_opts_parsev(list, params, ap);
+    va_end(ap);
+
+    return opts;
+}
+
 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
                           int permit_abbrev)
 {
diff --git a/qemu-option.h b/qemu-option.h
index 4a6717c..85ab58e 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -129,6 +129,8 @@ void qemu_opts_del(QemuOpts *opts);
 int qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc);
 int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char *firstname);
 QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int permit_abbrev);
+QemuOpts *qemu_opts_parsev(QemuOptsList *list, const char *params, va_list ap);
+QemuOpts *qemu_opts_parsef(QemuOptsList *list, const char *params, ...);
 QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict);
 QDict *qemu_opts_to_qdict(QemuOpts *opts, QDict *qdict);
 
diff --git a/qemu-options.hx b/qemu-options.hx
index a6928b7..32fd32a 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -35,6 +35,14 @@ STEXI
 Select the emulated @var{machine} (@code{-M ?} for list)
 ETEXI
 
+DEF("machine", HAS_ARG, QEMU_OPTION_machine,
+    "-machine machine[,opt=val...] select emulated machine\n", QEMU_ARCH_ALL)
+STEXI
+@item -machine @var{machine}[,@var{opt}=@var{val}...]
+@findex -machine
+Select the emulated @var{machine}
+ETEXI
+
 DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
     "-cpu cpu        select CPU (-cpu ? for list)\n", QEMU_ARCH_ALL)
 STEXI
diff --git a/vl.c b/vl.c
index 4fc4c20..001adbe 100644
--- a/vl.c
+++ b/vl.c
@@ -2555,6 +2555,24 @@ static QemuOptDesc common_machine_opts[] = {
     { /* end of list */ },
 };
 
+static int machine_combine_opt(const char *name, const char *value, void *opaque)
+{
+    QemuOpts *base_opts = opaque;
+    qemu_opt_set(base_opts, name, value);
+    return 0;
+}
+
+static int machine_combine_opts(QemuOpts *opts, void *opaque)
+{
+    QemuOpts *base_opts = opaque;
+
+    if (base_opts == opts) {
+        return 0;
+    }
+
+    return qemu_opt_foreach(opts, machine_combine_opt, base_opts, 0);
+}
+
 int main(int argc, char **argv, char **envp)
 {
     const char *gdbstub_dev = NULL;
@@ -2571,7 +2589,7 @@ int main(int argc, char **argv, char **envp)
     int optind;
     const char *optarg;
     const char *loadvm = NULL;
-    QEMUMachine *machine;
+    QEMUMachine *machine = NULL;
     const char *cpu_model;
 #ifndef _WIN32
     int fds[2];
@@ -2587,6 +2605,7 @@ int main(int argc, char **argv, char **envp)
 #endif
     int show_vnc_port = 0;
     int defconfig = 1;
+    QemuOpts *machine_opts = NULL;
 
     error_set_progname(argv[0]);
 
@@ -2626,7 +2645,6 @@ int main(int argc, char **argv, char **envp)
 #endif
 
     module_call_init(MODULE_INIT_MACHINE);
-    machine = find_default_machine();
     cpu_model = NULL;
     initrd_filename = NULL;
     ram_size = 0;
@@ -2698,8 +2716,7 @@ int main(int argc, char **argv, char **envp)
             }
             switch(popt->index) {
             case QEMU_OPTION_M:
-                machine = find_machine(optarg);
-                if (!machine) {
+                if (strcmp(optarg, "?") == 0) {
                     QEMUMachine *m;
                     printf("Supported machines are:\n");
                     for(m = first_machine; m != NULL; m = m->next) {
@@ -2710,7 +2727,13 @@ int main(int argc, char **argv, char **envp)
                                m->name, m->desc,
                                m->is_default ? " (default)" : "");
                     }
-                    exit(*optarg != '?');
+                    exit(0);
+                }
+                qemu_opts_parsef(&qemu_machine_opts, "driver=%s", optarg);
+                break;
+            case QEMU_OPTION_machine:
+                if (!qemu_opts_parse(&qemu_machine_opts, optarg, 1)) {
+                    exit(1);
                 }
                 break;
             case QEMU_OPTION_cpu:
@@ -3431,6 +3454,26 @@ int main(int argc, char **argv, char **envp)
         data_dir = CONFIG_QEMU_SHAREDIR;
     }
 
+    /* Combine all -machine options into one option group */
+    machine_opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
+    qemu_opts_foreach(&qemu_machine_opts, machine_combine_opts, machine_opts, 0);
+
+    if (!qemu_opt_get(machine_opts, "driver")) {
+        machine = find_default_machine();
+    } else {
+        machine = find_machine(qemu_opt_get(machine_opts, "driver"));
+    }
+
+    if (machine->opts_desc) {
+        if (qemu_opts_validate(machine_opts, machine->opts_desc) < 0) {
+            exit(1);
+        }
+    } else {
+        if (qemu_opts_validate(machine_opts, common_machine_opts) < 0) {
+            exit(1);
+        }
+    }
+    
     /*
      * Default to max_cpus = smp_cpus, in case the user doesn't
      * specify a max_cpus value.
@@ -3723,47 +3766,36 @@ int main(int argc, char **argv, char **envp)
     }
     qemu_add_globals();
 
-    opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
     if (kernel_filename) {
-        qemu_opt_set(opts, "kernel", kernel_filename);
+        qemu_opt_set(machine_opts, "kernel", kernel_filename);
         if (kernel_cmdline) {
-            qemu_opt_set(opts, "cmdline", kernel_cmdline);
+            qemu_opt_set(machine_opts, "cmdline", kernel_cmdline);
         }
         if (initrd_filename) {
-            qemu_opt_set(opts, "initrd", initrd_filename);
+            qemu_opt_set(machine_opts, "initrd", initrd_filename);
         }
     }
 
-    qemu_opt_set(opts, "boot_device", boot_devices);
+    qemu_opt_set(machine_opts, "boot_device", boot_devices);
 
     if (cpu_model) {
-        qemu_opt_set(opts, "cpu", cpu_model);
+        qemu_opt_set(machine_opts, "cpu", cpu_model);
     }
 
     if (ram_size) {
         char buffer[64];
         snprintf(buffer, sizeof(buffer),
                  "%" PRId64, ram_size);
-        qemu_opt_set(opts, "ram_size", buffer);
+        qemu_opt_set(machine_opts, "ram_size", buffer);
     }
 
     if (acpi_enabled == 0) {
-        qemu_opt_set(opts, "acpi", "off");
+        qemu_opt_set(machine_opts, "acpi", "off");
     }
 
-    if (machine->opts_desc) {
-        if (qemu_opts_validate(opts, machine->opts_desc) < 0) {
-            exit(1);
-        }
-    } else {
-        if (qemu_opts_validate(opts, common_machine_opts) < 0) {
-            exit(1);
-        }
-    }
-    
-    machine->init(opts);
+    machine->init(machine_opts);
 
-    qemu_opts_del(opts);
+    qemu_opts_del(machine_opts);
 
     cpu_synchronize_all_post_init();
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 08/22] machine: implement -kernel/-append/-initrd options in term of -machine
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (6 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 07/22] machine: introduce -machine option Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 09/22] machine: implement -m in terms " Anthony Liguori
                   ` (14 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/vl.c b/vl.c
index 001adbe..4553648 100644
--- a/vl.c
+++ b/vl.c
@@ -2577,10 +2577,8 @@ int main(int argc, char **argv, char **envp)
 {
     const char *gdbstub_dev = NULL;
     int i;
-    int snapshot, linux_boot;
+    int snapshot;
     const char *icount_option = NULL;
-    const char *initrd_filename;
-    const char *kernel_filename, *kernel_cmdline;
     char boot_devices[33] = "cad"; /* default to HD->floppy->CD-ROM */
     DisplayState *ds;
     DisplayChangeListener *dcl;
@@ -2646,11 +2644,8 @@ int main(int argc, char **argv, char **envp)
 
     module_call_init(MODULE_INIT_MACHINE);
     cpu_model = NULL;
-    initrd_filename = NULL;
     ram_size = 0;
     snapshot = 0;
-    kernel_filename = NULL;
-    kernel_cmdline = "";
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
 
@@ -2746,7 +2741,7 @@ int main(int argc, char **argv, char **envp)
                 }
                 break;
             case QEMU_OPTION_initrd:
-                initrd_filename = optarg;
+                qemu_opts_parsef(&qemu_machine_opts, "initrd=%s", optarg);
                 break;
             case QEMU_OPTION_hda:
                 if (cyls == 0)
@@ -2856,10 +2851,10 @@ int main(int argc, char **argv, char **envp)
                 graphic_rotate = 1;
                 break;
             case QEMU_OPTION_kernel:
-                kernel_filename = optarg;
+                qemu_opts_parsef(&qemu_machine_opts, "kernel=%s", optarg);
                 break;
             case QEMU_OPTION_append:
-                kernel_cmdline = optarg;
+                qemu_opts_parsef(&qemu_machine_opts, "cmdline=%s", optarg);
                 break;
             case QEMU_OPTION_cdrom:
                 drive_add(optarg, CDROM_ALIAS);
@@ -3629,17 +3624,6 @@ int main(int argc, char **argv, char **envp)
         fprintf(stderr, "qemu_init_main_loop failed\n");
         exit(1);
     }
-    linux_boot = (kernel_filename != NULL);
-
-    if (!linux_boot && *kernel_cmdline != '\0') {
-        fprintf(stderr, "-append only allowed with -kernel option\n");
-        exit(1);
-    }
-
-    if (!linux_boot && initrd_filename != NULL) {
-        fprintf(stderr, "-initrd only allowed with -kernel option\n");
-        exit(1);
-    }
 
 #ifndef _WIN32
     /* Win32 doesn't support line-buffering and requires size >= 2 */
@@ -3766,16 +3750,6 @@ int main(int argc, char **argv, char **envp)
     }
     qemu_add_globals();
 
-    if (kernel_filename) {
-        qemu_opt_set(machine_opts, "kernel", kernel_filename);
-        if (kernel_cmdline) {
-            qemu_opt_set(machine_opts, "cmdline", kernel_cmdline);
-        }
-        if (initrd_filename) {
-            qemu_opt_set(machine_opts, "initrd", initrd_filename);
-        }
-    }
-
     qemu_opt_set(machine_opts, "boot_device", boot_devices);
 
     if (cpu_model) {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 09/22] machine: implement -m in terms of -machine
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (7 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 08/22] machine: implement -kernel/-append/-initrd options in term of -machine Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc Anthony Liguori
                   ` (13 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/vl.c b/vl.c
index 4553648..398d3b4 100644
--- a/vl.c
+++ b/vl.c
@@ -2968,35 +2968,14 @@ int main(int argc, char **argv, char **envp)
                 version();
                 exit(0);
                 break;
-            case QEMU_OPTION_m: {
-                uint64_t value;
-                char *ptr;
-
-                value = strtoul(optarg, &ptr, 10);
-                switch (*ptr) {
-                case 0: case 'M': case 'm':
-                    value <<= 20;
-                    break;
-                case 'G': case 'g':
-                    value <<= 30;
-                    break;
-                default:
-                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
-                    exit(1);
-                }
-
-                /* On 32-bit hosts, QEMU is limited by virtual address space */
-                if (value > (2047 << 20) && HOST_LONG_BITS == 32) {
-                    fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
-                    exit(1);
-                }
-                if (value != (uint64_t)(ram_addr_t)value) {
-                    fprintf(stderr, "qemu: ram size too large\n");
-                    exit(1);
+            case QEMU_OPTION_m:
+                /* Default to 'M' which is not the normal behavior */
+                if (*optarg && isdigit(optarg[strlen(optarg) - 1])) {
+                    qemu_opts_parsef(&qemu_machine_opts, "ram_size=%sM", optarg);
+                } else {
+                    qemu_opts_parsef(&qemu_machine_opts, "ram_size=%s", optarg);
                 }
-                ram_size = value;
                 break;
-            }
             case QEMU_OPTION_mempath:
                 mem_path = optarg;
                 break;
@@ -3645,8 +3624,26 @@ int main(int argc, char **argv, char **envp)
         exit(1);
 
     /* init the memory */
-    if (ram_size == 0)
-        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+    ram_size = qemu_opt_get_size(machine_opts, "ram_size", 
+                                 DEFAULT_RAM_SIZE * 1024 * 1024);
+
+
+    if (!qemu_opt_get(machine_opts, "ram_size")) {
+        char buffer[64];
+        snprintf(buffer, sizeof(buffer), "%" PRId64, ram_size);
+        qemu_opt_set(machine_opts, "ram_size", buffer);
+    }
+
+    /* On 32-bit hosts, QEMU is limited by virtual address space */
+    if (ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
+        fprintf(stderr, "qemu: at most 2047 MB RAM can be simulated\n");
+        exit(1);
+    }
+
+    if (ram_size != (uint64_t)(ram_addr_t)ram_size) {
+        fprintf(stderr, "qemu: ram size too large\n");
+        exit(1);
+    }
 
     /* init the dynamic translator */
     cpu_exec_init_all(tb_size * 1024 * 1024);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (8 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 09/22] machine: implement -m in terms " Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-08  8:03   ` Gerd Hoffmann
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 11/22] machine: replace compat_props with opts_default Anthony Liguori
                   ` (12 subsequent siblings)
  22 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Let boards describe default options.  Structuring this way is an important step
in making board definitions readable by a config file.

To use the new mechanism, introduce a pci=on|off option to the pc boards and
unify all of them into a single function.  isapc is now just another pc board
that happens to have different default values.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index 0092557..06b9f73 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -26,6 +26,7 @@ struct QEMUMachine {
     int is_default;
     GlobalProperty *compat_props;
     QemuOptDesc *opts_desc;
+    QemuOptValue *opts_default;
     struct QEMUMachine *next;
 };
 
diff --git a/hw/pc.c b/hw/pc.c
index 48b3730..44f5b62 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -794,15 +794,6 @@ void pc_cpus_init(const char *cpu_model)
 {
     int i;
 
-    /* init CPUs */
-    if (cpu_model == NULL) {
-#ifdef TARGET_X86_64
-        cpu_model = "qemu64";
-#else
-        cpu_model = "qemu32";
-#endif
-    }
-
     for(i = 0; i < smp_cpus; i++) {
         pc_new_cpu(cpu_model);
     }
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 1830aca..0ad1145 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -40,7 +40,7 @@ static const int ide_iobase2[MAX_IDE_BUS] = { 0x3f6, 0x376 };
 static const int ide_irq[MAX_IDE_BUS] = { 14, 15 };
 
 /* PC hardware initialisation */
-static void pc_init1(QemuOpts *opts, int pci_enabled)
+static void pc_init(QemuOpts *opts)
 {
     ram_addr_t ram_size = qemu_opt_get_size(opts, "ram_size", 0);
     const char *boot_device = qemu_opt_get(opts, "boot_device");
@@ -48,6 +48,7 @@ static void pc_init1(QemuOpts *opts, int pci_enabled)
     const char *kernel_cmdline = qemu_opt_get(opts, "cmdline");
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
+    int pci_enabled = qemu_opt_get_bool(opts, "pci", 1);
     int i;
     ram_addr_t below_4g_mem_size, above_4g_mem_size;
     PCIBus *pci_bus;
@@ -161,45 +162,71 @@ static void pc_init1(QemuOpts *opts, int pci_enabled)
     }
 }
 
-static void pc_init_pci(QemuOpts *opts)
-{
-    pc_init1(opts, 1);
-}
-
-static void pc_init_isa(QemuOpts *opts)
-{
-    if (!qemu_opt_get(opts, "cpu")) {
-        qemu_opt_set(opts, "cpu", "486");
-    }
-
-    pc_init1(opts, 0);
-}
-
 static QemuOptDesc pc_opts_desc[] = {
     COMMON_MACHINE_OPTS(),
     {
         .name = "acpi",
         .type = QEMU_OPT_BOOL,
     },
+    {
+        .name = "pci",
+        .type = QEMU_OPT_BOOL,
+    },
     { /* end of list */ },
 };
 
+#ifdef TARGET_X86_64
+#define PC_DEFAULT_CPU_MODEL "qemu64"
+#else
+#define PC_DEFAULT_CPU_MODEL "qemu32"
+#endif
+
 static QEMUMachine pc_machine = {
     .name = "pc-0.13",
     .alias = "pc",
     .desc = "Standard PC",
-    .init = pc_init_pci,
+    .init = pc_init,
     .max_cpus = 255,
     .is_default = 1,
     .opts_desc = pc_opts_desc,
+    .opts_default = (QemuOptValue[]) {
+        {
+            .name  = "acpi",
+            .value = "on",
+        },
+        {
+            .name  = "pci",
+            .value = "on",
+        },
+        {
+            .name = "cpu",
+            .value = PC_DEFAULT_CPU_MODEL,
+        },
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine pc_machine_v0_12 = {
     .name = "pc-0.12",
     .desc = "Standard PC",
-    .init = pc_init_pci,
+    .init = pc_init,
     .max_cpus = 255,
     .opts_desc = pc_opts_desc,
+    .opts_default = (QemuOptValue[]) {
+        {
+            .name  = "acpi",
+            .value = "on",
+        },
+        {
+            .name  = "pci",
+            .value = "on",
+        },
+        {
+            .name = "cpu",
+            .value = PC_DEFAULT_CPU_MODEL,
+        },
+        { /* end of list */ }
+    },
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-serial-pci",
@@ -217,9 +244,24 @@ static QEMUMachine pc_machine_v0_12 = {
 static QEMUMachine pc_machine_v0_11 = {
     .name = "pc-0.11",
     .desc = "Standard PC, qemu 0.11",
-    .init = pc_init_pci,
+    .init = pc_init,
     .max_cpus = 255,
     .opts_desc = pc_opts_desc,
+    .opts_default = (QemuOptValue[]) {
+        {
+            .name  = "acpi",
+            .value = "on",
+        },
+        {
+            .name  = "pci",
+            .value = "on",
+        },
+        {
+            .name = "cpu",
+            .value = PC_DEFAULT_CPU_MODEL,
+        },
+        { /* end of list */ }
+    },
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-blk-pci",
@@ -253,9 +295,24 @@ static QEMUMachine pc_machine_v0_11 = {
 static QEMUMachine pc_machine_v0_10 = {
     .name = "pc-0.10",
     .desc = "Standard PC, qemu 0.10",
-    .init = pc_init_pci,
+    .init = pc_init,
     .max_cpus = 255,
     .opts_desc = pc_opts_desc,
+    .opts_default = (QemuOptValue[]) {
+        {
+            .name  = "acpi",
+            .value = "on",
+        },
+        {
+            .name  = "pci",
+            .value = "on",
+        },
+        {
+            .name = "cpu",
+            .value = PC_DEFAULT_CPU_MODEL,
+        },
+        { /* end of list */ }
+    },
     .compat_props = (GlobalProperty[]) {
         {
             .driver   = "virtio-blk-pci",
@@ -301,7 +358,23 @@ static QEMUMachine pc_machine_v0_10 = {
 static QEMUMachine isapc_machine = {
     .name = "isapc",
     .desc = "ISA-only PC",
-    .init = pc_init_isa,
+    .opts_desc = pc_opts_desc,
+    .init = pc_init,
+    .opts_default = (QemuOptValue[]) {
+        {
+            .name  = "acpi",
+            .value = "off",
+        },
+        {
+            .name  = "pci",
+            .value = "off",
+        },
+        {
+            .name = "cpu",
+            .value = "486",
+        },
+        { /* end of list */ }
+    },
     .max_cpus = 1,
 };
 
diff --git a/vl.c b/vl.c
index 398d3b4..a7f0a3d 100644
--- a/vl.c
+++ b/vl.c
@@ -3438,6 +3438,10 @@ int main(int argc, char **argv, char **envp)
         machine = find_machine(qemu_opt_get(machine_opts, "driver"));
     }
 
+    if (machine->opts_default) {
+        qemu_opts_set_defaults(machine_opts, machine->opts_default);
+    }
+
     if (machine->opts_desc) {
         if (qemu_opts_validate(machine_opts, machine->opts_desc) < 0) {
             exit(1);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 11/22] machine: replace compat_props with opts_default
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (9 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc Anthony Liguori
@ 2010-06-07 23:51 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 12/22] machine: some sugary macros to simplify machine default options Anthony Liguori
                   ` (11 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:51 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Right now, machine structs can hard code GlobalProperty lists of default qdev
global properties.  This doesn't generalize well to a config file though because
there are three parameters: driver, property, value.

This patch moves this data to the generic machine opts default list.  In the
process, it converts the form to driver.property=value.  Now any option with
a '.' in the name is treated as a compat global property.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index 06b9f73..c7358ae 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -24,7 +24,6 @@ struct QEMUMachine {
         no_cdrom:1,
         no_sdcard:1;
     int is_default;
-    GlobalProperty *compat_props;
     QemuOptDesc *opts_desc;
     QemuOptValue *opts_default;
     struct QEMUMachine *next;
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 0ad1145..28c1408 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -225,20 +225,15 @@ static QEMUMachine pc_machine_v0_12 = {
             .name = "cpu",
             .value = PC_DEFAULT_CPU_MODEL,
         },
-        { /* end of list */ }
-    },
-    .compat_props = (GlobalProperty[]) {
         {
-            .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
-            .value    = stringify(1),
+            .name = "virtio-serial-pci.max_nr_ports",
+            .value = stringify(1),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
+            .name = "virtio-serial-pci.vectors",
+            .value = stringify(0),
         },
         { /* end of list */ }
-    }
+    },
 };
 
 static QEMUMachine pc_machine_v0_11 = {
@@ -260,33 +255,24 @@ static QEMUMachine pc_machine_v0_11 = {
             .name = "cpu",
             .value = PC_DEFAULT_CPU_MODEL,
         },
-        { /* end of list */ }
-    },
-    .compat_props = (GlobalProperty[]) {
         {
-            .driver   = "virtio-blk-pci",
-            .property = "vectors",
-            .value    = stringify(0),
+            .name = "virtio-blk-pci.vectors",
+            .value = stringify(0),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
-            .value    = stringify(1),
+            .name = "virtio-serial-pci.max_nr_ports",
+            .value = stringify(1),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
+            .name = "virtio-serial-pci.vectors",
+            .value = stringify(0),
         },{
-            .driver   = "ide-drive",
-            .property = "ver",
-            .value    = "0.11",
+            .name = "ide-drive.ver",
+            .value = "0.11",
         },{
-            .driver   = "scsi-disk",
-            .property = "ver",
-            .value    = "0.11",
+            .name = "scsi-disk.ver",
+            .value = "0.11",
         },{
-            .driver   = "PCI",
-            .property = "rombar",
-            .value    = stringify(0),
+            .name = "PCI.rombar",
+            .value = stringify(0),
         },
         { /* end of list */ }
     }
@@ -311,45 +297,33 @@ static QEMUMachine pc_machine_v0_10 = {
             .name = "cpu",
             .value = PC_DEFAULT_CPU_MODEL,
         },
-        { /* end of list */ }
-    },
-    .compat_props = (GlobalProperty[]) {
         {
-            .driver   = "virtio-blk-pci",
-            .property = "class",
-            .value    = stringify(PCI_CLASS_STORAGE_OTHER),
+            .name = "virtio-blk-pci.class",
+            .value = stringify(PCI_CLASS_STORAGE_OTHER),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "class",
-            .value    = stringify(PCI_CLASS_DISPLAY_OTHER),
+            .name = "virtio-serial-pci.class",
+            .value = stringify(PCI_CLASS_DISPLAY_OTHER),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
-            .value    = stringify(1),
+            .name = "virtio-serial-pci.max_nr_ports",
+            .value = stringify(1),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
+            .name = "virtio-serial-pci.vectors",
+            .value = stringify(0),
         },{
-            .driver   = "virtio-net-pci",
-            .property = "vectors",
-            .value    = stringify(0),
+            .name = "virtio-net-pci.vectors",
+            .value = stringify(0),
         },{
-            .driver   = "virtio-blk-pci",
-            .property = "vectors",
-            .value    = stringify(0),
+            .name = "virtio-blk-pci.vectors",
+            .value = stringify(0),
         },{
-            .driver   = "ide-drive",
-            .property = "ver",
-            .value    = "0.10",
+            .name = "ide-drive.ver",
+            .value = "0.10",
         },{
-            .driver   = "scsi-disk",
-            .property = "ver",
-            .value    = "0.10",
+            .name = "scsi-disk.ver",
+            .value = "0.10",
         },{
-            .driver   = "PCI",
-            .property = "rombar",
-            .value    = stringify(0),
+            .name = "PCI.rombar",
+            .value = stringify(0),
         },
         { /* end of list */ }
     },
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index ddbefb7..8ed4632 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -183,15 +183,13 @@ static QEMUMachine bamboo_machine_v0_12 = {
     .name = "bamboo-0.12",
     .desc = "bamboo",
     .init = bamboo_init,
-    .compat_props = (GlobalProperty[]) {
+    .opts_default = (QemuOptValue[]) {
         {
-            .driver   = "virtio-serial-pci",
-            .property = "max_nr_ports",
-            .value    = stringify(1),
+            .name = "virtio-serial-pci.max_nr_ports",
+            .value = stringify(1),
         },{
-            .driver   = "virtio-serial-pci",
-            .property = "vectors",
-            .value    = stringify(0),
+            .name = "virtio-serial-pci.vectors",
+            .value = stringify(0),
         },
         { /* end of list */ }
     },
diff --git a/hw/qdev-properties.c b/hw/qdev-properties.c
index 9ffdba7..edd5ebd 100644
--- a/hw/qdev-properties.c
+++ b/hw/qdev-properties.c
@@ -661,7 +661,7 @@ void qdev_prop_set_defaults(DeviceState *dev, Property *props)
 
 static QTAILQ_HEAD(, GlobalProperty) global_props = QTAILQ_HEAD_INITIALIZER(global_props);
 
-static void qdev_prop_register_global(GlobalProperty *prop)
+void qdev_prop_register_global(GlobalProperty *prop)
 {
     QTAILQ_INSERT_TAIL(&global_props, prop, next);
 }
diff --git a/hw/qdev.h b/hw/qdev.h
index a44060e..9700b7a 100644
--- a/hw/qdev.h
+++ b/hw/qdev.h
@@ -277,6 +277,7 @@ void qdev_prop_set_macaddr(DeviceState *dev, const char *name, uint8_t *value);
 void qdev_prop_set_ptr(DeviceState *dev, const char *name, void *value);
 void qdev_prop_set_defaults(DeviceState *dev, Property *props);
 
+void qdev_prop_register_global(GlobalProperty *props);
 void qdev_prop_register_global_list(GlobalProperty *props);
 void qdev_prop_set_globals(DeviceState *dev);
 
diff --git a/vl.c b/vl.c
index a7f0a3d..0a31a45 100644
--- a/vl.c
+++ b/vl.c
@@ -2558,7 +2558,42 @@ static QemuOptDesc common_machine_opts[] = {
 static int machine_combine_opt(const char *name, const char *value, void *opaque)
 {
     QemuOpts *base_opts = opaque;
-    qemu_opt_set(base_opts, name, value);
+    char *ptr;
+
+    ptr = strchr(name, '.');
+    if (ptr) {
+        GlobalProperty *prop;
+        char *driver, *property;
+
+        prop = qemu_mallocz(sizeof(*prop));
+        driver = qemu_mallocz(strlen(name) + 1);
+        property = qemu_mallocz(strlen(name) + 1);
+
+        memcpy(driver, name, (ptr - name));
+        driver[(ptr - name)] = 0;
+        strcpy(property, ptr + 1);
+
+        prop->driver = driver;
+        prop->property = property;
+        prop->value = strdup(value);
+
+        qdev_prop_register_global(prop);
+    } else {
+        qemu_opt_set(base_opts, name, value);
+    }
+    return 0;
+}
+
+static int machine_find(QemuOpts *opts, void *opaque)
+{
+    QEMUMachine **machinep = opaque;
+    const char *driver;
+
+    driver = qemu_opt_get(opts, "driver");
+    if (driver) {
+        *machinep = find_machine(driver);
+    }
+
     return 0;
 }
 
@@ -3428,20 +3463,20 @@ int main(int argc, char **argv, char **envp)
         data_dir = CONFIG_QEMU_SHAREDIR;
     }
 
-    /* Combine all -machine options into one option group */
-    machine_opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
-    qemu_opts_foreach(&qemu_machine_opts, machine_combine_opts, machine_opts, 0);
-
-    if (!qemu_opt_get(machine_opts, "driver")) {
+    qemu_opts_foreach(&qemu_machine_opts, machine_find, &machine, 0);
+    if (!machine) {
         machine = find_default_machine();
-    } else {
-        machine = find_machine(qemu_opt_get(machine_opts, "driver"));
     }
 
     if (machine->opts_default) {
-        qemu_opts_set_defaults(machine_opts, machine->opts_default);
+        opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
+        qemu_opts_set_defaults(opts, machine->opts_default);
     }
 
+    /* Combine all -machine options into one option group */
+    machine_opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
+    qemu_opts_foreach(&qemu_machine_opts, machine_combine_opts, machine_opts, 0);
+
     if (machine->opts_desc) {
         if (qemu_opts_validate(machine_opts, machine->opts_desc) < 0) {
             exit(1);
@@ -3746,9 +3781,6 @@ int main(int argc, char **argv, char **envp)
             exit (i == 1 ? 1 : 0);
     }
 
-    if (machine->compat_props) {
-        qdev_prop_register_global_list(machine->compat_props);
-    }
     qemu_add_globals();
 
     qemu_opt_set(machine_opts, "boot_device", boot_devices);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 12/22] machine: some sugary macros to simplify machine default options
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (10 preceding siblings ...)
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 11/22] machine: replace compat_props with opts_default Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 13/22] machine: get rid of global default QEMUMachine members Anthony Liguori
                   ` (10 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index c7358ae..e05637b 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -33,6 +33,12 @@ int qemu_register_machine(QEMUMachine *m);
 
 extern QEMUMachine *current_machine;
 
+#define QOPT_COMPAT(driver, property, value) \
+    QOPT_VALUE(driver "." property, value)
+
+#define QOPT_COMPAT_INT(driver, property, value) \
+    QOPT_VALUE(driver "." property, stringify(value))
+
 #define COMMON_MACHINE_OPTS() 		\
     {                                   \
         .name = "driver",               \
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 28c1408..104206c 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -190,18 +190,9 @@ static QEMUMachine pc_machine = {
     .is_default = 1,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
-        {
-            .name  = "acpi",
-            .value = "on",
-        },
-        {
-            .name  = "pci",
-            .value = "on",
-        },
-        {
-            .name = "cpu",
-            .value = PC_DEFAULT_CPU_MODEL,
-        },
+        QOPT_VALUE("acpi", "on"),
+        QOPT_VALUE("pci", "on"),
+        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
         { /* end of list */ }
     },
 };
@@ -213,25 +204,11 @@ static QEMUMachine pc_machine_v0_12 = {
     .max_cpus = 255,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
-        {
-            .name  = "acpi",
-            .value = "on",
-        },
-        {
-            .name  = "pci",
-            .value = "on",
-        },
-        {
-            .name = "cpu",
-            .value = PC_DEFAULT_CPU_MODEL,
-        },
-        {
-            .name = "virtio-serial-pci.max_nr_ports",
-            .value = stringify(1),
-        },{
-            .name = "virtio-serial-pci.vectors",
-            .value = stringify(0),
-        },
+        QOPT_VALUE("acpi", "on"),
+        QOPT_VALUE("pci", "on"),
+        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
+        QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
         { /* end of list */ }
     },
 };
@@ -243,37 +220,15 @@ static QEMUMachine pc_machine_v0_11 = {
     .max_cpus = 255,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
-        {
-            .name  = "acpi",
-            .value = "on",
-        },
-        {
-            .name  = "pci",
-            .value = "on",
-        },
-        {
-            .name = "cpu",
-            .value = PC_DEFAULT_CPU_MODEL,
-        },
-        {
-            .name = "virtio-blk-pci.vectors",
-            .value = stringify(0),
-        },{
-            .name = "virtio-serial-pci.max_nr_ports",
-            .value = stringify(1),
-        },{
-            .name = "virtio-serial-pci.vectors",
-            .value = stringify(0),
-        },{
-            .name = "ide-drive.ver",
-            .value = "0.11",
-        },{
-            .name = "scsi-disk.ver",
-            .value = "0.11",
-        },{
-            .name = "PCI.rombar",
-            .value = stringify(0),
-        },
+        QOPT_VALUE("acpi", "on"),
+        QOPT_VALUE("pci", "on"),
+        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
+        QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
+        QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
+        QOPT_COMPAT("ide-drive", "ver", "0.11"),
+        QOPT_COMPAT("scsi-disk", "ver", "0.11"),
+        QOPT_COMPAT_INT("PCI", "rombar", 0),
         { /* end of list */ }
     }
 };
@@ -285,46 +240,18 @@ static QEMUMachine pc_machine_v0_10 = {
     .max_cpus = 255,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
-        {
-            .name  = "acpi",
-            .value = "on",
-        },
-        {
-            .name  = "pci",
-            .value = "on",
-        },
-        {
-            .name = "cpu",
-            .value = PC_DEFAULT_CPU_MODEL,
-        },
-        {
-            .name = "virtio-blk-pci.class",
-            .value = stringify(PCI_CLASS_STORAGE_OTHER),
-        },{
-            .name = "virtio-serial-pci.class",
-            .value = stringify(PCI_CLASS_DISPLAY_OTHER),
-        },{
-            .name = "virtio-serial-pci.max_nr_ports",
-            .value = stringify(1),
-        },{
-            .name = "virtio-serial-pci.vectors",
-            .value = stringify(0),
-        },{
-            .name = "virtio-net-pci.vectors",
-            .value = stringify(0),
-        },{
-            .name = "virtio-blk-pci.vectors",
-            .value = stringify(0),
-        },{
-            .name = "ide-drive.ver",
-            .value = "0.10",
-        },{
-            .name = "scsi-disk.ver",
-            .value = "0.10",
-        },{
-            .name = "PCI.rombar",
-            .value = stringify(0),
-        },
+        QOPT_VALUE("acpi", "on"),
+        QOPT_VALUE("pci", "on"),
+        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_COMPAT_INT("virtio-blk-pci", "class", PCI_CLASS_STORAGE_OTHER),
+        QOPT_COMPAT_INT("virtio-serial-pci", "class", PCI_CLASS_DISPLAY_OTHER),
+        QOPT_COMPAT_INT("virtio-net-pci", "vectors", 0),
+        QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
+        QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
+        QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
+        QOPT_COMPAT("ide-drive", "ver", "0.10"),
+        QOPT_COMPAT("scsi-disk", "ver", "0.10"),
+        QOPT_COMPAT_INT("PCI", "rombar", 0),
         { /* end of list */ }
     },
 };
@@ -335,18 +262,9 @@ static QEMUMachine isapc_machine = {
     .opts_desc = pc_opts_desc,
     .init = pc_init,
     .opts_default = (QemuOptValue[]) {
-        {
-            .name  = "acpi",
-            .value = "off",
-        },
-        {
-            .name  = "pci",
-            .value = "off",
-        },
-        {
-            .name = "cpu",
-            .value = "486",
-        },
+        QOPT_VALUE("acpi", "off"),
+        QOPT_VALUE("pci", "off"),
+        QOPT_VALUE("cpu", "486"),
         { /* end of list */ }
     },
     .max_cpus = 1,
diff --git a/qemu-option.h b/qemu-option.h
index 85ab58e..5fc60ac 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -109,6 +109,12 @@ typedef struct QemuOptValue {
     const char *value;
 } QemuOptValue;
 
+#define QOPT_VALUE(_name, _value) \
+    {                             \
+        .name = _name,            \
+        .value = _value,          \
+    }
+
 const char *qemu_opt_get(QemuOpts *opts, const char *name);
 int qemu_opt_get_bool(QemuOpts *opts, const char *name, int defval);
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 13/22] machine: get rid of global default QEMUMachine members
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (11 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 12/22] machine: some sugary macros to simplify machine default options Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 14/22] machine: replace QEMUMachine.use_scsi with -machine default_drive Anthony Liguori
                   ` (9 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Right now, we have a lot of default device type options in the QEMUMachine
structure.  This is used by code within vl.c to determine whether it should
add classes of devices (like serial).

Really, vl.c has no business adding devices but all we need to do to support
this is create common machine options to describe whether there are default
devices of each class.  vl.c can then use that to determine whether to add
said devices.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index e05637b..f33c44b 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -16,13 +16,6 @@ struct QEMUMachine {
     QEMUMachineInitFunc *init;
     int use_scsi;
     int max_cpus;
-    unsigned int no_serial:1,
-        no_parallel:1,
-        use_virtcon:1,
-        no_vga:1,
-        no_floppy:1,
-        no_cdrom:1,
-        no_sdcard:1;
     int is_default;
     QemuOptDesc *opts_desc;
     QemuOptValue *opts_default;
@@ -43,29 +36,46 @@ extern QEMUMachine *current_machine;
     {                                   \
         .name = "driver",               \
         .type = QEMU_OPT_STRING,        \
-    },                                  \
-    {                                   \
+    },{                                 \
         .name = "ram_size",             \
         .type = QEMU_OPT_SIZE,          \
     },{                                 \
         .name = "kernel",               \
         .type = QEMU_OPT_STRING,        \
-    },                                  \
-    {                                   \
+    },{                                 \
         .name = "cmdline",              \
         .type = QEMU_OPT_STRING,        \
-    },                                  \
-    {                                   \
+    },{                                 \
         .name = "initrd",               \
         .type = QEMU_OPT_STRING,        \
-    },                                  \
-    {                                   \
+    },{                                 \
         .name = "boot_device",          \
         .type = QEMU_OPT_STRING,        \
-    },                                  \
-    {                                   \
+    },{                                 \
         .name = "cpu",                  \
         .type = QEMU_OPT_STRING,        \
+    },{                                 \
+        .name = "serial",               \
+        .type = QEMU_OPT_BOOL,          \
+    },{                                 \
+        .name = "parallel",             \
+        .type = QEMU_OPT_BOOL,          \
+    },{                                 \
+        .name = "virtcon",              \
+        .type = QEMU_OPT_BOOL,          \
+    },{                                 \
+        .name = "vga",                  \
+        .type = QEMU_OPT_BOOL,          \
+    },{                                 \
+        .name = "floppy",               \
+        .type = QEMU_OPT_BOOL,          \
+    },{                                 \
+        .name = "cdrom",                \
+        .type = QEMU_OPT_BOOL,          \
+    },{                                 \
+        .name = "sdcard",               \
+        .type = QEMU_OPT_BOOL,          \
     }
 
+
 #endif
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 70b88df..e4d6ecd 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -273,9 +273,13 @@ static QEMUMachine s390_machine = {
     .alias = "s390",
     .desc = "VirtIO based S390 machine",
     .init = s390_init,
-    .no_serial = 1,
-    .no_parallel = 1,
-    .use_virtcon = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("serial", "off"),
+        QOPT_VALUE("parallel", "off"),
+        QOPT_VALUE("virtcon", "on"),
+        QOPT_VALUE("vga", "off"),
+        { /* end of list */ }
+    },
     .no_vga = 1,
     .max_cpus = 255,
     .is_default = 1,
diff --git a/vl.c b/vl.c
index 0a31a45..553da4d 100644
--- a/vl.c
+++ b/vl.c
@@ -3505,25 +3505,25 @@ int main(int argc, char **argv, char **envp)
     qemu_opts_foreach(&qemu_device_opts, default_driver_check, NULL, 0);
     qemu_opts_foreach(&qemu_global_opts, default_driver_check, NULL, 0);
 
-    if (machine->no_serial) {
+    if (!qemu_opt_get_bool(machine_opts, "serial", 1)) {
         default_serial = 0;
     }
-    if (machine->no_parallel) {
+    if (!qemu_opt_get_bool(machine_opts, "parallel", 1)) {
         default_parallel = 0;
     }
-    if (!machine->use_virtcon) {
+    if (!qemu_opt_get_bool(machine_opts, "virtcon", 0)) {
         default_virtcon = 0;
     }
-    if (machine->no_vga) {
+    if (!qemu_opt_get_bool(machine_opts, "vga", 1)) {
         default_vga = 0;
     }
-    if (machine->no_floppy) {
+    if (!qemu_opt_get_bool(machine_opts, "floppy", 1)) {
         default_floppy = 0;
     }
-    if (machine->no_cdrom) {
+    if (!qemu_opt_get_bool(machine_opts, "cdrom", 1)) {
         default_cdrom = 0;
     }
-    if (machine->no_sdcard) {
+    if (!qemu_opt_get_bool(machine_opts, "sdcard", 1)) {
         default_sdcard = 0;
     }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 14/22] machine: replace QEMUMachine.use_scsi with -machine default_drive
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (12 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 13/22] machine: get rid of global default QEMUMachine members Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option Anthony Liguori
                   ` (8 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Some boards only support scsi and there's some ugliness to accomodate this.

This patch removes that and introduces a default_drive common option for
machines.  The absence of this option assumes ide.  It can be explicitly set
to scsi and this is used to replace all current occurrances of use_scsi.

As fall out to this patch, current_machine disappears because it's actually
not needed since we no longer access the machine state to check for use_scsi.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index f33c44b..887487e 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -14,7 +14,6 @@ struct QEMUMachine {
     const char *alias;
     const char *desc;
     QEMUMachineInitFunc *init;
-    int use_scsi;
     int max_cpus;
     int is_default;
     QemuOptDesc *opts_desc;
@@ -75,6 +74,9 @@ extern QEMUMachine *current_machine;
     },{                                 \
         .name = "sdcard",               \
         .type = QEMU_OPT_BOOL,          \
+    },{                                 \
+        .name = "default_drive",        \
+        .type = QEMU_OPT_STRING,        \
     }
 
 
diff --git a/hw/device-hotplug.c b/hw/device-hotplug.c
index 9cc8376..feb8aa3 100644
--- a/hw/device-hotplug.c
+++ b/hw/device-hotplug.c
@@ -38,7 +38,7 @@ DriveInfo *add_init_drive(const char *optstr)
     if (!opts)
         return NULL;
 
-    dinfo = drive_init(opts, current_machine, &fatal_error);
+    dinfo = drive_init(opts, NULL, &fatal_error);
     if (!dinfo) {
         qemu_opts_del(opts);
         return NULL;
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 1ba9475..7e1e119 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -319,14 +319,20 @@ static QEMUMachine mips_magnum_machine = {
     .name = "magnum",
     .desc = "MIPS Magnum",
     .init = mips_magnum_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine mips_pica61_machine = {
     .name = "pica61",
     .desc = "Acer Pica 61",
     .init = mips_pica61_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static void mips_jazz_machine_init(void)
diff --git a/hw/realview.c b/hw/realview.c
index 4364b7b..a36bdbe 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -432,14 +432,20 @@ static QEMUMachine realview_eb_machine = {
     .name = "realview-eb",
     .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
     .init = realview_eb_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine realview_eb_mpcore_machine = {
     .name = "realview-eb-mpcore",
     .desc = "ARM RealView Emulation Baseboard (ARM11MPCore)",
     .init = realview_eb_mpcore_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .max_cpus = 4,
 };
 
@@ -453,7 +459,10 @@ static QEMUMachine realview_pbx_a9_machine = {
     .name = "realview-pbx-a9",
     .desc = "ARM RealView Platform Baseboard Explore for Cortex-A9",
     .init = realview_pbx_a9_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .max_cpus = 4,
 };
 
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 5aa3de1..a400530 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -1319,7 +1319,10 @@ static QEMUMachine ss5_machine = {
     .name = "SS-5",
     .desc = "Sun4m platform, SPARCstation 5",
     .init = ss5_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .is_default = 1,
 };
 
@@ -1327,7 +1330,10 @@ static QEMUMachine ss10_machine = {
     .name = "SS-10",
     .desc = "Sun4m platform, SPARCstation 10",
     .init = ss10_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .max_cpus = 4,
 };
 
@@ -1335,7 +1341,10 @@ static QEMUMachine ss600mp_machine = {
     .name = "SS-600MP",
     .desc = "Sun4m platform, SPARCserver 600MP",
     .init = ss600mp_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .max_cpus = 4,
 };
 
@@ -1343,7 +1352,10 @@ static QEMUMachine ss20_machine = {
     .name = "SS-20",
     .desc = "Sun4m platform, SPARCstation 20",
     .init = ss20_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .max_cpus = 4,
 };
 
@@ -1351,35 +1363,50 @@ static QEMUMachine voyager_machine = {
     .name = "Voyager",
     .desc = "Sun4m platform, SPARCstation Voyager",
     .init = vger_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine ss_lx_machine = {
     .name = "LX",
     .desc = "Sun4m platform, SPARCstation LX",
     .init = ss_lx_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine ss4_machine = {
     .name = "SS-4",
     .desc = "Sun4m platform, SPARCstation 4",
     .init = ss4_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine scls_machine = {
     .name = "SPARCClassic",
     .desc = "Sun4m platform, SPARCClassic",
     .init = scls_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine sbook_machine = {
     .name = "SPARCbook",
     .desc = "Sun4m platform, SPARCbook",
     .init = sbook_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static const struct sun4d_hwdef sun4d_hwdefs[] = {
@@ -1599,7 +1626,10 @@ static QEMUMachine ss1000_machine = {
     .name = "SS-1000",
     .desc = "Sun4d platform, SPARCserver 1000",
     .init = ss1000_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .max_cpus = 8,
 };
 
@@ -1607,7 +1637,10 @@ static QEMUMachine ss2000_machine = {
     .name = "SS-2000",
     .desc = "Sun4d platform, SPARCcenter 2000",
     .init = ss2000_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
     .max_cpus = 20,
 };
 
@@ -1782,7 +1815,10 @@ static QEMUMachine ss2_machine = {
     .name = "SS-2",
     .desc = "Sun4c platform, SPARCstation 2",
     .init = ss2_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static void ss2_machine_init(void)
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index 59b66d7..f407669 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -321,14 +321,20 @@ static QEMUMachine versatilepb_machine = {
     .name = "versatilepb",
     .desc = "ARM Versatile/PB (ARM926EJ-S)",
     .init = vpb_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static QEMUMachine versatileab_machine = {
     .name = "versatileab",
     .desc = "ARM Versatile/AB (ARM926EJ-S)",
     .init = vab_init,
-    .use_scsi = 1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("default_drive", "scsi"),
+        { /* end of list */ }
+    },
 };
 
 static void versatile_machine_init(void)
diff --git a/vl.c b/vl.c
index 553da4d..1065233 100644
--- a/vl.c
+++ b/vl.c
@@ -783,7 +783,7 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
     int bus_id, unit_id;
     int cyls, heads, secs, translation;
     BlockDriver *drv = NULL;
-    QEMUMachine *machine = opaque;
+    const char *default_drive = opaque;
     int max_devs;
     int index;
     int ro = 0;
@@ -797,10 +797,14 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
 
     translation = BIOS_ATA_TRANSLATION_AUTO;
 
-    if (machine && machine->use_scsi) {
+    if (default_drive && strcmp(default_drive, "scsi") == 0) {
         type = IF_SCSI;
         max_devs = MAX_SCSI_DEVS;
         pstrcpy(devname, sizeof(devname), "scsi");
+    } else if (default_drive && strcmp(default_drive, "virtio") == 0) {
+        type = IF_VIRTIO;
+        max_devs = MAX_DRIVES;
+        pstrcpy(devname, sizeof(devname), "virtio");
     } else {
         type = IF_IDE;
         max_devs = MAX_IDE_DEVS;
@@ -1136,10 +1140,10 @@ DriveInfo *drive_init(QemuOpts *opts, void *opaque,
 
 static int drive_init_func(QemuOpts *opts, void *opaque)
 {
-    QEMUMachine *machine = opaque;
+    const char *default_drive = opaque;
     int fatal_error = 0;
 
-    if (drive_init(opts, machine, &fatal_error) == NULL) {
+    if (drive_init(opts, (void *)default_drive, &fatal_error) == NULL) {
         if (fatal_error)
             return 1;
     }
@@ -1582,7 +1586,6 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
 /* machine registration */
 
 static QEMUMachine *first_machine = NULL;
-QEMUMachine *current_machine = NULL;
 
 int qemu_register_machine(QEMUMachine *m)
 {
@@ -3709,8 +3712,18 @@ int main(int argc, char **argv, char **envp)
     /* open the virtual block devices */
     if (snapshot)
         qemu_opts_foreach(&qemu_drive_opts, drive_enable_snapshot, NULL, 0);
-    if (qemu_opts_foreach(&qemu_drive_opts, drive_init_func, machine, 1) != 0)
-        exit(1);
+
+    {
+        int ret;
+        const char *default_drive;
+
+        default_drive = qemu_opt_get(machine_opts, "default_drive");
+        ret = qemu_opts_foreach(&qemu_drive_opts, drive_init_func,
+                                (void *)default_drive, 1);
+        if (ret != 0) {
+            exit(1);
+        }
+    }
 
     register_savevm_live("ram", 0, 3, NULL, ram_save_live, NULL, 
                          ram_load, NULL);
@@ -3813,8 +3826,6 @@ int main(int argc, char **argv, char **envp)
 
     set_numa_modes();
 
-    current_machine = machine;
-
     /* init USB devices */
     if (usb_enabled) {
         if (foreach_device_config(DEV_USB, usb_parse) < 0)
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (13 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 14/22] machine: replace QEMUMachine.use_scsi with -machine default_drive Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-08  1:01   ` Paul Brook
  2010-06-09  7:47   ` Jes Sorensen
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 16/22] machine: move default machine out of machine definitions Anthony Liguori
                   ` (7 subsequent siblings)
  22 siblings, 2 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

max_cpus is a weird property today.  On the one hand, it represents the maximum
CPUs a board can support and is used to validate the number of vcpus requested
by the user.

On the other hand, max_cpus can be set by the user in which case it is taken
to mean the number of physical sockets that should be advertised by the
firmware.  Furthermore, if max_cpus isn't explicitly set by the user, it's
defaulted to the number of smp_cpus.  But there's actually a second copy of
max_cpus that still represents the maximum cpus spported by the platform.

Yes, it's confusing.  So let's be a bit more obvious.  This patch introduces
a sockets parameter that allows a user to explicitly set the number of
advertised sockets apart from the number of maximum cpus.

This is something of a stop gap.  We really ought to specify a more rich
NUMA topology as machine options but that will come later.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index 887487e..5176e95 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -14,7 +14,6 @@ struct QEMUMachine {
     const char *alias;
     const char *desc;
     QEMUMachineInitFunc *init;
-    int max_cpus;
     int is_default;
     QemuOptDesc *opts_desc;
     QemuOptValue *opts_default;
@@ -77,6 +76,12 @@ extern QEMUMachine *current_machine;
     },{                                 \
         .name = "default_drive",        \
         .type = QEMU_OPT_STRING,        \
+    },{                                 \
+        .name = "max_cpus",             \
+        .type = QEMU_OPT_NUMBER,        \
+    },{                                 \
+        .name = "sockets",              \
+        .type = QEMU_OPT_NUMBER,        \
     }
 
 
diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
index 22ebb50..de4454f 100644
--- a/hw/fw_cfg.c
+++ b/hw/fw_cfg.c
@@ -321,7 +321,8 @@ int fw_cfg_add_file(FWCfgState *s,  const char *dir, const char *filename,
 }
 
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
-                        target_phys_addr_t ctl_addr, target_phys_addr_t data_addr)
+                        target_phys_addr_t ctl_addr, target_phys_addr_t data_addr,
+                        QemuOpts *opts)
 {
     FWCfgState *s;
     int io_ctl_memory, io_data_memory;
@@ -349,7 +350,8 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
     fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
     fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
     fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
-    fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
+    fw_cfg_add_i16(s, FW_CFG_MAX_CPUS,
+                   (uint16_t)qemu_opt_get_number(opts, "sockets", smp_cpus));
     fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);
 
     vmstate_register(-1, &vmstate_fw_cfg, s);
diff --git a/hw/fw_cfg.h b/hw/fw_cfg.h
index 4d13a4f..bdf9227 100644
--- a/hw/fw_cfg.h
+++ b/hw/fw_cfg.h
@@ -63,7 +63,8 @@ int fw_cfg_add_callback(FWCfgState *s, uint16_t key, FWCfgCallback callback,
 int fw_cfg_add_file(FWCfgState *s, const char *dir, const char *filename,
                     uint8_t *data, uint32_t len);
 FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
-                        target_phys_addr_t crl_addr, target_phys_addr_t data_addr);
+                        target_phys_addr_t crl_addr, target_phys_addr_t data_addr,
+                        QemuOpts *opts);
 
 #endif /* NO_QEMU_PROTOS */
 
diff --git a/hw/multiboot.c b/hw/multiboot.c
index a1b665c..7cdc77b 100644
--- a/hw/multiboot.c
+++ b/hw/multiboot.c
@@ -22,6 +22,8 @@
  * THE SOFTWARE.
  */
 
+#include "qemu-common.h"
+#include "qemu-option.h"
 #include "hw.h"
 #include "fw_cfg.h"
 #include "multiboot.h"
diff --git a/hw/pc.c b/hw/pc.c
index 44f5b62..55681d8 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -449,7 +449,7 @@ int e820_add_entry(uint64_t address, uint64_t length, uint32_t type)
     return e820_table.count;
 }
 
-static void *bochs_bios_init(void)
+static void *bochs_bios_init(QemuOpts *opts)
 {
     void *fw_cfg;
     uint8_t *smbios_table;
@@ -468,7 +468,7 @@ static void *bochs_bios_init(void)
     register_ioport_write(0x500, 1, 1, bochs_bios_write, NULL);
     register_ioport_write(0x503, 1, 1, bochs_bios_write, NULL);
 
-    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
+    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0, opts);
 
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
@@ -804,7 +804,8 @@ void pc_memory_init(ram_addr_t ram_size,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t *below_4g_mem_size_p,
-                    ram_addr_t *above_4g_mem_size_p)
+                    ram_addr_t *above_4g_mem_size_p,
+                    QemuOpts *opts)
 {
     char *filename;
     int ret, linux_boot, i;
@@ -882,7 +883,7 @@ void pc_memory_init(ram_addr_t ram_size,
     cpu_register_physical_memory((uint32_t)(-bios_size),
                                  bios_size, bios_offset | IO_MEM_ROM);
 
-    fw_cfg = bochs_bios_init();
+    fw_cfg = bochs_bios_init(opts);
     rom_set_fw(fw_cfg);
 
     if (linux_boot) {
diff --git a/hw/pc.h b/hw/pc.h
index 1ae61e0..1f838c1 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -91,7 +91,8 @@ void pc_memory_init(ram_addr_t ram_size,
                     const char *kernel_cmdline,
                     const char *initrd_filename,
                     ram_addr_t *below_4g_mem_size_p,
-                    ram_addr_t *above_4g_mem_size_p);
+                    ram_addr_t *above_4g_mem_size_p,
+                    QemuOpts *opts);
 qemu_irq *pc_allocate_cpu_irq(void);
 void pc_vga_init(PCIBus *pci_bus);
 void pc_basic_device_init(qemu_irq *isa_irq,
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 104206c..d02bf20 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -70,7 +70,7 @@ static void pc_init(QemuOpts *opts)
 
     /* allocate ram and load rom/bios */
     pc_memory_init(ram_size, kernel_filename, kernel_cmdline, initrd_filename,
-                   &below_4g_mem_size, &above_4g_mem_size);
+                   &below_4g_mem_size, &above_4g_mem_size, opts);
 
     cpu_irq = pc_allocate_cpu_irq();
     i8259 = i8259_init(cpu_irq[0]);
@@ -186,13 +186,13 @@ static QEMUMachine pc_machine = {
     .alias = "pc",
     .desc = "Standard PC",
     .init = pc_init,
-    .max_cpus = 255,
     .is_default = 1,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_VALUE("max_cpus", "255"),
         { /* end of list */ }
     },
 };
@@ -201,12 +201,12 @@ static QEMUMachine pc_machine_v0_12 = {
     .name = "pc-0.12",
     .desc = "Standard PC",
     .init = pc_init,
-    .max_cpus = 255,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_VALUE("max_cpus", "255"),
         QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
         QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
         { /* end of list */ }
@@ -217,12 +217,12 @@ static QEMUMachine pc_machine_v0_11 = {
     .name = "pc-0.11",
     .desc = "Standard PC, qemu 0.11",
     .init = pc_init,
-    .max_cpus = 255,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_VALUE("max_cpus", "255"),
         QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
         QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
         QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
@@ -237,12 +237,12 @@ static QEMUMachine pc_machine_v0_10 = {
     .name = "pc-0.10",
     .desc = "Standard PC, qemu 0.10",
     .init = pc_init,
-    .max_cpus = 255,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_VALUE("max_cpu", "255"),
         QOPT_COMPAT_INT("virtio-blk-pci", "class", PCI_CLASS_STORAGE_OTHER),
         QOPT_COMPAT_INT("virtio-serial-pci", "class", PCI_CLASS_DISPLAY_OTHER),
         QOPT_COMPAT_INT("virtio-net-pci", "vectors", 0),
@@ -265,9 +265,9 @@ static QEMUMachine isapc_machine = {
         QOPT_VALUE("acpi", "off"),
         QOPT_VALUE("pci", "off"),
         QOPT_VALUE("cpu", "486"),
+        QOPT_VALUE("max_cpus", "1"),
         { /* end of list */ }
     },
-    .max_cpus = 1,
 };
 
 static void pc_machine_init(void)
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 1737cc4..3be0c2d 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -407,7 +407,7 @@ static void ppc_core99_init (QemuOpts *opts)
     macio_nvram_map(nvr, 0xFFF04000);
     /* No PCI init: the BIOS will do it */
 
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2, opts);
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, machine_arch);
@@ -442,7 +442,10 @@ static QEMUMachine core99_machine = {
     .name = "mac99",
     .desc = "Mac99 based PowerMAC",
     .init = ppc_core99_init,
-    .max_cpus = MAX_CPUS,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
+        { /* end of list */ }
+    },
 #ifdef TARGET_PPC64
     .is_default = 1,
 #endif
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index b1ce88d..7fab893 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -379,7 +379,7 @@ static void ppc_heathrow_init (QemuOpts *opts)
 
     /* No PCI init: the BIOS will do it */
 
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2, opts);
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW);
@@ -414,7 +414,10 @@ static QEMUMachine heathrow_machine = {
     .name = "g3beige",
     .desc = "Heathrow based PowerMAC",
     .init = ppc_heathrow_init,
-    .max_cpus = MAX_CPUS,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
+        { /* end of list */ }
+    },
 #ifndef TARGET_PPC64
     .is_default = 1,
 #endif
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 090c8ac..868ef17 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -793,7 +793,10 @@ static QEMUMachine prep_machine = {
     .name = "prep",
     .desc = "PowerPC PREP platform",
     .init = ppc_prep_init,
-    .max_cpus = MAX_CPUS,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
+        { /* end of list */ }
+    },
 };
 
 static void prep_machine_init(void)
diff --git a/hw/realview.c b/hw/realview.c
index a36bdbe..8dcef80 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -444,9 +444,9 @@ static QEMUMachine realview_eb_mpcore_machine = {
     .init = realview_eb_mpcore_init,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("default_drive", "scsi"),
+        QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
     },
-    .max_cpus = 4,
 };
 
 static QEMUMachine realview_pb_a8_machine = {
@@ -461,9 +461,9 @@ static QEMUMachine realview_pbx_a9_machine = {
     .init = realview_pbx_a9_init,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("default_drive", "scsi"),
+        QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
     },
-    .max_cpus = 4,
 };
 
 static void realview_machine_init(void)
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index e4d6ecd..a769ba0 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -278,10 +278,9 @@ static QEMUMachine s390_machine = {
         QOPT_VALUE("parallel", "off"),
         QOPT_VALUE("virtcon", "on"),
         QOPT_VALUE("vga", "off"),
+        QOPT_VALUE("max_cpus", "255"),
         { /* end of list */ }
     },
-    .no_vga = 1,
-    .max_cpus = 255,
     .is_default = 1,
 };
 
diff --git a/hw/sun4m.c b/hw/sun4m.c
index a400530..7d24873 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -798,7 +798,8 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
                           const char *boot_device,
                           const char *kernel_filename,
                           const char *kernel_cmdline,
-                          const char *initrd_filename, const char *cpu_model)
+                          const char *initrd_filename, const char *cpu_model,
+                          QemuOpts *opts)
 {
     unsigned int i;
     void *iommu, *espdma, *ledma, *nvram;
@@ -932,7 +933,7 @@ static void sun4m_hw_init(const struct sun4m_hwdef *hwdef, ram_addr_t RAM_size,
         ecc_init(hwdef->ecc_base, slavio_irq[28],
                  hwdef->ecc_version);
 
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2, opts);
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
@@ -1208,7 +1209,7 @@ static void ss5_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[0], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCstation 10 hardware initialisation */
@@ -1221,7 +1222,7 @@ static void ss10_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[1], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCserver 600MP hardware initialisation */
@@ -1234,7 +1235,7 @@ static void ss600mp_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[2], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCstation 20 hardware initialisation */
@@ -1247,7 +1248,7 @@ static void ss20_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[3], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCstation Voyager hardware initialisation */
@@ -1260,7 +1261,7 @@ static void vger_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[4], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCstation LX hardware initialisation */
@@ -1273,7 +1274,7 @@ static void ss_lx_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[5], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCstation 4 hardware initialisation */
@@ -1286,7 +1287,7 @@ static void ss4_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[6], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCClassic hardware initialisation */
@@ -1299,7 +1300,7 @@ static void scls_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[7], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCbook hardware initialisation */
@@ -1312,7 +1313,7 @@ static void sbook_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4m_hw_init(&sun4m_hwdefs[8], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 static QEMUMachine ss5_machine = {
@@ -1332,9 +1333,9 @@ static QEMUMachine ss10_machine = {
     .init = ss10_init,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("default_drive", "scsi"),
+        QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
     },
-    .max_cpus = 4,
 };
 
 static QEMUMachine ss600mp_machine = {
@@ -1343,9 +1344,9 @@ static QEMUMachine ss600mp_machine = {
     .init = ss600mp_init,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("default_drive", "scsi"),
+        QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
     },
-    .max_cpus = 4,
 };
 
 static QEMUMachine ss20_machine = {
@@ -1354,9 +1355,9 @@ static QEMUMachine ss20_machine = {
     .init = ss20_init,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("default_drive", "scsi"),
+        QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
     },
-    .max_cpus = 4,
 };
 
 static QEMUMachine voyager_machine = {
@@ -1488,7 +1489,8 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
                           const char *boot_device,
                           const char *kernel_filename,
                           const char *kernel_cmdline,
-                          const char *initrd_filename, const char *cpu_model)
+                          const char *initrd_filename, const char *cpu_model,
+                          QemuOpts *opts)
 {
     unsigned int i;
     void *iounits[MAX_IOUNITS], *espdma, *ledma, *nvram;
@@ -1574,7 +1576,7 @@ static void sun4d_hw_init(const struct sun4d_hwdef *hwdef, ram_addr_t RAM_size,
                graphic_height, graphic_depth, hwdef->nvram_machine_id,
                "Sun4d");
 
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2, opts);
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
@@ -1606,7 +1608,7 @@ static void ss1000_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4d_hw_init(&sun4d_hwdefs[0], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 /* SPARCcenter 2000 hardware initialisation */
@@ -1619,7 +1621,7 @@ static void ss2000_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4d_hw_init(&sun4d_hwdefs[1], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 static QEMUMachine ss1000_machine = {
@@ -1628,9 +1630,9 @@ static QEMUMachine ss1000_machine = {
     .init = ss1000_init,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("default_drive", "scsi"),
+        QOPT_VALUE("max_cpus", "8"),
         { /* end of list */ }
     },
-    .max_cpus = 8,
 };
 
 static QEMUMachine ss2000_machine = {
@@ -1639,9 +1641,9 @@ static QEMUMachine ss2000_machine = {
     .init = ss2000_init,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("default_drive", "scsi"),
+        QOPT_VALUE("max_cpus", "20"),
         { /* end of list */ }
     },
-    .max_cpus = 20,
 };
 
 static const struct sun4c_hwdef sun4c_hwdefs[] = {
@@ -1691,7 +1693,8 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
                           const char *boot_device,
                           const char *kernel_filename,
                           const char *kernel_cmdline,
-                          const char *initrd_filename, const char *cpu_model)
+                          const char *initrd_filename, const char *cpu_model,
+                          QemuOpts *opts)
 {
     void *iommu, *espdma, *ledma, *nvram;
     qemu_irq *cpu_irqs, slavio_irq[8], espdma_irq, ledma_irq;
@@ -1776,7 +1779,7 @@ static void sun4c_hw_init(const struct sun4c_hwdef *hwdef, ram_addr_t RAM_size,
                graphic_height, graphic_depth, hwdef->nvram_machine_id,
                "Sun4c");
 
-    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2);
+    fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2, opts);
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
@@ -1808,7 +1811,7 @@ static void ss2_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4c_hw_init(&sun4c_hwdefs[0], RAM_size, boot_device, kernel_filename,
-                  kernel_cmdline, initrd_filename, cpu_model);
+                  kernel_cmdline, initrd_filename, cpu_model, opts);
 }
 
 static QEMUMachine ss2_machine = {
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 7abb027..8b112be 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -742,7 +742,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
                         const char *boot_devices,
                         const char *kernel_filename, const char *kernel_cmdline,
                         const char *initrd_filename, const char *cpu_model,
-                        const struct hwdef *hwdef)
+                        const struct hwdef *hwdef, QemuOpts *opts)
 {
     CPUState *env;
     M48t59State *nvram;
@@ -824,7 +824,7 @@ static void sun4uv_init(ram_addr_t RAM_size,
                            graphic_width, graphic_height, graphic_depth,
                            (uint8_t *)&nd_table[0].macaddr);
 
-    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0);
+    fw_cfg = fw_cfg_init(BIOS_CFG_IOPORT, BIOS_CFG_IOPORT + 1, 0, 0, opts);
     fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1);
     fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size);
     fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, hwdef->machine_id);
@@ -890,7 +890,7 @@ static void sun4u_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4uv_init(RAM_size, boot_devices, kernel_filename,
-                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0]);
+                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[0], opts);
 }
 
 /* Sun4v hardware initialisation */
@@ -903,7 +903,7 @@ static void sun4v_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4uv_init(RAM_size, boot_devices, kernel_filename,
-                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1]);
+                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[1], opts);
 }
 
 /* Niagara hardware initialisation */
@@ -916,14 +916,13 @@ static void niagara_init(QemuOpts *opts)
     const char *initrd_filename = qemu_opt_get(opts, "initrd");
     const char *cpu_model = qemu_opt_get(opts, "cpu");
     sun4uv_init(RAM_size, boot_devices, kernel_filename,
-                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2]);
+                kernel_cmdline, initrd_filename, cpu_model, &hwdefs[2], opts);
 }
 
 static QEMUMachine sun4u_machine = {
     .name = "sun4u",
     .desc = "Sun4u platform",
     .init = sun4u_init,
-    .max_cpus = 1, // XXX for now
     .is_default = 1,
 };
 
@@ -931,14 +930,12 @@ static QEMUMachine sun4v_machine = {
     .name = "sun4v",
     .desc = "Sun4v platform",
     .init = sun4v_init,
-    .max_cpus = 1, // XXX for now
 };
 
 static QEMUMachine niagara_machine = {
     .name = "Niagara",
     .desc = "Sun4v platform, Niagara",
     .init = niagara_init,
-    .max_cpus = 1, // XXX for now
 };
 
 static void sun4u_machine_init(void)
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 58c68de..077c0f6 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -112,7 +112,6 @@ static QEMUMachine xenpv_machine = {
     .name = "xenpv",
     .desc = "Xen Para-virtualized PC",
     .init = xen_init_pv,
-    .max_cpus = 1,
 };
 
 static void xenpv_machine_init(void)
diff --git a/sysemu.h b/sysemu.h
index 879446a..ff73582 100644
--- a/sysemu.h
+++ b/sysemu.h
@@ -124,7 +124,6 @@ extern int alt_grab;
 extern int ctrl_grab;
 extern int usb_enabled;
 extern int smp_cpus;
-extern int max_cpus;
 extern int cursor_hide;
 extern int graphic_rotate;
 extern int no_quit;
diff --git a/vl.c b/vl.c
index 1065233..34e48f8 100644
--- a/vl.c
+++ b/vl.c
@@ -205,7 +205,6 @@ int rtc_td_hack = 0;
 int usb_enabled = 0;
 int singlestep = 0;
 int smp_cpus = 1;
-int max_cpus = 0;
 int smp_cores = 1;
 int smp_threads = 1;
 const char *vnc_display;
@@ -1278,6 +1277,7 @@ static void smp_parse(const char *optarg)
     int smp, sockets = 0, threads = 0, cores = 0;
     char *endptr;
     char option[128];
+    int max_cpus = 0;
 
     smp = strtoul(optarg, &endptr, 10);
     if (endptr != optarg) {
@@ -1315,8 +1315,13 @@ static void smp_parse(const char *optarg)
     smp_cpus = smp;
     smp_cores = cores > 0 ? cores : 1;
     smp_threads = threads > 0 ? threads : 1;
-    if (max_cpus == 0)
+    if (max_cpus == 0) {
         max_cpus = smp_cpus;
+    }
+
+    if (max_cpus) {
+        qemu_opts_parsef(&qemu_machine_opts, "max_cpus=%d", max_cpus);
+    }
 }
 
 /***********************************************************/
@@ -2642,6 +2647,7 @@ int main(int argc, char **argv, char **envp)
     int show_vnc_port = 0;
     int defconfig = 1;
     QemuOpts *machine_opts = NULL;
+    int max_cpus = 0;
 
     error_set_progname(argv[0]);
 
@@ -3277,15 +3283,6 @@ int main(int argc, char **argv, char **envp)
                     fprintf(stderr, "Invalid number of CPUs\n");
                     exit(1);
                 }
-                if (max_cpus < smp_cpus) {
-                    fprintf(stderr, "maxcpus must be equal to or greater than "
-                            "smp\n");
-                    exit(1);
-                }
-                if (max_cpus > 255) {
-                    fprintf(stderr, "Unsupported number of maxcpus\n");
-                    exit(1);
-                }
                 break;
 	    case QEMU_OPTION_vnc:
                 display_type = DT_VNC;
@@ -3490,18 +3487,11 @@ int main(int argc, char **argv, char **envp)
         }
     }
     
-    /*
-     * Default to max_cpus = smp_cpus, in case the user doesn't
-     * specify a max_cpus value.
-     */
-    if (!max_cpus)
-        max_cpus = smp_cpus;
-
-    machine->max_cpus = machine->max_cpus ?: 1; /* Default to UP */
-    if (smp_cpus > machine->max_cpus) {
+    max_cpus = qemu_opt_get_number(machine_opts, "max_cpus", 1);
+    if (smp_cpus > max_cpus) {
         fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
                 "supported by machine `%s' (%d)\n", smp_cpus,  machine->name,
-                machine->max_cpus);
+                max_cpus);
         exit(1);
     }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 16/22] machine: move default machine out of machine definitions
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (14 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 17/22] machine: kill machine->alias Anthony Liguori
                   ` (6 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

There can only be one default machine so instead of setting in each machine
whether it's the default, simply declare what the name of the default machine
is.  A nice characteristic of this is that we technically don't need to
describe the default machine in QEMU anymore.  Instead, it could be described
in a config file but this patch doesn't do that.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index 5176e95..b99dc68 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -14,13 +14,13 @@ struct QEMUMachine {
     const char *alias;
     const char *desc;
     QEMUMachineInitFunc *init;
-    int is_default;
     QemuOptDesc *opts_desc;
     QemuOptValue *opts_default;
     struct QEMUMachine *next;
 };
 
 int qemu_register_machine(QEMUMachine *m);
+void machine_set_default(const char *name);
 
 extern QEMUMachine *current_machine;
 
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index 1cb6052..e41d1ce 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -176,12 +176,12 @@ static QEMUMachine bareetraxfs_machine = {
     .name = "bareetraxfs",
     .desc = "Bare ETRAX FS board",
     .init = bareetraxfs_init,
-    .is_default = 1,
 };
 
 static void bareetraxfs_machine_init(void)
 {
     qemu_register_machine(&bareetraxfs_machine);
+    machine_set_default("bareetraxfs");
 }
 
 machine_init(bareetraxfs_machine_init);
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index 36ebaf0..b505773 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -515,12 +515,12 @@ static QEMUMachine integratorcp_machine = {
     .name = "integratorcp",
     .desc = "ARM Integrator/CP (ARM926EJ-S)",
     .init = integratorcp_init,
-    .is_default = 1,
 };
 
 static void integratorcp_machine_init(void)
 {
     qemu_register_machine(&integratorcp_machine);
+    machine_set_default("integratorcp");
 }
 
 machine_init(integratorcp_machine_init);
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index b6eb94d..1ed8871 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -293,12 +293,12 @@ static QEMUMachine mcf5208evb_machine = {
     .name = "mcf5208evb",
     .desc = "MCF5206EVB",
     .init = mcf5208evb_init,
-    .is_default = 1,
 };
 
 static void mcf5208evb_machine_init(void)
 {
     qemu_register_machine(&mcf5208evb_machine);
+    machine_set_default("mcf5208evb");
 }
 
 machine_init(mcf5208evb_machine_init);
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index 0ef0090..f89be6d 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -993,12 +993,12 @@ static QEMUMachine mips_malta_machine = {
     .name = "malta",
     .desc = "MIPS Malta Core LV",
     .init = mips_malta_init,
-    .is_default = 1,
 };
 
 static void mips_malta_machine_init(void)
 {
     qemu_register_machine(&mips_malta_machine);
+    machine_set_default("malta");
 }
 
 machine_init(mips_malta_machine_init);
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index d02bf20..1bb6bee 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -186,7 +186,6 @@ static QEMUMachine pc_machine = {
     .alias = "pc",
     .desc = "Standard PC",
     .init = pc_init,
-    .is_default = 1,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
         QOPT_VALUE("acpi", "on"),
@@ -277,6 +276,7 @@ static void pc_machine_init(void)
     qemu_register_machine(&pc_machine_v0_11);
     qemu_register_machine(&pc_machine_v0_10);
     qemu_register_machine(&isapc_machine);
+    machine_set_default("pc");
 }
 
 machine_init(pc_machine_init);
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 5cc5787..5528960 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -201,12 +201,12 @@ static QEMUMachine petalogix_s3adsp1800_machine = {
     .name = "petalogix-s3adsp1800",
     .desc = "Petalogix linux refdesign for xilinx Spartan 3ADSP1800",
     .init = petalogix_s3adsp1800_init,
-    .is_default = 1
 };
 
 static void petalogix_s3adsp1800_machine_init(void)
 {
     qemu_register_machine(&petalogix_s3adsp1800_machine);
+    machine_set_default("petalogix-s3adsp1800");
 }
 
 machine_init(petalogix_s3adsp1800_machine_init);
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index 3be0c2d..acc320a 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -446,14 +446,14 @@ static QEMUMachine core99_machine = {
         QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
         { /* end of list */ }
     },
-#ifdef TARGET_PPC64
-    .is_default = 1,
-#endif
 };
 
 static void core99_machine_init(void)
 {
     qemu_register_machine(&core99_machine);
+#ifdef TARGET_PPC64
+    machine_set_default("mac99");
+#endif
 }
 
 machine_init(core99_machine_init);
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 7fab893..365a2b6 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -418,14 +418,14 @@ static QEMUMachine heathrow_machine = {
         QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
         { /* end of list */ }
     },
-#ifndef TARGET_PPC64
-    .is_default = 1,
-#endif
 };
 
 static void heathrow_machine_init(void)
 {
     qemu_register_machine(&heathrow_machine);
+#ifndef TARGET_PPC64
+    machine_set_default("g3beige");
+#endif
 }
 
 machine_init(heathrow_machine_init);
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index a769ba0..6c0f400 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -281,12 +281,12 @@ static QEMUMachine s390_machine = {
         QOPT_VALUE("max_cpus", "255"),
         { /* end of list */ }
     },
-    .is_default = 1,
 };
 
 static void s390_machine_init(void)
 {
     qemu_register_machine(&s390_machine);
+    machine_set_default("s390-virtio");
 }
 
 machine_init(s390_machine_init);
diff --git a/hw/shix.c b/hw/shix.c
index da5716e..8648c41 100644
--- a/hw/shix.c
+++ b/hw/shix.c
@@ -91,12 +91,12 @@ static QEMUMachine shix_machine = {
     .name = "shix",
     .desc = "shix card",
     .init = shix_init,
-    .is_default = 1,
 };
 
 static void shix_machine_init(void)
 {
     qemu_register_machine(&shix_machine);
+    machine_set_default("shix");
 }
 
 machine_init(shix_machine_init);
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 7d24873..8098cef 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -1324,7 +1324,6 @@ static QEMUMachine ss5_machine = {
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
-    .is_default = 1,
 };
 
 static QEMUMachine ss10_machine = {
@@ -1838,6 +1837,7 @@ static void ss2_machine_init(void)
     qemu_register_machine(&ss1000_machine);
     qemu_register_machine(&ss2000_machine);
     qemu_register_machine(&ss2_machine);
+    machine_set_default("SS-5");
 }
 
 machine_init(ss2_machine_init);
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 8b112be..13e7219 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -923,7 +923,6 @@ static QEMUMachine sun4u_machine = {
     .name = "sun4u",
     .desc = "Sun4u platform",
     .init = sun4u_init,
-    .is_default = 1,
 };
 
 static QEMUMachine sun4v_machine = {
@@ -943,6 +942,7 @@ static void sun4u_machine_init(void)
     qemu_register_machine(&sun4u_machine);
     qemu_register_machine(&sun4v_machine);
     qemu_register_machine(&niagara_machine);
+    machine_set_default("sun4u");
 }
 
 machine_init(sun4u_machine_init);
diff --git a/vl.c b/vl.c
index 34e48f8..3d49ba7 100644
--- a/vl.c
+++ b/vl.c
@@ -1591,6 +1591,7 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
 /* machine registration */
 
 static QEMUMachine *first_machine = NULL;
+static const char *default_machine = NULL;
 
 int qemu_register_machine(QEMUMachine *m)
 {
@@ -1603,6 +1604,11 @@ int qemu_register_machine(QEMUMachine *m)
     return 0;
 }
 
+void machine_set_default(const char *name)
+{
+    default_machine = name;
+}
+
 static QEMUMachine *find_machine(const char *name)
 {
     QEMUMachine *m;
@@ -1618,14 +1624,7 @@ static QEMUMachine *find_machine(const char *name)
 
 static QEMUMachine *find_default_machine(void)
 {
-    QEMUMachine *m;
-
-    for(m = first_machine; m != NULL; m = m->next) {
-        if (m->is_default) {
-            return m;
-        }
-    }
-    return NULL;
+    return find_machine(default_machine);
 }
 
 /***********************************************************/
@@ -2764,7 +2763,9 @@ int main(int argc, char **argv, char **envp)
                                    m->alias, m->desc, m->name);
                         printf("%-10s %s%s\n",
                                m->name, m->desc,
-                               m->is_default ? " (default)" : "");
+                               (!strcmp(m->name, default_machine) ||
+                                !strcmp(m->alias, default_machine)) ? 
+                               " (default)" : "");
                     }
                     exit(0);
                 }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 17/22] machine: kill machine->alias
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (15 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 16/22] machine: move default machine out of machine definitions Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 18/22] machine: final conversion to pure QemuOpts Anthony Liguori
                   ` (5 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Just duplicate the machine structure for now

diff --git a/hw/boards.h b/hw/boards.h
index b99dc68..a4dde9f 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -11,7 +11,6 @@ typedef void QEMUMachineInitFunc(QemuOpts *opts);
 
 struct QEMUMachine {
     const char *name;
-    const char *alias;
     const char *desc;
     QEMUMachineInitFunc *init;
     QemuOptDesc *opts_desc;
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 1bb6bee..e043942 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -182,8 +182,21 @@ static QemuOptDesc pc_opts_desc[] = {
 #endif
 
 static QEMUMachine pc_machine = {
+    .name = "pc",
+    .desc = "Standard PC",
+    .init = pc_init,
+    .opts_desc = pc_opts_desc,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("acpi", "on"),
+        QOPT_VALUE("pci", "on"),
+        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+        QOPT_VALUE("max_cpus", "255"),
+        { /* end of list */ }
+    },
+};
+
+static QEMUMachine pc_machine_v0_13 = {
     .name = "pc-0.13",
-    .alias = "pc",
     .desc = "Standard PC",
     .init = pc_init,
     .opts_desc = pc_opts_desc,
@@ -272,6 +285,7 @@ static QEMUMachine isapc_machine = {
 static void pc_machine_init(void)
 {
     qemu_register_machine(&pc_machine);
+    qemu_register_machine(&pc_machine_v0_13);
     qemu_register_machine(&pc_machine_v0_12);
     qemu_register_machine(&pc_machine_v0_11);
     qemu_register_machine(&pc_machine_v0_10);
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 8ed4632..1650a17 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -173,8 +173,13 @@ static void bamboo_init(QemuOpts *opts)
 }
 
 static QEMUMachine bamboo_machine = {
+    .name = "bamboo",
+    .desc = "bamboo",
+    .init = bamboo_init,
+};
+
+static QEMUMachine bamboo_machine_v0_13 = {
     .name = "bamboo-0.13",
-    .alias = "bamboo",
     .desc = "bamboo",
     .init = bamboo_init,
 };
@@ -198,6 +203,7 @@ static QEMUMachine bamboo_machine_v0_12 = {
 static void bamboo_machine_init(void)
 {
     qemu_register_machine(&bamboo_machine);
+    qemu_register_machine(&bamboo_machine_v0_13);
     qemu_register_machine(&bamboo_machine_v0_12);
 }
 
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index 6c0f400..fd1fe52 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -269,8 +269,21 @@ static void s390_init(QemuOpts *opts)
 }
 
 static QEMUMachine s390_machine = {
+    .name = "s390",
+    .desc = "VirtIO based S390 machine",
+    .init = s390_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("serial", "off"),
+        QOPT_VALUE("parallel", "off"),
+        QOPT_VALUE("virtcon", "on"),
+        QOPT_VALUE("vga", "off"),
+        QOPT_VALUE("max_cpus", "255"),
+        { /* end of list */ }
+    },
+};
+
+static QEMUMachine s390_virtio_machine = {
     .name = "s390-virtio",
-    .alias = "s390",
     .desc = "VirtIO based S390 machine",
     .init = s390_init,
     .opts_default = (QemuOptValue[]) {
@@ -286,7 +299,8 @@ static QEMUMachine s390_machine = {
 static void s390_machine_init(void)
 {
     qemu_register_machine(&s390_machine);
-    machine_set_default("s390-virtio");
+    qemu_register_machine(&s390_virtio_machine);
+    machine_set_default("s390");
 }
 
 machine_init(s390_machine_init);
diff --git a/vl.c b/vl.c
index 3d49ba7..8fc89c1 100644
--- a/vl.c
+++ b/vl.c
@@ -1616,8 +1616,6 @@ static QEMUMachine *find_machine(const char *name)
     for(m = first_machine; m != NULL; m = m->next) {
         if (!strcmp(m->name, name))
             return m;
-        if (m->alias && !strcmp(m->alias, name))
-            return m;
     }
     return NULL;
 }
@@ -2758,13 +2756,9 @@ int main(int argc, char **argv, char **envp)
                     QEMUMachine *m;
                     printf("Supported machines are:\n");
                     for(m = first_machine; m != NULL; m = m->next) {
-                        if (m->alias)
-                            printf("%-10s %s (alias of %s)\n",
-                                   m->alias, m->desc, m->name);
                         printf("%-10s %s%s\n",
                                m->name, m->desc,
-                               (!strcmp(m->name, default_machine) ||
-                                !strcmp(m->alias, default_machine)) ? 
+                               !strcmp(m->name, default_machine) ?
                                " (default)" : "");
                     }
                     exit(0);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 18/22] machine: final conversion to pure QemuOpts
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (16 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 17/22] machine: kill machine->alias Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 19/22] machine: introduce accel option to allow selection of kvm or tcg Anthony Liguori
                   ` (4 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

All we need to do is convert name and desc over and we're now purely opts
driven.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/an5206.c b/hw/an5206.c
index 0d6a6f0..5dd679c 100644
--- a/hw/an5206.c
+++ b/hw/an5206.c
@@ -88,9 +88,12 @@ static void an5206_init(QemuOpts *opts)
 }
 
 static QEMUMachine an5206_machine = {
-    .name = "an5206",
-    .desc = "Arnewsh 5206",
     .init = an5206_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "an5206"),
+        QOPT_VALUE("desc", "Arnewsh 5206"),
+        { /* end of list */ },
+    },
 };
 
 static void an5206_machine_init(void)
diff --git a/hw/axis_dev88.c b/hw/axis_dev88.c
index 7999d47..f1ac577 100644
--- a/hw/axis_dev88.c
+++ b/hw/axis_dev88.c
@@ -386,9 +386,12 @@ void axisdev88_init (QemuOpts *opts)
 }
 
 static QEMUMachine axisdev88_machine = {
-    .name = "axis-dev88",
-    .desc = "AXIS devboard 88",
     .init = axisdev88_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "axis-dev88"),
+        QOPT_VALUE("desc", "AXIS devboard 88"),
+        { /* end of list */ },
+    },
 };
 
 static void axisdev88_machine_init(void)
diff --git a/hw/boards.h b/hw/boards.h
index a4dde9f..947fa33 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -5,24 +5,18 @@
 
 #include "qdev.h"
 
-typedef struct QEMUMachine QEMUMachine;
-
 typedef void QEMUMachineInitFunc(QemuOpts *opts);
 
-struct QEMUMachine {
-    const char *name;
-    const char *desc;
+typedef struct QEMUMachine {
     QEMUMachineInitFunc *init;
     QemuOptDesc *opts_desc;
     QemuOptValue *opts_default;
-    struct QEMUMachine *next;
-};
+    QTAILQ_ENTRY(QEMUMachine) node;
+} QEMUMachine;
 
-int qemu_register_machine(QEMUMachine *m);
+int qemu_register_machine(QEMUMachine *machine);
 void machine_set_default(const char *name);
 
-extern QEMUMachine *current_machine;
-
 #define QOPT_COMPAT(driver, property, value) \
     QOPT_VALUE(driver "." property, value)
 
@@ -31,9 +25,15 @@ extern QEMUMachine *current_machine;
 
 #define COMMON_MACHINE_OPTS() 		\
     {                                   \
+        .name = "name",                 \
+        .type = QEMU_OPT_STRING,        \
+    },{                                 \
         .name = "driver",               \
         .type = QEMU_OPT_STRING,        \
     },{                                 \
+        .name = "desc",                 \
+        .type = QEMU_OPT_STRING,        \
+    },{                                 \
         .name = "ram_size",             \
         .type = QEMU_OPT_SIZE,          \
     },{                                 \
diff --git a/hw/dummy_m68k.c b/hw/dummy_m68k.c
index db94251..e102a74 100644
--- a/hw/dummy_m68k.c
+++ b/hw/dummy_m68k.c
@@ -67,9 +67,12 @@ static void dummy_m68k_init(QemuOpts *opts)
 }
 
 static QEMUMachine dummy_m68k_machine = {
-    .name = "dummy",
-    .desc = "Dummy board",
     .init = dummy_m68k_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "dummy"),
+        QOPT_VALUE("desc", "Dummy board"),
+        { /* end of list */ },
+    },
 };
 
 static void dummy_m68k_machine_init(void)
diff --git a/hw/etraxfs.c b/hw/etraxfs.c
index e41d1ce..7fbf366 100644
--- a/hw/etraxfs.c
+++ b/hw/etraxfs.c
@@ -173,9 +173,12 @@ void bareetraxfs_init (QemuOpts *opts)
 }
 
 static QEMUMachine bareetraxfs_machine = {
-    .name = "bareetraxfs",
-    .desc = "Bare ETRAX FS board",
     .init = bareetraxfs_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "bareetraxfs"),
+        QOPT_VALUE("desc", "Bare ETRAX FS board"),
+        { /* end of list */ },
+    },
 };
 
 static void bareetraxfs_machine_init(void)
diff --git a/hw/gumstix.c b/hw/gumstix.c
index 6739332..659863c 100644
--- a/hw/gumstix.c
+++ b/hw/gumstix.c
@@ -113,15 +113,21 @@ static void verdex_init(QemuOpts *opts)
 }
 
 static QEMUMachine connex_machine = {
-    .name = "connex",
-    .desc = "Gumstix Connex (PXA255)",
     .init = connex_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "connex"),
+        QOPT_VALUE("desc", "Gumstix Connex (PXA255)"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine verdex_machine = {
-    .name = "verdex",
-    .desc = "Gumstix Verdex (PXA270)",
     .init = verdex_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "verdex"),
+        QOPT_VALUE("desc", "Gumstix Verdex (PXA270)"),
+        { /* end of list */ },
+    },
 };
 
 static void gumstix_machine_init(void)
diff --git a/hw/integratorcp.c b/hw/integratorcp.c
index b505773..110cb4c 100644
--- a/hw/integratorcp.c
+++ b/hw/integratorcp.c
@@ -512,9 +512,12 @@ static void integratorcp_init(QemuOpts *opts)
 }
 
 static QEMUMachine integratorcp_machine = {
-    .name = "integratorcp",
-    .desc = "ARM Integrator/CP (ARM926EJ-S)",
     .init = integratorcp_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "integratorcp"),
+        QOPT_VALUE("desc", "ARM Integrator/CP (ARM926EJ-S)"),
+        { /* end of list */ },
+    },
 };
 
 static void integratorcp_machine_init(void)
diff --git a/hw/mainstone.c b/hw/mainstone.c
index a7feacc..3f9f742 100644
--- a/hw/mainstone.c
+++ b/hw/mainstone.c
@@ -143,9 +143,12 @@ static void mainstone_init(QemuOpts *opts)
 }
 
 static QEMUMachine mainstone2_machine = {
-    .name = "mainstone",
-    .desc = "Mainstone II (PXA27x)",
     .init = mainstone_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "mainstone"),
+        QOPT_VALUE("desc", "Mainstone II (PXA27x)"),
+        { /* end of list */ },
+    },
 };
 
 static void mainstone_machine_init(void)
diff --git a/hw/mcf5208.c b/hw/mcf5208.c
index 1ed8871..a4df4d2 100644
--- a/hw/mcf5208.c
+++ b/hw/mcf5208.c
@@ -290,9 +290,12 @@ static void mcf5208evb_init(QemuOpts *opts)
 }
 
 static QEMUMachine mcf5208evb_machine = {
-    .name = "mcf5208evb",
-    .desc = "MCF5206EVB",
     .init = mcf5208evb_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "mcf5208evb"),
+        QOPT_VALUE("desc", "MCF5206EVB"),
+        { /* end of list */ },
+    },
 };
 
 static void mcf5208evb_machine_init(void)
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index 7e1e119..4bc561c 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -316,20 +316,20 @@ void mips_pica61_init (QemuOpts *opts)
 }
 
 static QEMUMachine mips_magnum_machine = {
-    .name = "magnum",
-    .desc = "MIPS Magnum",
     .init = mips_magnum_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "magnum"),
+        QOPT_VALUE("desc", "MIPS Magnum"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine mips_pica61_machine = {
-    .name = "pica61",
-    .desc = "Acer Pica 61",
     .init = mips_pica61_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "pica61"),
+        QOPT_VALUE("desc", "Acer Pica 61"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
diff --git a/hw/mips_malta.c b/hw/mips_malta.c
index f89be6d..791c76c 100644
--- a/hw/mips_malta.c
+++ b/hw/mips_malta.c
@@ -990,9 +990,12 @@ void mips_malta_init (QemuOpts *opts)
 }
 
 static QEMUMachine mips_malta_machine = {
-    .name = "malta",
-    .desc = "MIPS Malta Core LV",
     .init = mips_malta_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "malta"),
+        QOPT_VALUE("desc", "MIPS Malta Core LV"),
+        { /* end of list */ },
+    },
 };
 
 static void mips_malta_machine_init(void)
diff --git a/hw/mips_mipssim.c b/hw/mips_mipssim.c
index b5705e6..983c74d 100644
--- a/hw/mips_mipssim.c
+++ b/hw/mips_mipssim.c
@@ -202,9 +202,12 @@ mips_mipssim_init (QemuOpts *opts)
 }
 
 static QEMUMachine mips_mipssim_machine = {
-    .name = "mipssim",
-    .desc = "MIPS MIPSsim platform",
     .init = mips_mipssim_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "mipssim"),
+        QOPT_VALUE("desc", "MIPS MIPSsim platform"),
+        { /* end of list */ },
+    },
 };
 
 static void mips_mipssim_machine_init(void)
diff --git a/hw/mips_r4k.c b/hw/mips_r4k.c
index 853ea3b..4d60fab 100644
--- a/hw/mips_r4k.c
+++ b/hw/mips_r4k.c
@@ -310,9 +310,12 @@ void mips_r4k_init (QemuOpts *opts)
 }
 
 static QEMUMachine mips_machine = {
-    .name = "mips",
-    .desc = "mips r4k platform",
     .init = mips_r4k_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "mips"),
+        QOPT_VALUE("desc", "mips r4k platform"),
+        { /* end of list */ },
+    },
 };
 
 static void mips_machine_init(void)
diff --git a/hw/musicpal.c b/hw/musicpal.c
index 95469d9..1d340ba 100644
--- a/hw/musicpal.c
+++ b/hw/musicpal.c
@@ -1630,9 +1630,12 @@ static void musicpal_init(QemuOpts *opts)
 }
 
 static QEMUMachine musicpal_machine = {
-    .name = "musicpal",
-    .desc = "Marvell 88w8618 / MusicPal (ARM926EJ-S)",
     .init = musicpal_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "musicpal"),
+        QOPT_VALUE("desc", "Marvell 88w8618 / MusicPal (ARM926EJ-S)"),
+        { /* end of list */ },
+    },
 };
 
 static void musicpal_machine_init(void)
diff --git a/hw/nseries.c b/hw/nseries.c
index 13a370b..9f130ba 100644
--- a/hw/nseries.c
+++ b/hw/nseries.c
@@ -1403,15 +1403,21 @@ static void n810_init(QemuOpts *opts)
 }
 
 static QEMUMachine n800_machine = {
-    .name = "n800",
-    .desc = "Nokia N800 tablet aka. RX-34 (OMAP2420)",
     .init = n800_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "n800"),
+        QOPT_VALUE("desc", "Nokia N800 tablet aka. RX-34 (OMAP2420)"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine n810_machine = {
-    .name = "n810",
-    .desc = "Nokia N810 tablet aka. RX-44 (OMAP2420)",
     .init = n810_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "n810"),
+        QOPT_VALUE("desc", "Nokia N810 tablet aka. RX-44 (OMAP2420)"),
+        { /* end of list */ },
+    },
 };
 
 static void nseries_machine_init(void)
diff --git a/hw/omap_sx1.c b/hw/omap_sx1.c
index 46a8402..88f8f04 100644
--- a/hw/omap_sx1.c
+++ b/hw/omap_sx1.c
@@ -230,15 +230,21 @@ static void sx1_init_v2(QemuOpts *opts)
 }
 
 static QEMUMachine sx1_machine_v2 = {
-    .name = "sx1",
-    .desc = "Siemens SX1 (OMAP310) V2",
     .init = sx1_init_v2,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "sx1"),
+        QOPT_VALUE("desc", "Siemens SX1 (OMAP310) V2"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine sx1_machine_v1 = {
-    .name = "sx1-v1",
-    .desc = "Siemens SX1 (OMAP310) V1",
     .init = sx1_init_v1,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "sx1-v1"),
+        QOPT_VALUE("desc", "Siemens SX1 (OMAP310) V1"),
+        { /* end of list */ },
+    },
 };
 
 static void sx1_machine_init(void)
diff --git a/hw/palm.c b/hw/palm.c
index 6001f9b..255f176 100644
--- a/hw/palm.c
+++ b/hw/palm.c
@@ -272,9 +272,12 @@ static void palmte_init(QemuOpts *opts)
 }
 
 static QEMUMachine palmte_machine = {
-    .name = "cheetah",
-    .desc = "Palm Tungsten|E aka. Cheetah PDA (OMAP310)",
     .init = palmte_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "cheetah"),
+        QOPT_VALUE("desc", "Palm Tungsten|E aka. Cheetah PDA (OMAP310)"),
+        { /* end of list */ },
+    },
 };
 
 static void palmte_machine_init(void)
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index e043942..5696aa7 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -182,11 +182,11 @@ static QemuOptDesc pc_opts_desc[] = {
 #endif
 
 static QEMUMachine pc_machine = {
-    .name = "pc",
-    .desc = "Standard PC",
     .init = pc_init,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "pc"),
+        QOPT_VALUE("desc", "Standard PC"),
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
@@ -196,11 +196,11 @@ static QEMUMachine pc_machine = {
 };
 
 static QEMUMachine pc_machine_v0_13 = {
-    .name = "pc-0.13",
-    .desc = "Standard PC",
     .init = pc_init,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "pc-0.13"),
+        QOPT_VALUE("desc", "Standard PC"),
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
@@ -210,11 +210,11 @@ static QEMUMachine pc_machine_v0_13 = {
 };
 
 static QEMUMachine pc_machine_v0_12 = {
-    .name = "pc-0.12",
-    .desc = "Standard PC",
     .init = pc_init,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "pc-0.12"),
+        QOPT_VALUE("desc", "Standard PC"),
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
@@ -226,11 +226,11 @@ static QEMUMachine pc_machine_v0_12 = {
 };
 
 static QEMUMachine pc_machine_v0_11 = {
-    .name = "pc-0.11",
-    .desc = "Standard PC, qemu 0.11",
     .init = pc_init,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "pc-0.11"),
+        QOPT_VALUE("desc", "Standard PC, qemu 0.11"),
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
@@ -246,11 +246,11 @@ static QEMUMachine pc_machine_v0_11 = {
 };
 
 static QEMUMachine pc_machine_v0_10 = {
-    .name = "pc-0.10",
-    .desc = "Standard PC, qemu 0.10",
     .init = pc_init,
     .opts_desc = pc_opts_desc,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "pc-0.10"),
+        QOPT_VALUE("desc", "Standard PC, qemu 0.10"),
         QOPT_VALUE("acpi", "on"),
         QOPT_VALUE("pci", "on"),
         QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
@@ -269,11 +269,11 @@ static QEMUMachine pc_machine_v0_10 = {
 };
 
 static QEMUMachine isapc_machine = {
-    .name = "isapc",
-    .desc = "ISA-only PC",
     .opts_desc = pc_opts_desc,
     .init = pc_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "isapc"),
+        QOPT_VALUE("desc", "ISA-only PC"),
         QOPT_VALUE("acpi", "off"),
         QOPT_VALUE("pci", "off"),
         QOPT_VALUE("cpu", "486"),
diff --git a/hw/petalogix_s3adsp1800_mmu.c b/hw/petalogix_s3adsp1800_mmu.c
index 5528960..0b06717 100644
--- a/hw/petalogix_s3adsp1800_mmu.c
+++ b/hw/petalogix_s3adsp1800_mmu.c
@@ -198,9 +198,12 @@ petalogix_s3adsp1800_init(QemuOpts *opts)
 }
 
 static QEMUMachine petalogix_s3adsp1800_machine = {
-    .name = "petalogix-s3adsp1800",
-    .desc = "Petalogix linux refdesign for xilinx Spartan 3ADSP1800",
     .init = petalogix_s3adsp1800_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "petalogix-s3adsp1800"),
+        QOPT_VALUE("desc", "Petalogix linux refdesign for xilinx Spartan 3ADSP1800"),
+        { /* end of list */ },
+    },
 };
 
 static void petalogix_s3adsp1800_machine_init(void)
diff --git a/hw/ppc405_boards.c b/hw/ppc405_boards.c
index 088cbad..837d9be 100644
--- a/hw/ppc405_boards.c
+++ b/hw/ppc405_boards.c
@@ -349,9 +349,12 @@ static void ref405ep_init (QemuOpts *opts)
 }
 
 static QEMUMachine ref405ep_machine = {
-    .name = "ref405ep",
-    .desc = "ref405ep",
     .init = ref405ep_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "ref405ep"),
+        QOPT_VALUE("desc", "ref405ep"),
+        { /* end of list */ },
+    },
 };
 
 /*****************************************************************************/
@@ -631,9 +634,12 @@ static void taihu_405ep_init(QemuOpts *opts)
 }
 
 static QEMUMachine taihu_machine = {
-    .name = "taihu",
-    .desc = "taihu",
     .init = taihu_405ep_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "taihu"),
+        QOPT_VALUE("desc", "taihu"),
+        { /* end of list */ },
+    },
 };
 
 static void ppc405_machine_init(void)
diff --git a/hw/ppc440_bamboo.c b/hw/ppc440_bamboo.c
index 1650a17..71df6a0 100644
--- a/hw/ppc440_bamboo.c
+++ b/hw/ppc440_bamboo.c
@@ -173,22 +173,28 @@ static void bamboo_init(QemuOpts *opts)
 }
 
 static QEMUMachine bamboo_machine = {
-    .name = "bamboo",
-    .desc = "bamboo",
     .init = bamboo_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "bamboo"),
+        QOPT_VALUE("desc", "bamboo"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine bamboo_machine_v0_13 = {
-    .name = "bamboo-0.13",
-    .desc = "bamboo",
     .init = bamboo_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "bamboo-0.13"),
+        QOPT_VALUE("desc", "bamboo"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine bamboo_machine_v0_12 = {
-    .name = "bamboo-0.12",
-    .desc = "bamboo",
     .init = bamboo_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "bamboo-0.12"),
+        QOPT_VALUE("desc", "bamboo"),
         {
             .name = "virtio-serial-pci.max_nr_ports",
             .value = stringify(1),
diff --git a/hw/ppc_newworld.c b/hw/ppc_newworld.c
index acc320a..1414e5b 100644
--- a/hw/ppc_newworld.c
+++ b/hw/ppc_newworld.c
@@ -439,10 +439,10 @@ static void ppc_core99_init (QemuOpts *opts)
 }
 
 static QEMUMachine core99_machine = {
-    .name = "mac99",
-    .desc = "Mac99 based PowerMAC",
     .init = ppc_core99_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "mac99"),
+        QOPT_VALUE("desc", "Mac99 based PowerMAC"),
         QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
         { /* end of list */ }
     },
diff --git a/hw/ppc_oldworld.c b/hw/ppc_oldworld.c
index 365a2b6..45f469e 100644
--- a/hw/ppc_oldworld.c
+++ b/hw/ppc_oldworld.c
@@ -411,10 +411,10 @@ static void ppc_heathrow_init (QemuOpts *opts)
 }
 
 static QEMUMachine heathrow_machine = {
-    .name = "g3beige",
-    .desc = "Heathrow based PowerMAC",
     .init = ppc_heathrow_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "g3beige"),
+        QOPT_VALUE("desc", "Heathrow based PowerMAC"),
         QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
         { /* end of list */ }
     },
diff --git a/hw/ppc_prep.c b/hw/ppc_prep.c
index 868ef17..43f8dcc 100644
--- a/hw/ppc_prep.c
+++ b/hw/ppc_prep.c
@@ -790,10 +790,10 @@ static void ppc_prep_init (QemuOpts *opts)
 }
 
 static QEMUMachine prep_machine = {
-    .name = "prep",
-    .desc = "PowerPC PREP platform",
     .init = ppc_prep_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "prep"),
+        QOPT_VALUE("desc", "PowerPC PREP platform"),
         QOPT_VALUE("max_cpus", stringify(MAX_CPUS)),
         { /* end of list */ }
     },
diff --git a/hw/ppce500_mpc8544ds.c b/hw/ppce500_mpc8544ds.c
index b110114..6230962 100644
--- a/hw/ppce500_mpc8544ds.c
+++ b/hw/ppce500_mpc8544ds.c
@@ -283,9 +283,12 @@ static void mpc8544ds_init(QemuOpts *opts)
 }
 
 static QEMUMachine mpc8544ds_machine = {
-    .name = "mpc8544ds",
-    .desc = "mpc8544ds",
     .init = mpc8544ds_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "mpc8544ds"),
+        QOPT_VALUE("desc", "mpc8544ds"),
+        { /* end of list */ },
+    },
 };
 
 static void mpc8544ds_machine_init(void)
diff --git a/hw/r2d.c b/hw/r2d.c
index cf0fb89..dd28e9f 100644
--- a/hw/r2d.c
+++ b/hw/r2d.c
@@ -319,9 +319,12 @@ static void r2d_init(QemuOpts *opts)
 }
 
 static QEMUMachine r2d_machine = {
-    .name = "r2d",
-    .desc = "r2d-plus board",
     .init = r2d_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "r2d"),
+        QOPT_VALUE("desc", "r2d-plus board"),
+        { /* end of list */ },
+    },
 };
 
 static void r2d_machine_init(void)
diff --git a/hw/realview.c b/hw/realview.c
index 8dcef80..3eae70c 100644
--- a/hw/realview.c
+++ b/hw/realview.c
@@ -429,20 +429,20 @@ static void realview_pbx_a9_init(QemuOpts *opts)
 }
 
 static QEMUMachine realview_eb_machine = {
-    .name = "realview-eb",
-    .desc = "ARM RealView Emulation Baseboard (ARM926EJ-S)",
     .init = realview_eb_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "realview-eb"),
+        QOPT_VALUE("desc", "ARM RealView Emulation Baseboard (ARM926EJ-S)"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine realview_eb_mpcore_machine = {
-    .name = "realview-eb-mpcore",
-    .desc = "ARM RealView Emulation Baseboard (ARM11MPCore)",
     .init = realview_eb_mpcore_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "realview-eb-mpcore"),
+        QOPT_VALUE("desc", "ARM RealView Emulation Baseboard (ARM11MPCore)"),
         QOPT_VALUE("default_drive", "scsi"),
         QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
@@ -450,16 +450,19 @@ static QEMUMachine realview_eb_mpcore_machine = {
 };
 
 static QEMUMachine realview_pb_a8_machine = {
-    .name = "realview-pb-a8",
-    .desc = "ARM RealView Platform Baseboard for Cortex-A8",
     .init = realview_pb_a8_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "realview-pb-a8"),
+        QOPT_VALUE("desc", "ARM RealView Platform Baseboard for Cortex-A8"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine realview_pbx_a9_machine = {
-    .name = "realview-pbx-a9",
-    .desc = "ARM RealView Platform Baseboard Explore for Cortex-A9",
     .init = realview_pbx_a9_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "realview-pbx-a9"),
+        QOPT_VALUE("desc", "ARM RealView Platform Baseboard Explore for Cortex-A9"),
         QOPT_VALUE("default_drive", "scsi"),
         QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
diff --git a/hw/s390-virtio.c b/hw/s390-virtio.c
index fd1fe52..c254481 100644
--- a/hw/s390-virtio.c
+++ b/hw/s390-virtio.c
@@ -269,10 +269,10 @@ static void s390_init(QemuOpts *opts)
 }
 
 static QEMUMachine s390_machine = {
-    .name = "s390",
-    .desc = "VirtIO based S390 machine",
     .init = s390_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "s390"),
+        QOPT_VALUE("desc", "VirtIO based S390 machine"),
         QOPT_VALUE("serial", "off"),
         QOPT_VALUE("parallel", "off"),
         QOPT_VALUE("virtcon", "on"),
@@ -283,10 +283,10 @@ static QEMUMachine s390_machine = {
 };
 
 static QEMUMachine s390_virtio_machine = {
-    .name = "s390-virtio",
-    .desc = "VirtIO based S390 machine",
     .init = s390_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "s390-virtio"),
+        QOPT_VALUE("desc", "VirtIO based S390 machine"),
         QOPT_VALUE("serial", "off"),
         QOPT_VALUE("parallel", "off"),
         QOPT_VALUE("virtcon", "on"),
diff --git a/hw/shix.c b/hw/shix.c
index 8648c41..1d762db 100644
--- a/hw/shix.c
+++ b/hw/shix.c
@@ -88,9 +88,12 @@ static void shix_init(QemuOpts *opts)
 }
 
 static QEMUMachine shix_machine = {
-    .name = "shix",
-    .desc = "shix card",
     .init = shix_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "shix"),
+        QOPT_VALUE("desc", "shix card"),
+        { /* end of list */ },
+    },
 };
 
 static void shix_machine_init(void)
diff --git a/hw/spitz.c b/hw/spitz.c
index 44cda95..ea476a2 100644
--- a/hw/spitz.c
+++ b/hw/spitz.c
@@ -1046,27 +1046,39 @@ static void terrier_init(QemuOpts *opts)
 }
 
 static QEMUMachine akitapda_machine = {
-    .name = "akita",
-    .desc = "Akita PDA (PXA270)",
     .init = akita_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "akita"),
+        QOPT_VALUE("desc", "Akita PDA (PXA270)"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine spitzpda_machine = {
-    .name = "spitz",
-    .desc = "Spitz PDA (PXA270)",
     .init = spitz_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "spitz"),
+        QOPT_VALUE("desc", "Spitz PDA (PXA270)"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine borzoipda_machine = {
-    .name = "borzoi",
-    .desc = "Borzoi PDA (PXA270)",
     .init = borzoi_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "borzoi"),
+        QOPT_VALUE("desc", "Borzoi PDA (PXA270)"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine terrierpda_machine = {
-    .name = "terrier",
-    .desc = "Terrier PDA (PXA270)",
     .init = terrier_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "terrier"),
+        QOPT_VALUE("desc", "Terrier PDA (PXA270)"),
+        { /* end of list */ },
+    },
 };
 
 static void spitz_machine_init(void)
diff --git a/hw/stellaris.c b/hw/stellaris.c
index 42fb17b..3f6f419 100644
--- a/hw/stellaris.c
+++ b/hw/stellaris.c
@@ -1427,15 +1427,21 @@ static void lm3s6965evb_init(QemuOpts *opts)
 }
 
 static QEMUMachine lm3s811evb_machine = {
-    .name = "lm3s811evb",
-    .desc = "Stellaris LM3S811EVB",
     .init = lm3s811evb_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "lm3s811evb"),
+        QOPT_VALUE("desc", "Stellaris LM3S811EVB"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine lm3s6965evb_machine = {
-    .name = "lm3s6965evb",
-    .desc = "Stellaris LM3S6965EVB",
     .init = lm3s6965evb_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "lm3s6965evb"),
+        QOPT_VALUE("desc", "Stellaris LM3S6965EVB"),
+        { /* end of list */ },
+    },
 };
 
 static void stellaris_machine_init(void)
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 8098cef..5645c7c 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -1317,20 +1317,20 @@ static void sbook_init(QemuOpts *opts)
 }
 
 static QEMUMachine ss5_machine = {
-    .name = "SS-5",
-    .desc = "Sun4m platform, SPARCstation 5",
     .init = ss5_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-5"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCstation 5"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine ss10_machine = {
-    .name = "SS-10",
-    .desc = "Sun4m platform, SPARCstation 10",
     .init = ss10_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-10"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCstation 10"),
         QOPT_VALUE("default_drive", "scsi"),
         QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
@@ -1338,10 +1338,10 @@ static QEMUMachine ss10_machine = {
 };
 
 static QEMUMachine ss600mp_machine = {
-    .name = "SS-600MP",
-    .desc = "Sun4m platform, SPARCserver 600MP",
     .init = ss600mp_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-600MP"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCserver 600MP"),
         QOPT_VALUE("default_drive", "scsi"),
         QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
@@ -1349,10 +1349,10 @@ static QEMUMachine ss600mp_machine = {
 };
 
 static QEMUMachine ss20_machine = {
-    .name = "SS-20",
-    .desc = "Sun4m platform, SPARCstation 20",
     .init = ss20_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-20"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCstation 20"),
         QOPT_VALUE("default_drive", "scsi"),
         QOPT_VALUE("max_cpus", "4"),
         { /* end of list */ }
@@ -1360,50 +1360,50 @@ static QEMUMachine ss20_machine = {
 };
 
 static QEMUMachine voyager_machine = {
-    .name = "Voyager",
-    .desc = "Sun4m platform, SPARCstation Voyager",
     .init = vger_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "Voyager"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCstation Voyager"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine ss_lx_machine = {
-    .name = "LX",
-    .desc = "Sun4m platform, SPARCstation LX",
     .init = ss_lx_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "LX"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCstation LX"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine ss4_machine = {
-    .name = "SS-4",
-    .desc = "Sun4m platform, SPARCstation 4",
     .init = ss4_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-4"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCstation 4"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine scls_machine = {
-    .name = "SPARCClassic",
-    .desc = "Sun4m platform, SPARCClassic",
     .init = scls_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SPARCClassic"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCClassic"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine sbook_machine = {
-    .name = "SPARCbook",
-    .desc = "Sun4m platform, SPARCbook",
     .init = sbook_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SPARCbook"),
+        QOPT_VALUE("desc", "Sun4m platform, SPARCbook"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
@@ -1624,10 +1624,10 @@ static void ss2000_init(QemuOpts *opts)
 }
 
 static QEMUMachine ss1000_machine = {
-    .name = "SS-1000",
-    .desc = "Sun4d platform, SPARCserver 1000",
     .init = ss1000_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-1000"),
+        QOPT_VALUE("desc", "Sun4d platform, SPARCserver 1000"),
         QOPT_VALUE("default_drive", "scsi"),
         QOPT_VALUE("max_cpus", "8"),
         { /* end of list */ }
@@ -1635,10 +1635,10 @@ static QEMUMachine ss1000_machine = {
 };
 
 static QEMUMachine ss2000_machine = {
-    .name = "SS-2000",
-    .desc = "Sun4d platform, SPARCcenter 2000",
     .init = ss2000_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-2000"),
+        QOPT_VALUE("desc", "Sun4d platform, SPARCcenter 2000"),
         QOPT_VALUE("default_drive", "scsi"),
         QOPT_VALUE("max_cpus", "20"),
         { /* end of list */ }
@@ -1814,10 +1814,10 @@ static void ss2_init(QemuOpts *opts)
 }
 
 static QEMUMachine ss2_machine = {
-    .name = "SS-2",
-    .desc = "Sun4c platform, SPARCstation 2",
     .init = ss2_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "SS-2"),
+        QOPT_VALUE("desc", "Sun4c platform, SPARCstation 2"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
diff --git a/hw/sun4u.c b/hw/sun4u.c
index 13e7219..523b2f1 100644
--- a/hw/sun4u.c
+++ b/hw/sun4u.c
@@ -920,21 +920,30 @@ static void niagara_init(QemuOpts *opts)
 }
 
 static QEMUMachine sun4u_machine = {
-    .name = "sun4u",
-    .desc = "Sun4u platform",
     .init = sun4u_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "sun4u"),
+        QOPT_VALUE("desc", "Sun4u platform"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine sun4v_machine = {
-    .name = "sun4v",
-    .desc = "Sun4v platform",
     .init = sun4v_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "sun4v"),
+        QOPT_VALUE("desc", "Sun4v platform"),
+        { /* end of list */ },
+    },
 };
 
 static QEMUMachine niagara_machine = {
-    .name = "Niagara",
-    .desc = "Sun4v platform, Niagara",
     .init = niagara_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "Niagara"),
+        QOPT_VALUE("desc", "Sun4v platform, Niagara"),
+        { /* end of list */ },
+    },
 };
 
 static void sun4u_machine_init(void)
diff --git a/hw/syborg.c b/hw/syborg.c
index 6b796ce..d4b8100 100644
--- a/hw/syborg.c
+++ b/hw/syborg.c
@@ -101,9 +101,12 @@ static void syborg_init(QemuOpts *opts)
 }
 
 static QEMUMachine syborg_machine = {
-    .name = "syborg",
-    .desc = "Syborg (Symbian Virtual Platform)",
     .init = syborg_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "syborg"),
+        QOPT_VALUE("desc", "Syborg (Symbian Virtual Platform)"),
+        { /* end of list */ },
+    },
 };
 
 static void syborg_machine_init(void)
diff --git a/hw/tosa.c b/hw/tosa.c
index 0a691e0..ddc276c 100644
--- a/hw/tosa.c
+++ b/hw/tosa.c
@@ -239,9 +239,12 @@ static void tosa_init(QemuOpts *opts)
 }
 
 static QEMUMachine tosapda_machine = {
-    .name = "tosa",
-    .desc = "Tosa PDA (PXA255)",
     .init = tosa_init,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "tosa"),
+        QOPT_VALUE("desc", "Tosa PDA (PXA255)"),
+        { /* end of list */ },
+    },
 };
 
 static void tosapda_machine_init(void)
diff --git a/hw/versatilepb.c b/hw/versatilepb.c
index f407669..029a288 100644
--- a/hw/versatilepb.c
+++ b/hw/versatilepb.c
@@ -318,20 +318,20 @@ static void vab_init(QemuOpts *opts)
 }
 
 static QEMUMachine versatilepb_machine = {
-    .name = "versatilepb",
-    .desc = "ARM Versatile/PB (ARM926EJ-S)",
     .init = vpb_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "versatilepb"),
+        QOPT_VALUE("desc", "ARM Versatile/PB (ARM926EJ-S)"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
 };
 
 static QEMUMachine versatileab_machine = {
-    .name = "versatileab",
-    .desc = "ARM Versatile/AB (ARM926EJ-S)",
     .init = vab_init,
     .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "versatileab"),
+        QOPT_VALUE("desc", "ARM Versatile/AB (ARM926EJ-S)"),
         QOPT_VALUE("default_drive", "scsi"),
         { /* end of list */ }
     },
diff --git a/hw/xen_machine_pv.c b/hw/xen_machine_pv.c
index 077c0f6..2e63fc9 100644
--- a/hw/xen_machine_pv.c
+++ b/hw/xen_machine_pv.c
@@ -109,9 +109,12 @@ static void xen_init_pv(QemuOpts *opts)
 }
 
 static QEMUMachine xenpv_machine = {
-    .name = "xenpv",
-    .desc = "Xen Para-virtualized PC",
     .init = xen_init_pv,
+    .opts_default = (QemuOptValue[]) {
+        QOPT_VALUE("name", "xenpv"),
+        QOPT_VALUE("desc", "Xen Para-virtualized PC"),
+        { /* end of list */ },
+    },
 };
 
 static void xenpv_machine_init(void)
diff --git a/vl.c b/vl.c
index 8fc89c1..d84fc65 100644
--- a/vl.c
+++ b/vl.c
@@ -1590,17 +1590,13 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
 /***********************************************************/
 /* machine registration */
 
-static QEMUMachine *first_machine = NULL;
+static QTAILQ_HEAD(, QEMUMachine) machine_list =
+    QTAILQ_HEAD_INITIALIZER(machine_list);
 static const char *default_machine = NULL;
 
-int qemu_register_machine(QEMUMachine *m)
+int qemu_register_machine(QEMUMachine *n)
 {
-    QEMUMachine **pm;
-    pm = &first_machine;
-    while (*pm != NULL)
-        pm = &(*pm)->next;
-    m->next = NULL;
-    *pm = m;
+    QTAILQ_INSERT_TAIL(&machine_list, n, node);
     return 0;
 }
 
@@ -1609,13 +1605,26 @@ void machine_set_default(const char *name)
     default_machine = name;
 }
 
+static const char *find_machine_defval(QEMUMachine *m, const char *name)
+{
+    int i;
+    for (i = 0; m->opts_default[i].name; i++) {
+        if (!strcmp(m->opts_default[i].name, name)) {
+            return m->opts_default[i].value;
+        }
+    }
+    return NULL;
+}
+
 static QEMUMachine *find_machine(const char *name)
 {
     QEMUMachine *m;
 
-    for(m = first_machine; m != NULL; m = m->next) {
-        if (!strcmp(m->name, name))
+    QTAILQ_FOREACH(m, &machine_list, node) {
+        const char *val = find_machine_defval(m, "name");
+        if (strcmp(name, val) == 0) {
             return m;
+        }
     }
     return NULL;
 }
@@ -2755,10 +2764,15 @@ int main(int argc, char **argv, char **envp)
                 if (strcmp(optarg, "?") == 0) {
                     QEMUMachine *m;
                     printf("Supported machines are:\n");
-                    for(m = first_machine; m != NULL; m = m->next) {
+                    QTAILQ_FOREACH(m, &machine_list, node) {
+                        const char *name;
+                        const char *desc;
+
+                        name = find_machine_defval(m, "name");
+                        desc = find_machine_defval(m, "desc");
                         printf("%-10s %s%s\n",
-                               m->name, m->desc,
-                               !strcmp(m->name, default_machine) ?
+                               name, desc, 
+                               !strcmp(name, default_machine) ?
                                " (default)" : "");
                     }
                     exit(0);
@@ -3485,7 +3499,8 @@ int main(int argc, char **argv, char **envp)
     max_cpus = qemu_opt_get_number(machine_opts, "max_cpus", 1);
     if (smp_cpus > max_cpus) {
         fprintf(stderr, "Number of SMP cpus requested (%d), exceeds max cpus "
-                "supported by machine `%s' (%d)\n", smp_cpus,  machine->name,
+                "supported by machine `%s' (%d)\n", smp_cpus,
+                qemu_opt_get(machine_opts, "name"),
                 max_cpus);
         exit(1);
     }
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 19/22] machine: introduce accel option to allow selection of kvm or tcg
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (17 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 18/22] machine: final conversion to pure QemuOpts Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 20/22] machine: introduce machine core and split qemu_register_machine Anthony Liguori
                   ` (3 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Marcelo Tosatti, Anthony Liguori, Avi Kivity

Syntax is -machine accel=kvm
          -machine accel=tcg
          -machine accel=kvm|tcg

kvm|tcg tries kvm and fallbacks on tcg if kvm support isn't available.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index 947fa33..1097561 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -81,6 +81,9 @@ void machine_set_default(const char *name);
     },{                                 \
         .name = "sockets",              \
         .type = QEMU_OPT_NUMBER,        \
+    },{                                 \
+        .name = "accel",                \
+        .type = QEMU_OPT_STRING,        \
     }
 
 
diff --git a/vl.c b/vl.c
index d84fc65..7cb5865 100644
--- a/vl.c
+++ b/vl.c
@@ -2654,6 +2654,8 @@ int main(int argc, char **argv, char **envp)
     int defconfig = 1;
     QemuOpts *machine_opts = NULL;
     int max_cpus = 0;
+    const char *accel;
+    int tcg_fallback = 0;
 
     error_set_progname(argv[0]);
 
@@ -3272,7 +3274,10 @@ int main(int argc, char **argv, char **envp)
                 do_smbios_option(optarg);
                 break;
             case QEMU_OPTION_enable_kvm:
-                kvm_allowed = 1;
+                if (!qemu_opts_parsef(&qemu_machine_opts, "accel=kvm")) {
+                    printf("failed\n");
+                    exit(1);
+                }
                 break;
             case QEMU_OPTION_usb:
                 usb_enabled = 1;
@@ -3629,15 +3634,36 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
+    accel = qemu_opt_get(machine_opts, "accel");
+    if (accel) {
+        if (!strcmp(accel, "kvm")) {
+            kvm_allowed = 1;
+        } else if (!strcmp(accel, "tcg")) {
+            kvm_allowed = 0;
+        } else if (!strcmp(accel, "kvm|tcg")) {
+            kvm_allowed = 1;
+            tcg_fallback = 1;
+        } else {
+            fprintf(stderr, "accel: invalid option %s\n", accel);
+            exit(1);
+        }
+    }
+
     if (kvm_allowed) {
         int ret = kvm_init(smp_cpus);
         if (ret < 0) {
             if (!kvm_available()) {
                 printf("KVM not supported for this target\n");
+                exit(1);
             } else {
                 fprintf(stderr, "failed to initialize KVM: %s\n", strerror(-ret));
+
+                if (tcg_fallback) {
+                    kvm_allowed = 0;
+                } else {
+                    exit(1);
+                }
             }
-            exit(1);
         }
     }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 20/22] machine: introduce machine core and split qemu_register_machine
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (18 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 19/22] machine: introduce accel option to allow selection of kvm or tcg Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 21/22] machine: convert pc machines to split core vs machine API Anthony Liguori
                   ` (2 subsequent siblings)
  22 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/boards.h b/hw/boards.h
index 1097561..25881bb 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -5,18 +5,25 @@
 
 #include "qdev.h"
 
-typedef void QEMUMachineInitFunc(QemuOpts *opts);
+typedef void QEMUCoreInitFunc(QemuOpts *opts);
 
 typedef struct QEMUMachine {
-    QEMUMachineInitFunc *init;
+    QEMUCoreInitFunc *init;
     QemuOptDesc *opts_desc;
     QemuOptValue *opts_default;
-    QTAILQ_ENTRY(QEMUMachine) node;
 } QEMUMachine;
 
 int qemu_register_machine(QEMUMachine *machine);
+
 void machine_set_default(const char *name);
 
+void machine_register_core(const char *name,
+                           QEMUCoreInitFunc *init,
+                           QemuOptDesc *opts_desc);
+
+int machine_create_from_core(const char *core,
+                             QemuOptValue *opts_default);
+
 #define QOPT_COMPAT(driver, property, value) \
     QOPT_VALUE(driver "." property, value)
 
diff --git a/vl.c b/vl.c
index 7cb5865..150dd41 100644
--- a/vl.c
+++ b/vl.c
@@ -1590,38 +1590,105 @@ void qemu_del_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque)
 /***********************************************************/
 /* machine registration */
 
-static QTAILQ_HEAD(, QEMUMachine) machine_list =
+typedef struct MachineCore {
+    const char *name;
+    QEMUCoreInitFunc *init;
+    QemuOptDesc *desc;
+    QTAILQ_ENTRY(MachineCore) node;
+} MachineCore;
+
+typedef struct Machine
+{
+    MachineCore *core;
+    QemuOptValue *defaults;
+    QTAILQ_ENTRY(Machine) node;
+} Machine;
+
+static QTAILQ_HEAD(, MachineCore) machine_core_list =
+    QTAILQ_HEAD_INITIALIZER(machine_core_list);
+static QTAILQ_HEAD(, Machine) machine_list =
     QTAILQ_HEAD_INITIALIZER(machine_list);
 static const char *default_machine = NULL;
 
-int qemu_register_machine(QEMUMachine *n)
+static const char *find_machine_defval(QemuOptValue *defaults, const char *name)
 {
-    QTAILQ_INSERT_TAIL(&machine_list, n, node);
-    return 0;
+    int i;
+    for (i = 0; defaults[i].name; i++) {
+        if (!strcmp(defaults[i].name, name)) {
+            return defaults[i].value;
+        }
+    }
+    return NULL;
 }
 
-void machine_set_default(const char *name)
+void machine_register_core(const char *name,
+                           QEMUCoreInitFunc *init,
+                           QemuOptDesc *desc)
 {
-    default_machine = name;
+    MachineCore *c;
+
+    c = qemu_mallocz(sizeof(*c));
+    c->name = strdup(name);
+    c->init = init;
+    c->desc = desc;
+
+    QTAILQ_INSERT_TAIL(&machine_core_list, c, node);
 }
 
-static const char *find_machine_defval(QEMUMachine *m, const char *name)
+static MachineCore *machine_core_find(const char *core)
 {
-    int i;
-    for (i = 0; m->opts_default[i].name; i++) {
-        if (!strcmp(m->opts_default[i].name, name)) {
-            return m->opts_default[i].value;
+    MachineCore *c;
+
+    QTAILQ_FOREACH(c, &machine_core_list, node) {
+        if (strcmp(c->name, core) == 0) {
+            return c;
         }
     }
+
     return NULL;
 }
 
-static QEMUMachine *find_machine(const char *name)
+int machine_create_from_core(const char *core,
+                             QemuOptValue *opts_default)
+{
+    MachineCore *c;
+    Machine *m;
+
+    c = machine_core_find(core);
+    if (c == NULL) {
+        return -1;
+    }
+
+    m = qemu_mallocz(sizeof(*m));
+    m->core = c;
+    m->defaults = opts_default;
+
+    QTAILQ_INSERT_TAIL(&machine_list, m, node);
+
+    return 0;
+}
+
+int qemu_register_machine(QEMUMachine *n)
+{
+    const char *name;
+
+    name = find_machine_defval(n->opts_default, "name");
+    machine_register_core(name, n->init, n->opts_desc);
+
+    return machine_create_from_core(name, n->opts_default);
+}
+
+void machine_set_default(const char *name)
+{
+    default_machine = name;
+}
+
+static Machine *find_machine(const char *name)
 {
-    QEMUMachine *m;
+    Machine *m;
 
     QTAILQ_FOREACH(m, &machine_list, node) {
-        const char *val = find_machine_defval(m, "name");
+        const char *val = find_machine_defval(m->defaults, "name");
         if (strcmp(name, val) == 0) {
             return m;
         }
@@ -1629,7 +1696,7 @@ static QEMUMachine *find_machine(const char *name)
     return NULL;
 }
 
-static QEMUMachine *find_default_machine(void)
+static Machine *find_default_machine(void)
 {
     return find_machine(default_machine);
 }
@@ -2600,7 +2667,7 @@ static int machine_combine_opt(const char *name, const char *value, void *opaque
 
 static int machine_find(QemuOpts *opts, void *opaque)
 {
-    QEMUMachine **machinep = opaque;
+    Machine **machinep = opaque;
     const char *driver;
 
     driver = qemu_opt_get(opts, "driver");
@@ -2636,7 +2703,7 @@ int main(int argc, char **argv, char **envp)
     int optind;
     const char *optarg;
     const char *loadvm = NULL;
-    QEMUMachine *machine = NULL;
+    Machine *machine = NULL;
     const char *cpu_model;
 #ifndef _WIN32
     int fds[2];
@@ -2764,14 +2831,14 @@ int main(int argc, char **argv, char **envp)
             switch(popt->index) {
             case QEMU_OPTION_M:
                 if (strcmp(optarg, "?") == 0) {
-                    QEMUMachine *m;
+                    Machine *m;
                     printf("Supported machines are:\n");
                     QTAILQ_FOREACH(m, &machine_list, node) {
                         const char *name;
                         const char *desc;
 
-                        name = find_machine_defval(m, "name");
-                        desc = find_machine_defval(m, "desc");
+                        name = find_machine_defval(m->defaults, "name");
+                        desc = find_machine_defval(m->defaults, "desc");
                         printf("%-10s %s%s\n",
                                name, desc, 
                                !strcmp(name, default_machine) ?
@@ -3482,17 +3549,17 @@ int main(int argc, char **argv, char **envp)
         machine = find_default_machine();
     }
 
-    if (machine->opts_default) {
+    if (machine->defaults) {
         opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
-        qemu_opts_set_defaults(opts, machine->opts_default);
+        qemu_opts_set_defaults(opts, machine->defaults);
     }
 
     /* Combine all -machine options into one option group */
     machine_opts = qemu_opts_create(&qemu_machine_opts, NULL, 0);
     qemu_opts_foreach(&qemu_machine_opts, machine_combine_opts, machine_opts, 0);
 
-    if (machine->opts_desc) {
-        if (qemu_opts_validate(machine_opts, machine->opts_desc) < 0) {
+    if (machine->core->desc) {
+        if (qemu_opts_validate(machine_opts, machine->core->desc) < 0) {
             exit(1);
         }
     } else {
@@ -3839,7 +3906,7 @@ int main(int argc, char **argv, char **envp)
         qemu_opt_set(machine_opts, "acpi", "off");
     }
 
-    machine->init(machine_opts);
+    machine->core->init(machine_opts);
 
     qemu_opts_del(machine_opts);
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 21/22] machine: convert pc machines to split core vs machine API
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (19 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 20/22] machine: introduce machine core and split qemu_register_machine Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-09  7:51   ` Jes Sorensen
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config Anthony Liguori
  2010-06-08  3:12 ` [Qemu-devel] [PATCH 0/22] Refactor machine support Paul Brook
  22 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index 5696aa7..c7c1bd7 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -162,134 +162,113 @@ static void pc_init(QemuOpts *opts)
     }
 }
 
-static QemuOptDesc pc_opts_desc[] = {
-    COMMON_MACHINE_OPTS(),
-    {
-        .name = "acpi",
-        .type = QEMU_OPT_BOOL,
-    },
-    {
-        .name = "pci",
-        .type = QEMU_OPT_BOOL,
-    },
-    { /* end of list */ },
-};
-
 #ifdef TARGET_X86_64
 #define PC_DEFAULT_CPU_MODEL "qemu64"
 #else
 #define PC_DEFAULT_CPU_MODEL "qemu32"
 #endif
 
-static QEMUMachine pc_machine = {
-    .init = pc_init,
-    .opts_desc = pc_opts_desc,
-    .opts_default = (QemuOptValue[]) {
-        QOPT_VALUE("name", "pc"),
-        QOPT_VALUE("desc", "Standard PC"),
-        QOPT_VALUE("acpi", "on"),
-        QOPT_VALUE("pci", "on"),
-        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
-        QOPT_VALUE("max_cpus", "255"),
-        { /* end of list */ }
-    },
+static QemuOptValue pc_machine[] = {
+    QOPT_VALUE("name", "pc"),
+    QOPT_VALUE("desc", "Standard PC"),
+    QOPT_VALUE("acpi", "on"),
+    QOPT_VALUE("pci", "on"),
+    QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+    QOPT_VALUE("max_cpus", "255"),
+    { /* end of list */ }
 };
 
-static QEMUMachine pc_machine_v0_13 = {
-    .init = pc_init,
-    .opts_desc = pc_opts_desc,
-    .opts_default = (QemuOptValue[]) {
-        QOPT_VALUE("name", "pc-0.13"),
-        QOPT_VALUE("desc", "Standard PC"),
-        QOPT_VALUE("acpi", "on"),
-        QOPT_VALUE("pci", "on"),
-        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
-        QOPT_VALUE("max_cpus", "255"),
-        { /* end of list */ }
-    },
+static QemuOptValue pc_machine_v0_13[] = {
+    QOPT_VALUE("name", "pc-0.13"),
+    QOPT_VALUE("desc", "Standard PC"),
+    QOPT_VALUE("acpi", "on"),
+    QOPT_VALUE("pci", "on"),
+    QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+    QOPT_VALUE("max_cpus", "255"),
+    { /* end of list */ }
 };
 
-static QEMUMachine pc_machine_v0_12 = {
-    .init = pc_init,
-    .opts_desc = pc_opts_desc,
-    .opts_default = (QemuOptValue[]) {
-        QOPT_VALUE("name", "pc-0.12"),
-        QOPT_VALUE("desc", "Standard PC"),
-        QOPT_VALUE("acpi", "on"),
-        QOPT_VALUE("pci", "on"),
-        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
-        QOPT_VALUE("max_cpus", "255"),
-        QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
-        QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
-        { /* end of list */ }
-    },
+static QemuOptValue pc_machine_v0_12[] = {
+    QOPT_VALUE("name", "pc-0.12"),
+    QOPT_VALUE("desc", "Standard PC"),
+    QOPT_VALUE("acpi", "on"),
+    QOPT_VALUE("pci", "on"),
+    QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+    QOPT_VALUE("max_cpus", "255"),
+    QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
+    QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
+    { /* end of list */ }
 };
 
-static QEMUMachine pc_machine_v0_11 = {
-    .init = pc_init,
-    .opts_desc = pc_opts_desc,
-    .opts_default = (QemuOptValue[]) {
-        QOPT_VALUE("name", "pc-0.11"),
-        QOPT_VALUE("desc", "Standard PC, qemu 0.11"),
-        QOPT_VALUE("acpi", "on"),
-        QOPT_VALUE("pci", "on"),
-        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
-        QOPT_VALUE("max_cpus", "255"),
-        QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
-        QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
-        QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
-        QOPT_COMPAT("ide-drive", "ver", "0.11"),
-        QOPT_COMPAT("scsi-disk", "ver", "0.11"),
-        QOPT_COMPAT_INT("PCI", "rombar", 0),
-        { /* end of list */ }
-    }
+static QemuOptValue pc_machine_v0_11[] = {
+    QOPT_VALUE("name", "pc-0.11"),
+    QOPT_VALUE("desc", "Standard PC, qemu 0.11"),
+    QOPT_VALUE("acpi", "on"),
+    QOPT_VALUE("pci", "on"),
+    QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+    QOPT_VALUE("max_cpus", "255"),
+    QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
+    QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
+    QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
+    QOPT_COMPAT("ide-drive", "ver", "0.11"),
+    QOPT_COMPAT("scsi-disk", "ver", "0.11"),
+    QOPT_COMPAT_INT("PCI", "rombar", 0),
+    { /* end of list */ }
 };
 
-static QEMUMachine pc_machine_v0_10 = {
-    .init = pc_init,
-    .opts_desc = pc_opts_desc,
-    .opts_default = (QemuOptValue[]) {
-        QOPT_VALUE("name", "pc-0.10"),
-        QOPT_VALUE("desc", "Standard PC, qemu 0.10"),
-        QOPT_VALUE("acpi", "on"),
-        QOPT_VALUE("pci", "on"),
-        QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
-        QOPT_VALUE("max_cpu", "255"),
-        QOPT_COMPAT_INT("virtio-blk-pci", "class", PCI_CLASS_STORAGE_OTHER),
-        QOPT_COMPAT_INT("virtio-serial-pci", "class", PCI_CLASS_DISPLAY_OTHER),
-        QOPT_COMPAT_INT("virtio-net-pci", "vectors", 0),
-        QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
-        QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
-        QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
-        QOPT_COMPAT("ide-drive", "ver", "0.10"),
-        QOPT_COMPAT("scsi-disk", "ver", "0.10"),
-        QOPT_COMPAT_INT("PCI", "rombar", 0),
-        { /* end of list */ }
-    },
+static QemuOptValue pc_machine_v0_10[] = {
+    QOPT_VALUE("name", "pc-0.10"),
+    QOPT_VALUE("desc", "Standard PC, qemu 0.10"),
+    QOPT_VALUE("acpi", "on"),
+    QOPT_VALUE("pci", "on"),
+    QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
+    QOPT_VALUE("max_cpu", "255"),
+    QOPT_COMPAT_INT("virtio-blk-pci", "class", PCI_CLASS_STORAGE_OTHER),
+    QOPT_COMPAT_INT("virtio-serial-pci", "class", PCI_CLASS_DISPLAY_OTHER),
+    QOPT_COMPAT_INT("virtio-net-pci", "vectors", 0),
+    QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
+    QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
+    QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
+    QOPT_COMPAT("ide-drive", "ver", "0.10"),
+    QOPT_COMPAT("scsi-disk", "ver", "0.10"),
+    QOPT_COMPAT_INT("PCI", "rombar", 0),
+    { /* end of list */ }
+};
+
+static QemuOptValue isapc_machine[] = {
+    QOPT_VALUE("name", "isapc"),
+    QOPT_VALUE("desc", "ISA-only PC"),
+    QOPT_VALUE("acpi", "off"),
+    QOPT_VALUE("pci", "off"),
+    QOPT_VALUE("cpu", "486"),
+    QOPT_VALUE("max_cpus", "1"),
+    { /* end of list */ }
 };
 
-static QEMUMachine isapc_machine = {
-    .opts_desc = pc_opts_desc,
-    .init = pc_init,
-    .opts_default = (QemuOptValue[]) {
-        QOPT_VALUE("name", "isapc"),
-        QOPT_VALUE("desc", "ISA-only PC"),
-        QOPT_VALUE("acpi", "off"),
-        QOPT_VALUE("pci", "off"),
-        QOPT_VALUE("cpu", "486"),
-        QOPT_VALUE("max_cpus", "1"),
-        { /* end of list */ }
+static QemuOptDesc pc_opts_desc[] = {
+    COMMON_MACHINE_OPTS(),
+    {
+        .name = "acpi",
+        .type = QEMU_OPT_BOOL,
+    },
+    {
+        .name = "pci",
+        .type = QEMU_OPT_BOOL,
     },
+    { /* end of list */ },
 };
 
 static void pc_machine_init(void)
 {
-    qemu_register_machine(&pc_machine);
-    qemu_register_machine(&pc_machine_v0_13);
-    qemu_register_machine(&pc_machine_v0_12);
-    qemu_register_machine(&pc_machine_v0_11);
-    qemu_register_machine(&pc_machine_v0_10);
-    qemu_register_machine(&isapc_machine);
+    machine_register_core("pc", pc_init, pc_opts_desc);
+
+    machine_create_from_core("pc", pc_machine);
+    machine_create_from_core("pc", pc_machine_v0_13);
+    machine_create_from_core("pc", pc_machine_v0_12);
+    machine_create_from_core("pc", pc_machine_v0_11);
+    machine_create_from_core("pc", pc_machine_v0_10);
+    machine_create_from_core("pc", isapc_machine);
+
     machine_set_default("pc");
 }
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (20 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 21/22] machine: convert pc machines to split core vs machine API Anthony Liguori
@ 2010-06-07 23:52 ` Anthony Liguori
  2010-06-08  0:50   ` Anthony Liguori
  2010-06-08  3:12 ` [Qemu-devel] [PATCH 0/22] Refactor machine support Paul Brook
  22 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-07 23:52 UTC (permalink / raw)
  To: qemu-devel; +Cc: Glauber Costa, Anthony Liguori

Since we have MachineCore and can represent a machine entirely via default
options, we can introduce a new option that let's us dynamically register a
machine based on those options.

For instance, we could add the following to target-x86_64.conf:

[machine-def]
 name = "pc-0.11"
 desc = "Standard PC"
 acpi = "on"
 pci = "on"
 cpu = "qemu64"
 max_cpus = "255"
 virtio-blk-pci.vectors = "0"
 virtio-serial-pci.max_nr_ports = "1"
 virtio-serial-pci.vectors = "0"
 ide-drive.ver = "0.11"
 scsi-disk.ver = "0.11"
 PCI.rombar = "0"

What's really exciting, is that a user can then define their own machines
that better suite their desires:

[kvmpc]
 name = "kvmpc"
 accel = "kvm|tcg"
 ram_size = "512M"
 max_cpus = "64"
 sockets = "16"
 default_drive = "virtio"

I'd eventually like to move all PC compatibility machines to the default
config but for now, I wanted to keep this simple.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu-config.c b/qemu-config.c
index a0cb34f..9b5415d 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -345,6 +345,15 @@ QemuOptsList qemu_machine_opts = {
     },
 };        
 
+QemuOptsList qemu_machine_def_opts = {
+    .name = "machine-def",
+    .implied_opt_name = "name",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_def_opts.head),
+    .desc = {
+        { /* end of list */ }
+    },
+};
+
 static QemuOptsList *vm_config_groups[] = {
     &qemu_drive_opts,
     &qemu_chardev_opts,
@@ -356,6 +365,7 @@ static QemuOptsList *vm_config_groups[] = {
     &qemu_mon_opts,
     &qemu_cpudef_opts,
     &qemu_machine_opts,
+    &qemu_machine_def_opts,
     NULL,
 };
 
diff --git a/qemu-config.h b/qemu-config.h
index 6f52188..1b7324c 100644
--- a/qemu-config.h
+++ b/qemu-config.h
@@ -15,6 +15,7 @@ extern QemuOptsList qemu_global_opts;
 extern QemuOptsList qemu_mon_opts;
 extern QemuOptsList qemu_cpudef_opts;
 extern QemuOptsList qemu_machine_opts;
+extern QemuOptsList qemu_machine_def_opts;
 
 QemuOptsList *qemu_find_opts(const char *group);
 int qemu_set_option(const char *str);
diff --git a/qemu-options.hx b/qemu-options.hx
index 32fd32a..2bafe22 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -43,6 +43,14 @@ STEXI
 Select the emulated @var{machine}
 ETEXI
 
+DEF("machine-def", HAS_ARG, QEMU_OPTION_machine_def,
+    "-machine-def name[,opt=val...] define a new machine\n", QEMU_ARCH_ALL)
+STEXI
+@item -machine-def @var{name}[,@var{opt}=@var{val}...]
+@findex -machine-def
+Define a new machine
+ETEXI
+
 DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
     "-cpu cpu        select CPU (-cpu ? for list)\n", QEMU_ARCH_ALL)
 STEXI
diff --git a/vl.c b/vl.c
index 150dd41..7797187 100644
--- a/vl.c
+++ b/vl.c
@@ -1683,6 +1683,59 @@ void machine_set_default(const char *name)
     default_machine = name;
 }
 
+typedef struct MachineDefineHelper
+{
+    QemuOptValue *defaults;
+    int length;
+    int capacity;
+} MachineDefineHelper;
+
+static void helper_grow(MachineDefineHelper *helper)
+{
+    if ((helper->capacity - helper->length) < 2) {
+        helper->capacity += 100;
+        helper->defaults = qemu_realloc(helper->defaults,
+                                        helper->capacity * sizeof(QemuOptValue));
+    }
+}
+
+static int machine_define_prop(const char *name, const char *value, void *opaque)
+{
+    MachineDefineHelper *helper = opaque;
+    QemuOptValue *v;
+
+    if (strcmp(name, "core") == 0) {
+        return 0;
+    }
+
+    helper_grow(helper);
+    v = &helper->defaults[helper->length++];
+    v->name = qemu_strdup(name);
+    v->value = qemu_strdup(value);
+
+    return 0;
+}
+
+static int machine_define(QemuOpts *opts, void *opaque)
+{
+    MachineDefineHelper *helper;
+    const char *core;
+
+    core = qemu_opt_get(opts, "core");
+    if (!core) {
+        fprintf(stderr, "machine-def: No core specified\n");
+        return -1;
+    }
+
+    helper = qemu_mallocz(sizeof(*helper));
+    qemu_opt_foreach(opts, machine_define_prop, helper, 1);
+    helper->defaults[helper->length].name = NULL;
+    machine_create_from_core(core, helper->defaults);
+    qemu_free(helper);
+
+    return 0;
+}
+
 static Machine *find_machine(const char *name)
 {
     Machine *m;
@@ -2812,6 +2865,7 @@ int main(int argc, char **argv, char **envp)
         }
     }
     cpudef_init();
+    qemu_opts_foreach(&qemu_machine_def_opts, machine_define, NULL, 1);
 
     /* second pass of option parsing */
     optind = 1;
@@ -2853,6 +2907,14 @@ int main(int argc, char **argv, char **envp)
                     exit(1);
                 }
                 break;
+            case QEMU_OPTION_machine_def:
+                opts = qemu_opts_parse(&qemu_machine_def_opts, optarg, 1);
+                if (!opts) {
+                    exit(1);
+                }
+
+                machine_define(opts, NULL);
+                break;
             case QEMU_OPTION_cpu:
                 /* hw initialization will check this */
                 if (*optarg == '?') {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config Anthony Liguori
@ 2010-06-08  0:50   ` Anthony Liguori
  2010-06-10 17:48     ` Daniel P. Berrange
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08  0:50 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

On 06/07/2010 06:52 PM, Anthony Liguori wrote:
> Since we have MachineCore and can represent a machine entirely via default
> options, we can introduce a new option that let's us dynamically register a
> machine based on those options.
>
> For instance, we could add the following to target-x86_64.conf:
>
> [machine-def]
>   name = "pc-0.11"
>   desc = "Standard PC"
>   acpi = "on"
>   pci = "on"
>   cpu = "qemu64"
>   max_cpus = "255"
>   virtio-blk-pci.vectors = "0"
>   virtio-serial-pci.max_nr_ports = "1"
>   virtio-serial-pci.vectors = "0"
>   ide-drive.ver = "0.11"
>   scsi-disk.ver = "0.11"
>   PCI.rombar = "0"
>
> What's really exciting, is that a user can then define their own machines
> that better suite their desires:
>
> [kvmpc]
>   name = "kvmpc"
>   accel = "kvm|tcg"
>   ram_size = "512M"
>   max_cpus = "64"
>   sockets = "16"
>   default_drive = "virtio"
>
> I'd eventually like to move all PC compatibility machines to the default
> config but for now, I wanted to keep this simple.
>
> Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
>    

 From the perspective of a tool like libvirt, I think there are a couple 
ways it could handle something like this and I think it's worth 
discussing the options.

Assume we move all the compat machine definitions into a config file, 
since libvirt presumably uses -nodefconfig today, it could simply 
include it's own machine definitions for each qemu version based on the 
definitions we ship.  That makes sure that the definition is always 
static for libvirt.

Another option would be for libvirt to not use -nodefconfig, and instead 
to let the user's global configs be read.  libvirt would then read the 
config file from the running qemu instance to sync it's state up.

The later option is a bit more work up front but longer term, I think it 
addresses a couple things nicely.  It provides a way for a user 
specified config to co-exist with libvirt.  It also let's tools tweak 
power config options in a way that's compatible with libvirt.

If libvirt can embed the qemu config description in its own XML, then 
there is no problem for libvirt to recreate the system on a different 
box even if the global configuration is different.

Regards,

Anthony Liguori

> diff --git a/qemu-config.c b/qemu-config.c
> index a0cb34f..9b5415d 100644
> --- a/qemu-config.c
> +++ b/qemu-config.c
> @@ -345,6 +345,15 @@ QemuOptsList qemu_machine_opts = {
>       },
>   };
>
> +QemuOptsList qemu_machine_def_opts = {
> +    .name = "machine-def",
> +    .implied_opt_name = "name",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_def_opts.head),
> +    .desc = {
> +        { /* end of list */ }
> +    },
> +};
> +
>   static QemuOptsList *vm_config_groups[] = {
>       &qemu_drive_opts,
>       &qemu_chardev_opts,
> @@ -356,6 +365,7 @@ static QemuOptsList *vm_config_groups[] = {
>       &qemu_mon_opts,
>       &qemu_cpudef_opts,
>       &qemu_machine_opts,
> +&qemu_machine_def_opts,
>       NULL,
>   };
>
> diff --git a/qemu-config.h b/qemu-config.h
> index 6f52188..1b7324c 100644
> --- a/qemu-config.h
> +++ b/qemu-config.h
> @@ -15,6 +15,7 @@ extern QemuOptsList qemu_global_opts;
>   extern QemuOptsList qemu_mon_opts;
>   extern QemuOptsList qemu_cpudef_opts;
>   extern QemuOptsList qemu_machine_opts;
> +extern QemuOptsList qemu_machine_def_opts;
>
>   QemuOptsList *qemu_find_opts(const char *group);
>   int qemu_set_option(const char *str);
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 32fd32a..2bafe22 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -43,6 +43,14 @@ STEXI
>   Select the emulated @var{machine}
>   ETEXI
>
> +DEF("machine-def", HAS_ARG, QEMU_OPTION_machine_def,
> +    "-machine-def name[,opt=val...] define a new machine\n", QEMU_ARCH_ALL)
> +STEXI
> +@item -machine-def @var{name}[,@var{opt}=@var{val}...]
> +@findex -machine-def
> +Define a new machine
> +ETEXI
> +
>   DEF("cpu", HAS_ARG, QEMU_OPTION_cpu,
>       "-cpu cpu        select CPU (-cpu ? for list)\n", QEMU_ARCH_ALL)
>   STEXI
> diff --git a/vl.c b/vl.c
> index 150dd41..7797187 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -1683,6 +1683,59 @@ void machine_set_default(const char *name)
>       default_machine = name;
>   }
>
> +typedef struct MachineDefineHelper
> +{
> +    QemuOptValue *defaults;
> +    int length;
> +    int capacity;
> +} MachineDefineHelper;
> +
> +static void helper_grow(MachineDefineHelper *helper)
> +{
> +    if ((helper->capacity - helper->length)<  2) {
> +        helper->capacity += 100;
> +        helper->defaults = qemu_realloc(helper->defaults,
> +                                        helper->capacity * sizeof(QemuOptValue));
> +    }
> +}
> +
> +static int machine_define_prop(const char *name, const char *value, void *opaque)
> +{
> +    MachineDefineHelper *helper = opaque;
> +    QemuOptValue *v;
> +
> +    if (strcmp(name, "core") == 0) {
> +        return 0;
> +    }
> +
> +    helper_grow(helper);
> +    v =&helper->defaults[helper->length++];
> +    v->name = qemu_strdup(name);
> +    v->value = qemu_strdup(value);
> +
> +    return 0;
> +}
> +
> +static int machine_define(QemuOpts *opts, void *opaque)
> +{
> +    MachineDefineHelper *helper;
> +    const char *core;
> +
> +    core = qemu_opt_get(opts, "core");
> +    if (!core) {
> +        fprintf(stderr, "machine-def: No core specified\n");
> +        return -1;
> +    }
> +
> +    helper = qemu_mallocz(sizeof(*helper));
> +    qemu_opt_foreach(opts, machine_define_prop, helper, 1);
> +    helper->defaults[helper->length].name = NULL;
> +    machine_create_from_core(core, helper->defaults);
> +    qemu_free(helper);
> +
> +    return 0;
> +}
> +
>   static Machine *find_machine(const char *name)
>   {
>       Machine *m;
> @@ -2812,6 +2865,7 @@ int main(int argc, char **argv, char **envp)
>           }
>       }
>       cpudef_init();
> +    qemu_opts_foreach(&qemu_machine_def_opts, machine_define, NULL, 1);
>
>       /* second pass of option parsing */
>       optind = 1;
> @@ -2853,6 +2907,14 @@ int main(int argc, char **argv, char **envp)
>                       exit(1);
>                   }
>                   break;
> +            case QEMU_OPTION_machine_def:
> +                opts = qemu_opts_parse(&qemu_machine_def_opts, optarg, 1);
> +                if (!opts) {
> +                    exit(1);
> +                }
> +
> +                machine_define(opts, NULL);
> +                break;
>               case QEMU_OPTION_cpu:
>                   /* hw initialization will check this */
>                   if (*optarg == '?') {
>    

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option Anthony Liguori
@ 2010-06-08  1:01   ` Paul Brook
  2010-06-08  1:56     ` Anthony Liguori
  2010-06-09  7:47   ` Jes Sorensen
  1 sibling, 1 reply; 64+ messages in thread
From: Paul Brook @ 2010-06-08  1:01 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Glauber Costa

> diff --git a/hw/realview.c b/hw/realview.c
> index a36bdbe..8dcef80 100644
> --- a/hw/realview.c
> +++ b/hw/realview.c
> @@ -444,9 +444,9 @@ static QEMUMachine realview_eb_mpcore_machine = {
>      .init = realview_eb_mpcore_init,
>      .opts_default = (QemuOptValue[]) {
>          QOPT_VALUE("default_drive", "scsi"),
> +        QOPT_VALUE("max_cpus", "4"),
>          { /* end of list */ }
>      },
> -    .max_cpus = 4,
>  };

By my reading this allows the user to modify this value. If so it is wrong. 

This is a fundamental property/limitation of the hardware. Expect qemu to 
crash if the value is modified.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option
  2010-06-08  1:01   ` Paul Brook
@ 2010-06-08  1:56     ` Anthony Liguori
  2010-06-08  2:56       ` Paul Brook
  2010-06-09  7:44       ` Jes Sorensen
  0 siblings, 2 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08  1:56 UTC (permalink / raw)
  To: Paul Brook; +Cc: Glauber Costa, qemu-devel

On 06/07/2010 08:01 PM, Paul Brook wrote:
>> diff --git a/hw/realview.c b/hw/realview.c
>> index a36bdbe..8dcef80 100644
>> --- a/hw/realview.c
>> +++ b/hw/realview.c
>> @@ -444,9 +444,9 @@ static QEMUMachine realview_eb_mpcore_machine = {
>>       .init = realview_eb_mpcore_init,
>>       .opts_default = (QemuOptValue[]) {
>>           QOPT_VALUE("default_drive", "scsi"),
>> +        QOPT_VALUE("max_cpus", "4"),
>>           { /* end of list */ }
>>       },
>> -    .max_cpus = 4,
>>   };
>>      
> By my reading this allows the user to modify this value. If so it is wrong.
>    

max_cpus is complicated because it was used for multiple purposes.

I think max_cpus ought to be configurable.  The reason it's useful to 
configure it that it lets a downstream specify a recommended max cpu 
that's mostly relevant from a scalability perspective.  For instance, 
you may want to set the pc max_cpus to 64 since this is the highest that 
KVM supports today.

> This is a fundamental property/limitation of the hardware. Expect qemu to
> crash if the value is modified.
>    

In this case, the machine cores should be rejecting totally invalid 
values to prevent crashes from occurring.  My reading of realview does 
not suggest that a crash would occur.  Are you speaking in general terms 
or do you think it will actually fail in realview?

Regards,

Anthony Liguori


> Paul
>
>    

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option
  2010-06-08  1:56     ` Anthony Liguori
@ 2010-06-08  2:56       ` Paul Brook
  2010-06-09  7:44       ` Jes Sorensen
  1 sibling, 0 replies; 64+ messages in thread
From: Paul Brook @ 2010-06-08  2:56 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

> max_cpus is complicated because it was used for multiple purposes.

I don't see any such uses.

> > This is a fundamental property/limitation of the hardware. Expect qemu to
> > crash if the value is modified.
> 
> In this case, the machine cores should be rejecting totally invalid
> values to prevent crashes from occurring.  My reading of realview does
> not suggest that a crash would occur.  Are you speaking in general terms
> or do you think it will actually fail in realview?

    qemu_irq cpu_irq[4];
    ...
    for (n = 0; n < smp_cpus; n++) {
        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];

I'm pretty sure bad things will happen there if smp_cpus is > 4.
Similar assumptions exist in apic.c, and probably others.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 0/22] Refactor machine support
  2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
                   ` (21 preceding siblings ...)
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config Anthony Liguori
@ 2010-06-08  3:12 ` Paul Brook
  2010-06-08 10:24   ` [Qemu-devel] " Paolo Bonzini
  2010-06-08 14:04   ` [Qemu-devel] " Anthony Liguori
  22 siblings, 2 replies; 64+ messages in thread
From: Paul Brook @ 2010-06-08  3:12 UTC (permalink / raw)
  To: qemu-devel; +Cc: Anthony Liguori, Glauber Costa

> This series introduces a rather radical change in the way we deal with
> machine definitions in QEMU.

I think we should aim to eliminate machine_register_core, and design 
appropriately.  In particular I'd try and avoid adding options that become 
trivially redundant once you can easily change the device trees.

I'm undecided how much parameterisation it's worth trying to support in the 
device tree. IMO the current code has way too much magic, because creating a 
new variant involves hacking and rebuilding pc.c.

I'm extremely tempted by the extreme approach of punting everything to an 
external device tree builder. i.e. remove automagical device reation 
altogether. If you want USB and 6 virtio disks then ask your device tree 
builder to create a machine description that includes pci-ohci and a bunch of 
virtio-blk-pci devices. The virtio-blk devices reference "drives" by id, so 
the same host configuration can be used with a scsi HBA. A small shell script 
should be sufficient to replicate the limited machine variants currently 
supported.

The problem with doing clever device tree generation/manipulation inside qemu 
is that for anything vaguely nonstandard you're likely to have to hack your 
own device tree anyway. Even ram allocation is nontrivial, e.g. the hole below 
4G on the PC, and that's before you start with numa-like layouts.

On a similar note, I don't see any point having machine_create_from_core,
we can just ship appropriate config files.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice Anthony Liguori
@ 2010-06-08  7:51   ` Gerd Hoffmann
  2010-06-08 10:32     ` [Qemu-devel] " Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Gerd Hoffmann @ 2010-06-08  7:51 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

On 06/08/10 01:51, Anthony Liguori wrote:
> Right now, if you set a QemuOpts option in a section twice, when you get the
> option you'll receive the value that was set the first time.  This is less than
> ideal because if you're manipulating options in two places like a global config
> followed by the command line, you really want the later to override the former.
>
> This patch fixes this behavior.

Note that this reverses the ordering for users which want multiple 
values (slirp forwarding for example).

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 05/22] machine: pass all init options as a single QemuOpts
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 05/22] machine: pass all init options as a single QemuOpts Anthony Liguori
@ 2010-06-08  7:58   ` Gerd Hoffmann
  0 siblings, 0 replies; 64+ messages in thread
From: Gerd Hoffmann @ 2010-06-08  7:58 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

On 06/08/10 01:51, Anthony Liguori wrote:
> This patch redefines the machine init signature to just take a QemuOpts.  It
> also passes the machine as the first parameter to allow multiple boards to be
> defined with one init function.

> +typedef void QEMUMachineInitFunc(QemuOpts *opts);

Hmm?  Where is the machine parameter?

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc
  2010-06-07 23:51 ` [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc Anthony Liguori
@ 2010-06-08  8:03   ` Gerd Hoffmann
  2010-06-08 13:09     ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Gerd Hoffmann @ 2010-06-08  8:03 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

>   static QEMUMachine pc_machine = {
>       .name = "pc-0.13",
>       .alias = "pc",
>       .desc = "Standard PC",
> -    .init = pc_init_pci,
> +    .init = pc_init,
>       .max_cpus = 255,
>       .is_default = 1,
>       .opts_desc = pc_opts_desc,
> +    .opts_default = (QemuOptValue[]) {
> +        {
> +            .name  = "acpi",
> +            .value = "on",
> +        },

Should be moved into a separate struct and just referenced as it is 
identical for pc-0.*

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08  3:12 ` [Qemu-devel] [PATCH 0/22] Refactor machine support Paul Brook
@ 2010-06-08 10:24   ` Paolo Bonzini
  2010-06-08 14:30     ` Paul Brook
  2010-06-08 14:04   ` [Qemu-devel] " Anthony Liguori
  1 sibling, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2010-06-08 10:24 UTC (permalink / raw)
  To: Paul Brook; +Cc: Anthony Liguori, Glauber Costa, qemu-devel

On 06/08/2010 05:12 AM, Paul Brook wrote:
>> This series introduces a rather radical change in the way we deal with
>> machine definitions in QEMU.
>
> I think we should aim to eliminate machine_register_core, and design
> appropriately.  In particular I'd try and avoid adding options that become
> trivially redundant once you can easily change the device trees.

I agree I don't like patch 13 (the parallel/virtcon/vga/floppy/cdrom 
QemuOpts).  Maybe those QemuOpts can be marked in a way that they're not 
user-accessible (and though in some cases customizing max_cpus may make 
sense, that option could also fall in that category).  Everything else 
is very much reasonable in Anthony's patch series, I think.

> I'm undecided how much parameterisation it's worth trying to support in the
> device tree. IMO the current code has way too much magic, because creating a
> new variant involves hacking and rebuilding pc.c.

See patch 22/22.  There is really no magic involved, even though the 
compat machines are not yet as config files.

> I'm extremely tempted by the extreme approach of punting everything to an
> external device tree builder. i.e. remove automagical device reation
> altogether.

I think this should have been raised when the -readconfig/-writeconfig 
scheme was proposed and committed.  I don't think it's reasonable to 
block this patch series (or something very much like it) on the grounds 
that a better device tree description model than QemuOpts can be designed.

> The problem with doing clever device tree generation/manipulation inside qemu
> is that for anything vaguely nonstandard you're likely to have to hack your
> own device tree anyway. Even ram allocation is nontrivial, e.g. the hole below
> 4G on the PC, and that's before you start with numa-like layouts.

Again, the patch is not making anything worse.

> On a similar note, I don't see any point having machine_create_from_core,
> we can just ship appropriate config files.

I think that's the obvious next step, but there's no reason not to split 
it at this point.

Paolo

^ permalink raw reply	[flat|nested] 64+ messages in thread

* [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08  7:51   ` Gerd Hoffmann
@ 2010-06-08 10:32     ` Paolo Bonzini
  2010-06-08 13:07       ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Paolo Bonzini @ 2010-06-08 10:32 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Anthony Liguori, Glauber Costa, qemu-devel

On 06/08/2010 09:51 AM, Gerd Hoffmann wrote:
> On 06/08/10 01:51, Anthony Liguori wrote:
>> Right now, if you set a QemuOpts option in a section twice, when
>> you get the option you'll receive the value that was set the first
>> time. This is less than ideal because if you're manipulating
>> options in two places like a global config followed by the command
>> line, you really want the later to override the former.
>>
>> This patch fixes this behavior.
>
> Note that this reverses the ordering for users which want multiple
> values (slirp forwarding for example).

And qemu_opt_find seems to have thought about this too:

static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
{
     QemuOpt *opt;

     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
         if (strcmp(opt->name, name) != 0)
             continue;
         return opt;
     }
     return NULL;
}

Can you show the behavior with commandline arguments only?

Paolo

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 10:32     ` [Qemu-devel] " Paolo Bonzini
@ 2010-06-08 13:07       ` Anthony Liguori
  2010-06-08 13:44         ` Gerd Hoffmann
  2010-06-08 14:38         ` Paul Brook
  0 siblings, 2 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 13:07 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Glauber Costa, Gerd Hoffmann, qemu-devel

On 06/08/2010 05:32 AM, Paolo Bonzini wrote:
> On 06/08/2010 09:51 AM, Gerd Hoffmann wrote:
>> On 06/08/10 01:51, Anthony Liguori wrote:
>>> Right now, if you set a QemuOpts option in a section twice, when
>>> you get the option you'll receive the value that was set the first
>>> time. This is less than ideal because if you're manipulating
>>> options in two places like a global config followed by the command
>>> line, you really want the later to override the former.
>>>
>>> This patch fixes this behavior.
>>
>> Note that this reverses the ordering for users which want multiple
>> values (slirp forwarding for example).
>
> And qemu_opt_find seems to have thought about this too:
>
> static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
> {
>     QemuOpt *opt;
>
>     QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
>         if (strcmp(opt->name, name) != 0)
>             continue;
>         return opt;
>     }
>     return NULL;
> }
>
> Can you show the behavior with commandline arguments only?

The problem I was trying to address can be seen with something like:

-drive file=foo.img,if=virtio,file=bar.img

You get no error, and foo.img is what gets used.  It's fair to argue 
this is a silly use case but what I'm trying to achieve is to make it 
possible to do:

-drive file=foo.img,if=virtio,id=bar -drive file=bar.img,id=bar

Or more specifically:

foo.conf:

[drive]
   file=foo.img
   if=virtio
   id=bar

qemu -readconfig foo.conf -drive file=bar.img,id=bar

IMHO, what's specified next on the command line ought to override what's 
in the config.

Suggestions how to achieve this in a more elegant way would be appreciated.

Regards,

Anthony Liguori

> Paolo
>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc
  2010-06-08  8:03   ` Gerd Hoffmann
@ 2010-06-08 13:09     ` Anthony Liguori
  2010-06-08 13:29       ` Gerd Hoffmann
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 13:09 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Glauber Costa, qemu-devel

On 06/08/2010 03:03 AM, Gerd Hoffmann wrote:
>>   static QEMUMachine pc_machine = {
>>       .name = "pc-0.13",
>>       .alias = "pc",
>>       .desc = "Standard PC",
>> -    .init = pc_init_pci,
>> +    .init = pc_init,
>>       .max_cpus = 255,
>>       .is_default = 1,
>>       .opts_desc = pc_opts_desc,
>> +    .opts_default = (QemuOptValue[]) {
>> +        {
>> +            .name  = "acpi",
>> +            .value = "on",
>> +        },
>
> Should be moved into a separate struct and just referenced as it is 
> identical for pc-0.*

Would need to be macros because in future patches, things get more 
complicated.  That may be worth it though.

Regards,

Anthony Liguori

> cheers,
>   Gerd
>
>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc
  2010-06-08 13:09     ` Anthony Liguori
@ 2010-06-08 13:29       ` Gerd Hoffmann
  0 siblings, 0 replies; 64+ messages in thread
From: Gerd Hoffmann @ 2010-06-08 13:29 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

On 06/08/10 15:09, Anthony Liguori wrote:
> On 06/08/2010 03:03 AM, Gerd Hoffmann wrote:
>>> + .opts_default = (QemuOptValue[]) {
>>> + {
>>> + .name = "acpi",
>>> + .value = "on",
>>> + },
>>
>> Should be moved into a separate struct and just referenced as it is
>> identical for pc-0.*
>
> Would need to be macros because in future patches, things get more
> complicated. That may be worth it though.

Well, maybe not.  Later patches add the compat properties to that list, 
which are different for the pc-0.* versions, so you would have to split 
again ...

cheers
   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 13:07       ` Anthony Liguori
@ 2010-06-08 13:44         ` Gerd Hoffmann
  2010-06-08 15:17           ` Anthony Liguori
  2010-06-08 14:38         ` Paul Brook
  1 sibling, 1 reply; 64+ messages in thread
From: Gerd Hoffmann @ 2010-06-08 13:44 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

On 06/08/10 15:07, Anthony Liguori wrote:
>>> Note that this reverses the ordering for users which want multiple
>>> values (slirp forwarding for example).
>>
>> And qemu_opt_find seems to have thought about this too:
>>
>> static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
>> {
>> QemuOpt *opt;
>>
>> QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
>> if (strcmp(opt->name, name) != 0)
>> continue;
>> return opt;
>> }
>> return NULL;
>> }
>>
>> Can you show the behavior with commandline arguments only?
>
> The problem I was trying to address can be seen with something like:
>
> -drive file=foo.img,if=virtio,file=bar.img
>
> You get no error, and foo.img is what gets used.

Hmm.  I think qemuopts need to carry information about the option types, 
whenever it is single-entry or multiple-entry.

Oh, and likewise for the sections.  With multiple (unnamed) [device] 
sections we want create multiple (id-less) device sections.  With 
multiple [machine] sections we probably want to merge the options instead.

> Or more specifically:
>
> foo.conf:
>
> [drive]
> file=foo.img
> if=virtio
> id=bar

This would be '[drive "bar"]' without id= line btw.

> qemu -readconfig foo.conf -drive file=bar.img,id=bar

> IMHO, what's specified next on the command line ought to override what's
> in the config.

Or the user's config the global config.

For multi-entry options this will be tricky.  What do you expect to 
happen here:

global.conf
   [net "user"]
     type="slirp"
     guestfwd=<fw1>

user.conf
   [net "user"]
     guestfwd=<fw2>
     guestfwd=<fw3>

Which forwardings will be active then?  All of them?  Or will the 
user.conf forwardings override the global one?

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 0/22] Refactor machine support
  2010-06-08  3:12 ` [Qemu-devel] [PATCH 0/22] Refactor machine support Paul Brook
  2010-06-08 10:24   ` [Qemu-devel] " Paolo Bonzini
@ 2010-06-08 14:04   ` Anthony Liguori
  1 sibling, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 14:04 UTC (permalink / raw)
  To: Paul Brook; +Cc: Glauber Costa, qemu-devel

On 06/07/2010 10:12 PM, Paul Brook wrote:
>> This series introduces a rather radical change in the way we deal with
>> machine definitions in QEMU.
>>      
> I think we should aim to eliminate machine_register_core, and design
> appropriately.  In particular I'd try and avoid adding options that become
> trivially redundant once you can easily change the device trees.
>
>    

Long term, I'd rather that machine_register_core started with a core 
device tree and manipulated from there.

> I'm undecided how much parameterisation it's worth trying to support in the
> device tree. IMO the current code has way too much magic, because creating a
> new variant involves hacking and rebuilding pc.c.
>
> I'm extremely tempted by the extreme approach of punting everything to an
> external device tree builder. i.e. remove automagical device reation
> altogether. If you want USB and 6 virtio disks then ask your device tree
> builder to create a machine description that includes pci-ohci and a bunch of
> virtio-blk-pci devices. The virtio-blk devices reference "drives" by id, so
> the same host configuration can be used with a scsi HBA. A small shell script
> should be sufficient to replicate the limited machine variants currently
> supported.
>    

This is not optimizing for the common case.  The overwhelmingly common 
case is a user that makes small changes to a pre-supplied machine core 
in QEMU.  The problem is that those small changes are not simple things 
like add a device or remove a device.  They often require more 
complicated mapping logic like translate user supplied ram size to the 
following ram allocation layout.  We cannot expect all users to specify 
an explicit ram layout.

An external builder is a usability nightmare.  It has to be something 
that is included as part of qemu proper and that's effectively what 
MachineCore's are.  They are internal builders.

That doesn't mean we shouldn't aim to support external builders.  
Everything that a MachineCore generates should be possible to generate 
via a config file statically.

> The problem with doing clever device tree generation/manipulation inside qemu
> is that for anything vaguely nonstandard you're likely to have to hack your
> own device tree anyway. Even ram allocation is nontrivial, e.g. the hole below
> 4G on the PC, and that's before you start with numa-like layouts.
>    

I'm 100% in agreement that a user should be able to specify the exact 
ram layout for a PC.  However, I strongly disagree that a user should 
have to specify the explicit ram layout if they want to adjust the 
allocated ram for a guest.  Relying on an external shell script would be 
a nightmare for users.

What I think we want is MachineCore to only make use of interfaces that 
are available via the command line. IOW, things like qdev_create() and 
friends.

> On a similar note, I don't see any point having machine_create_from_core,
> we can just ship appropriate config files.
>    

I strongly agree.  I didn't include that in this series because I was 
trying to keep this small and slightly less radical.  It'll be a pain 
for people that don't regularly update their config file via a make install.

Regards,

Anthony Liguori

> Paul
>
>    

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 10:24   ` [Qemu-devel] " Paolo Bonzini
@ 2010-06-08 14:30     ` Paul Brook
  2010-06-08 15:28       ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Paul Brook @ 2010-06-08 14:30 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Anthony Liguori, Glauber Costa

> > I'm undecided how much parameterisation it's worth trying to support in
> > the device tree. IMO the current code has way too much magic, because
> > creating a new variant involves hacking and rebuilding pc.c.
> 
> See patch 22/22.  There is really no magic involved, even though the
> compat machines are not yet as config files.

The magic I'm preferring to is precisely things like pci="on".
This is an artifact of only having a hardcoded single device tree (defined by 
pc_init), so we need magic parameters to pick between different variants.

If this were just a cleanup of how we implement the various machines that 
would be harmless. However these are now a user-visible interface.

It implies that qemu is expected to know how to add/remove PCI capabilities 
from a machine. Once you eliminate machine_register_core that knowledge has 
somehow got to come from your device tree description file.  Having a single 
device tree that can morph into significantly different machines seems like 
unnecessary complexity given this is a user-specified file.

> > I'm extremely tempted by the extreme approach of punting everything to an
> > external device tree builder. i.e. remove automagical device reation
> > altogether.
> 
> I think this should have been raised when the -readconfig/-writeconfig
> scheme was proposed and committed.  I don't think it's reasonable to
> block this patch series (or something very much like it) on the grounds
> that a better device tree description model than QemuOpts can be designed.

I don't see how the introduction of QemuOpts is relevant. That's just a 
flexible commandline option handling system, which makes a lot of sense.

What I'm objecting to is making machine construction be controlled by an 
arbitrary set of hardcoded parameters. One of the goals of the qdev work is 
that you don't need to have hardcoded all the interesting ways a machine can 
vary. Instead you can directly specify how to construct the machine.

My argument is that in the short term this parameterization provides limited 
benefit, and longer term it's going to be obsolete and probably painful to 
support.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 13:07       ` Anthony Liguori
  2010-06-08 13:44         ` Gerd Hoffmann
@ 2010-06-08 14:38         ` Paul Brook
  2010-06-08 15:14           ` Anthony Liguori
  1 sibling, 1 reply; 64+ messages in thread
From: Paul Brook @ 2010-06-08 14:38 UTC (permalink / raw)
  To: qemu-devel; +Cc: Paolo Bonzini, Glauber Costa, Gerd Hoffmann

> The problem I was trying to address can be seen with something like:
> 
> -drive file=foo.img,if=virtio,file=bar.img
> 
> You get no error, and foo.img is what gets used.  It's fair to argue
> this is a silly use case but what I'm trying to achieve is to make it
> possible to do:
> 
> -drive file=foo.img,if=virtio,id=bar -drive file=bar.img,id=bar

IMO these should both behave consistently. I'd prefer that both of are errors.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 14:38         ` Paul Brook
@ 2010-06-08 15:14           ` Anthony Liguori
  0 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 15:14 UTC (permalink / raw)
  To: Paul Brook; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel, Gerd Hoffmann

On 06/08/2010 09:38 AM, Paul Brook wrote:
>> The problem I was trying to address can be seen with something like:
>>
>> -drive file=foo.img,if=virtio,file=bar.img
>>
>> You get no error, and foo.img is what gets used.  It's fair to argue
>> this is a silly use case but what I'm trying to achieve is to make it
>> possible to do:
>>
>> -drive file=foo.img,if=virtio,id=bar -drive file=bar.img,id=bar
>>      
> IMO these should both behave consistently. I'd prefer that both of are errors.
>    

It's fairly common that the last specified argument is what's 
respected.  For instance, if you do qemu -m 512M -m 1G, you'll get 1G of 
memory.

Regards,

Anthony Liguori

> Paul
>    

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 13:44         ` Gerd Hoffmann
@ 2010-06-08 15:17           ` Anthony Liguori
  2010-06-08 15:37             ` Gerd Hoffmann
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 15:17 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

On 06/08/2010 08:44 AM, Gerd Hoffmann wrote:
> On 06/08/10 15:07, Anthony Liguori wrote:
>>>> Note that this reverses the ordering for users which want multiple
>>>> values (slirp forwarding for example).
>>>
>>> And qemu_opt_find seems to have thought about this too:
>>>
>>> static QemuOpt *qemu_opt_find(QemuOpts *opts, const char *name)
>>> {
>>> QemuOpt *opt;
>>>
>>> QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
>>> if (strcmp(opt->name, name) != 0)
>>> continue;
>>> return opt;
>>> }
>>> return NULL;
>>> }
>>>
>>> Can you show the behavior with commandline arguments only?
>>
>> The problem I was trying to address can be seen with something like:
>>
>> -drive file=foo.img,if=virtio,file=bar.img
>>
>> You get no error, and foo.img is what gets used.
>
> Hmm.  I think qemuopts need to carry information about the option 
> types, whenever it is single-entry or multiple-entry.
>
> Oh, and likewise for the sections.  With multiple (unnamed) [device] 
> sections we want create multiple (id-less) device sections.  With 
> multiple [machine] sections we probably want to merge the options 
> instead.
>
>> Or more specifically:
>>
>> foo.conf:
>>
>> [drive]
>> file=foo.img
>> if=virtio
>> id=bar
>
> This would be '[drive "bar"]' without id= line btw.
>
>> qemu -readconfig foo.conf -drive file=bar.img,id=bar
>
>> IMHO, what's specified next on the command line ought to override what's
>> in the config.
>
> Or the user's config the global config.
>
> For multi-entry options this will be tricky.  What do you expect to 
> happen here:
>
> global.conf
>   [net "user"]
>     type="slirp"
>     guestfwd=<fw1>
>
> user.conf
>   [net "user"]
>     guestfwd=<fw2>
>     guestfwd=<fw3>
>
> Which forwardings will be active then?  All of them?  Or will the 
> user.conf forwardings override the global one?

What'd expect is:

[net "user"]
guestfwd = <fw1> <fw2> <fw3>..

I think multiple entry options are probably not a good thing to have.

Regards,

Anthony Liguori

> cheers,
>   Gerd
>

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 14:30     ` Paul Brook
@ 2010-06-08 15:28       ` Anthony Liguori
  2010-06-08 15:36         ` Paul Brook
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 15:28 UTC (permalink / raw)
  To: Paul Brook; +Cc: Paolo Bonzini, Anthony Liguori, Glauber Costa, qemu-devel

On 06/08/2010 09:30 AM, Paul Brook wrote:
>>> I'm undecided how much parameterisation it's worth trying to support in
>>> the device tree. IMO the current code has way too much magic, because
>>> creating a new variant involves hacking and rebuilding pc.c.
>>>        
>> See patch 22/22.  There is really no magic involved, even though the
>> compat machines are not yet as config files.
>>      
> The magic I'm preferring to is precisely things like pci="on".
> This is an artifact of only having a hardcoded single device tree (defined by
> pc_init), so we need magic parameters to pick between different variants.
>
> If this were just a cleanup of how we implement the various machines that
> would be harmless. However these are now a user-visible interface.
>
> It implies that qemu is expected to know how to add/remove PCI capabilities
> from a machine.

No, this implies that the 'pc' MachineCore is capable of removing PCI 
from a machine and that's all.  'pci' is a MachineCore specific option.

>   Once you eliminate machine_register_core that knowledge has
> somehow got to come from your device tree description file.  Having a single
> device tree that can morph into significantly different machines seems like
> unnecessary complexity given this is a user-specified file.
>    

99% of qemu users will never touch a device tree.  The practical matter 
is, we're going to have to provide higher level interfaces that allow a 
user to significantly morph a base device tree into something different.

> What I'm objecting to is making machine construction be controlled by an
> arbitrary set of hardcoded parameters. One of the goals of the qdev work is
> that you don't need to have hardcoded all the interesting ways a machine can
> vary. Instead you can directly specify how to construct the machine.
>    

MachineCore is orthogonal to constructing a device tree from scratch.  
If you want to express the types of things we allow users to do with 
machines, you are going to need a C function that can manipulate these 
devices trees based on higher level constructs (like PCI enabled and a 
scalar RAM size).

IMHO, the only real question is whether this should be built into QEMU 
or we should rely on an external script to do this work.  Since the vast 
majority of users are going to want this higher level interface, I feel 
pretty confident that we should build this into QEMU.

> My argument is that in the short term this parameterization provides limited
> benefit, and longer term it's going to be obsolete and probably painful to
> support.
>    

And how do you expect this to work for x86 machines?  Even if you had a 
pc-0.13.fdt that represented the base pc-0.13, how do we translate -hda 
foo.img into "add an IDE disk to the primary slot as master to the IDE 
controller on the PIIX3 IDE bus".  Sure, you can say -device 
ide-disk,parent=/piix3/ide0 or something like that but something needs 
to make that translation and it's entirely machine specific.  Because 
with the arm boards, -hda foo.img translates to -device scsi-disk,...

A more complicated example is how you support the behavior of something 
like -usbdevice which adds a usb controller if one isn't already present.

This is the logic that MachineCore implements and it will always be 
needed.  The MachineCores expose whatever tunables make sense for the 
machines they represent.

Regards,

Anthony Liguori

> Paul
>
>    

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 15:28       ` Anthony Liguori
@ 2010-06-08 15:36         ` Paul Brook
  2010-06-08 15:58           ` Paolo Bonzini
  0 siblings, 1 reply; 64+ messages in thread
From: Paul Brook @ 2010-06-08 15:36 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Anthony Liguori, Glauber Costa, qemu-devel

> >   Once you eliminate machine_register_core that knowledge has
> > 
> > somehow got to come from your device tree description file.  Having a
> > single device tree that can morph into significantly different machines
> > seems like unnecessary complexity given this is a user-specified file.
> 
> 99% of qemu users will never touch a device tree.  The practical matter
> is, we're going to have to provide higher level interfaces that allow a
> user to significantly morph a base device tree into something different.

That's the bit I don't get.  Why are we significantly morphing a base device 
tree?  Surely it's easier to just use a different base tree.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 15:17           ` Anthony Liguori
@ 2010-06-08 15:37             ` Gerd Hoffmann
  2010-06-08 16:04               ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Gerd Hoffmann @ 2010-06-08 15:37 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

> What'd expect is:
>
> [net "user"]
> guestfwd = <fw1> <fw2> <fw3>..
>
> I think multiple entry options are probably not a good thing to have.

We already have them though (-net switch so QemuOpts added them).

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 15:36         ` Paul Brook
@ 2010-06-08 15:58           ` Paolo Bonzini
  2010-06-08 16:15             ` Anthony Liguori
                               ` (2 more replies)
  0 siblings, 3 replies; 64+ messages in thread
From: Paolo Bonzini @ 2010-06-08 15:58 UTC (permalink / raw)
  To: Paul Brook; +Cc: Anthony Liguori, Glauber Costa, qemu-devel

On 06/08/2010 05:36 PM, Paul Brook wrote:
>>>    Once you eliminate machine_register_core that knowledge has
>>>
>>> somehow got to come from your device tree description file.  Having a
>>> single device tree that can morph into significantly different machines
>>> seems like unnecessary complexity given this is a user-specified file.
>>
>> 99% of qemu users will never touch a device tree.  The practical matter
>> is, we're going to have to provide higher level interfaces that allow a
>> user to significantly morph a base device tree into something different.
>
> That's the bit I don't get.  Why are we significantly morphing a base device
> tree?  Surely it's easier to just use a different base tree.

Because at some point the base tree will have to be written in C.  Of 
course you have to decide where to stop allowing customization, but 
anyway it will be significantly more complex than a QemuOpts config 
file.  QemuOpts obviously doesn't have the flexibility to create an 
entire device tree.

Want to let the user add an IDE controller?  Fine, you need to provide 
him with a way of writing the following logic:

     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
         hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
     }
     pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);

What do you do?  Invent your own language (another YaST? no thanks)? 
Massive refactoring of QEMU's bowels (cannot solve all the problems, 
Anthony gave more examples in the email I replied to)?  Keep C code 
(then you're not doing anything different than what Anthony's 
MachineCore is doing)?


I think there are four choices:

1) only merge the first 5-7 patches of the series, basically up to the 
creation of -machine and conversion of -kernel/-initrd/-M/-m.  This is 
also what is needed for KVM's irqchip.  Think about some other smart way 
to implement default devices.

2) do not expose some things to the config files.  This requires 
implementing an additional QemuOpts feature for internal options, plus 
the current patchset.  It means that moving machine types out to config 
files is not possible.

3) put some things into an implementation-dependent namespace, i.e. 
__pci or __default_device or __serial.  In the future it's possible to 
these things in config files, just nobody has to worry about users 
relying on them and can refactor to death.  This is the current patchset 
plus some search and replace, and is my favorite.

4) expose everything to the user, at the cost of regretting it later. 
This is the current patchset.


One "smart way to implement default devices" could be an inclusion 
mechanism where a machine can ask qemu to read other config files.  Then 
you'd have config files for the default serial/parallel/etc.  This could 
also be implemented on top of choices 2/3/4 though.

Paolo

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 15:37             ` Gerd Hoffmann
@ 2010-06-08 16:04               ` Anthony Liguori
  2010-06-09  7:01                 ` Gerd Hoffmann
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 16:04 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

On 06/08/2010 10:37 AM, Gerd Hoffmann wrote:
>> What'd expect is:
>>
>> [net "user"]
>> guestfwd = <fw1> <fw2> <fw3>..
>>
>> I think multiple entry options are probably not a good thing to have.
>
> We already have them though (-net switch so QemuOpts added them).

Yeah, but let's ignore that for the moment.  If we didn't have 
historical baggage, would we prefer the syntax above or do you think 
there's value in specifying it on separate lines?

At this stage, I'm not worried about config file compatibility.  If we 
need to add some special logic to the -net switch to accommodate it's 
strange behavior, that's okay with me.

Regards,

Anthony Liguori

> cheers,
>   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 15:58           ` Paolo Bonzini
@ 2010-06-08 16:15             ` Anthony Liguori
  2010-06-08 21:05               ` Alexander Graf
  2010-06-08 17:23             ` Anthony Liguori
  2010-06-09  2:11             ` Paul Brook
  2 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 16:15 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Anthony Liguori, Glauber Costa, Paul Brook, qemu-devel

On 06/08/2010 10:58 AM, Paolo Bonzini wrote:
> On 06/08/2010 05:36 PM, Paul Brook wrote:
>>>>    Once you eliminate machine_register_core that knowledge has
>>>>
>>>> somehow got to come from your device tree description file.  Having a
>>>> single device tree that can morph into significantly different 
>>>> machines
>>>> seems like unnecessary complexity given this is a user-specified file.
>>>
>>> 99% of qemu users will never touch a device tree.  The practical matter
>>> is, we're going to have to provide higher level interfaces that allow a
>>> user to significantly morph a base device tree into something 
>>> different.
>>
>> That's the bit I don't get.  Why are we significantly morphing a base 
>> device
>> tree?  Surely it's easier to just use a different base tree.
>
> Because at some point the base tree will have to be written in C.  Of 
> course you have to decide where to stop allowing customization, but 
> anyway it will be significantly more complex than a QemuOpts config 
> file.  QemuOpts obviously doesn't have the flexibility to create an 
> entire device tree.
>
> Want to let the user add an IDE controller?  Fine, you need to provide 
> him with a way of writing the following logic:
>
>     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
>         hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
>     }
>     pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
>
> What do you do?  Invent your own language (another YaST? no thanks)? 
> Massive refactoring of QEMU's bowels (cannot solve all the problems, 
> Anthony gave more examples in the email I replied to)?  Keep C code 
> (then you're not doing anything different than what Anthony's 
> MachineCore is doing)?

Or punt all of the complexity to the user such that have to manually 
figure out where in the device tree a drive has to be inserted.  That's 
not really reasonable IMHO.

> I think there are four choices:
>
> 1) only merge the first 5-7 patches of the series, basically up to the 
> creation of -machine and conversion of -kernel/-initrd/-M/-m.  This is 
> also what is needed for KVM's irqchip.  Think about some other smart 
> way to implement default devices.

Or don't declare MachineCore options stable across releases.  I concur 
that we probably don't want to support some of these interfaces long 
term but I think we can pretty quickly figure out some better interfaces.

The advantage of a full conversion is that it allows us to focus on 
improving the interfaces since we'll have the architecture in place.

> 2) do not expose some things to the config files.  This requires 
> implementing an additional QemuOpts feature for internal options, plus 
> the current patchset.  It means that moving machine types out to 
> config files is not possible.

I dislike having internal only options as it means we have to keep 
things within qemu.  For things like max_cpus, I think we just need to 
validate that we've got passed sane values.  Setting max_cpus in a 
global config is actually a really useful thing for downstreams to do 
since they are all having a fixed support statement of X VCPUs per VM.

> 3) put some things into an implementation-dependent namespace, i.e. 
> __pci or __default_device or __serial.  In the future it's possible to 
> these things in config files, just nobody has to worry about users 
> relying on them and can refactor to death.  This is the current 
> patchset plus some search and replace, and is my favorite.

Yeah, I'm good with being explicit.  I'd prefer x-pci or x-serial since 
we've already established that as the experimential namespace.

> 4) expose everything to the user, at the cost of regretting it later. 
> This is the current patchset.
>
>
> One "smart way to implement default devices" could be an inclusion 
> mechanism where a machine can ask qemu to read other config files.  
> Then you'd have config files for the default serial/parallel/etc.  
> This could also be implemented on top of choices 2/3/4 though.

Default devices are a real pain.  Fortunately, we only mess with it in 
s390 so I'm fairly certain we can simplify things considerable.  It's 
just not something I wanted to tackle in this series.

Regards,

Anthony Liguori

> Paolo

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 15:58           ` Paolo Bonzini
  2010-06-08 16:15             ` Anthony Liguori
@ 2010-06-08 17:23             ` Anthony Liguori
  2010-06-09  2:11             ` Paul Brook
  2 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 17:23 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Glauber Costa, Gerd Hoffmann, Paul Brook, qemu-devel


> One "smart way to implement default devices" could be an inclusion 
> mechanism where a machine can ask qemu to read other config files.  
> Then you'd have config files for the default serial/parallel/etc.  
> This could also be implemented on top of choices 2/3/4 though.

Defaults are tough because there are multiple ways to create devices 
today.  Here's something that could potentially address the problem.  
I'll focus on -serial but it's equally applicable to the other default 
devices.

We would introduce serial0, serial1, serial2, serial3 MachineCore 
properties.  These properties would be chardev names.

The pc machine types would do:
    QOPT_VALUE("serial0", "__default_serial0");

In vl.c, we would always create a __default_serial0 chardev of 'vc'.

The -serial option would keep a counter and:

   -serial mon:stdio -serial vc

Would be equivalent to:

  -chardev mon:stdio,id=__serial0 -machine serial0=__serial0 \
  -chardev vc,id=__serial1 -machine serial1=__serial1

-nodefaults simply suppresses the creation of the default serial devices.

It's the job of the MachineCore to try to find each of the serialN 
properties and if the chardevs have been created, use qdev to create an 
appropriate serial port device.

This would apply equally well to parallel and virtcon.

Networking is a bit of a nightmare as many boards simply ignore the 
networking options.  Floppy and cdrom can work in this way too.

Regards,

Anthony Liguori

> Paolo

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 16:15             ` Anthony Liguori
@ 2010-06-08 21:05               ` Alexander Graf
  2010-06-08 21:16                 ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Alexander Graf @ 2010-06-08 21:05 UTC (permalink / raw)
  To: Anthony Liguori
  Cc: qemu-devel, Paolo Bonzini, Anthony Liguori, Glauber Costa, Paul Brook


On 08.06.2010, at 18:15, Anthony Liguori wrote:

> 
>> 4) expose everything to the user, at the cost of regretting it later. This is the current patchset.
>> 
>> 
>> One "smart way to implement default devices" could be an inclusion mechanism where a machine can ask qemu to read other config files.  Then you'd have config files for the default serial/parallel/etc.  This could also be implemented on top of choices 2/3/4 though.
> 
> Default devices are a real pain.  Fortunately, we only mess with it in s390 so I'm fairly certain we can simplify things considerable.  It's just not something I wanted to tackle in this series.

Wait, what? The only "default" device we have on s390 is virtio-console - and that's basically the same as having VGA output on x86 enabled by default, no?

But either way, I agree that we should make things easy for 99% of the users. And taking incremental improvements is useful too. pc.c as it is right now can only be improved, no matter what you do with it.


Alex

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 21:05               ` Alexander Graf
@ 2010-06-08 21:16                 ` Anthony Liguori
  0 siblings, 0 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-08 21:16 UTC (permalink / raw)
  To: Alexander Graf
  Cc: qemu-devel, Paolo Bonzini, Anthony Liguori, Glauber Costa, Paul Brook

On 06/08/2010 04:05 PM, Alexander Graf wrote:
> On 08.06.2010, at 18:15, Anthony Liguori wrote:
>
>    
>>      
>>> 4) expose everything to the user, at the cost of regretting it later. This is the current patchset.
>>>
>>>
>>> One "smart way to implement default devices" could be an inclusion mechanism where a machine can ask qemu to read other config files.  Then you'd have config files for the default serial/parallel/etc.  This could also be implemented on top of choices 2/3/4 though.
>>>        
>> Default devices are a real pain.  Fortunately, we only mess with it in s390 so I'm fairly certain we can simplify things considerable.  It's just not something I wanted to tackle in this series.
>>      
> Wait, what? The only "default" device we have on s390 is virtio-console - and that's basically the same as having VGA output on x86 enabled by default, no?
>    

What I was saying is that all the .no_vga/.no_serial/.use_virtcon bits 
in QEMUMachine are strictly due to s390.  Since the use of these are so 
specific, it'll be fairly easy to eliminate them in a more natural way.

What most other boards do is simply ignore whatever vl.c does FWIW.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-08 15:58           ` Paolo Bonzini
  2010-06-08 16:15             ` Anthony Liguori
  2010-06-08 17:23             ` Anthony Liguori
@ 2010-06-09  2:11             ` Paul Brook
  2010-06-09 13:55               ` Anthony Liguori
  2 siblings, 1 reply; 64+ messages in thread
From: Paul Brook @ 2010-06-09  2:11 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Anthony Liguori, Glauber Costa, qemu-devel

> >>>    Once you eliminate machine_register_core that knowledge has
> >>> 
> >>> somehow got to come from your device tree description file.  Having a
> >>> single device tree that can morph into significantly different machines
> >>> seems like unnecessary complexity given this is a user-specified file.
> >> 
> >> 99% of qemu users will never touch a device tree.  The practical matter
> >> is, we're going to have to provide higher level interfaces that allow a
> >> user to significantly morph a base device tree into something different.
> > 
> > That's the bit I don't get.  Why are we significantly morphing a base
> > device tree?  Surely it's easier to just use a different base tree.
> 
> Because at some point the base tree will have to be written in C.

No. You can start with a completely empty machine.
We don't/shouldn't need any machine specific C code.
When I submitted the original qdev code I also posted a proof-of-concept patch 
that built the whole machine based on a config file with no hardcoded 
knowledge of the machine structure.

> Of course you have to decide where to stop allowing customization, but
> anyway it will be significantly more complex than a QemuOpts config
> file.  QemuOpts obviously doesn't have the flexibility to create an
> entire device tree.

Why not?
The current -device option already provides the majority of the functionality 
required.  Most of the missing bits are incomplete qdev conversion.
I'm not saying that creating a whole machine via -device options is an elegant 
solution (hence the interest in things like FDT) but in I see no reason why it 
shouldn't work.

IMO all uses of the no_user flag are bugs resulting from incomplete/incorrect 
qdev conversions.
 
> Want to let the user add an IDE controller?  Fine, you need to provide
> him with a way of writing the following logic:
> 
>      for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
>          hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
>      }
>      pci_piix3_ide_init(pci_bus, hd, piix3_devfn + 1);
> 
> What do you do?

-device piix3-ide. See also docs/qdev-device-use.txt

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice
  2010-06-08 16:04               ` Anthony Liguori
@ 2010-06-09  7:01                 ` Gerd Hoffmann
  0 siblings, 0 replies; 64+ messages in thread
From: Gerd Hoffmann @ 2010-06-09  7:01 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

On 06/08/10 18:04, Anthony Liguori wrote:
> On 06/08/2010 10:37 AM, Gerd Hoffmann wrote:
>>> What'd expect is:
>>>
>>> [net "user"]
>>> guestfwd = <fw1> <fw2> <fw3>..
>>>
>>> I think multiple entry options are probably not a good thing to have.
>>
>> We already have them though (-net switch so QemuOpts added them).
>
> Yeah, but let's ignore that for the moment. If we didn't have historical
> baggage, would we prefer the syntax above or do you think there's value
> in specifying it on separate lines?

guestfwd entries are relatively long, so having them on one line is 
slightly annonying.  I'd tend to have them on separate lines.  But maybe 
it isn't a bad idea to extend the config file syntax to allow being more 
explicit here, like this (borrowed from makefile syntax):

   option := value       assign, overriding any existing value(s)
   option += value       append

Maybe also

   option ?= value       set only in case it isn't set yet.

cheers,
   Gerd

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option
  2010-06-08  1:56     ` Anthony Liguori
  2010-06-08  2:56       ` Paul Brook
@ 2010-06-09  7:44       ` Jes Sorensen
  1 sibling, 0 replies; 64+ messages in thread
From: Jes Sorensen @ 2010-06-09  7:44 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, Paul Brook, qemu-devel

On 06/08/10 03:56, Anthony Liguori wrote:
> On 06/07/2010 08:01 PM, Paul Brook wrote:
>>> diff --git a/hw/realview.c b/hw/realview.c
>>> index a36bdbe..8dcef80 100644
>>> --- a/hw/realview.c
>>> +++ b/hw/realview.c
>>> @@ -444,9 +444,9 @@ static QEMUMachine realview_eb_mpcore_machine = {
>>>       .init = realview_eb_mpcore_init,
>>>       .opts_default = (QemuOptValue[]) {
>>>           QOPT_VALUE("default_drive", "scsi"),
>>> +        QOPT_VALUE("max_cpus", "4"),
>>>           { /* end of list */ }
>>>       },
>>> -    .max_cpus = 4,
>>>   };
>>>      
>> By my reading this allows the user to modify this value. If so it is
>> wrong.  
> 
> max_cpus is complicated because it was used for multiple purposes.
> 
> I think max_cpus ought to be configurable.  The reason it's useful to
> configure it that it lets a downstream specify a recommended max cpu
> that's mostly relevant from a scalability perspective.  For instance,
> you may want to set the pc max_cpus to 64 since this is the highest that
> KVM supports today.

max_cpus was designed to set the upper limit of allowable cpus on a
system. The main intention for it was to offer limits to things like
SeaBIOS to tell it how many entries to put into the BIOS tables for
systems where we allow hotplug etc. It was not meant to be used to set
limits higher than what the system is able to support, like on with the
current ACPI implementation in SeaBIOS we cannot go above 255 on PC
hardware.

However I don't really see the point in allowing max_cpus to be
configurable on a system like this where 4 is the possible max, per what
Paul is saying. If the user wants to run < 4 cpus, he/she should specify
-smp X with 1 <= X <= 4.

Cheers,
Jes

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option Anthony Liguori
  2010-06-08  1:01   ` Paul Brook
@ 2010-06-09  7:47   ` Jes Sorensen
  1 sibling, 0 replies; 64+ messages in thread
From: Jes Sorensen @ 2010-06-09  7:47 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

On 06/08/10 01:52, Anthony Liguori wrote:
> max_cpus is a weird property today.  On the one hand, it represents the maximum
> CPUs a board can support and is used to validate the number of vcpus requested
> by the user.
> 
> On the other hand, max_cpus can be set by the user in which case it is taken
> to mean the number of physical sockets that should be advertised by the
> firmware.  Furthermore, if max_cpus isn't explicitly set by the user, it's
> defaulted to the number of smp_cpus.  But there's actually a second copy of
> max_cpus that still represents the maximum cpus spported by the platform.

Sorry this is wrong, max_cpus never meant to advertise the number of
sockets, it means the number of cores (ie. cpus) as the limit advertised
by firmware.

> Yes, it's confusing.  So let's be a bit more obvious.  This patch introduces
> a sockets parameter that allows a user to explicitly set the number of
> advertised sockets apart from the number of maximum cpus.
> 
> This is something of a stop gap.  We really ought to specify a more rich
> NUMA topology as machine options but that will come later.
> 
> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
> 
[snip]
> diff --git a/hw/fw_cfg.c b/hw/fw_cfg.c
> index 22ebb50..de4454f 100644
> --- a/hw/fw_cfg.c
> +++ b/hw/fw_cfg.c
> @@ -321,7 +321,8 @@ int fw_cfg_add_file(FWCfgState *s,  const char *dir, const char *filename,
>  }
>  
>  FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
> -                        target_phys_addr_t ctl_addr, target_phys_addr_t data_addr)
> +                        target_phys_addr_t ctl_addr, target_phys_addr_t data_addr,
> +                        QemuOpts *opts)
>  {
>      FWCfgState *s;
>      int io_ctl_memory, io_data_memory;
> @@ -349,7 +350,8 @@ FWCfgState *fw_cfg_init(uint32_t ctl_port, uint32_t data_port,
>      fw_cfg_add_bytes(s, FW_CFG_UUID, qemu_uuid, 16);
>      fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)(display_type == DT_NOGRAPHIC));
>      fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus);
> -    fw_cfg_add_i16(s, FW_CFG_MAX_CPUS, (uint16_t)max_cpus);
> +    fw_cfg_add_i16(s, FW_CFG_MAX_CPUS,
> +                   (uint16_t)qemu_opt_get_number(opts, "sockets", smp_cpus));
>      fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu);

NACK this is just plain wrong!

Sorry Anthony, but max_cpus never meant number of sockets. It is used by
the BIOS to calculate table sizes for CPU entries, and that number is
based on cores, not sockets.

If you want to pass a number of sockets onto the BIOS, I will totally
support that, but you need to introduce FW_CFG_MAX_SOCKETS for that
instead, and tell the BIOS to use that for the SRAT.

Cheers,
Jes

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 21/22] machine: convert pc machines to split core vs machine API
  2010-06-07 23:52 ` [Qemu-devel] [PATCH 21/22] machine: convert pc machines to split core vs machine API Anthony Liguori
@ 2010-06-09  7:51   ` Jes Sorensen
  0 siblings, 0 replies; 64+ messages in thread
From: Jes Sorensen @ 2010-06-09  7:51 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Glauber Costa, qemu-devel

On 06/08/10 01:52, Anthony Liguori wrote:
> +static QemuOptValue pc_machine_v0_11[] = {
> +    QOPT_VALUE("name", "pc-0.11"),
> +    QOPT_VALUE("desc", "Standard PC, qemu 0.11"),
> +    QOPT_VALUE("acpi", "on"),
> +    QOPT_VALUE("pci", "on"),
> +    QOPT_VALUE("cpu", PC_DEFAULT_CPU_MODEL),
> +    QOPT_VALUE("max_cpus", "255"),
> +    QOPT_COMPAT_INT("virtio-blk-pci", "vectors", 0),
> +    QOPT_COMPAT_INT("virtio-serial-pci", "max_nr_ports", 1),
> +    QOPT_COMPAT_INT("virtio-serial-pci", "vectors", 0),
> +    QOPT_COMPAT("ide-drive", "ver", "0.11"),
> +    QOPT_COMPAT("scsi-disk", "ver", "0.11"),
> +    QOPT_COMPAT_INT("PCI", "rombar", 0),
> +    { /* end of list */ }
>  };

For v11 and older, you might want to change max_cpus to what the BIOS we
supported back then actually was able to run with, ie. 15.

Cheers,
Jes

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-09  2:11             ` Paul Brook
@ 2010-06-09 13:55               ` Anthony Liguori
  2010-06-09 14:30                 ` Paul Brook
  0 siblings, 1 reply; 64+ messages in thread
From: Anthony Liguori @ 2010-06-09 13:55 UTC (permalink / raw)
  To: Paul Brook; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

On 06/08/2010 09:11 PM, Paul Brook wrote:
>>
>> Because at some point the base tree will have to be written in C.
>>      
> No. You can start with a completely empty machine.
> We don't/shouldn't need any machine specific C code.
>    

I think you're missing the argument.  I should be possible to create a 
machine entirely from a FDT or via -device options.

However, to continue to support the interfaces that we support today, it 
will be necessary to have C code that manipulates a base device tree.

When a user specifies '-M pc -hda foo.img'  verses '-M versatilepb -hda 
foo.img', the equivalent are two very different operations on a device 
tree.  The former adds an ide disk to the default controller and the 
later potentially creates a new scsi bus and then adds a disk to a 
specific bus.

We could force users to these explicit operations instead of the generic 
options we provide today but we would certain end up having our users 
hate us as a result.

> When I submitted the original qdev code I also posted a proof-of-concept patch
> that built the whole machine based on a config file with no hardcoded
> knowledge of the machine structure.
>    

And in your proof-of-concept patches, you couldn't use -hda or any of 
the other command line options that are currently used.  To support 
those things, something would have to understand the device tree well 
enough to know what -hda is supposed to mean.  That's the point of 
MachineCore.

>> Of course you have to decide where to stop allowing customization, but
>> anyway it will be significantly more complex than a QemuOpts config
>> file.  QemuOpts obviously doesn't have the flexibility to create an
>> entire device tree.
>>      
> Why not?
> The current -device option already provides the majority of the functionality
> required.  Most of the missing bits are incomplete qdev conversion.
> I'm not saying that creating a whole machine via -device options is an elegant
> solution (hence the interest in things like FDT) but in I see no reason why it
> shouldn't work.
>
> IMO all uses of the no_user flag are bugs resulting from incomplete/incorrect
> qdev conversions.
>    

I don't disagree.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-09 13:55               ` Anthony Liguori
@ 2010-06-09 14:30                 ` Paul Brook
  2010-06-09 20:47                   ` Blue Swirl
  0 siblings, 1 reply; 64+ messages in thread
From: Paul Brook @ 2010-06-09 14:30 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

> >> Because at some point the base tree will have to be written in C.
> > 
> > No. You can start with a completely empty machine.
> > We don't/shouldn't need any machine specific C code.
> 
> I think you're missing the argument.  I should be possible to create a
> machine entirely from a FDT or via -device options.
> 
> However, to continue to support the interfaces that we support today, it
> will be necessary to have C code that manipulates a base device tree.
>
> When a user specifies '-M pc -hda foo.img'  verses '-M versatilepb -hda
> foo.img', the equivalent are two very different operations on a device
> tree.  The former adds an ide disk to the default controller and the
> later potentially creates a new scsi bus and then adds a disk to a
> specific bus.

AFAICS the current commandline options only result in simple addition of 
devices. They might add slightly different devices in slightly different 
places, but that's easy to accommodate by having the machine define a few 
standard device/bus IDs.

IMO it's even more lame if -hda shops working when you supply a device tree.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-09 14:30                 ` Paul Brook
@ 2010-06-09 20:47                   ` Blue Swirl
  2010-06-09 20:52                     ` Anthony Liguori
  0 siblings, 1 reply; 64+ messages in thread
From: Blue Swirl @ 2010-06-09 20:47 UTC (permalink / raw)
  To: Paul Brook; +Cc: Paolo Bonzini, Glauber Costa, qemu-devel

On Wed, Jun 9, 2010 at 2:30 PM, Paul Brook <paul@codesourcery.com> wrote:
>> >> Because at some point the base tree will have to be written in C.
>> >
>> > No. You can start with a completely empty machine.
>> > We don't/shouldn't need any machine specific C code.
>>
>> I think you're missing the argument.  I should be possible to create a
>> machine entirely from a FDT or via -device options.
>>
>> However, to continue to support the interfaces that we support today, it
>> will be necessary to have C code that manipulates a base device tree.
>>
>> When a user specifies '-M pc -hda foo.img'  verses '-M versatilepb -hda
>> foo.img', the equivalent are two very different operations on a device
>> tree.  The former adds an ide disk to the default controller and the
>> later potentially creates a new scsi bus and then adds a disk to a
>> specific bus.
>
> AFAICS the current commandline options only result in simple addition of
> devices. They might add slightly different devices in slightly different
> places, but that's easy to accommodate by having the machine define a few
> standard device/bus IDs.
>
> IMO it's even more lame if -hda shops working when you supply a device tree.

The tree supplied by the user should label a bus node with a property
'QEMU,hda'. The C version (called by the board) would be something
like setprop("/i440fx/pci.0/ide.0", "QEMU,hda"). QEMU should search
the device tree for such labels at startup.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-09 20:47                   ` Blue Swirl
@ 2010-06-09 20:52                     ` Anthony Liguori
  2010-06-09 21:09                       ` Blue Swirl
  2010-06-09 22:26                       ` Paul Brook
  0 siblings, 2 replies; 64+ messages in thread
From: Anthony Liguori @ 2010-06-09 20:52 UTC (permalink / raw)
  To: Blue Swirl; +Cc: Paolo Bonzini, Glauber Costa, Paul Brook, qemu-devel

On 06/09/2010 03:47 PM, Blue Swirl wrote:
> On Wed, Jun 9, 2010 at 2:30 PM, Paul Brook<paul@codesourcery.com>  wrote:
>    
>>>>> Because at some point the base tree will have to be written in C.
>>>>>            
>>>> No. You can start with a completely empty machine.
>>>> We don't/shouldn't need any machine specific C code.
>>>>          
>>> I think you're missing the argument.  I should be possible to create a
>>> machine entirely from a FDT or via -device options.
>>>
>>> However, to continue to support the interfaces that we support today, it
>>> will be necessary to have C code that manipulates a base device tree.
>>>
>>> When a user specifies '-M pc -hda foo.img'  verses '-M versatilepb -hda
>>> foo.img', the equivalent are two very different operations on a device
>>> tree.  The former adds an ide disk to the default controller and the
>>> later potentially creates a new scsi bus and then adds a disk to a
>>> specific bus.
>>>        
>> AFAICS the current commandline options only result in simple addition of
>> devices. They might add slightly different devices in slightly different
>> places, but that's easy to accommodate by having the machine define a few
>> standard device/bus IDs.
>>
>> IMO it's even more lame if -hda shops working when you supply a device tree.
>>      
> The tree supplied by the user should label a bus node with a property
> 'QEMU,hda'. The C version (called by the board) would be something
> like setprop("/i440fx/pci.0/ide.0", "QEMU,hda"). QEMU should search
> the device tree for such labels at startup.
>    

That works for the very simple case of -hda, but what do you do for:

-drive file=foo.img,bus=0,index=2

I think it's possible to come up with some form of solution once you 
start adding synthetic properties or dummy devices but ultimately I 
think it pollutes the device tree.  I think the easiest way to support 
the interfaces we provide now is to just code the device tree 
manipulation in C.

Regards,

Anthony Liguori

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-09 20:52                     ` Anthony Liguori
@ 2010-06-09 21:09                       ` Blue Swirl
  2010-06-09 22:26                       ` Paul Brook
  1 sibling, 0 replies; 64+ messages in thread
From: Blue Swirl @ 2010-06-09 21:09 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Paolo Bonzini, Glauber Costa, Paul Brook, qemu-devel

On Wed, Jun 9, 2010 at 8:52 PM, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 06/09/2010 03:47 PM, Blue Swirl wrote:
>>
>> On Wed, Jun 9, 2010 at 2:30 PM, Paul Brook<paul@codesourcery.com>  wrote:
>>
>>>>>>
>>>>>> Because at some point the base tree will have to be written in C.
>>>>>>
>>>>>
>>>>> No. You can start with a completely empty machine.
>>>>> We don't/shouldn't need any machine specific C code.
>>>>>
>>>>
>>>> I think you're missing the argument.  I should be possible to create a
>>>> machine entirely from a FDT or via -device options.
>>>>
>>>> However, to continue to support the interfaces that we support today, it
>>>> will be necessary to have C code that manipulates a base device tree.
>>>>
>>>> When a user specifies '-M pc -hda foo.img'  verses '-M versatilepb -hda
>>>> foo.img', the equivalent are two very different operations on a device
>>>> tree.  The former adds an ide disk to the default controller and the
>>>> later potentially creates a new scsi bus and then adds a disk to a
>>>> specific bus.
>>>>
>>>
>>> AFAICS the current commandline options only result in simple addition of
>>> devices. They might add slightly different devices in slightly different
>>> places, but that's easy to accommodate by having the machine define a few
>>> standard device/bus IDs.
>>>
>>> IMO it's even more lame if -hda shops working when you supply a device
>>> tree.
>>>
>>
>> The tree supplied by the user should label a bus node with a property
>> 'QEMU,hda'. The C version (called by the board) would be something
>> like setprop("/i440fx/pci.0/ide.0", "QEMU,hda"). QEMU should search
>> the device tree for such labels at startup.
>>
>
> That works for the very simple case of -hda, but what do you do for:
>
> -drive file=foo.img,bus=0,index=2

This is a host device, so the device tree does not address that. But
previously I proposed that also the host devices (drives, chardev,
netdev etc.) could be considered to be qdev like devices and qemu_irqs
could be used to communicate between the host devices and
machine/board. Maybe that should be reconsidered.

> I think it's possible to come up with some form of solution once you start
> adding synthetic properties or dummy devices but ultimately I think it
> pollutes the device tree.  I think the easiest way to support the interfaces
> we provide now is to just code the device tree manipulation in C.

I don't think pollution is a problem with careful prefixing, also
Linux adds some properties to its device tree. We could also prune our
properties from the tree before passing it around if necessary.

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] Re: [PATCH 0/22] Refactor machine support
  2010-06-09 20:52                     ` Anthony Liguori
  2010-06-09 21:09                       ` Blue Swirl
@ 2010-06-09 22:26                       ` Paul Brook
  1 sibling, 0 replies; 64+ messages in thread
From: Paul Brook @ 2010-06-09 22:26 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Blue Swirl, Paolo Bonzini, Glauber Costa, qemu-devel

> >> AFAICS the current commandline options only result in simple addition of
> >> devices. They might add slightly different devices in slightly different
> >> places, but that's easy to accommodate by having the machine define a
> >> few standard device/bus IDs.
> >> 
> >> IMO it's even more lame if -hda shops working when you supply a device
> >> tree.
> > 
> > The tree supplied by the user should label a bus node with a property
> > 'QEMU,hda'. The C version (called by the board) would be something
> > like setprop("/i440fx/pci.0/ide.0", "QEMU,hda"). QEMU should search
> > the device tree for such labels at startup.
> 
> That works for the very simple case of -hda, but what do you do for:
> 
> -drive file=foo.img,bus=0,index=2

I don't see how that is any harder. I'm assuming that -hda is a trivial alias 
for -drive bus=0,index=0. Fact is that -drive supports a very limited set of 
operations. Figuring out the default interface is easy - use whatever exists 
on the machine. Creating IDE disks is easy, just add them to the existing IDE 
bus.  For SCSI/virtio you might need to add a HBA first, but that's also 
fairly trivial.  Most other interfaces (sd, pflash) don't do automagical 
device creation to start with - if you don't specify an image then you get an 
empty/disconnected device.

> I think it's possible to come up with some form of solution once you
> start adding synthetic properties or dummy devices but ultimately I
> think it pollutes the device tree.  I think the easiest way to support
> the interfaces we provide now is to just code the device tree
> manipulation in C.

I disagree. If programmatic machine construction/manipulation was sufficient 
then we wouldn't need device trees at all.  Current qemu supports an extremely 
limited set of machines.  Bear in mind that x86 PCs are, pretty much by 
definition, approximately all the same to start with.  Once you start looking 
at other platforms (e.g. arm boards) you realise just how cripplingly 
restrictive the this is.  Restricting -hda, -drive, etc. and similar to a 
small subset of built-in machines is IMO and unacceptably poor solution.

Some of your arguments seem to be self-fulfilling prophecies. If you design 
your new option structure around a magical self-morphing device tree then it's 
unlikely that this will work with user specified device trees.  I believe the 
current set of commandline options are sufficient abstract that they do not 
dictate a particular implementation.

Paul

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config
  2010-06-08  0:50   ` Anthony Liguori
@ 2010-06-10 17:48     ` Daniel P. Berrange
  2010-06-11 13:03       ` Daniel P. Berrange
  0 siblings, 1 reply; 64+ messages in thread
From: Daniel P. Berrange @ 2010-06-10 17:48 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Anthony Liguori, Glauber Costa, qemu-devel

On Mon, Jun 07, 2010 at 07:50:14PM -0500, Anthony Liguori wrote:
> On 06/07/2010 06:52 PM, Anthony Liguori wrote:
> >Since we have MachineCore and can represent a machine entirely via default
> >options, we can introduce a new option that let's us dynamically register a
> >machine based on those options.
> >
> >For instance, we could add the following to target-x86_64.conf:
> >
> >[machine-def]
> >  name = "pc-0.11"
> >  desc = "Standard PC"
> >  acpi = "on"
> >  pci = "on"
> >  cpu = "qemu64"
> >  max_cpus = "255"
> >  virtio-blk-pci.vectors = "0"
> >  virtio-serial-pci.max_nr_ports = "1"
> >  virtio-serial-pci.vectors = "0"
> >  ide-drive.ver = "0.11"
> >  scsi-disk.ver = "0.11"
> >  PCI.rombar = "0"
> >
> >What's really exciting, is that a user can then define their own machines
> >that better suite their desires:
> >
> >[kvmpc]
> >  name = "kvmpc"
> >  accel = "kvm|tcg"
> >  ram_size = "512M"
> >  max_cpus = "64"
> >  sockets = "16"
> >  default_drive = "virtio"
> >
> >I'd eventually like to move all PC compatibility machines to the default
> >config but for now, I wanted to keep this simple.
> >
> >Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
> >   
> 
> From the perspective of a tool like libvirt, I think there are a couple 
> ways it could handle something like this and I think it's worth 
> discussing the options.
> 
> Assume we move all the compat machine definitions into a config file, 
> since libvirt presumably uses -nodefconfig today, it could simply 
> include it's own machine definitions for each qemu version based on the 
> definitions we ship.  That makes sure that the definition is always 
> static for libvirt.

Due to a screwup on my part, we don't currently use -nodefconfig
but we should be. I had originally thought '-nodefaults' turned off
all defaults, but I see it only does defaults hardware, but not
default configs. 

> Another option would be for libvirt to not use -nodefconfig, and instead 
> to let the user's global configs be read.  libvirt would then read the 
> config file from the running qemu instance to sync it's state up.

The tricky thing I'm seeing here is the scope of the stuff you can 
put in the configuration files. 

On the one had there are config options that effectively provide new 
capabilities to the QEMU binary eg new machine types, new CPU definitions.
These don't cause any trouble, since that are a complete no-op unless you
launch a guest that actually requests to make use of them eg by adding a
-M mycustommachine or  a  -cpu mycustomCPUmodel flag. A '-M pc-010' guest
will never be impacted by fact that you added some new machine types in
the global config.

On the other hand there are config options that immediately change the 
virtual hardware in all guests launched, eg if I edit the 
/etc/qemu/target-i386.conf and add

  [drive]
    if = "ide"
    file = "foo.iso"

then every single guest gets a new piece of hardware, which is what we
tried to avoid with the '-nodefaults' flag already.

> The later option is a bit more work up front but longer term, I think it 
> addresses a couple things nicely.  It provides a way for a user 
> specified config to co-exist with libvirt.  It also let's tools tweak 
> power config options in a way that's compatible with libvirt.
> 
> If libvirt can embed the qemu config description in its own XML, then 
> there is no problem for libvirt to recreate the system on a different 
> box even if the global configuration is different.

If the global config is just adding new capabilities (machine types,
cpu types, etc) I see no problem with having these loaded by default
for any libvirt guest.

When the global config can add extra hardware (eg drives) this becomes
very tricky to re-concile, which is exactly why we had '-nodefaults'
to turn off extra global hardware. 

We want all hardware libvirt knows about to be visible in the XML. 
eg, if the default config contained a [drive] section, you'd expect 
that to appear as a <disk> in libvirt XML. So if we parsed the default 
global config to sync it to the libvirt XML, when we come to launch the
guest, we have even more fun figuring out which of the disks in the XML
config needs a '-drive' on the ARGV, and which don't need any arg because
they're in the global config. To make that practical we'd need to read 
the global config, turn it into libvirt XML, and then launch the guest
with -nodefconfig and just use -drive as normal for everything. But then
we loose useful things like new machine types & cpu types :-(

Is it practical to a way to separate the global config into two global
configs. One config that is used to define extra capabilities (machine
types, cpu types, etc) that on their own are guarenteed to never impact
any existing guest config. One that is used to add default hardware 
(disks nics, etc) which clearly does impact every guest.

Then, we could let the global capabilities config be in effect at all 
times, QEMU wouldn't even need a way to turn that off. The global
hardware config could be enabled/disable as per the needs of the mgmt
app, reconciled with their config as required.

Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 64+ messages in thread

* Re: [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config
  2010-06-10 17:48     ` Daniel P. Berrange
@ 2010-06-11 13:03       ` Daniel P. Berrange
  0 siblings, 0 replies; 64+ messages in thread
From: Daniel P. Berrange @ 2010-06-11 13:03 UTC (permalink / raw)
  To: Anthony Liguori; +Cc: Anthony Liguori, Glauber Costa, qemu-devel

On Thu, Jun 10, 2010 at 06:48:42PM +0100, Daniel P. Berrange wrote:
> On Mon, Jun 07, 2010 at 07:50:14PM -0500, Anthony Liguori wrote:
> > On 06/07/2010 06:52 PM, Anthony Liguori wrote:
> > >Since we have MachineCore and can represent a machine entirely via default
> > >options, we can introduce a new option that let's us dynamically register a
> > >machine based on those options.
> > >
> > >For instance, we could add the following to target-x86_64.conf:
> > >
> > >[machine-def]
> > >  name = "pc-0.11"
> > >  desc = "Standard PC"
> > >  acpi = "on"
> > >  pci = "on"
> > >  cpu = "qemu64"
> > >  max_cpus = "255"
> > >  virtio-blk-pci.vectors = "0"
> > >  virtio-serial-pci.max_nr_ports = "1"
> > >  virtio-serial-pci.vectors = "0"
> > >  ide-drive.ver = "0.11"
> > >  scsi-disk.ver = "0.11"
> > >  PCI.rombar = "0"
> > >
> > >What's really exciting, is that a user can then define their own machines
> > >that better suite their desires:
> > >
> > >[kvmpc]
> > >  name = "kvmpc"
> > >  accel = "kvm|tcg"
> > >  ram_size = "512M"
> > >  max_cpus = "64"
> > >  sockets = "16"
> > >  default_drive = "virtio"
> > >
> > >I'd eventually like to move all PC compatibility machines to the default
> > >config but for now, I wanted to keep this simple.
> > >
> > >Signed-off-by: Anthony Liguori<aliguori@us.ibm.com>
> > >   
> > 
> > From the perspective of a tool like libvirt, I think there are a couple 
> > ways it could handle something like this and I think it's worth 
> > discussing the options.
> > 
> > Assume we move all the compat machine definitions into a config file, 
> > since libvirt presumably uses -nodefconfig today, it could simply 
> > include it's own machine definitions for each qemu version based on the 
> > definitions we ship.  That makes sure that the definition is always 
> > static for libvirt.
> 
> Due to a screwup on my part, we don't currently use -nodefconfig
> but we should be. I had originally thought '-nodefaults' turned off
> all defaults, but I see it only does defaults hardware, but not
> default configs. 
> 
> > Another option would be for libvirt to not use -nodefconfig, and instead 
> > to let the user's global configs be read.  libvirt would then read the 
> > config file from the running qemu instance to sync it's state up.
> 
> The tricky thing I'm seeing here is the scope of the stuff you can 
> put in the configuration files. 
> 
> On the one had there are config options that effectively provide new 
> capabilities to the QEMU binary eg new machine types, new CPU definitions.
> These don't cause any trouble, since that are a complete no-op unless you
> launch a guest that actually requests to make use of them eg by adding a
> -M mycustommachine or  a  -cpu mycustomCPUmodel flag. A '-M pc-010' guest
> will never be impacted by fact that you added some new machine types in
> the global config.
> 
> On the other hand there are config options that immediately change the 
> virtual hardware in all guests launched, eg if I edit the 
> /etc/qemu/target-i386.conf and add
> 
>   [drive]
>     if = "ide"
>     file = "foo.iso"
> 
> then every single guest gets a new piece of hardware, which is what we
> tried to avoid with the '-nodefaults' flag already.
> 
> > The later option is a bit more work up front but longer term, I think it 
> > addresses a couple things nicely.  It provides a way for a user 
> > specified config to co-exist with libvirt.  It also let's tools tweak 
> > power config options in a way that's compatible with libvirt.
> > 
> > If libvirt can embed the qemu config description in its own XML, then 
> > there is no problem for libvirt to recreate the system on a different 
> > box even if the global configuration is different.
> 
> If the global config is just adding new capabilities (machine types,
> cpu types, etc) I see no problem with having these loaded by default
> for any libvirt guest.
> 
> When the global config can add extra hardware (eg drives) this becomes
> very tricky to re-concile, which is exactly why we had '-nodefaults'
> to turn off extra global hardware. 
> 
> We want all hardware libvirt knows about to be visible in the XML. 
> eg, if the default config contained a [drive] section, you'd expect 
> that to appear as a <disk> in libvirt XML. So if we parsed the default 
> global config to sync it to the libvirt XML, when we come to launch the
> guest, we have even more fun figuring out which of the disks in the XML
> config needs a '-drive' on the ARGV, and which don't need any arg because
> they're in the global config. To make that practical we'd need to read 
> the global config, turn it into libvirt XML, and then launch the guest
> with -nodefconfig and just use -drive as normal for everything. But then
> we loose useful things like new machine types & cpu types :-(
> 
> Is it practical to a way to separate the global config into two global
> configs. One config that is used to define extra capabilities (machine
> types, cpu types, etc) that on their own are guarenteed to never impact
> any existing guest config. One that is used to add default hardware 
> (disks nics, etc) which clearly does impact every guest.
> 
> Then, we could let the global capabilities config be in effect at all 
> times, QEMU wouldn't even need a way to turn that off. The global
> hardware config could be enabled/disable as per the needs of the mgmt
> app, reconciled with their config as required.

Actually thinking about it some more, it doesn't require a separation of
global configs. Instead we're just use my capabilities patches to query
the desired CPU & machine definitions from the global, and write them out 
to a new config and then use -nodefconfig to turn off the global config,
and -readconfig re-add just the bits of the global config we wanted.


Daniel
-- 
|: Red Hat, Engineering, London    -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org -o- http://virt-manager.org -o- http://deltacloud.org :|
|: http://autobuild.org        -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-   F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

^ permalink raw reply	[flat|nested] 64+ messages in thread

end of thread, other threads:[~2010-06-11 13:03 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-06-07 23:51 [Qemu-devel] [PATCH 0/22] Refactor machine support Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 01/22] QemuOpts: fix a bug in QemuOpts when setting an option twice Anthony Liguori
2010-06-08  7:51   ` Gerd Hoffmann
2010-06-08 10:32     ` [Qemu-devel] " Paolo Bonzini
2010-06-08 13:07       ` Anthony Liguori
2010-06-08 13:44         ` Gerd Hoffmann
2010-06-08 15:17           ` Anthony Liguori
2010-06-08 15:37             ` Gerd Hoffmann
2010-06-08 16:04               ` Anthony Liguori
2010-06-09  7:01                 ` Gerd Hoffmann
2010-06-08 14:38         ` Paul Brook
2010-06-08 15:14           ` Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 02/22] QemuOpts: make qemu_opts_validate() store the description list for later use Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 03/22] QemuOpts: add function to set QemuOpts from defaults Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 04/22] machine: package all init arguments into a QemuOpts (v2) Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 05/22] machine: pass all init options as a single QemuOpts Anthony Liguori
2010-06-08  7:58   ` Gerd Hoffmann
2010-06-07 23:51 ` [Qemu-devel] [PATCH 06/22] Make -acpi-enable a machine specific option Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 07/22] machine: introduce -machine option Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 08/22] machine: implement -kernel/-append/-initrd options in term of -machine Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 09/22] machine: implement -m in terms " Anthony Liguori
2010-06-07 23:51 ` [Qemu-devel] [PATCH 10/22] machine: allow boards to specify default values and use it in isapc Anthony Liguori
2010-06-08  8:03   ` Gerd Hoffmann
2010-06-08 13:09     ` Anthony Liguori
2010-06-08 13:29       ` Gerd Hoffmann
2010-06-07 23:51 ` [Qemu-devel] [PATCH 11/22] machine: replace compat_props with opts_default Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 12/22] machine: some sugary macros to simplify machine default options Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 13/22] machine: get rid of global default QEMUMachine members Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 14/22] machine: replace QEMUMachine.use_scsi with -machine default_drive Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 15/22] machine: make max_cpus a -machine option Anthony Liguori
2010-06-08  1:01   ` Paul Brook
2010-06-08  1:56     ` Anthony Liguori
2010-06-08  2:56       ` Paul Brook
2010-06-09  7:44       ` Jes Sorensen
2010-06-09  7:47   ` Jes Sorensen
2010-06-07 23:52 ` [Qemu-devel] [PATCH 16/22] machine: move default machine out of machine definitions Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 17/22] machine: kill machine->alias Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 18/22] machine: final conversion to pure QemuOpts Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 19/22] machine: introduce accel option to allow selection of kvm or tcg Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 20/22] machine: introduce machine core and split qemu_register_machine Anthony Liguori
2010-06-07 23:52 ` [Qemu-devel] [PATCH 21/22] machine: convert pc machines to split core vs machine API Anthony Liguori
2010-06-09  7:51   ` Jes Sorensen
2010-06-07 23:52 ` [Qemu-devel] [PATCH 22/22] machine: introduce -machine-def option to define a machine via config Anthony Liguori
2010-06-08  0:50   ` Anthony Liguori
2010-06-10 17:48     ` Daniel P. Berrange
2010-06-11 13:03       ` Daniel P. Berrange
2010-06-08  3:12 ` [Qemu-devel] [PATCH 0/22] Refactor machine support Paul Brook
2010-06-08 10:24   ` [Qemu-devel] " Paolo Bonzini
2010-06-08 14:30     ` Paul Brook
2010-06-08 15:28       ` Anthony Liguori
2010-06-08 15:36         ` Paul Brook
2010-06-08 15:58           ` Paolo Bonzini
2010-06-08 16:15             ` Anthony Liguori
2010-06-08 21:05               ` Alexander Graf
2010-06-08 21:16                 ` Anthony Liguori
2010-06-08 17:23             ` Anthony Liguori
2010-06-09  2:11             ` Paul Brook
2010-06-09 13:55               ` Anthony Liguori
2010-06-09 14:30                 ` Paul Brook
2010-06-09 20:47                   ` Blue Swirl
2010-06-09 20:52                     ` Anthony Liguori
2010-06-09 21:09                       ` Blue Swirl
2010-06-09 22:26                       ` Paul Brook
2010-06-08 14:04   ` [Qemu-devel] " Anthony Liguori

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.