diff options
Diffstat (limited to 'hw/core')
| -rw-r--r-- | hw/core/machine.c | 55 | ||||
| -rw-r--r-- | hw/core/qdev-properties.c | 61 | ||||
| -rw-r--r-- | hw/core/qdev.c | 28 |
3 files changed, 116 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-properties.c b/hw/core/qdev-properties.c index 1dc80fcea2..24c17800e3 100644 --- a/hw/core/qdev-properties.c +++ b/hw/core/qdev-properties.c @@ -10,6 +10,7 @@ #include "net/hub.h" #include "qapi/visitor.h" #include "chardev/char.h" +#include "qemu/uuid.h" void qdev_prop_set_after_realize(DeviceState *dev, const char *name, Error **errp) @@ -883,6 +884,66 @@ const PropertyInfo qdev_prop_pci_host_devaddr = { .set = set_pci_host_devaddr, }; +/* --- UUID --- */ + +static void get_uuid(Object *obj, Visitor *v, const char *name, void *opaque, + Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + QemuUUID *uuid = qdev_get_prop_ptr(dev, prop); + char buffer[UUID_FMT_LEN + 1]; + char *p = buffer; + + qemu_uuid_unparse(uuid, buffer); + + visit_type_str(v, name, &p, errp); +} + +#define UUID_VALUE_AUTO "auto" + +static void set_uuid(Object *obj, Visitor *v, const char *name, void *opaque, + Error **errp) +{ + DeviceState *dev = DEVICE(obj); + Property *prop = opaque; + QemuUUID *uuid = qdev_get_prop_ptr(dev, prop); + Error *local_err = NULL; + char *str; + + if (dev->realized) { + qdev_prop_set_after_realize(dev, name, errp); + return; + } + + visit_type_str(v, name, &str, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + if (!strcmp(str, UUID_VALUE_AUTO)) { + qemu_uuid_generate(uuid); + } else if (qemu_uuid_parse(str, uuid) < 0) { + error_set_from_qdev_prop_error(errp, EINVAL, dev, prop, str); + } + g_free(str); +} + +static void set_default_uuid_auto(Object *obj, const Property *prop) +{ + object_property_set_str(obj, UUID_VALUE_AUTO, prop->name, &error_abort); +} + +const PropertyInfo qdev_prop_uuid = { + .name = "str", + .description = "UUID (aka GUID) or \"" UUID_VALUE_AUTO + "\" for random value (default)", + .get = get_uuid, + .set = set_uuid, + .set_default_value = set_default_uuid_auto, +}; + /* --- support for array properties --- */ /* Used as an opaque for the object properties we add for each 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; } |