summary refs log tree commit diff stats
path: root/hw/core
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-01-19 16:35:25 +0000
committerPeter Maydell <peter.maydell@linaro.org>2018-01-19 16:35:25 +0000
commitb384cd95eb9c6f73ad84ed1bb0717a26e29cc78f (patch)
treebbd0e7a39efd262c9196edea6d75a88d47557d8a /hw/core
parent3e5bdc6573edf0585e4085e6a4e349b135abf3b4 (diff)
parentd6b6abc51dda79a97f2c7bd6652c1940c068f1ec (diff)
downloadfocaccia-qemu-b384cd95eb9c6f73ad84ed1bb0717a26e29cc78f.tar.gz
focaccia-qemu-b384cd95eb9c6f73ad84ed1bb0717a26e29cc78f.zip
Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging
machine queue, 2018-01-19

# gpg: Signature made Fri 19 Jan 2018 16:30:19 GMT
# gpg:                using RSA key 0x2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/machine-next-pull-request:
  fw_cfg: fix memory corruption when all fw_cfg slots are used
  possible_cpus: add CPUArchId::type field
  nvdimm: add 'unarmed' option
  nvdimm: add a macro for property "label-size"
  hostmem-file: add "align" option
  scripts: Remove fixed entries from the device-crash-test
  qdev: Check for the availability of a hotplug controller before adding a device
  qdev_monitor: Simplify error handling in qdev_device_add()
  q35: Allow only supported dynamic sysbus devices
  xen: Add only xen-sysdev to dynamic sysbus device list
  spapr: Allow only supported dynamic sysbus devices
  ppc: e500: Allow only supported dynamic sysbus devices
  hw/arm/virt: Allow only supported dynamic sysbus devices
  machine: Replace has_dynamic_sysbus with list of allowed devices
  numa: fix missing '-numa cpu' in '-help' output
  qemu-options: document memory-backend-ram
  qemu-options: document missing memory-backend-file options
  memfd: remove needless include
  memfd: split qemu_memfd_alloc()

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to '')
-rw-r--r--hw/core/machine.c55
-rw-r--r--hw/core/qdev.c28
2 files changed, 55 insertions, 28 deletions
diff --git a/hw/core/machine.c b/hw/core/machine.c
index c857f3f934..cdc1163dc6 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -334,46 +334,61 @@ static bool machine_get_enforce_config_section(Object *obj, Error **errp)
     return ms->enforce_config_section;
 }
 
-static void error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
+void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type)
 {
-    error_report("Option '-device %s' cannot be handled by this machine",
-                 object_class_get_name(object_get_class(OBJECT(sbdev))));
-    exit(1);
+    strList *item = g_new0(strList, 1);
+
+    item->value = g_strdup(type);
+    item->next = mc->allowed_dynamic_sysbus_devices;
+    mc->allowed_dynamic_sysbus_devices = item;
 }
 
-static void machine_init_notify(Notifier *notifier, void *data)
+static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque)
 {
-    Object *machine = qdev_get_machine();
-    ObjectClass *oc = object_get_class(machine);
-    MachineClass *mc = MACHINE_CLASS(oc);
+    MachineState *machine = opaque;
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
+    bool allowed = false;
+    strList *wl;
 
-    if (mc->has_dynamic_sysbus) {
-        /* Our machine can handle dynamic sysbus devices, we're all good */
-        return;
+    for (wl = mc->allowed_dynamic_sysbus_devices;
+         !allowed && wl;
+         wl = wl->next) {
+        allowed |= !!object_dynamic_cast(OBJECT(sbdev), wl->value);
+    }
+
+    if (!allowed) {
+        error_report("Option '-device %s' cannot be handled by this machine",
+                     object_class_get_name(object_get_class(OBJECT(sbdev))));
+        exit(1);
     }
+}
+
+static void machine_init_notify(Notifier *notifier, void *data)
+{
+    MachineState *machine = MACHINE(qdev_get_machine());
 
     /*
-     * Loop through all dynamically created devices and check whether there
-     * are sysbus devices among them. If there are, error out.
+     * Loop through all dynamically created sysbus devices and check if they are
+     * all allowed.  If a device is not allowed, error out.
      */
-    foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL);
+    foreach_dynamic_sysbus_device(validate_sysbus_device, machine);
 }
 
 HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
 {
     int i;
-    Object *cpu;
     HotpluggableCPUList *head = NULL;
-    const char *cpu_type;
+    MachineClass *mc = MACHINE_GET_CLASS(machine);
+
+    /* force board to initialize possible_cpus if it hasn't been done yet */
+    mc->possible_cpu_arch_ids(machine);
 
-    cpu = machine->possible_cpus->cpus[0].cpu;
-    assert(cpu); /* Boot cpu is always present */
-    cpu_type = object_get_typename(cpu);
     for (i = 0; i < machine->possible_cpus->len; i++) {
+        Object *cpu;
         HotpluggableCPUList *list_item = g_new0(typeof(*list_item), 1);
         HotpluggableCPU *cpu_item = g_new0(typeof(*cpu_item), 1);
 
-        cpu_item->type = g_strdup(cpu_type);
+        cpu_item->type = g_strdup(machine->possible_cpus->cpus[i].type);
         cpu_item->vcpus_count = machine->possible_cpus->cpus[i].vcpus_count;
         cpu_item->props = g_memdup(&machine->possible_cpus->cpus[i].props,
                                    sizeof(*cpu_item->props));
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 11112951a5..f739753e3a 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -253,19 +253,31 @@ void qdev_set_legacy_instance_id(DeviceState *dev, int alias_id,
     dev->alias_required_for_version = required_for_version;
 }
 
+HotplugHandler *qdev_get_machine_hotplug_handler(DeviceState *dev)
+{
+    MachineState *machine;
+    MachineClass *mc;
+    Object *m_obj = qdev_get_machine();
+
+    if (object_dynamic_cast(m_obj, TYPE_MACHINE)) {
+        machine = MACHINE(m_obj);
+        mc = MACHINE_GET_CLASS(machine);
+        if (mc->get_hotplug_handler) {
+            return mc->get_hotplug_handler(machine, dev);
+        }
+    }
+
+    return NULL;
+}
+
 HotplugHandler *qdev_get_hotplug_handler(DeviceState *dev)
 {
-    HotplugHandler *hotplug_ctrl = NULL;
+    HotplugHandler *hotplug_ctrl;
 
     if (dev->parent_bus && dev->parent_bus->hotplug_handler) {
         hotplug_ctrl = dev->parent_bus->hotplug_handler;
-    } else if (object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
-        MachineState *machine = MACHINE(qdev_get_machine());
-        MachineClass *mc = MACHINE_GET_CLASS(machine);
-
-        if (mc->get_hotplug_handler) {
-            hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
-        }
+    } else {
+        hotplug_ctrl = qdev_get_machine_hotplug_handler(dev);
     }
     return hotplug_ctrl;
 }