qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
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 == '?') {
>    

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).