diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2018-10-25 20:17:12 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-10-25 20:17:12 +0100 |
commit | 6e6ffc9ffa88eb6af6f39931f6b495805b150c95 (patch) | |
tree | 53a644b33cb096e07a48a7a9e5efba5feea2e6a3 | |
parent | 808ebd66e467f77c0d1f8c6346235f81e9c99cf2 (diff) | |
parent | 8fa922c241e63f018f5b55c03ac494ae3d5fe594 (diff) |
Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging
Machine queue, 2018-10-25
* sysbus init/realize cleanups
(Cédric Le Goater, Philippe Mathieu-Daudé)
* memory-device refactoring (David Hildenbrand)
* -smp: deprecate incorrect CPUs topology (Igor Mammedov)
* -numa parsing cleanups (Markus Armbruster)
* Fix hostmem-file memory leak (Zhang Yi)
* Typo fix (Li Qiang)
# gpg: Signature made Thu 25 Oct 2018 14:31:46 BST
# gpg: using RSA key 2807936F984DC5A6
# 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: (43 commits)
net: xgmac: convert SysBus init method to a realize method
net: stellaris_enet: add a reset method
net: stellaris_enet: convert SysBus init method to a realize method
net: smc91c111: convert SysBus init method to a realize method
net: opencores_eth: convert SysBus init method to a realize method
net: mipsnet: convert SysBus init method to a realize method
net: milkymist_minimac2: convert SysBus init method to a realize method
net: lance: convert SysBus init method to a realize method
net: lan9118: convert SysBus init method to a realize method
net: etraxfs_eth: add a reset method
net: etraxfs_eth: convert SysBus init method to a realize method
memory-device: trace when pre_plugging/plugging/unplugging
memory-device: complete factoring out unplug handling
memory-device: complete factoring out plug handling
memory-device: complete factoring out pre_plug handling
memory-device: add device class function set_addr()
memory-device: drop get_region_size()
memory-device: factor out get_memory_region() from pc-dimm
memory-device: add and use memory_device_get_region_size()
memory-device: document MemoryDeviceClass
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
38 files changed, 344 insertions, 286 deletions
diff --git a/backends/hostmem-file.c b/backends/hostmem-file.c index e64074954f..639c8d4307 100644 --- a/backends/hostmem-file.c +++ b/backends/hostmem-file.c @@ -145,20 +145,26 @@ static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp) HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o); if (host_memory_backend_mr_inited(backend)) { + char *path = object_get_canonical_path_component(o); + error_setg(errp, "cannot change property 'pmem' of %s '%s'", object_get_typename(o), - object_get_canonical_path_component(o)); + path); + g_free(path); return; } #ifndef CONFIG_LIBPMEM if (value) { Error *local_err = NULL; + char *path = object_get_canonical_path_component(o); + error_setg(&local_err, "Lack of libpmem support while setting the 'pmem=on'" " of %s '%s'. We can't ensure data persistence.", object_get_typename(o), - object_get_canonical_path_component(o)); + path); + g_free(path); error_propagate(errp, local_err); return; } diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak index 210cff2781..64c998c4c8 100644 --- a/default-configs/i386-softmmu.mak +++ b/default-configs/i386-softmmu.mak @@ -51,7 +51,8 @@ CONFIG_PCI_Q35=y CONFIG_APIC=y CONFIG_IOAPIC=y CONFIG_PVPANIC=y -CONFIG_MEM_HOTPLUG=y +CONFIG_MEM_DEVICE=y +CONFIG_DIMM=y CONFIG_NVDIMM=y CONFIG_ACPI_NVDIMM=y CONFIG_PCIE_PORT=y diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak index b94af6c7c6..f550573782 100644 --- a/default-configs/ppc64-softmmu.mak +++ b/default-configs/ppc64-softmmu.mak @@ -16,4 +16,5 @@ CONFIG_VIRTIO_VGA=y CONFIG_XICS=$(CONFIG_PSERIES) CONFIG_XICS_SPAPR=$(CONFIG_PSERIES) CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM)) -CONFIG_MEM_HOTPLUG=y +CONFIG_MEM_DEVICE=y +CONFIG_DIMM=y diff --git a/default-configs/sparc64-softmmu.mak b/default-configs/sparc64-softmmu.mak index 52edafe547..ce63d47046 100644 --- a/default-configs/sparc64-softmmu.mak +++ b/default-configs/sparc64-softmmu.mak @@ -16,5 +16,4 @@ CONFIG_SIMBA=y CONFIG_SUNHME=y CONFIG_MC146818RTC=y CONFIG_ISA_TESTDEV=y -CONFIG_EMPTY_SLOT=y CONFIG_SUN4V_RTC=y diff --git a/hw/Makefile.objs b/hw/Makefile.objs index 30722ccf98..39d882af6f 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -34,7 +34,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += vfio/ devices-dirs-$(CONFIG_SOFTMMU) += virtio/ devices-dirs-$(CONFIG_SOFTMMU) += watchdog/ devices-dirs-$(CONFIG_SOFTMMU) += xen/ -devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/ +devices-dirs-$(CONFIG_MEM_DEVICE) += mem/ devices-dirs-$(CONFIG_SOFTMMU) += smbios/ devices-dirs-y += core/ common-obj-y += $(devices-dirs-y) diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index d74b5b55e1..8004afe45b 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -932,23 +932,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus, return b; } -static int typhoon_pcihost_init(SysBusDevice *dev) -{ - return 0; -} - -static void typhoon_pcihost_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = typhoon_pcihost_init; -} - static const TypeInfo typhoon_pcihost_info = { .name = TYPE_TYPHOON_PCI_HOST_BRIDGE, .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(TyphoonState), - .class_init = typhoon_pcihost_class_init, }; static void typhoon_iommu_memory_region_class_init(ObjectClass *klass, diff --git a/hw/core/machine.c b/hw/core/machine.c index 1987557833..da50ad6de7 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -636,7 +636,7 @@ static void machine_class_init(ObjectClass *oc, void *data) machine_get_memory_encryption, machine_set_memory_encryption, &error_abort); object_class_property_set_description(oc, "memory-encryption", - "Set memory encyption object to use", &error_abort); + "Set memory encryption object to use", &error_abort); } static void machine_class_base_init(ObjectClass *oc, void *data) diff --git a/hw/hppa/dino.c b/hw/hppa/dino.c index 564b938e3a..31e09942b5 100644 --- a/hw/hppa/dino.c +++ b/hw/hppa/dino.c @@ -488,17 +488,10 @@ PCIBus *dino_init(MemoryRegion *addr_space, return b; } -static int dino_pcihost_init(SysBusDevice *dev) -{ - return 0; -} - static void dino_pcihost_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - k->init = dino_pcihost_init; dc->vmsd = &vmstate_dino; } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index eab8572f2a..f095725dba 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1704,7 +1704,7 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, return; } - pc_dimm_pre_plug(dev, MACHINE(hotplug_dev), + pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), pcmc->enforce_aligned_dimm ? NULL : &legacy_align, errp); } @@ -1716,7 +1716,7 @@ static void pc_memory_plug(HotplugHandler *hotplug_dev, PCMachineState *pcms = PC_MACHINE(hotplug_dev); bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM); - pc_dimm_plug(dev, MACHINE(pcms), &local_err); + pc_dimm_plug(PC_DIMM(dev), MACHINE(pcms), &local_err); if (local_err) { goto out; } @@ -1776,7 +1776,7 @@ static void pc_memory_unplug(HotplugHandler *hotplug_dev, goto out; } - pc_dimm_unplug(dev, MACHINE(pcms)); + pc_dimm_unplug(PC_DIMM(dev), MACHINE(pcms)); object_unparent(OBJECT(dev)); out: diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs index 10be4df2a2..3e2f7c5ca2 100644 --- a/hw/mem/Makefile.objs +++ b/hw/mem/Makefile.objs @@ -1,3 +1,3 @@ -common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o -common-obj-$(CONFIG_MEM_HOTPLUG) += memory-device.o +common-obj-$(CONFIG_DIMM) += pc-dimm.o +common-obj-$(CONFIG_MEM_DEVICE) += memory-device.o common-obj-$(CONFIG_NVDIMM) += nvdimm.o diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c index 6de4f70bb4..7de1ccd497 100644 --- a/hw/mem/memory-device.c +++ b/hw/mem/memory-device.c @@ -17,6 +17,7 @@ #include "qemu/range.h" #include "hw/virtio/vhost.h" #include "sysemu/kvm.h" +#include "trace.h" static gint memory_device_addr_sort(gconstpointer a, gconstpointer b) { @@ -57,10 +58,9 @@ static int memory_device_used_region_size(Object *obj, void *opaque) if (object_dynamic_cast(obj, TYPE_MEMORY_DEVICE)) { const DeviceState *dev = DEVICE(obj); const MemoryDeviceState *md = MEMORY_DEVICE(obj); - const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj); if (dev->realized) { - *size += mdc->get_region_size(md); + *size += memory_device_get_region_size(md, &error_abort); } } @@ -87,16 +87,17 @@ static void memory_device_check_addable(MachineState *ms, uint64_t size, memory_device_used_region_size(OBJECT(ms), &used_region_size); if (used_region_size + size > ms->maxram_size - ms->ram_size) { error_setg(errp, "not enough space, currently 0x%" PRIx64 - " in use of total hot pluggable 0x" RAM_ADDR_FMT, + " in use of total space for memory devices 0x" RAM_ADDR_FMT, used_region_size, ms->maxram_size - ms->ram_size); return; } } -uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, - uint64_t align, uint64_t size, - Error **errp) +static uint64_t memory_device_get_free_addr(MachineState *ms, + const uint64_t *hint, + uint64_t align, uint64_t size, + Error **errp) { uint64_t address_space_start, address_space_end; GSList *list = NULL, *item; @@ -120,7 +121,7 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, /* address_space_start indicates the maximum alignment we expect */ if (QEMU_ALIGN_UP(address_space_start, align) != address_space_start) { - error_setg(errp, "the alignment (0%" PRIx64 ") is not supported", + error_setg(errp, "the alignment (0x%" PRIx64 ") is not supported", align); return 0; } @@ -145,11 +146,12 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, if (hint) { new_addr = *hint; if (new_addr < address_space_start) { - error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64 - "] at 0x%" PRIx64, new_addr, size, address_space_start); + error_setg(errp, "can't add memory device [0x%" PRIx64 ":0x%" PRIx64 + "] before 0x%" PRIx64, new_addr, size, + address_space_start); return 0; } else if ((new_addr + size) > address_space_end) { - error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64 + error_setg(errp, "can't add memory device [0x%" PRIx64 ":0x%" PRIx64 "] beyond 0x%" PRIx64, new_addr, size, address_space_end); return 0; @@ -166,15 +168,13 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, uint64_t md_size, md_addr; md_addr = mdc->get_addr(md); - md_size = mdc->get_region_size(md); - if (*errp) { - goto out; - } + md_size = memory_device_get_region_size(md, &error_abort); if (ranges_overlap(md_addr, md_size, new_addr, size)) { if (hint) { const DeviceState *d = DEVICE(md); - error_setg(errp, "address range conflicts with '%s'", d->id); + error_setg(errp, "address range conflicts with memory device" + " id='%s'", d->id ? d->id : "(unnamed)"); goto out; } new_addr = QEMU_ALIGN_UP(md_addr + md_size, align); @@ -232,7 +232,7 @@ static int memory_device_plugged_size(Object *obj, void *opaque) const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj); if (dev->realized) { - *size += mdc->get_plugged_size(md); + *size += mdc->get_plugged_size(md, &error_abort); } } @@ -249,22 +249,83 @@ uint64_t get_plugged_memory_size(void) return size; } -void memory_device_plug_region(MachineState *ms, MemoryRegion *mr, - uint64_t addr) +void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms, + const uint64_t *legacy_align, Error **errp) +{ + const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md); + Error *local_err = NULL; + uint64_t addr, align; + MemoryRegion *mr; + + mr = mdc->get_memory_region(md, &local_err); + if (local_err) { + goto out; + } + + align = legacy_align ? *legacy_align : memory_region_get_alignment(mr); + addr = mdc->get_addr(md); + addr = memory_device_get_free_addr(ms, !addr ? NULL : &addr, align, + memory_region_size(mr), &local_err); + if (local_err) { + goto out; + } + mdc->set_addr(md, addr, &local_err); + if (!local_err) { + trace_memory_device_pre_plug(DEVICE(md)->id ? DEVICE(md)->id : "", + addr); + } +out: + error_propagate(errp, local_err); +} + +void memory_device_plug(MemoryDeviceState *md, MachineState *ms) { - /* we expect a previous call to memory_device_get_free_addr() */ + const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md); + const uint64_t addr = mdc->get_addr(md); + MemoryRegion *mr; + + /* + * We expect that a previous call to memory_device_pre_plug() succeeded, so + * it can't fail at this point. + */ + mr = mdc->get_memory_region(md, &error_abort); g_assert(ms->device_memory); memory_region_add_subregion(&ms->device_memory->mr, addr - ms->device_memory->base, mr); + trace_memory_device_plug(DEVICE(md)->id ? DEVICE(md)->id : "", addr); } -void memory_device_unplug_region(MachineState *ms, MemoryRegion *mr) +void memory_device_unplug(MemoryDeviceState *md, MachineState *ms) { - /* we expect a previous call to memory_device_get_free_addr() */ + const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md); + MemoryRegion *mr; + + /* + * We expect that a previous call to memory_device_pre_plug() succeeded, so + * it can't fail at this point. + */ + mr = mdc->get_memory_region(md, &error_abort); g_assert(ms->device_memory); memory_region_del_subregion(&ms->device_memory->mr, mr); + trace_memory_device_unplug(DEVICE(md)->id ? DEVICE(md)->id : "", + mdc->get_addr(md)); +} + +uint64_t memory_device_get_region_size(const MemoryDeviceState *md, + Error **errp) +{ + const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md); + MemoryRegion *mr; + + /* dropping const here is fine as we don't touch the memory region */ + mr = mdc->get_memory_region((MemoryDeviceState *)md, errp); + if (!mr) { + return 0; + } + + return memory_region_size(mr); } static const TypeInfo memory_device_info = { diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index 1c6674c4ed..49324f3fae 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -27,6 +27,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "hw/mem/nvdimm.h" +#include "hw/mem/memory-device.h" static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) @@ -118,9 +119,10 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp) nvdimm->nvdimm_mr->align = align; } -static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp) +static MemoryRegion *nvdimm_md_get_memory_region(MemoryDeviceState *md, + Error **errp) { - NVDIMMDevice *nvdimm = NVDIMM(dimm); + NVDIMMDevice *nvdimm = NVDIMM(md); Error *local_err = NULL; if (!nvdimm->nvdimm_mr) { @@ -190,11 +192,12 @@ static Property nvdimm_properties[] = { static void nvdimm_class_init(ObjectClass *oc, void *data) { PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc); + MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc); NVDIMMClass *nvc = NVDIMM_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); ddc->realize = nvdimm_realize; - ddc->get_memory_region = nvdimm_get_memory_region; + mdc->get_memory_region = nvdimm_md_get_memory_region; dc->props = nvdimm_properties; nvc->read_label_data = nvdimm_read_label_data; diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index fb6bcaedc4..0c9b9e8292 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -29,72 +29,47 @@ static int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp); -void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine, +void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine, const uint64_t *legacy_align, Error **errp) { - PCDIMMDevice *dimm = PC_DIMM(dev); - PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); Error *local_err = NULL; - MemoryRegion *mr; - uint64_t addr, align; int slot; - slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP, + slot = object_property_get_int(OBJECT(dimm), PC_DIMM_SLOT_PROP, &error_abort); slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot, machine->ram_slots, &local_err); if (local_err) { goto out; } - object_property_set_int(OBJECT(dev), slot, PC_DIMM_SLOT_PROP, &error_abort); + object_property_set_int(OBJECT(dimm), slot, PC_DIMM_SLOT_PROP, + &error_abort); trace_mhp_pc_dimm_assigned_slot(slot); - mr = ddc->get_memory_region(dimm, &local_err); - if (local_err) { - goto out; - } - - align = legacy_align ? *legacy_align : memory_region_get_alignment(mr); - addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP, - &error_abort); - addr = memory_device_get_free_addr(machine, !addr ? NULL : &addr, align, - memory_region_size(mr), &local_err); - if (local_err) { - goto out; - } - trace_mhp_pc_dimm_assigned_address(addr); - object_property_set_uint(OBJECT(dev), addr, PC_DIMM_ADDR_PROP, - &error_abort); + memory_device_pre_plug(MEMORY_DEVICE(dimm), machine, legacy_align, + &local_err); out: error_propagate(errp, local_err); } -void pc_dimm_plug(DeviceState *dev, MachineState *machine, Error **errp) +void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp) { - PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm, &error_abort); - MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort); - uint64_t addr; - - addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP, - &error_abort); - memory_device_plug_region(machine, mr, addr); - vmstate_register_ram(vmstate_mr, dev); + memory_device_plug(MEMORY_DEVICE(dimm), machine); + vmstate_register_ram(vmstate_mr, DEVICE(dimm)); } -void pc_dimm_unplug(DeviceState *dev, MachineState *machine) +void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine) { - PCDIMMDevice *dimm = PC_DIMM(dev); PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm, &error_abort); - MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort); - memory_device_unplug_region(machine, mr); - vmstate_unregister_ram(vmstate_mr, dev); + memory_device_unplug(MEMORY_DEVICE(dimm), machine); + vmstate_unregister_ram(vmstate_mr, DEVICE(dimm)); } static int pc_dimm_slot2bitmap(Object *obj, void *opaque) @@ -163,16 +138,14 @@ static Property pc_dimm_properties[] = { static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { + Error *local_err = NULL; uint64_t value; - MemoryRegion *mr; - PCDIMMDevice *dimm = PC_DIMM(obj); - PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj); - mr = ddc->get_memory_region(dimm, errp); - if (!mr) { + value = memory_device_get_region_size(MEMORY_DEVICE(obj), &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } - value = memory_region_size(mr); visit_type_uint64(v, name, &value, errp); } @@ -236,19 +209,16 @@ static uint64_t pc_dimm_md_get_addr(const MemoryDeviceState *md) return dimm->addr; } -static uint64_t pc_dimm_md_get_region_size(const MemoryDeviceState *md) +static void pc_dimm_md_set_addr(MemoryDeviceState *md, uint64_t addr, + Error **errp) { - /* dropping const here is fine as we don't touch the memory region */ - PCDIMMDevice *dimm = PC_DIMM(md); - const PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(md); - MemoryRegion *mr; - - mr = ddc->get_memory_region(dimm, &error_abort); - if (!mr) { - return 0; - } + object_property_set_uint(OBJECT(md), addr, PC_DIMM_ADDR_PROP, errp); +} - return memory_region_size(mr); +static MemoryRegion *pc_dimm_md_get_memory_region(MemoryDeviceState *md, + Error **errp) +{ + return pc_dimm_get_memory_region(PC_DIMM(md), errp); } static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md, @@ -292,13 +262,13 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data) dc->props = pc_dimm_properties; dc->desc = "DIMM memory module"; - ddc->get_memory_region = pc_dimm_get_memory_region; ddc->get_vmstate_memory_region = pc_dimm_get_memory_region; mdc->get_addr = pc_dimm_md_get_addr; + mdc->set_addr = pc_dimm_md_set_addr; /* for a dimm plugged_size == region_size */ - mdc->get_plugged_size = pc_dimm_md_get_region_size; - mdc->get_region_size = pc_dimm_md_get_region_size; + mdc->get_plugged_size = memory_device_get_region_size; + mdc->get_memory_region = pc_dimm_md_get_memory_region; mdc->fill_device_info = pc_dimm_md_fill_device_info; } diff --git a/hw/mem/trace-events b/hw/mem/trace-events index e150dcc497..0f2f278ff2 100644 --- a/hw/mem/trace-events +++ b/hw/mem/trace-events @@ -2,4 +2,7 @@ # hw/mem/pc-dimm.c mhp_pc_dimm_assigned_slot(int slot) "%d" -mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64 +# hw/mem/memory-device.c +memory_device_pre_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64 +memory_device_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64 +memory_device_unplug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64 diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c index 24ad0ad024..1cd8aac658 100644 --- a/hw/mips/gt64xxx_pci.c +++ b/hw/mips/gt64xxx_pci.c @@ -992,9 +992,9 @@ static void gt64120_pci_set_irq(void *opaque, int irq_num, int level) } -static void gt64120_reset(void *opaque) +static void gt64120_reset(DeviceState *dev) { - GT64120State *s = opaque; + GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev); /* FIXME: Malta specific hw assumptions ahead */ @@ -1184,16 +1184,6 @@ PCIBus *gt64120_register(qemu_irq *pic) return phb->bus; } -static int gt64120_init(SysBusDevice *dev) -{ - GT64120State *s; - - s = GT64120_PCI_HOST_BRIDGE(dev); - - qemu_register_reset(gt64120_reset, s); - return 0; -} - static void gt64120_pci_realize(PCIDevice *d, Error **errp) { /* FIXME: Malta specific hw assumptions ahead */ @@ -1241,9 +1231,9 @@ static const TypeInfo gt64120_pci_info = { static void gt64120_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); - sdc->init = gt64120_init; + set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->reset = gt64120_reset; dc->vmsd = &vmstate_gt64120; } diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index 29b90bacf3..c1cf0fe12e 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -1422,23 +1422,10 @@ void mips_malta_init(MachineState *machine) pci_vga_init(pci_bus); } -static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev) -{ - return 0; -} - -static void mips_malta_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - - k->init = mips_malta_sysbus_device_init; -} - static const TypeInfo mips_malta_device = { .name = TYPE_MIPS_MALTA, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(MaltaState), - .class_init = mips_malta_class_init, }; static void mips_malta_machine_init(MachineClass *mc) diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c index a6932432b1..36855804db 100644 --- a/hw/net/etraxfs_eth.c +++ b/hw/net/etraxfs_eth.c @@ -23,6 +23,7 @@ */ #include "qemu/osdep.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "net/net.h" #include "hw/cris/etraxfs.h" @@ -126,7 +127,7 @@ tdk_write(struct qemu_phy *phy, unsigned int req, unsigned int data) } static void -tdk_init(struct qemu_phy *phy) +tdk_reset(struct qemu_phy *phy) { phy->regs[0] = 0x3100; /* PHY Id. */ @@ -135,9 +136,6 @@ tdk_init(struct qemu_phy *phy) /* Autonegotiation advertisement reg. */ phy->regs[4] = 0x01E1; phy->link = 1; - - phy->read = tdk_read; - phy->write = tdk_write; } struct qemu_mdio @@ -584,14 +582,35 @@ static NetClientInfo net_etraxfs_info = { .link_status_changed = eth_set_link, }; -static int fs_eth_init(SysBusDevice *sbd) +static void etraxfs_eth_reset(DeviceState *dev) +{ + ETRAXFSEthState *s = ETRAX_FS_ETH(dev); + + memset(s->regs, 0, sizeof(s->regs)); + memset(s->macaddr, 0, sizeof(s->macaddr)); + s->duplex_mismatch = 0; + + s->mdio_bus.mdc = 0; + s->mdio_bus.mdio = 0; + s->mdio_bus.state = 0; + s->mdio_bus.drive = 0; + s->mdio_bus.cnt = 0; + s->mdio_bus.addr = 0; + s->mdio_bus.opc = 0; + s->mdio_bus.req = 0; + s->mdio_bus.data = 0; + + tdk_reset(&s->phy); +} + +static void etraxfs_eth_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); ETRAXFSEthState *s = ETRAX_FS_ETH(dev); if (!s->dma_out || !s->dma_in) { - error_report("Unconnected ETRAX-FS Ethernet MAC"); - return -1; + error_setg(errp, "Unconnected ETRAX-FS Ethernet MAC"); + return; } s->dma_out->client.push = eth_tx_push; @@ -608,10 +627,9 @@ static int fs_eth_init(SysBusDevice *sbd) object_get_typename(OBJECT(s)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); - - tdk_init(&s->phy); + s->phy.read = tdk_read; + s->phy.write = tdk_write; mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr); - return 0; } static Property etraxfs_eth_properties[] = { @@ -625,9 +643,9 @@ static Property etraxfs_eth_properties[] = { static void etraxfs_eth_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = fs_eth_init; + dc->realize = etraxfs_eth_realize; + dc->reset = etraxfs_eth_reset; dc->props = etraxfs_eth_properties; /* Reason: pointer properties "dma_out", "dma_in" */ dc->user_creatable = false; diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index b9032dac59..a6269d9463 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c @@ -1320,9 +1320,9 @@ static NetClientInfo net_lan9118_info = { .link_status_changed = lan9118_set_link, }; -static int lan9118_init1(SysBusDevice *sbd) +static void lan9118_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); lan9118_state *s = LAN9118(dev); QEMUBH *bh; int i; @@ -1349,8 +1349,6 @@ static int lan9118_init1(SysBusDevice *sbd) s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT); ptimer_set_freq(s->timer, 10000); ptimer_set_limit(s->timer, 0xffff, 1); - - return 0; } static Property lan9118_properties[] = { @@ -1362,12 +1360,11 @@ static Property lan9118_properties[] = { static void lan9118_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = lan9118_init1; dc->reset = lan9118_reset; dc->props = lan9118_properties; dc->vmsd = &vmstate_lan9118; + dc->realize = lan9118_realize; } static const TypeInfo lan9118_info = { diff --git a/hw/net/lance.c b/hw/net/lance.c index a08d5ac6a8..f987b2fd18 100644 --- a/hw/net/lance.c +++ b/hw/net/lance.c @@ -97,9 +97,9 @@ static const VMStateDescription vmstate_lance = { } }; -static int lance_init(SysBusDevice *sbd) +static void lance_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); SysBusPCNetState *d = SYSBUS_PCNET(dev); PCNetState *s = &d->state; @@ -115,7 +115,6 @@ static int lance_init(SysBusDevice *sbd) s->phys_mem_read = ledma_memory_read; s->phys_mem_write = ledma_memory_write; pcnet_common_init(dev, s, &net_lance_info); - return 0; } static void lance_reset(DeviceState *dev) @@ -144,9 +143,8 @@ static Property lance_properties[] = { static void lance_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = lance_init; + dc->realize = lance_realize; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->fw_name = "ethernet"; dc->reset = lance_reset; diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c index 3eaa19dfde..7ef1daee41 100644 --- a/hw/net/milkymist-minimac2.c +++ b/hw/net/milkymist-minimac2.c @@ -452,9 +452,9 @@ static NetClientInfo net_milkymist_minimac2_info = { .receive = minimac2_rx, }; -static int milkymist_minimac2_init(SysBusDevice *sbd) +static void milkymist_minimac2_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(dev); size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE); @@ -479,8 +479,6 @@ static int milkymist_minimac2_init(SysBusDevice *sbd) s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); - - return 0; } static const VMStateDescription vmstate_milkymist_minimac2_mdio = { @@ -521,9 +519,8 @@ static Property milkymist_minimac2_properties[] = { static void milkymist_minimac2_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_minimac2_init; + dc->realize = milkymist_minimac2_realize; dc->reset = milkymist_minimac2_reset; dc->vmsd = &vmstate_milkymist_minimac2; dc->props = milkymist_minimac2_properties; diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c index 5a63df7ccb..03b3104278 100644 --- a/hw/net/mipsnet.c +++ b/hw/net/mipsnet.c @@ -236,9 +236,9 @@ static const MemoryRegionOps mipsnet_ioport_ops = { .impl.max_access_size = 4, }; -static int mipsnet_sysbus_init(SysBusDevice *sbd) +static void mipsnet_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); MIPSnetState *s = MIPS_NET(dev); memory_region_init_io(&s->io, OBJECT(dev), &mipsnet_ioport_ops, s, @@ -249,8 +249,6 @@ static int mipsnet_sysbus_init(SysBusDevice *sbd) s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); - - return 0; } static void mipsnet_sysbus_reset(DeviceState *dev) @@ -267,9 +265,8 @@ static Property mipsnet_properties[] = { static void mipsnet_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = mipsnet_sysbus_init; + dc->realize = mipsnet_realize; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->desc = "MIPS Simulator network device"; dc->reset = mipsnet_sysbus_reset; diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c index d42b79c08c..d6f54f8d82 100644 --- a/hw/net/opencores_eth.c +++ b/hw/net/opencores_eth.c @@ -715,9 +715,9 @@ static const MemoryRegionOps open_eth_desc_ops = { .write = open_eth_desc_write, }; -static int sysbus_open_eth_init(SysBusDevice *sbd) +static void sysbus_open_eth_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); OpenEthState *s = OPEN_ETH(dev); memory_region_init_io(&s->reg_io, OBJECT(dev), &open_eth_reg_ops, s, @@ -732,7 +732,6 @@ static int sysbus_open_eth_init(SysBusDevice *sbd) s->nic = qemu_new_nic(&net_open_eth_info, &s->conf, object_get_typename(OBJECT(s)), dev->id, s); - return 0; } static void qdev_open_eth_reset(DeviceState *dev) @@ -750,9 +749,8 @@ static Property open_eth_properties[] = { static void open_eth_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = sysbus_open_eth_init; + dc->realize = sysbus_open_eth_realize; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); dc->desc = "Opencores 10/100 Mbit Ethernet"; dc->reset = qdev_open_eth_reset; diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c index d2fd2040e8..99da2d9297 100644 --- a/hw/net/smc91c111.c +++ b/hw/net/smc91c111.c @@ -766,9 +766,9 @@ static NetClientInfo net_smc91c111_info = { .receive = smc91c111_receive, }; -static int smc91c111_init1(SysBusDevice *sbd) +static void smc91c111_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); smc91c111_state *s = SMC91C111(dev); memory_region_init_io(&s->mmio, OBJECT(s), &smc91c111_mem_ops, s, @@ -780,7 +780,6 @@ static int smc91c111_init1(SysBusDevice *sbd) object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); /* ??? Save/restore. */ - return 0; } static Property smc91c111_properties[] = { @@ -791,9 +790,8 @@ static Property smc91c111_properties[] = { static void smc91c111_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = smc91c111_init1; + dc->realize = smc91c111_realize; dc->reset = smc91c111_reset; dc->vmsd = &vmstate_smc91c111; dc->props = smc91c111_properties; diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c index 165562d788..b3375ebb45 100644 --- a/hw/net/stellaris_enet.c +++ b/hw/net/stellaris_enet.c @@ -457,8 +457,10 @@ static const MemoryRegionOps stellaris_enet_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void stellaris_enet_reset(stellaris_enet_state *s) +static void stellaris_enet_reset(DeviceState *dev) { + stellaris_enet_state *s = STELLARIS_ENET(dev); + s->mdv = 0x80; s->rctl = SE_RCTL_BADCRC; s->im = SE_INT_PHY | SE_INT_MD | SE_INT_RXER | SE_INT_FOV | SE_INT_TXEMP @@ -473,9 +475,9 @@ static NetClientInfo net_stellaris_enet_info = { .receive = stellaris_enet_receive, }; -static int stellaris_enet_init(SysBusDevice *sbd) +static void stellaris_enet_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); stellaris_enet_state *s = STELLARIS_ENET(dev); memory_region_init_io(&s->mmio, OBJECT(s), &stellaris_enet_ops, s, @@ -487,9 +489,6 @@ static int stellaris_enet_init(SysBusDevice *sbd) s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s); qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); - - stellaris_enet_reset(s); - return 0; } static Property stellaris_enet_properties[] = { @@ -500,9 +499,9 @@ static Property stellaris_enet_properties[] = { static void stellaris_enet_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = stellaris_enet_init; + dc->realize = stellaris_enet_realize; + dc->reset = stellaris_enet_reset; dc->props = stellaris_enet_properties; dc->vmsd = &vmstate_stellaris_enet; } diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c index fa001563d3..63f5a62ebf 100644 --- a/hw/net/xgmac.c +++ b/hw/net/xgmac.c @@ -374,9 +374,9 @@ static NetClientInfo net_xgmac_enet_info = { .receive = eth_rx, }; -static int xgmac_enet_init(SysBusDevice *sbd) +static void xgmac_enet_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); XgmacState *s = XGMAC(dev); memory_region_init_io(&s->iomem, OBJECT(s), &enet_mem_ops, s, @@ -397,8 +397,6 @@ static int xgmac_enet_init(SysBusDevice *sbd) (s->conf.macaddr.a[2] << 16) | (s->conf.macaddr.a[1] << 8) | s->conf.macaddr.a[0]; - - return 0; } static Property xgmac_properties[] = { @@ -408,10 +406,9 @@ static Property xgmac_properties[] = { static void xgmac_enet_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); - sbc->init = xgmac_enet_init; + dc->realize = xgmac_enet_realize; dc->vmsd = &vmstate_xgmac; dc->props = xgmac_properties; } diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 9868e2eccc..9f33582706 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -595,7 +595,7 @@ static const VMStateDescription vmstate_bonito = { } }; -static int bonito_pcihost_initfn(SysBusDevice *dev) +static void bonito_pcihost_realize(DeviceState *dev, Error **errp) { PCIHostState *phb = PCI_HOST_BRIDGE(dev); @@ -603,8 +603,6 @@ static int bonito_pcihost_initfn(SysBusDevice *dev) pci_bonito_set_irq, pci_bonito_map_irq, dev, get_system_memory(), get_system_io(), 0x28, 32, TYPE_PCI_BUS); - - return 0; } static void bonito_realize(PCIDevice *dev, Error **errp) @@ -684,7 +682,6 @@ PCIBus *bonito_init(qemu_irq *pic) pcihost->pic = pic; qdev_init_nofail(dev); - /* set the pcihost pointer before bonito_initfn is called */ d = pci_create(phb->bus, PCI_DEVFN(0, 0), TYPE_PCI_BONITO); s = PCI_BONITO(d); s->pcihost = pcihost; @@ -726,9 +723,9 @@ static const TypeInfo bonito_info = { static void bonito_pcihost_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - k->init = bonito_pcihost_initfn; + dc->realize = bonito_pcihost_realize; } static const TypeInfo bonito_pcihost_info = { diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 98868d893a..c08130facb 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -3128,14 +3128,12 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, Error *local_err = NULL; sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); - PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort); uint64_t size, addr; uint32_t node; - size = memory_region_size(mr); + size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort); - pc_dimm_plug(dev, MACHINE(ms), &local_err); + pc_dimm_plug(dimm, MACHINE(ms), &local_err); if (local_err) { goto out; } @@ -3158,7 +3156,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev, return; out_unplug: - pc_dimm_unplug(dev, MACHINE(ms)); + pc_dimm_unplug(dimm, MACHINE(ms)); out: error_propagate(errp, local_err); } @@ -3169,9 +3167,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev); sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev); PCDIMMDevice *dimm = PC_DIMM(dev); - PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); Error *local_err = NULL; - MemoryRegion *mr; uint64_t size; Object *memdev; hwaddr pagesize; @@ -3181,11 +3177,11 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, return; } - mr = ddc->get_memory_region(dimm, errp); - if (!mr) { + size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err); + if (local_err) { + error_propagate(errp, local_err); return; } - size = memory_region_size(mr); if (size % SPAPR_MEMORY_BLOCK_SIZE) { error_setg(errp, "Hotplugged memory size must be a multiple of " @@ -3202,7 +3198,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev, return; } - pc_dimm_pre_plug(dev, MACHINE(hotplug_dev), NULL, errp); + pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp); } struct sPAPRDIMMState { @@ -3257,9 +3253,8 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms, PCDIMMDevice *dimm) { sPAPRDRConnector *drc; - PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort); - uint64_t size = memory_region_size(mr); + uint64_t size = memory_device_get_region_size(MEMORY_DEVICE(dimm), + &error_abort); uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; uint32_t avail_lmbs = 0; uint64_t addr_start, addr; @@ -3314,7 +3309,7 @@ static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev) sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev); sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev)); - pc_dimm_unplug(dev, MACHINE(hotplug_dev)); + pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev)); object_unparent(OBJECT(dev)); spapr_pending_dimm_unplugs_remove(spapr, ds); } @@ -3325,14 +3320,12 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev, sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev); Error *local_err = NULL; PCDIMMDevice *dimm = PC_DIMM(dev); - PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort); uint32_t nr_lmbs; uint64_t size, addr_start, addr; int i; sPAPRDRConnector *drc; - size = memory_region_size(mr); + size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort); nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE; addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP, diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c index 4ec2e35500..379d0685ed 100644 --- a/hw/sh4/sh_pci.c +++ b/hw/sh4/sh_pci.c @@ -120,16 +120,15 @@ static void sh_pci_set_irq(void *opaque, int irq_num, int level) qemu_set_irq(pic[irq_num], level); } -static int sh_pci_device_init(SysBusDevice *dev) +static void sh_pci_device_realize(DeviceState *dev, Error **errp) { - PCIHostState *phb; - SHPCIState *s; + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + SHPCIState *s = SH_PCI_HOST_BRIDGE(dev); + PCIHostState *phb = PCI_HOST_BRIDGE(s); int i; - s = SH_PCI_HOST_BRIDGE(dev); - phb = PCI_HOST_BRIDGE(s); for (i = 0; i < 4; i++) { - sysbus_init_irq(dev, &s->irq[i]); + sysbus_init_irq(sbd, &s->irq[i]); } phb->bus = pci_register_root_bus(DEVICE(dev), "pci", sh_pci_set_irq, sh_pci_map_irq, @@ -143,13 +142,12 @@ static int sh_pci_device_init(SysBusDevice *dev) &s->memconfig_p4, 0, 0x224); memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa", get_system_io(), 0, 0x40000); - sysbus_init_mmio(dev, &s->memconfig_p4); - sysbus_init_mmio(dev, &s->memconfig_a7); + sysbus_init_mmio(sbd, &s->memconfig_p4); + sysbus_init_mmio(sbd, &s->memconfig_a7); s->iobr = 0xfe240000; memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa); s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host"); - return 0; } static void sh_pci_host_realize(PCIDevice *d, Error **errp) @@ -187,9 +185,9 @@ static const TypeInfo sh_pci_host_info = { static void sh_pci_device_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = sh_pci_device_init; + dc->realize = sh_pci_device_realize; } static const TypeInfo sh_pci_device_info = { diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c index 4fa8cb2904..f8a856f611 100644 --- a/hw/sparc64/niagara.c +++ b/hw/sparc64/niagara.c @@ -29,7 +29,7 @@ #include "hw/hw.h" #include "hw/boards.h" #include "hw/char/serial.h" -#include "hw/empty_slot.h" +#include "hw/misc/unimp.h" #include "hw/loader.h" #include "hw/sparc/sparc64.h" #include "hw/timer/sun4v-rtc.h" @@ -161,7 +161,7 @@ static void niagara_init(MachineState *machine) serial_mm_init(sysmem, NIAGARA_UART_BASE, 0, NULL, 115200, serial_hd(0), DEVICE_BIG_ENDIAN); } - empty_slot_init(NIAGARA_IOBBASE, NIAGARA_IOBSIZE); + create_unimplemented_device("sun4v-iob", NIAGARA_IOBBASE, NIAGARA_IOBSIZE); sun4v_rtc_init(NIAGARA_RTC_BASE); } diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c index 83585bc8b2..3dae303d5b 100644 --- a/hw/ssi/xilinx_spi.c +++ b/hw/ssi/xilinx_spi.c @@ -319,9 +319,9 @@ static const MemoryRegionOps spi_ops = { } }; -static int xilinx_spi_init(SysBusDevice *sbd) +static void xilinx_spi_realize(DeviceState *dev, Error **errp) { - DeviceState *dev = DEVICE(sbd); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); XilinxSPI *s = XILINX_SPI(dev); int i; @@ -344,8 +344,6 @@ static int xilinx_spi_init(SysBusDevice *sbd) fifo8_create(&s->tx_fifo, FIFO_CAPACITY); fifo8_create(&s->rx_fifo, FIFO_CAPACITY); - - return 0; } static const VMStateDescription vmstate_xilinx_spi = { @@ -368,9 +366,8 @@ static Property xilinx_spi_properties[] = { static void xilinx_spi_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = xilinx_spi_init; + dc->realize = xilinx_spi_realize; dc->reset = xlx_spi_reset; dc->props = xilinx_spi_properties; dc->vmsd = &vmstate_xilinx_spi; diff --git a/hw/timer/sun4v-rtc.c b/hw/timer/sun4v-rtc.c index 310523225f..4e7f6a1eff 100644 --- a/hw/timer/sun4v-rtc.c +++ b/hw/timer/sun4v-rtc.c @@ -14,15 +14,8 @@ #include "hw/sysbus.h" #include "qemu/timer.h" #include "hw/timer/sun4v-rtc.h" +#include "trace.h" -//#define DEBUG_SUN4V_RTC - -#ifdef DEBUG_SUN4V_RTC -#define DPRINTF(fmt, ...) \ - do { printf("sun4v_rtc: " fmt , ## __VA_ARGS__); } while (0) -#else -#define DPRINTF(fmt, ...) do {} while (0) -#endif #define TYPE_SUN4V_RTC "sun4v_rtc" #define SUN4V_RTC(obj) OBJECT_CHECK(Sun4vRtc, (obj), TYPE_SUN4V_RTC) @@ -41,14 +34,14 @@ static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr, /* accessing the high 32 bits */ val >>= 32; } - DPRINTF("read from " TARGET_FMT_plx " val %lx\n", addr, val); + trace_sun4v_rtc_read(addr, val); return val; } static void sun4v_rtc_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { - DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr); + trace_sun4v_rtc_read(addr, val); } static const MemoryRegionOps sun4v_rtc_ops = { @@ -70,21 +63,21 @@ void sun4v_rtc_init(hwaddr addr) sysbus_mmio_map(s, 0, addr); } -static int sun4v_rtc_init1(SysBusDevice *dev) +static void sun4v_rtc_realize(DeviceState *dev, Error **errp) { + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); Sun4vRtc *s = SUN4V_RTC(dev); memory_region_init_io(&s->iomem, OBJECT(s), &sun4v_rtc_ops, s, "sun4v-rtc", 0x08ULL); - sysbus_init_mmio(dev, &s->iomem); - return 0; + sysbus_init_mmio(sbd, &s->iomem); } static void sun4v_rtc_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - k->init = sun4v_rtc_init1; + dc->realize = sun4v_rtc_realize; } static const TypeInfo sun4v_rtc_info = { diff --git a/hw/timer/trace-events b/hw/timer/trace-events index fa4213df5b..75bd3b1042 100644 --- a/hw/timer/trace-events +++ b/hw/timer/trace-events @@ -56,7 +56,7 @@ systick_timer_tick(void) "systick reload" systick_read(uint64_t addr, uint32_t value, unsigned size) "systick read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" systick_write(uint64_t addr, uint32_t value, unsigned size) "systick write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u" -# hw/char/cmsdk_apb_timer.c +# hw/timer/cmsdk_apb_timer.c cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset" @@ -66,5 +66,9 @@ cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK A cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u" cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset" +# hw/timer/sun4v-rtc.c +sun4v_rtc_read(uint64_t addr, uint64_t value) "read: addr 0x%" PRIx64 " value 0x%" PRIx64 +sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " value 0x%" PRIx64 + # hw/timer/xlnx-zynqmp-rtc.c xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d" diff --git a/include/hw/mem/memory-device.h b/include/hw/mem/memory-device.h index 2853b084b5..e904e194d5 100644 --- a/include/hw/mem/memory-device.h +++ b/include/hw/mem/memory-device.h @@ -29,23 +29,81 @@ typedef struct MemoryDeviceState { Object parent_obj; } MemoryDeviceState; +/** + * MemoryDeviceClass: + * + * All memory devices need to implement TYPE_MEMORY_DEVICE as an interface. + * + * A memory device is a device that owns a memory region which is + * mapped into guest physical address space at a certain address. The + * address in guest physical memory can either be specified explicitly + * or get assigned automatically. + * + * Conceptually, memory devices only span one memory region. If multiple + * successive memory regions are used, a covering memory region has to + * be provided. Scattered memory regions are not supported for single + * devices. + */ typedef struct MemoryDeviceClass { + /* private */ InterfaceClass parent_class; + /* + * Return the address of the memory device in guest physical memory. + * + * Called when (un)plugging a memory device or when iterating over + * all memory devices mapped into guest physical address space. + * + * If "0" is returned, no address has been specified by the user and + * no address has been assigned to this memory device yet. + */ uint64_t (*get_addr)(const MemoryDeviceState *md); - uint64_t (*get_plugged_size)(const MemoryDeviceState *md); - uint64_t (*get_region_size)(const MemoryDeviceState *md); + + /* + * Set the address of the memory device in guest physical memory. + * + * Called when plugging the memory device to configure the determined + * address in guest physical memory. + */ + void (*set_addr)(MemoryDeviceState *md, uint64_t addr, Error **errp); + + /* + * Return the amount of memory provided by the memory device currently + * usable ("plugged") by the VM. + * + * Called when calculating the total amount of ram available to the + * VM (e.g. to report memory stats to the user). + * + * This is helpful for devices that dynamically manage the amount of + * memory accessible by the guest via the reserved memory region. For + * most devices, this corresponds to the size of the memory region. + */ + uint64_t (*get_plugged_size)(const MemoryDeviceState *md, Error **errp); + + /* + * Return the memory region of the memory device. + * + * Called when (un)plugging the memory device, to (un)map the + * memory region in guest physical memory, but also to detect the + * required alignment during address assignment or when the size of the + * memory region is required. + */ + MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp); + + /* + * Translate the memory device into #MemoryDeviceInfo. + */ void (*fill_device_info)(const MemoryDeviceState *md, MemoryDeviceInfo *info); } MemoryDeviceClass; MemoryDeviceInfoList *qmp_memory_device_list(void); uint64_t get_plugged_memory_size(void); -uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint, - uint64_t align, uint64_t size, - Error **errp); -void memory_device_plug_region(MachineState *ms, MemoryRegion *mr, - uint64_t addr); -void memory_device_unplug_region(MachineState *ms, MemoryRegion *mr); +void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms, + const uint64_t *legacy_align, Error **errp); +void memory_device_plug(MemoryDeviceState *md, MachineState *ms); +void memory_device_unplug(MemoryDeviceState *md, MachineState *ms); +uint64_t memory_device_get_region_size(const MemoryDeviceState *md, + Error **errp); #endif diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h index b382eb4303..01436b9f50 100644 --- a/include/hw/mem/pc-dimm.h +++ b/include/hw/mem/pc-dimm.h @@ -61,9 +61,6 @@ typedef struct PCDIMMDevice { * PCDIMMDeviceClass: * @realize: called after common dimm is realized so that the dimm based * devices get the chance to do specified operations. - * @get_memory_region: returns #MemoryRegion associated with @dimm which - * is directly mapped into the physical address space of guest. Will not - * fail after the device was realized. * @get_vmstate_memory_region: returns #MemoryRegion which indicates the * memory of @dimm should be kept during live migration. Will not fail * after the device was realized. @@ -74,13 +71,12 @@ typedef struct PCDIMMDeviceClass { /* public */ void (*realize)(PCDIMMDevice *dimm, Error **errp); - MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm, Error **errp); MemoryRegion *(*get_vmstate_memory_region)(PCDIMMDevice *dimm, Error **errp); } PCDIMMDeviceClass; -void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine, +void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine, const uint64_t *legacy_align, Error **errp); -void pc_dimm_plug(DeviceState *dev, MachineState *machine, Error **errp); -void pc_dimm_unplug(DeviceState *dev, MachineState *machine); +void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp); +void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine); #endif diff --git a/qapi/misc.json b/qapi/misc.json index c85c6c8ca3..6c1c5c0a37 100644 --- a/qapi/misc.json +++ b/qapi/misc.json @@ -2066,7 +2066,7 @@ # # @plugged-memory: size of memory that can be hot-unplugged. This field # is omitted if target doesn't support memory hotplug -# (i.e. CONFIG_MEM_HOTPLUG not defined on build time). +# (i.e. CONFIG_MEM_DEVICE not defined at build time). # # Since: 2.11.0 ## diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi index 11b870c5c1..5d2d7a3588 100644 --- a/qemu-deprecated.texi +++ b/qemu-deprecated.texi @@ -86,6 +86,18 @@ for these file types is 'host_cdrom' or 'host_device' as appropriate. The @option{name} parameter of the @option{-net} option is a synonym for the @option{id} parameter, which should now be used instead. +@subsection -smp (invalid topologies) (since 3.1) + +CPU topology properties should describe whole machine topology including +possible CPUs. + +However, historically it was possible to start QEMU with an incorrect topology +where @math{@var{n} <= @var{sockets} * @var{cores} * @var{threads} < @var{maxcpus}}, +which could lead to an incorrect topology enumeration by the guest. +Support for invalid topologies will be removed, the user must ensure +topologies described with -smp include all possible cpus, i.e. + @math{@var{sockets} * @var{cores} * @var{threads} = @var{maxcpus}}. + @section QEMU Machine Protocol (QMP) commands @subsection block-dirty-bitmap-add "autoload" parameter (since 2.12.0) diff --git a/tests/cpu-plug-test.c b/tests/cpu-plug-test.c index 3e93c8e096..f4a677d238 100644 --- a/tests/cpu-plug-test.c +++ b/tests/cpu-plug-test.c @@ -32,12 +32,12 @@ static void test_plug_with_cpu_add(gconstpointer data) unsigned int i; args = g_strdup_printf("-machine %s -cpu %s " - "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u", + "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u", s->machine, s->cpu_model, s->sockets, s->cores, s->threads, s->maxcpus); qtest_start(args); - for (i = s->sockets * s->cores * s->threads; i < s->maxcpus; i++) { + for (i = 1; i < s->maxcpus; i++) { response = qmp("{ 'execute': 'cpu-add'," " 'arguments': { 'id': %d } }", i); g_assert(response); @@ -56,7 +56,7 @@ static void test_plug_without_cpu_add(gconstpointer data) QDict *response; args = g_strdup_printf("-machine %s -cpu %s " - "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u", + "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u", s->machine, s->cpu_model, s->sockets, s->cores, s->threads, s->maxcpus); qtest_start(args); @@ -79,12 +79,12 @@ static void test_plug_with_device_add_x86(gconstpointer data) unsigned int s, c, t; args = g_strdup_printf("-machine %s -cpu %s " - "-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u", + "-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u", td->machine, td->cpu_model, td->sockets, td->cores, td->threads, td->maxcpus); qtest_start(args); - for (s = td->sockets; s < td->maxcpus / td->cores / td->threads; s++) { + for (s = 1; s < td->sockets; s++) { for (c = 0; c < td->cores; c++) { for (t = 0; t < td->threads; t++) { char *id = g_strdup_printf("id-%i-%i-%i", s, c, t); @@ -113,7 +113,7 @@ static void test_plug_with_device_add_coreid(gconstpointer data) td->sockets, td->cores, td->threads, td->maxcpus); qtest_start(args); - for (c = td->cores; c < td->maxcpus / td->sockets / td->threads; c++) { + for (c = 1; c < td->cores; c++) { char *id = g_strdup_printf("id-%i", c); qtest_qmp_device_add(td->device_model, id, "{'core-id':%u}", c); g_free(id); @@ -148,7 +148,7 @@ static void add_pc_test_case(const char *mname) data->sockets = 1; data->cores = 3; data->threads = 2; - data->maxcpus = data->sockets * data->cores * data->threads * 2; + data->maxcpus = data->sockets * data->cores * data->threads; if (g_str_has_suffix(mname, "-1.4") || (strcmp(mname, "pc-1.3") == 0) || (strcmp(mname, "pc-1.2") == 0) || @@ -203,7 +203,7 @@ static void add_pseries_test_case(const char *mname) data->sockets = 2; data->cores = 3; data->threads = 1; - data->maxcpus = data->sockets * data->cores * data->threads * 2; + data->maxcpus = data->sockets * data->cores * data->threads; path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u", mname, data->sockets, data->cores, @@ -229,7 +229,7 @@ static void add_s390x_test_case(const char *mname) data->sockets = 1; data->cores = 3; data->threads = 1; - data->maxcpus = data->sockets * data->cores * data->threads * 2; + data->maxcpus = data->sockets * data->cores * data->threads; data2 = g_memdup(data, sizeof(PlugTestData)); data2->machine = g_strdup(data->machine); @@ -1230,11 +1230,14 @@ static void smp_parse(QemuOpts *opts) /* compute missing values, prefer sockets over cores over threads */ if (cpus == 0 || sockets == 0) { - sockets = sockets > 0 ? sockets : 1; cores = cores > 0 ? cores : 1; threads = threads > 0 ? threads : 1; if (cpus == 0) { + sockets = sockets > 0 ? sockets : 1; cpus = cores * threads * sockets; + } else { + max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus); + sockets = max_cpus / (cores * threads); } } else if (cores == 0) { threads = threads > 0 ? threads : 1; @@ -1266,6 +1269,13 @@ static void smp_parse(QemuOpts *opts) exit(1); } + if (sockets * cores * threads != max_cpus) { + warn_report("Invalid CPU topology deprecated: " + "sockets (%u) * cores (%u) * threads (%u) " + "!= maxcpus (%u)", + sockets, cores, threads, max_cpus); + } + smp_cpus = cpus; smp_cores = cores; smp_threads = threads; |