aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/arm/virt.c3
-rw-r--r--hw/core/machine.c43
-rw-r--r--hw/i386/pc_q35.c3
-rw-r--r--hw/ppc/e500plat.c4
-rw-r--r--hw/ppc/spapr.c3
-rw-r--r--hw/xen/xen_backend.c7
-rw-r--r--include/hw/boards.h5
7 files changed, 48 insertions, 20 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index 543f9bd6cc..7549895fd2 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -1591,7 +1591,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
* configuration of the particular instance.
*/
mc->max_cpus = 255;
- mc->has_dynamic_sysbus = true;
+ /*TODO: allow only sysbus devices that really work with this machine */
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SYS_BUS_DEVICE);
mc->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1;
mc->pci_allow_0_address = true;
diff --git a/hw/core/machine.c b/hw/core/machine.c
index c857f3f934..0320a8efa1 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -334,29 +334,44 @@ 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)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 5c6c608fcb..0505730a99 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -299,7 +299,8 @@ static void pc_q35_machine_options(MachineClass *m)
m->default_machine_opts = "firmware=bios-256k.bin";
m->default_display = "std";
m->no_floppy = 1;
- m->has_dynamic_sysbus = true;
+ /*TODO: allow only sysbus devices that really work with this machine */
+ machine_class_allow_dynamic_sysbus_dev(m, TYPE_SYS_BUS_DEVICE);
m->max_cpus = 288;
}
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index e59e80fb9e..438118c29b 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -15,6 +15,7 @@
#include "hw/boards.h"
#include "sysemu/device_tree.h"
#include "sysemu/kvm.h"
+#include "hw/sysbus.h"
#include "hw/pci/pci.h"
#include "hw/ppc/openpic.h"
#include "kvm_ppc.h"
@@ -63,7 +64,8 @@ static void e500plat_machine_init(MachineClass *mc)
mc->desc = "generic paravirt e500 platform";
mc->init = e500plat_init;
mc->max_cpus = 32;
- mc->has_dynamic_sysbus = true;
+ /*TODO: allow only sysbus devices that really work with this machine */
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SYS_BUS_DEVICE);
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("e500v2_v30");
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 499ab647d8..5847175fd9 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -3843,7 +3843,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
mc->default_boot_order = "";
mc->default_ram_size = 512 * M_BYTE;
mc->kvm_type = spapr_kvm_type;
- mc->has_dynamic_sysbus = true;
+ /*TODO: allow only sysbus devices that really work with this machine */
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SYS_BUS_DEVICE);
mc->pci_allow_0_address = true;
mc->get_hotplug_handler = spapr_get_hotplug_handler;
hc->pre_plug = spapr_machine_device_pre_plug;
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 0f849a26d2..82380ea9ee 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -564,7 +564,12 @@ static void xen_set_dynamic_sysbus(void)
ObjectClass *oc = object_get_class(machine);
MachineClass *mc = MACHINE_CLASS(oc);
- mc->has_dynamic_sysbus = true;
+ /*
+ * Emulate old mc->has_dynamic_sysbus=true assignment
+ *
+ *TODO: add only Xen devices to the list
+ */
+ machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SYS_BUS_DEVICE);
}
int xen_be_register(const char *type, struct XenDevOps *ops)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 156b16f7a6..041bc08971 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -76,6 +76,9 @@ void machine_set_cpu_numa_node(MachineState *machine,
const CpuInstanceProperties *props,
Error **errp);
+void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type);
+
+
/**
* CPUArchId:
* @arch_id - architecture-dependent CPU ID of present or possible CPU
@@ -179,7 +182,6 @@ struct MachineClass {
no_floppy:1,
no_cdrom:1,
no_sdcard:1,
- has_dynamic_sysbus:1,
pci_allow_0_address:1,
legacy_fw_cfg_order:1;
int is_default;
@@ -197,6 +199,7 @@ struct MachineClass {
bool ignore_memory_transaction_failures;
int numa_mem_align_shift;
const char **valid_cpu_types;
+ strList *allowed_dynamic_sysbus_devices;
bool auto_enable_numa_with_memhp;
void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
int nb_nodes, ram_addr_t size);