aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-10-25 20:17:12 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-10-25 20:17:12 +0100
commit6e6ffc9ffa88eb6af6f39931f6b495805b150c95 (patch)
tree53a644b33cb096e07a48a7a9e5efba5feea2e6a3
parent808ebd66e467f77c0d1f8c6346235f81e9c99cf2 (diff)
parent8fa922c241e63f018f5b55c03ac494ae3d5fe594 (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>
-rw-r--r--backends/hostmem-file.c10
-rw-r--r--default-configs/i386-softmmu.mak3
-rw-r--r--default-configs/ppc64-softmmu.mak3
-rw-r--r--default-configs/sparc64-softmmu.mak1
-rw-r--r--hw/Makefile.objs2
-rw-r--r--hw/alpha/typhoon.c13
-rw-r--r--hw/core/machine.c2
-rw-r--r--hw/hppa/dino.c7
-rw-r--r--hw/i386/pc.c6
-rw-r--r--hw/mem/Makefile.objs4
-rw-r--r--hw/mem/memory-device.c103
-rw-r--r--hw/mem/nvdimm.c9
-rw-r--r--hw/mem/pc-dimm.c84
-rw-r--r--hw/mem/trace-events5
-rw-r--r--hw/mips/gt64xxx_pci.c18
-rw-r--r--hw/mips/mips_malta.c13
-rw-r--r--hw/net/etraxfs_eth.c44
-rw-r--r--hw/net/lan9118.c9
-rw-r--r--hw/net/lance.c8
-rw-r--r--hw/net/milkymist-minimac2.c9
-rw-r--r--hw/net/mipsnet.c9
-rw-r--r--hw/net/opencores_eth.c8
-rw-r--r--hw/net/smc91c111.c8
-rw-r--r--hw/net/stellaris_enet.c15
-rw-r--r--hw/net/xgmac.c9
-rw-r--r--hw/pci-host/bonito.c9
-rw-r--r--hw/ppc/spapr.c29
-rw-r--r--hw/sh4/sh_pci.c20
-rw-r--r--hw/sparc64/niagara.c4
-rw-r--r--hw/ssi/xilinx_spi.c9
-rw-r--r--hw/timer/sun4v-rtc.c23
-rw-r--r--hw/timer/trace-events6
-rw-r--r--include/hw/mem/memory-device.h74
-rw-r--r--include/hw/mem/pc-dimm.h10
-rw-r--r--qapi/misc.json2
-rw-r--r--qemu-deprecated.texi12
-rw-r--r--tests/cpu-plug-test.c18
-rw-r--r--vl.c12
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);
diff --git a/vl.c b/vl.c
index b2a405f80f..1fcacc5caa 100644
--- a/vl.c
+++ b/vl.c
@@ -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;