From: Anthony Liguori <aliguori@linux.vnet.ibm.com>
To: Glauber Costa <glommer@redhat.com>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [PATCH v2 2/2] basic machine opts framework
Date: Thu, 03 Jun 2010 09:13:23 -0500 [thread overview]
Message-ID: <4C07B883.3080408@linux.vnet.ibm.com> (raw)
In-Reply-To: <1275414976-18258-3-git-send-email-glommer@redhat.com>
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 == '?') {
>
next prev parent reply other threads:[~2010-06-03 14:14 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-01 17:56 [Qemu-devel] [PATCH v2 0/2] basic machine opts framework Glauber Costa
2010-06-01 17:56 ` [Qemu-devel] [PATCH v2 1/2] early set current_machine Glauber Costa
2010-06-01 17:56 ` [Qemu-devel] [PATCH v2 2/2] basic machine opts framework Glauber Costa
2010-06-02 7:15 ` [Qemu-devel] " Jan Kiszka
2010-06-02 14:06 ` Glauber Costa
2010-06-03 6:07 ` Jan Kiszka
2010-06-03 13:11 ` Anthony Liguori
2010-06-03 9:02 ` Paul Brook
2010-06-03 14:13 ` Anthony Liguori [this message]
2010-06-03 13:14 ` [Qemu-devel] Re: [PATCH v2 1/2] early set current_machine Anthony Liguori
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4C07B883.3080408@linux.vnet.ibm.com \
--to=aliguori@linux.vnet.ibm.com \
--cc=glommer@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.