[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] Re: [PATCH v2 2/2] basic machine opts framework
From: |
Anthony Liguori |
Subject: |
[Qemu-devel] Re: [PATCH v2 2/2] basic machine opts framework |
Date: |
Thu, 03 Jun 2010 09:13:23 -0500 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100423 Lightning/1.0b1 Thunderbird/3.0.4 |
On 06/01/2010 12:56 PM, Glauber Costa wrote:
This patch adds initial support for the -machine option, that allows
command line specification of machine attributes (always relying on safe
defaults). Besides its value per-se, it is the saner way we found to
allow for enabling/disabling of kvm's in-kernel irqchip.
A machine with in-kernel-irqchip could be specified as:
-machine irqchip=apic-kvm
And one without it:
-machine irqchip=apic
To demonstrate how it'd work, this patch introduces a choice between
"pic" and "apic", pic being the old-style isa thing.
---
hw/boards.h | 10 ++++++++++
hw/pc.c | 45 +++++++++++++++++++++++++++++++++++++++------
qemu-config.c | 16 ++++++++++++++++
qemu-config.h | 1 +
qemu-options.hx | 9 +++++++++
vl.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 129 insertions(+), 6 deletions(-)
diff --git a/hw/boards.h b/hw/boards.h
index d889341..187794e 100644
--- a/hw/boards.h
+++ b/hw/boards.h
@@ -12,6 +12,15 @@ typedef void QEMUMachineInitFunc(ram_addr_t ram_size,
const char *initrd_filename,
const char *cpu_model);
+typedef void (QEMUIrqchipFunc)(void *opaque);
+
+typedef struct QEMUIrqchip {
+ const char *name;
+ QEMUIrqchipFunc *init;
+ int used;
+ int is_default;
+} QEMUIrqchip;
+
typedef struct QEMUMachine {
const char *name;
const char *alias;
@@ -21,6 +30,7 @@ typedef struct QEMUMachine {
int max_cpus;
int is_default;
CompatProperty *compat_props;
+ QEMUIrqchip *irqchip;
struct QEMUMachine *next;
} QEMUMachine;
We really need machine specific state. I've sent a patch out to add this.
diff --git a/hw/pc.c b/hw/pc.c
index 408d6d6..b3de30a 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -1007,21 +1007,43 @@ int cpu_is_bsp(CPUState *env)
return env->cpuid_apic_id == 0;
}
+static void qemu_apic_init(void *opaque)
+{
+ CPUState *env = opaque;
+ if (!(env->cpuid_features& CPUID_APIC)) {
+ fprintf(stderr, "CPU lacks APIC cpuid flag\n");
+ exit(1);
+ }
+ env->cpuid_apic_id = env->cpu_index;
+ /* APIC reset callback resets cpu */
+ apic_init(env);
+}
+
+static void qemu_pic_init(void *opaque)
+{
+ CPUState *env = opaque;
+
+ if (smp_cpus> 1) {
+ fprintf(stderr, "PIC can't support smp systems\n");
+ exit(1);
+ }
+ qemu_register_reset((QEMUResetHandler*)cpu_reset, env);
+}
+
static CPUState *pc_new_cpu(const char *cpu_model)
{
CPUState *env;
+ QEMUIrqchip *ic;
env = cpu_init(cpu_model);
if (!env) {
fprintf(stderr, "Unable to find x86 CPU definition\n");
exit(1);
}
- if ((env->cpuid_features& CPUID_APIC) || smp_cpus> 1) {
- env->cpuid_apic_id = env->cpu_index;
- /* APIC reset callback resets cpu */
- apic_init(env);
- } else {
- qemu_register_reset((QEMUResetHandler*)cpu_reset, env);
+
+ for (ic = current_machine->irqchip; ic->name != NULL; ic++) {
+ if (ic->used)
+ ic->init(env);
}
return env;
}
@@ -1370,6 +1392,17 @@ static QEMUMachine pc_machine = {
.desc = "Standard PC",
.init = pc_init_pci,
.max_cpus = 255,
+ .irqchip = (QEMUIrqchip[]){
+ {
+ .name = "apic",
+ .init = qemu_apic_init,
+ .is_default = 1,
+ },{
+ .name = "pic",
+ .init = qemu_pic_init,
+ },
+ { /* end of list */ },
+ },
.is_default = 1,
};
I don't think it's really useful to specify the apic vs. pic like this.
I think the current scheme of cpu flag is adequate.
diff --git a/qemu-config.c b/qemu-config.c
index cae92f7..e83b301 100644
--- a/qemu-config.c
+++ b/qemu-config.c
@@ -196,6 +196,21 @@ QemuOptsList qemu_rtc_opts = {
},
};
+QemuOptsList qemu_machine_opts = {
+ .name = "M",
machine
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_machine_opts.head),
+ .desc = {
+ {
+ .name = "mach",
+ .type = QEMU_OPT_STRING,
+ },{
driver, and it ought to be an implied option so that '-machine pc' works.
+ .name = "irqchip",
+ .type = QEMU_OPT_STRING,
+ },
+ { /* end of list */ }
+ },
+};
But let's actually make this an empty list, then do a #define that
containers just the "machine" option. Then we can setup a pc-specific
qemu_machine_opts that contains the apic option.
Once we've found the machine based on the driver property, we can
validate the machine-specific options in vl.c.
diff --git a/vl.c b/vl.c
index 7a8b20b..cabbd1e 100644
--- a/vl.c
+++ b/vl.c
@@ -3217,9 +3217,15 @@ static QEMUMachine *find_machine(const char *name)
static QEMUMachine *find_default_machine(void)
{
QEMUMachine *m;
+ QEMUIrqchip *ic;
for(m = first_machine; m != NULL; m = m->next) {
if (m->is_default) {
+ for (ic = m->irqchip; ic->name != NULL; ic++) {
+ if (ic->is_default) {
+ ic->used = 1;
+ }
+ }
return m;
}
}
@@ -4902,6 +4908,54 @@ int main(int argc, char **argv, char **envp)
exit(*optarg != '?');
}
break;
+ case QEMU_OPTION_machine: {
+ const char *mach;
+ const char *op;
+
+ opts = qemu_opts_parse(&qemu_machine_opts, optarg, 0);
+ if (!opts) {
+ fprintf(stderr, "parse error: %s\n", optarg);
+ exit(1);
+ }
+
+ mach = qemu_opt_get(opts, "mach");
+ if (mach) {
+ machine = find_machine(mach);
+ if (!machine) {
+ 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,
+ m->is_default ? " (default)" : "");
+ }
+ exit(*optarg != '?');
+ }
+ }
+
+ op = qemu_opt_get(opts, "irqchip");
+ if (op) {
+ int found = 0;
+ QEMUIrqchip *ic;
+ for (ic = machine->irqchip; ic->name != NULL; ic++) {
+ if (!strcmp(op, ic->name)) {
+ ic->used = 1;
+ found = 1;
+ } else
+ ic->used = 0;
+ }
+ if (!found) {
+ fprintf(stderr, "irqchip %s not found\n", op);
+ exit(1);
+
+ }
+ }
Can't do this type of work here because it won't get run when loaded via
-readconfig.
We don't need to do it as part of this series, but we should fold all
the parameters (mem_size, kernel_cmdline, etc.) into this qemuopts and
make the other command lines syntactic wrappers.
Regards,
Anthony Liguori
+ break;
+ }
case QEMU_OPTION_cpu:
/* hw initialization will check this */
if (*optarg == '?') {
[Qemu-devel] Re: [PATCH v2 1/2] early set current_machine, Anthony Liguori, 2010/06/03