machine: Replace has_dynamic_sysbus with list of allowed devices

The existing has_dynamic_sysbus flag makes the machine accept
every user-creatable sysbus device type on the command-line.
Replace it with a list of allowed device types, so machines can
easily accept some sysbus devices while rejecting others.

To keep exactly the same behavior as before, the existing
has_dynamic_sysbus=true assignments are replaced with a
TYPE_SYS_BUS_DEVICE entry on the allowed list.  Other patches
will replace the TYPE_SYS_BUS_DEVICE entries with more specific
lists of devices.

Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: Marcel Apfelbaum <marcel@redhat.com>
Cc: "Michael S. Tsirkin" <mst@redhat.com>
Cc: Alexander Graf <agraf@suse.de>
Cc: David Gibson <david@gibson.dropbear.id.au>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Anthony Perard <anthony.perard@citrix.com>
Cc: qemu-arm@nongnu.org
Cc: qemu-ppc@nongnu.org
Cc: xen-devel@lists.xenproject.org
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
Message-Id: <20171125151610.20547-2-ehabkost@redhat.com>
Reviewed-by: Greg Kurz <groug@kaod.org>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
Eduardo Habkost 2017-11-25 13:16:05 -02:00
parent 2d19c65661
commit 0bd1909da6
7 changed files with 49 additions and 21 deletions

View File

@ -1591,7 +1591,8 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
* configuration of the particular instance. * configuration of the particular instance.
*/ */
mc->max_cpus = 255; 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->block_default_type = IF_VIRTIO;
mc->no_cdrom = 1; mc->no_cdrom = 1;
mc->pci_allow_0_address = true; mc->pci_allow_0_address = true;

View File

@ -334,29 +334,44 @@ static bool machine_get_enforce_config_section(Object *obj, Error **errp)
return ms->enforce_config_section; 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", strList *item = g_new0(strList, 1);
object_class_get_name(object_get_class(OBJECT(sbdev))));
exit(1); item->value = g_strdup(type);
item->next = mc->allowed_dynamic_sysbus_devices;
mc->allowed_dynamic_sysbus_devices = item;
}
static void validate_sysbus_device(SysBusDevice *sbdev, void *opaque)
{
MachineState *machine = opaque;
MachineClass *mc = MACHINE_GET_CLASS(machine);
bool allowed = false;
strList *wl;
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) static void machine_init_notify(Notifier *notifier, void *data)
{ {
Object *machine = qdev_get_machine(); MachineState *machine = MACHINE(qdev_get_machine());
ObjectClass *oc = object_get_class(machine);
MachineClass *mc = MACHINE_CLASS(oc);
if (mc->has_dynamic_sysbus) {
/* Our machine can handle dynamic sysbus devices, we're all good */
return;
}
/* /*
* Loop through all dynamically created devices and check whether there * Loop through all dynamically created sysbus devices and check if they are
* are sysbus devices among them. If there are, error out. * 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) HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)

View File

@ -299,7 +299,8 @@ static void pc_q35_machine_options(MachineClass *m)
m->default_machine_opts = "firmware=bios-256k.bin"; m->default_machine_opts = "firmware=bios-256k.bin";
m->default_display = "std"; m->default_display = "std";
m->no_floppy = 1; 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; m->max_cpus = 288;
} }

View File

@ -15,6 +15,7 @@
#include "hw/boards.h" #include "hw/boards.h"
#include "sysemu/device_tree.h" #include "sysemu/device_tree.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "hw/sysbus.h"
#include "hw/pci/pci.h" #include "hw/pci/pci.h"
#include "hw/ppc/openpic.h" #include "hw/ppc/openpic.h"
#include "kvm_ppc.h" #include "kvm_ppc.h"
@ -63,7 +64,8 @@ static void e500plat_machine_init(MachineClass *mc)
mc->desc = "generic paravirt e500 platform"; mc->desc = "generic paravirt e500 platform";
mc->init = e500plat_init; mc->init = e500plat_init;
mc->max_cpus = 32; 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"); mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("e500v2_v30");
} }

View File

@ -3843,7 +3843,8 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
mc->default_boot_order = ""; mc->default_boot_order = "";
mc->default_ram_size = 512 * M_BYTE; mc->default_ram_size = 512 * M_BYTE;
mc->kvm_type = spapr_kvm_type; 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->pci_allow_0_address = true;
mc->get_hotplug_handler = spapr_get_hotplug_handler; mc->get_hotplug_handler = spapr_get_hotplug_handler;
hc->pre_plug = spapr_machine_device_pre_plug; hc->pre_plug = spapr_machine_device_pre_plug;

View File

@ -564,7 +564,12 @@ static void xen_set_dynamic_sysbus(void)
ObjectClass *oc = object_get_class(machine); ObjectClass *oc = object_get_class(machine);
MachineClass *mc = MACHINE_CLASS(oc); 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) int xen_be_register(const char *type, struct XenDevOps *ops)

View File

@ -76,6 +76,9 @@ void machine_set_cpu_numa_node(MachineState *machine,
const CpuInstanceProperties *props, const CpuInstanceProperties *props,
Error **errp); Error **errp);
void machine_class_allow_dynamic_sysbus_dev(MachineClass *mc, const char *type);
/** /**
* CPUArchId: * CPUArchId:
* @arch_id - architecture-dependent CPU ID of present or possible CPU * @arch_id - architecture-dependent CPU ID of present or possible CPU
@ -179,7 +182,6 @@ struct MachineClass {
no_floppy:1, no_floppy:1,
no_cdrom:1, no_cdrom:1,
no_sdcard:1, no_sdcard:1,
has_dynamic_sysbus:1,
pci_allow_0_address:1, pci_allow_0_address:1,
legacy_fw_cfg_order:1; legacy_fw_cfg_order:1;
int is_default; int is_default;
@ -197,6 +199,7 @@ struct MachineClass {
bool ignore_memory_transaction_failures; bool ignore_memory_transaction_failures;
int numa_mem_align_shift; int numa_mem_align_shift;
const char **valid_cpu_types; const char **valid_cpu_types;
strList *allowed_dynamic_sysbus_devices;
bool auto_enable_numa_with_memhp; bool auto_enable_numa_with_memhp;
void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes, void (*numa_auto_assign_ram)(MachineClass *mc, NodeInfo *nodes,
int nb_nodes, ram_addr_t size); int nb_nodes, ram_addr_t size);