Merge remote-tracking branch 'stefanha/net' into staging

* stefanha/net:
  net: add the support for -netdev socket, listen
  net: fix the coding style
  hub: add the support for hub own flow control
  net: determine if packets can be sent before net queue deliver packets
  net: cleanup deliver/deliver_iov func pointers
  net: Make "info network" output more readable info
  net: Rename qemu_del_vlan_client() to qemu_del_net_client()
  net: Rename vc local variables to nc
  net: Rename VLANClientState to NetClientState
  net: Rename non_vlan_clients to net_clients
  net: Remove VLANState
  net: Remove vlan code from net.c
  net: Convert qdev_prop_vlan to peer with hub
  net: Drop vlan argument to qemu_new_net_client()
  hub: Check that hubs are configured correctly
  net: Look up 'vlan' net clients using hubs
  net: Use hubs for the vlan feature
  net: Add a hub net client
  net: Add interface to bridge when SIOCBRADDIF isn't available
diff --git a/Makefile b/Makefile
index 621cb86..000b46c 100644
--- a/Makefile
+++ b/Makefile
@@ -215,8 +215,8 @@
 	rm -f *.o *.d *.a *.lo $(TOOLS) $(HELPERS-y) qemu-ga TAGS cscope.* *.pod *~ */*~
 	rm -Rf .libs
 	rm -f slirp/*.o slirp/*.d audio/*.o audio/*.d block/*.o block/*.d net/*.o net/*.d fsdev/*.o fsdev/*.d ui/*.o ui/*.d qapi/*.o qapi/*.d qga/*.o qga/*.d
-	rm -f qom/*.o qom/*.d
-	rm -f usb/*.o usb/*.d hw/*.o hw/*.d
+	rm -f qom/*.o qom/*.d libuser/qom/*.o libuser/qom/*.d
+	rm -f hw/usb/*.o hw/usb/*.d hw/*.o hw/*.d
 	rm -f qemu-img-cmds.h
 	rm -f trace/*.o trace/*.d
 	rm -f trace-dtrace.dtrace trace-dtrace.dtrace-timestamp
diff --git a/arch_init.c b/arch_init.c
index 26f30ef..60823ba 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -680,7 +680,7 @@
 {
     struct soundhw *c;
 
-    if (*optarg == '?') {
+    if (is_help_option(optarg)) {
     show_valid_cards:
 
         printf("Valid sound card names (comma separated):\n");
@@ -688,7 +688,7 @@
             printf ("%-11s %s\n", c->name, c->descr);
         }
         printf("\n-soundhw all will enable all of the above\n");
-        exit(*optarg != '?');
+        exit(!is_help_option(optarg));
     }
     else {
         size_t l;
diff --git a/blockdev.c b/blockdev.c
index 3d75015..8669142 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -398,11 +398,11 @@
 #endif
 
     if ((buf = qemu_opt_get(opts, "format")) != NULL) {
-       if (strcmp(buf, "?") == 0) {
-           error_printf("Supported formats:");
-           bdrv_iterate_format(bdrv_format_print, NULL);
-           error_printf("\n");
-           return NULL;
+        if (is_help_option(buf)) {
+            error_printf("Supported formats:");
+            bdrv_iterate_format(bdrv_format_print, NULL);
+            error_printf("\n");
+            return NULL;
         }
         drv = bdrv_find_whitelisted_format(buf);
         if (!drv) {
diff --git a/bsd-user/main.c b/bsd-user/main.c
index cd33d65..095ae8e 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -681,7 +681,7 @@
            "-g port           wait gdb connection to port\n"
            "-L path           set the elf interpreter prefix (default=%s)\n"
            "-s size           set the stack size in bytes (default=%ld)\n"
-           "-cpu model        select CPU (-cpu ? for list)\n"
+           "-cpu model        select CPU (-cpu help for list)\n"
            "-drop-ld-preload  drop LD_PRELOAD for target process\n"
            "-E var=value      sets/modifies targets environment variable(s)\n"
            "-U var            unsets targets environment variable(s)\n"
@@ -825,7 +825,7 @@
             qemu_uname_release = argv[optind++];
         } else if (!strcmp(r, "cpu")) {
             cpu_model = argv[optind++];
-            if (strcmp(cpu_model, "?") == 0) {
+            if (is_help_option(cpu_model)) {
 /* XXX: implement xxx_cpu_list for targets that still miss it */
 #if defined(cpu_list)
                     cpu_list(stdout, &fprintf);
diff --git a/exec.c b/exec.c
index feb4795..a42a0b5 100644
--- a/exec.c
+++ b/exec.c
@@ -2240,14 +2240,6 @@
     phys_sections_nb = 0;
 }
 
-/* register physical memory.
-   For RAM, 'size' must be a multiple of the target page size.
-   If (phys_offset & ~TARGET_PAGE_MASK) != 0, then it is an
-   io memory page.  The address used when calling the IO function is
-   the offset from the start of the region, plus region_offset.  Both
-   start_addr and region_offset are rounded down to a page boundary
-   before calculating this offset.  This should not be a problem unless
-   the low bits of start_addr and region_offset differ.  */
 static void register_subpage(MemoryRegionSection *section)
 {
     subpage_t *subpage;
@@ -2271,7 +2263,7 @@
         subpage = container_of(existing->mr, subpage_t, iomem);
     }
     start = section->offset_within_address_space & ~TARGET_PAGE_MASK;
-    end = start + section->size;
+    end = start + section->size - 1;
     subpage_register(subpage, start, end, phys_section_add(section));
 }
 
@@ -2305,10 +2297,15 @@
         remain.offset_within_address_space += now.size;
         remain.offset_within_region += now.size;
     }
-    now = remain;
-    now.size &= TARGET_PAGE_MASK;
-    if (now.size) {
-        register_multipage(&now);
+    while (remain.size >= TARGET_PAGE_SIZE) {
+        now = remain;
+        if (remain.offset_within_region & ~TARGET_PAGE_MASK) {
+            now.size = TARGET_PAGE_SIZE;
+            register_subpage(&now);
+        } else {
+            now.size &= TARGET_PAGE_MASK;
+            register_multipage(&now);
+        }
         remain.size -= now.size;
         remain.offset_within_address_space += now.size;
         remain.offset_within_region += now.size;
diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
index f4a7026..4b52540 100644
--- a/hw/9pfs/virtio-9p.c
+++ b/hw/9pfs/virtio-9p.c
@@ -983,11 +983,16 @@
     err += offset;
     trace_v9fs_attach_return(pdu->tag, pdu->id,
                              qid.type, qid.version, qid.path);
-    s->root_fid = fid;
-    /* disable migration */
-    error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
-              s->ctx.fs_root ? s->ctx.fs_root : "NULL", s->tag);
-    migrate_add_blocker(s->migration_blocker);
+    /*
+     * disable migration if we haven't done already.
+     * attach could get called multiple times for the same export.
+     */
+    if (!s->migration_blocker) {
+        s->root_fid = fid;
+        error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
+                  s->ctx.fs_root ? s->ctx.fs_root : "NULL", s->tag);
+        migrate_add_blocker(s->migration_blocker);
+    }
 out:
     put_fid(pdu, fidp);
 out_nofid:
diff --git a/hw/apic.h b/hw/apic.h
index a89542b..1d48e02 100644
--- a/hw/apic.h
+++ b/hw/apic.h
@@ -21,9 +21,12 @@
 void apic_handle_tpr_access_report(DeviceState *d, target_ulong ip,
                                    TPRAccess access);
 void apic_poll_irq(DeviceState *d);
+void apic_designate_bsp(DeviceState *d);
 
 /* pc.c */
-int cpu_is_bsp(CPUX86State *env);
 DeviceState *cpu_get_current_apic(void);
 
+/* cpu.c */
+bool cpu_is_bsp(X86CPU *cpu);
+
 #endif
diff --git a/hw/apic_common.c b/hw/apic_common.c
index 60b8259..58e63b0 100644
--- a/hw/apic_common.c
+++ b/hw/apic_common.c
@@ -43,8 +43,8 @@
         trace_cpu_get_apic_base((uint64_t)s->apicbase);
         return s->apicbase;
     } else {
-        trace_cpu_get_apic_base(0);
-        return 0;
+        trace_cpu_get_apic_base(MSR_IA32_APICBASE_BSP);
+        return MSR_IA32_APICBASE_BSP;
     }
 }
 
@@ -201,13 +201,23 @@
     s->timer_expiry = -1;
 }
 
+void apic_designate_bsp(DeviceState *d)
+{
+    if (d == NULL) {
+        return;
+    }
+
+    APICCommonState *s = APIC_COMMON(d);
+    s->apicbase |= MSR_IA32_APICBASE_BSP;
+}
+
 static void apic_reset_common(DeviceState *d)
 {
     APICCommonState *s = DO_UPCAST(APICCommonState, busdev.qdev, d);
     APICCommonClass *info = APIC_COMMON_GET_CLASS(s);
     bool bsp;
 
-    bsp = cpu_is_bsp(s->cpu_env);
+    bsp = cpu_is_bsp(x86_env_get_cpu(s->cpu_env));
     s->apicbase = 0xfee00000 |
         (bsp ? MSR_IA32_APICBASE_BSP : 0) | MSR_IA32_APICBASE_ENABLE;
 
diff --git a/hw/mips_jazz.c b/hw/mips_jazz.c
index bf1b799..db927f1 100644
--- a/hw/mips_jazz.c
+++ b/hw/mips_jazz.c
@@ -239,7 +239,7 @@
             dp83932_init(nd, 0x80001000, 2, get_system_memory(), rc4030[4],
                          rc4030_opaque, rc4030_dma_memory_rw);
             break;
-        } else if (strcmp(nd->model, "?") == 0) {
+        } else if (is_help_option(nd->model)) {
             fprintf(stderr, "qemu: Supported NICs: dp83932\n");
             exit(1);
         } else {
diff --git a/hw/pc.c b/hw/pc.c
index 598267a..bd193f3 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -857,12 +857,6 @@
     nb_ne2k++;
 }
 
-int cpu_is_bsp(CPUX86State *env)
-{
-    /* We hard-wire the BSP to the first CPU. */
-    return env->cpu_index == 0;
-}
-
 DeviceState *cpu_get_current_apic(void)
 {
     if (cpu_single_env) {
@@ -910,15 +904,6 @@
     }
 }
 
-static void pc_cpu_reset(void *opaque)
-{
-    X86CPU *cpu = opaque;
-    CPUX86State *env = &cpu->env;
-
-    cpu_reset(CPU(cpu));
-    env->halted = !cpu_is_bsp(env);
-}
-
 static X86CPU *pc_new_cpu(const char *cpu_model)
 {
     X86CPU *cpu;
@@ -933,8 +918,7 @@
     if ((env->cpuid_features & CPUID_APIC) || smp_cpus > 1) {
         env->apic_state = apic_init(env, env->cpuid_apic_id);
     }
-    qemu_register_reset(pc_cpu_reset, cpu);
-    pc_cpu_reset(cpu);
+    cpu_reset(CPU(cpu));
     return cpu;
 }
 
diff --git a/hw/qdev-monitor.c b/hw/qdev-monitor.c
index 7915b45..b22a37a 100644
--- a/hw/qdev-monitor.c
+++ b/hw/qdev-monitor.c
@@ -138,13 +138,13 @@
     ObjectClass *klass;
 
     driver = qemu_opt_get(opts, "driver");
-    if (driver && !strcmp(driver, "?")) {
+    if (driver && is_help_option(driver)) {
         bool show_no_user = false;
         object_class_foreach(qdev_print_devinfo, TYPE_DEVICE, false, &show_no_user);
         return 1;
     }
 
-    if (!driver || !qemu_opt_get(opts, "?")) {
+    if (!driver || !qemu_opt_has_help_opt(opts)) {
         return 0;
     }
 
diff --git a/hw/watchdog.c b/hw/watchdog.c
index a42124d..b52aced 100644
--- a/hw/watchdog.c
+++ b/hw/watchdog.c
@@ -55,7 +55,7 @@
     QemuOpts *opts;
 
     /* -watchdog ? lists available devices and exits cleanly. */
-    if (strcmp(p, "?") == 0) {
+    if (is_help_option(p)) {
         QLIST_FOREACH(model, &watchdog_list, entry) {
             fprintf(stderr, "\t%s\t%s\n",
                      model->wdt_name, model->wdt_description);
diff --git a/hw/xen_pt.c b/hw/xen_pt.c
index fdf68aa..307119a 100644
--- a/hw/xen_pt.c
+++ b/hw/xen_pt.c
@@ -764,7 +764,7 @@
     return 0;
 }
 
-static int xen_pt_unregister_device(PCIDevice *d)
+static void xen_pt_unregister_device(PCIDevice *d)
 {
     XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d);
     uint8_t machine_irq = s->machine_irq;
@@ -814,8 +814,6 @@
     memory_listener_unregister(&s->memory_listener);
 
     xen_host_pci_device_put(&s->real_device);
-
-    return 0;
 }
 
 static Property xen_pci_passthrough_properties[] = {
diff --git a/linux-user/main.c b/linux-user/main.c
index a0ab8e8..25eaa11 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -3140,7 +3140,7 @@
 static void handle_arg_cpu(const char *arg)
 {
     cpu_model = strdup(arg);
-    if (cpu_model == NULL || strcmp(cpu_model, "?") == 0) {
+    if (cpu_model == NULL || is_help_option(cpu_model)) {
         /* XXX: implement xxx_cpu_list for targets that still miss it */
 #if defined(cpu_list_id)
         cpu_list_id(stdout, &fprintf, "");
@@ -3231,7 +3231,7 @@
     {"s",          "QEMU_STACK_SIZE",  true,  handle_arg_stack_size,
      "size",       "set the stack size to 'size' bytes"},
     {"cpu",        "QEMU_CPU",         true,  handle_arg_cpu,
-     "model",      "select CPU (-cpu ? for list)"},
+     "model",      "select CPU (-cpu help for list)"},
     {"E",          "QEMU_SET_ENV",     true,  handle_arg_set_env,
      "var=value",  "sets targets environment variable (see below)"},
     {"U",          "QEMU_UNSET_ENV",   true,  handle_arg_unset_env,
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 97f30d9..9be5ac0 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -2849,7 +2849,7 @@
     * Arguments to signal handler:
     *
     *   a0 = signal number
-    *   a1 = pointer to struct siginfo
+    *   a1 = pointer to siginfo_t
     *   a2 = pointer to struct ucontext
     *
     * $25 and PC point to the signal handler, $29 points to the
@@ -3255,7 +3255,7 @@
 };
 
 struct rt_signal_frame {
-    struct siginfo info;
+    siginfo_t info;
     struct ucontext uc;
     uint32_t tramp[2];
 };
@@ -3474,9 +3474,9 @@
 };
 
 struct rt_signal_frame {
-        struct siginfo *pinfo;
+        siginfo_t *pinfo;
         void *puc;
-        struct siginfo info;
+        siginfo_t info;
         struct ucontext uc;
         uint8_t retcode[8];       /* Trampoline code. */
 };
diff --git a/net.c b/net.c
index 98109e5..60043dd 100644
--- a/net.c
+++ b/net.c
@@ -482,8 +482,9 @@
 {
     int i;
 
-    if (!arg || strcmp(arg, "?"))
+    if (!arg || !is_help_option(arg)) {
         return 0;
+    }
 
     fprintf(stderr, "qemu: Supported NIC models: ");
     for (i = 0 ; models[i]; i++)
diff --git a/qemu-common.h b/qemu-common.h
index ea0fe21..f16079f 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -136,6 +136,24 @@
 void qemu_get_timedate(struct tm *tm, int offset);
 int qemu_timedate_diff(struct tm *tm);
 
+/**
+ * is_help_option:
+ * @s: string to test
+ *
+ * Check whether @s is one of the standard strings which indicate
+ * that the user is asking for a list of the valid values for a
+ * command option like -cpu or -M. The current accepted strings
+ * are 'help' and '?'. '?' is deprecated (it is a shell wildcard
+ * which makes it annoying to use in a reliable way) but provided
+ * for backwards compatibility.
+ *
+ * Returns: true if @s is a request for a list.
+ */
+static inline bool is_help_option(const char *s)
+{
+    return !strcmp(s, "?") || !strcmp(s, "help");
+}
+
 /* cutils.c */
 void pstrcpy(char *buf, int buf_size, const char *str);
 void strpadcpy(char *buf, int buf_size, const char *str, char pad);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index 84dad19..a41448a 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -2390,7 +2390,7 @@
 @item -s size
 Set the x86 stack size in bytes (default=524288)
 @item -cpu model
-Select CPU model (-cpu ? for list and additional feature selection)
+Select CPU model (-cpu help for list and additional feature selection)
 @item -ignore-environment
 Start with an empty environment. Without this option,
 the initial environment is a copy of the caller's environment.
diff --git a/qemu-ga.c b/qemu-ga.c
index 8199da7..f1a39ec 100644
--- a/qemu-ga.c
+++ b/qemu-ga.c
@@ -736,7 +736,7 @@
             break;
         case 'b': {
             char **list_head, **list;
-            if (*optarg == '?') {
+            if (is_help_option(optarg)) {
                 list_head = list = qmp_get_command_list();
                 while (*list != NULL) {
                     printf("%s\n", *list);
diff --git a/qemu-img.c b/qemu-img.c
index 80cfb9b..b866f80 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -350,7 +350,7 @@
         img_size = (uint64_t)sval;
     }
 
-    if (options && !strcmp(options, "?")) {
+    if (options && is_help_option(options)) {
         ret = print_block_option_help(filename, fmt);
         goto out;
     }
@@ -744,7 +744,7 @@
     /* Initialize before goto out */
     qemu_progress_init(progress, 2.0);
 
-    if (options && !strcmp(options, "?")) {
+    if (options && is_help_option(options)) {
         ret = print_block_option_help(out_filename, out_fmt);
         goto out;
     }
diff --git a/qemu-option.c b/qemu-option.c
index 8334190..27891e7 100644
--- a/qemu-option.c
+++ b/qemu-option.c
@@ -529,6 +529,18 @@
     return opt ? opt->str : NULL;
 }
 
+bool qemu_opt_has_help_opt(QemuOpts *opts)
+{
+    QemuOpt *opt;
+
+    QTAILQ_FOREACH_REVERSE(opt, &opts->head, QemuOptHead, next) {
+        if (is_help_option(opt->name)) {
+            return true;
+        }
+    }
+    return false;
+}
+
 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval)
 {
     QemuOpt *opt = qemu_opt_find(opts, name);
diff --git a/qemu-option.h b/qemu-option.h
index 951dec3..ca72986 100644
--- a/qemu-option.h
+++ b/qemu-option.h
@@ -107,6 +107,18 @@
 };
 
 const char *qemu_opt_get(QemuOpts *opts, const char *name);
+/**
+ * qemu_opt_has_help_opt:
+ * @opts: options to search for a help request
+ *
+ * Check whether the options specified by @opts include one of the
+ * standard strings which indicate that the user is asking for a
+ * list of the valid values for a command line option (as defined
+ * by is_help_option()).
+ *
+ * Returns: true if @opts includes 'help' or equivalent.
+ */
+bool qemu_opt_has_help_opt(QemuOpts *opts);
 bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
 uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t defval);
 uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t defval);
diff --git a/qemu-options.hx b/qemu-options.hx
index dc68e15..9277414 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -6,6 +6,10 @@
 HXCOMM architectures.
 HXCOMM HXCOMM can be used for comments, discarded from both texi and C
 
+HXCOMM TODO : when we are able to change -help output without breaking
+HXCOMM libvirt we should update the help options which refer to -cpu ?,
+HXCOMM -driver ?, etc to use the preferred -cpu help etc instead.
+
 DEFHEADING(Standard options:)
 STEXI
 @table @option
diff --git a/qemu-sockets.c b/qemu-sockets.c
index 668fa93..beb2bb6 100644
--- a/qemu-sockets.c
+++ b/qemu-sockets.c
@@ -284,7 +284,6 @@
                         inet_strfamily(e->ai_family),
                         e->ai_canonname, uaddr, uport, strerror(errno));
             closesocket(sock);
-            sock = -1;
             continue;
         }
         freeaddrinfo(res);
diff --git a/qemu-timer.c b/qemu-timer.c
index de98977..062fdf2 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -183,7 +183,7 @@
     char *name;
     struct qemu_alarm_timer tmp;
 
-    if (!strcmp(opt, "?")) {
+    if (is_help_option(opt)) {
         show_available_alarms();
         exit(0);
     }
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6b9659f..857b94e 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -31,6 +31,8 @@
 
 #include "hyperv.h"
 
+#include "hw/hw.h"
+
 /* feature flags taken from "Intel Processor Identification and the CPUID
  * Instruction" and AMD's "CPUID Specification".  In cases of disagreement
  * between feature naming conventions, aliases may be added.
@@ -1686,8 +1688,31 @@
     env->dr[7] = DR7_FIXED_1;
     cpu_breakpoint_remove_all(env, BP_CPU);
     cpu_watchpoint_remove_all(env, BP_CPU);
+
+#if !defined(CONFIG_USER_ONLY)
+    /* We hard-wire the BSP to the first CPU. */
+    if (env->cpu_index == 0) {
+        apic_designate_bsp(env->apic_state);
+    }
+
+    env->halted = !cpu_is_bsp(cpu);
+#endif
 }
 
+#ifndef CONFIG_USER_ONLY
+bool cpu_is_bsp(X86CPU *cpu)
+{
+    return cpu_get_apic_base(cpu->env.apic_state) & MSR_IA32_APICBASE_BSP;
+}
+
+/* TODO: remove me, when reset over QOM tree is implemented */
+static void x86_cpu_machine_reset_cb(void *opaque)
+{
+    X86CPU *cpu = opaque;
+    cpu_reset(CPU(cpu));
+}
+#endif
+
 static void mce_init(X86CPU *cpu)
 {
     CPUX86State *cenv = &cpu->env;
@@ -1708,8 +1733,13 @@
 {
     X86CPU *cpu = X86_CPU(obj);
 
+#ifndef CONFIG_USER_ONLY
+    qemu_register_reset(x86_cpu_machine_reset_cb, cpu);
+#endif
+
     mce_init(cpu);
     qemu_init_vcpu(&cpu->env);
+    cpu_reset(CPU(cpu));
 }
 
 static void x86_cpu_initfn(Object *obj)
diff --git a/target-i386/helper.c b/target-i386/helper.c
index d3af6ea..b748d90 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1191,7 +1191,6 @@
     env->interrupt_request = sipi;
     env->pat = pat;
     apic_init_reset(env->apic_state);
-    env->halted = !cpu_is_bsp(env);
 }
 
 void do_cpu_sipi(X86CPU *cpu)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index e53c2f6..4cfb3fa 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -584,11 +584,13 @@
 
 void kvm_arch_reset_vcpu(CPUX86State *env)
 {
+    X86CPU *cpu = x86_env_get_cpu(env);
+
     env->exception_injected = -1;
     env->interrupt_injected = -1;
     env->xcr0 = 1;
     if (kvm_irqchip_in_kernel()) {
-        env->mp_state = cpu_is_bsp(env) ? KVM_MP_STATE_RUNNABLE :
+        env->mp_state = cpu_is_bsp(cpu) ? KVM_MP_STATE_RUNNABLE :
                                           KVM_MP_STATE_UNINITIALIZED;
     } else {
         env->mp_state = KVM_MP_STATE_RUNNABLE;
diff --git a/user-exec.c b/user-exec.c
index b2a4261..1a9c276 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -588,7 +588,7 @@
 int cpu_signal_handler(int host_signum, void *pinfo,
                        void *puc)
 {
-    struct siginfo *info = pinfo;
+    siginfo_t *info = pinfo;
     struct ucontext *uc = puc;
     unsigned long pc = uc->uc_mcontext.sc_iaoq[0];
     uint32_t insn = *(uint32_t *)pc;
diff --git a/vl.c b/vl.c
index 9fea320..1fd1114 100644
--- a/vl.c
+++ b/vl.c
@@ -2086,7 +2086,7 @@
         printf("%-20s %s%s\n", m->name, m->desc,
                m->is_default ? " (default)" : "");
     }
-    exit(!name || *name != '?');
+    exit(!name || !is_help_option(name));
 }
 
 static int tcg_init(void)
@@ -3216,7 +3216,7 @@
      */
     cpudef_init();
 
-    if (cpu_model && *cpu_model == '?') {
+    if (cpu_model && is_help_option(cpu_model)) {
         list_cpus(stdout, &fprintf, cpu_model);
         exit(0);
     }