diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/acpi/nvdimm.c | 7 | ||||
-rw-r--r-- | hw/arm/virt.c | 8 | ||||
-rw-r--r-- | hw/core/machine.c | 55 | ||||
-rw-r--r-- | hw/core/qdev.c | 28 | ||||
-rw-r--r-- | hw/i386/pc.c | 4 | ||||
-rw-r--r-- | hw/i386/pc_q35.c | 5 | ||||
-rw-r--r-- | hw/mem/nvdimm.c | 28 | ||||
-rw-r--r-- | hw/nvram/fw_cfg.c | 6 | ||||
-rw-r--r-- | hw/ppc/e500plat.c | 4 | ||||
-rw-r--r-- | hw/ppc/spapr.c | 15 | ||||
-rw-r--r-- | hw/s390x/s390-virtio-ccw.c | 1 | ||||
-rw-r--r-- | hw/xen/xen_backend.c | 2 |
12 files changed, 120 insertions, 43 deletions
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c index 6ceea196e7..59d6e4254c 100644 --- a/hw/acpi/nvdimm.c +++ b/hw/acpi/nvdimm.c @@ -138,6 +138,8 @@ struct NvdimmNfitMemDev { } QEMU_PACKED; typedef struct NvdimmNfitMemDev NvdimmNfitMemDev; +#define ACPI_NFIT_MEM_NOT_ARMED (1 << 3) + /* * NVDIMM Control Region Structure * @@ -284,6 +286,7 @@ static void nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev) { NvdimmNfitMemDev *nfit_memdev; + NVDIMMDevice *nvdimm = NVDIMM(OBJECT(dev)); uint64_t size = object_property_get_uint(OBJECT(dev), PC_DIMM_SIZE_PROP, NULL); int slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, @@ -312,6 +315,10 @@ nvdimm_build_structure_memdev(GArray *structures, DeviceState *dev) /* Only one interleave for PMEM. */ nfit_memdev->interleave_ways = cpu_to_le16(1); + + if (nvdimm->unarmed) { + nfit_memdev->flags |= cpu_to_le16(ACPI_NFIT_MEM_NOT_ARMED); + } } /* diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 543f9bd6cc..a4537af400 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -34,6 +34,8 @@ #include "hw/arm/arm.h" #include "hw/arm/primecell.h" #include "hw/arm/virt.h" +#include "hw/vfio/vfio-calxeda-xgmac.h" +#include "hw/vfio/vfio-amd-xgbe.h" #include "hw/devices.h" #include "net/net.h" #include "sysemu/block-backend.h" @@ -1357,7 +1359,7 @@ static void machvirt_init(MachineState *machine) break; } - cpuobj = object_new(machine->cpu_type); + cpuobj = object_new(possible_cpus->cpus[n].type); object_property_set_int(cpuobj, possible_cpus->cpus[n].arch_id, "mp-affinity", NULL); @@ -1573,6 +1575,7 @@ static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms) sizeof(CPUArchId) * max_cpus); ms->possible_cpus->len = max_cpus; for (n = 0; n < ms->possible_cpus->len; n++) { + ms->possible_cpus->cpus[n].type = ms->cpu_type; ms->possible_cpus->cpus[n].arch_id = virt_cpu_mp_affinity(vms, n); ms->possible_cpus->cpus[n].props.has_thread_id = true; @@ -1591,7 +1594,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; + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_CALXEDA_XGMAC); + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_VFIO_AMD_XGBE); 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..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; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 55686bf5d8..ccc50baa85 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1148,7 +1148,8 @@ void pc_cpus_init(PCMachineState *pcms) pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1; possible_cpus = mc->possible_cpu_arch_ids(ms); for (i = 0; i < smp_cpus; i++) { - pc_new_cpu(ms->cpu_type, possible_cpus->cpus[i].arch_id, &error_fatal); + pc_new_cpu(possible_cpus->cpus[i].type, possible_cpus->cpus[i].arch_id, + &error_fatal); } } @@ -2307,6 +2308,7 @@ static const CPUArchIdList *pc_possible_cpu_arch_ids(MachineState *ms) for (i = 0; i < ms->possible_cpus->len; i++) { X86CPUTopoInfo topo; + ms->possible_cpus->cpus[i].type = ms->cpu_type; ms->possible_cpus->cpus[i].vcpus_count = 1; ms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i); x86_topo_ids_from_apicid(ms->possible_cpus->cpus[i].arch_id, diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index 5c6c608fcb..ed3a0b8ff7 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -42,6 +42,8 @@ #include "exec/address-spaces.h" #include "hw/i386/pc.h" #include "hw/i386/ich9.h" +#include "hw/i386/amd_iommu.h" +#include "hw/i386/intel_iommu.h" #include "hw/smbios/smbios.h" #include "hw/ide/pci.h" #include "hw/ide/ahci.h" @@ -299,7 +301,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; + machine_class_allow_dynamic_sysbus_dev(m, TYPE_AMD_IOMMU_DEVICE); + machine_class_allow_dynamic_sysbus_dev(m, TYPE_INTEL_IOMMU_DEVICE); m->max_cpus = 288; } diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index 952fce5ec8..61e677f92f 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/visitor.h" +#include "qapi-visit.h" #include "hw/mem/nvdimm.h" static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name, @@ -64,11 +65,36 @@ out: error_propagate(errp, local_err); } +static bool nvdimm_get_unarmed(Object *obj, Error **errp) +{ + NVDIMMDevice *nvdimm = NVDIMM(obj); + + return nvdimm->unarmed; +} + +static void nvdimm_set_unarmed(Object *obj, bool value, Error **errp) +{ + NVDIMMDevice *nvdimm = NVDIMM(obj); + Error *local_err = NULL; + + if (memory_region_size(&nvdimm->nvdimm_mr)) { + error_setg(&local_err, "cannot change property value"); + goto out; + } + + nvdimm->unarmed = value; + + out: + error_propagate(errp, local_err); +} + static void nvdimm_init(Object *obj) { - object_property_add(obj, "label-size", "int", + object_property_add(obj, NVDIMM_LABLE_SIZE_PROP, "int", nvdimm_get_label_size, nvdimm_set_label_size, NULL, NULL, NULL); + object_property_add_bool(obj, NVDIMM_UNARMED_PROP, + nvdimm_get_unarmed, nvdimm_set_unarmed, NULL); } static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 753ac0e4ea..4313484b21 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -784,7 +784,7 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, * index and "i - 1" is the one being copied from, thus the * unusual start and end in the for statement. */ - for (i = count + 1; i > index; i--) { + for (i = count; i > index; i--) { s->files->f[i] = s->files->f[i - 1]; s->files->f[i].select = cpu_to_be16(FW_CFG_FILE_FIRST + i); s->entries[0][FW_CFG_FILE_FIRST + i] = @@ -833,7 +833,6 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, assert(s->files); index = be32_to_cpu(s->files->count); - assert(index < fw_cfg_file_slots(s)); for (i = 0; i < index; i++) { if (strcmp(filename, s->files->f[i].name) == 0) { @@ -843,6 +842,9 @@ void *fw_cfg_modify_file(FWCfgState *s, const char *filename, return ptr; } } + + assert(index < fw_cfg_file_slots(s)); + /* add new one */ fw_cfg_add_file_callback(s, filename, NULL, NULL, NULL, data, len, true); return NULL; diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c index e59e80fb9e..81d03e1038 100644 --- a/hw/ppc/e500plat.c +++ b/hw/ppc/e500plat.c @@ -12,9 +12,11 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "e500.h" +#include "hw/net/fsl_etsec/etsec.h" #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 +65,7 @@ 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; + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_ETSEC_COMMON); mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("e500v2_v30"); } diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 499ab647d8..a781dd22e7 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -2226,11 +2226,6 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) int boot_cores_nr = smp_cpus / smp_threads; int i; - if (!type) { - error_report("Unable to find sPAPR CPU Core definition"); - exit(1); - } - possible_cpus = mc->possible_cpu_arch_ids(machine); if (mc->has_hotpluggable_cpus) { if (smp_cpus % smp_threads) { @@ -3545,6 +3540,7 @@ static int64_t spapr_get_default_cpu_node_id(const MachineState *ms, int idx) static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine) { int i; + const char *core_type; int spapr_max_cores = max_cpus / smp_threads; MachineClass *mc = MACHINE_GET_CLASS(machine); @@ -3556,12 +3552,19 @@ static const CPUArchIdList *spapr_possible_cpu_arch_ids(MachineState *machine) return machine->possible_cpus; } + core_type = spapr_get_cpu_core_type(machine->cpu_type); + if (!core_type) { + error_report("Unable to find sPAPR CPU Core definition"); + exit(1); + } + machine->possible_cpus = g_malloc0(sizeof(CPUArchIdList) + sizeof(CPUArchId) * spapr_max_cores); machine->possible_cpus->len = spapr_max_cores; for (i = 0; i < machine->possible_cpus->len; i++) { int core_id = i * smp_threads; + machine->possible_cpus->cpus[i].type = core_type; machine->possible_cpus->cpus[i].vcpus_count = smp_threads; machine->possible_cpus->cpus[i].arch_id = core_id; machine->possible_cpus->cpus[i].props.has_core_id = true; @@ -3843,7 +3846,7 @@ 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; + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_SPAPR_PCI_HOST_BRIDGE); 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/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 35df7e19c5..3807dcb097 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -414,6 +414,7 @@ static const CPUArchIdList *s390_possible_cpu_arch_ids(MachineState *ms) sizeof(CPUArchId) * max_cpus); ms->possible_cpus->len = max_cpus; for (i = 0; i < ms->possible_cpus->len; i++) { + ms->possible_cpus->cpus[i].type = ms->cpu_type; ms->possible_cpus->cpus[i].vcpus_count = 1; ms->possible_cpus->cpus[i].arch_id = i; ms->possible_cpus->cpus[i].props.has_core_id = true; diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c index 0f849a26d2..7445b506ac 100644 --- a/hw/xen/xen_backend.c +++ b/hw/xen/xen_backend.c @@ -564,7 +564,7 @@ static void xen_set_dynamic_sysbus(void) ObjectClass *oc = object_get_class(machine); MachineClass *mc = MACHINE_CLASS(oc); - mc->has_dynamic_sysbus = true; + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_XENSYSDEV); } int xen_be_register(const char *type, struct XenDevOps *ops) |