From b0c14ec4efe912ae6f14a4802574f7b6b6db0648 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 23 Apr 2018 18:51:17 +0200 Subject: machine: make MemoryHotplugState accessible via the machine Let's allow to query the MemoryHotplugState directly from the machine. If the pointer is NULL, the machine does not support memory devices. If the pointer is !NULL, the machine supports memory devices and the data structure contains information about the applicable physical guest address space region. This allows us to generically detect if a certain machine has support for memory devices, and to generically manage it (find free address range, plug/unplug a memory region). We will rename "MemoryHotplugState" to something more meaningful ("DeviceMemory") after we completed factoring out the pc-dimm code into MemoryDevice code. Signed-off-by: David Hildenbrand Message-Id: <20180423165126.15441-3-david@redhat.com> Reviewed-by: Michael S. Tsirkin [ehabkost: rebased series, solved conflicts at spapr.c] [ehabkost: squashed fix to use g_malloc0()] Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'hw/i386/pc.c') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index b297a5d63b..0aa7885798 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1371,6 +1371,9 @@ void pc_memory_init(PCMachineState *pcms, exit(EXIT_FAILURE); } + /* always allocate the device memory information */ + machine->device_memory = g_malloc0(sizeof(*machine->device_memory)); + /* initialize hotplug memory address space */ if (pcmc->has_reserved_memory && (machine->ram_size < machine->maxram_size)) { @@ -1390,7 +1393,7 @@ void pc_memory_init(PCMachineState *pcms, exit(EXIT_FAILURE); } - pcms->hotplug_memory.base = + machine->device_memory->base = ROUND_UP(0x100000000ULL + pcms->above_4g_mem_size, 1ULL << 30); if (pcmc->enforce_aligned_dimm) { @@ -1398,17 +1401,17 @@ void pc_memory_init(PCMachineState *pcms, hotplug_mem_size += (1ULL << 30) * machine->ram_slots; } - if ((pcms->hotplug_memory.base + hotplug_mem_size) < + if ((machine->device_memory->base + hotplug_mem_size) < hotplug_mem_size) { error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT, machine->maxram_size); exit(EXIT_FAILURE); } - memory_region_init(&pcms->hotplug_memory.mr, OBJECT(pcms), + memory_region_init(&machine->device_memory->mr, OBJECT(pcms), "hotplug-memory", hotplug_mem_size); - memory_region_add_subregion(system_memory, pcms->hotplug_memory.base, - &pcms->hotplug_memory.mr); + memory_region_add_subregion(system_memory, machine->device_memory->base, + &machine->device_memory->mr); } /* Initialize PC system firmware */ @@ -1429,13 +1432,13 @@ void pc_memory_init(PCMachineState *pcms, rom_set_fw(fw_cfg); - if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) { + if (pcmc->has_reserved_memory && machine->device_memory->base) { uint64_t *val = g_malloc(sizeof(*val)); PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); - uint64_t res_mem_end = pcms->hotplug_memory.base; + uint64_t res_mem_end = machine->device_memory->base; if (!pcmc->broken_reserved_end) { - res_mem_end += memory_region_size(&pcms->hotplug_memory.mr); + res_mem_end += memory_region_size(&machine->device_memory->mr); } *val = cpu_to_le64(ROUND_UP(res_mem_end, 0x1ULL << 30)); fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val)); @@ -1462,12 +1465,13 @@ uint64_t pc_pci_hole64_start(void) { PCMachineState *pcms = PC_MACHINE(qdev_get_machine()); PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(pcms); + MachineState *ms = MACHINE(pcms); uint64_t hole64_start = 0; - if (pcmc->has_reserved_memory && pcms->hotplug_memory.base) { - hole64_start = pcms->hotplug_memory.base; + if (pcmc->has_reserved_memory && ms->device_memory->base) { + hole64_start = ms->device_memory->base; if (!pcmc->broken_reserved_end) { - hole64_start += memory_region_size(&pcms->hotplug_memory.mr); + hole64_start += memory_region_size(&ms->device_memory->mr); } } else { hole64_start = 0x100000000ULL + pcms->above_4g_mem_size; @@ -1711,7 +1715,8 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, goto out; } - pc_dimm_memory_plug(dev, &pcms->hotplug_memory, mr, align, &local_err); + pc_dimm_memory_plug(dev, MACHINE(pcms)->device_memory, mr, align, + &local_err); if (local_err) { goto out; } @@ -1779,7 +1784,7 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev, goto out; } - pc_dimm_memory_unplug(dev, &pcms->hotplug_memory, mr); + pc_dimm_memory_unplug(dev, MACHINE(pcms)->device_memory, mr); object_unparent(OBJECT(dev)); out: @@ -2072,8 +2077,8 @@ pc_machine_get_hotplug_memory_region_size(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) { - PCMachineState *pcms = PC_MACHINE(obj); - int64_t value = memory_region_size(&pcms->hotplug_memory.mr); + MachineState *ms = MACHINE(obj); + int64_t value = memory_region_size(&ms->device_memory->mr); visit_type_int(v, name, &value, errp); } -- cgit v1.2.1 From acc7fa17e6fe96bd68ad9af04fde5091383ef25e Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 23 Apr 2018 18:51:18 +0200 Subject: pc-dimm: no need to pass the memory region We can just query it ourselves. When unplugging, we should always be able to the region (as it was previously plugged). E.g. PPC already assumed that and used &error_abort. Signed-off-by: David Hildenbrand Message-Id: <20180423165126.15441-4-david@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'hw/i386/pc.c') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 0aa7885798..e337c6552d 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1715,8 +1715,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, goto out; } - pc_dimm_memory_plug(dev, MACHINE(pcms)->device_memory, mr, align, - &local_err); + pc_dimm_memory_plug(dev, MACHINE(pcms)->device_memory, align, &local_err); if (local_err) { goto out; } @@ -1766,17 +1765,9 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev, DeviceState *dev, Error **errp) { PCMachineState *pcms = PC_MACHINE(hotplug_dev); - PCDIMMDevice *dimm = PC_DIMM(dev); - PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm); - MemoryRegion *mr; HotplugHandlerClass *hhc; Error *local_err = NULL; - mr = ddc->get_memory_region(dimm, &local_err); - if (local_err) { - goto out; - } - hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev); hhc->unplug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err); @@ -1784,7 +1775,7 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev, goto out; } - pc_dimm_memory_unplug(dev, MACHINE(pcms)->device_memory, mr); + pc_dimm_memory_unplug(dev, MACHINE(pcms)->device_memory); object_unparent(OBJECT(dev)); out: -- cgit v1.2.1 From bd6c3e4a4975ee1e5cadbc1826af9bd0ca0954c2 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 23 Apr 2018 18:51:19 +0200 Subject: pc-dimm: pass in the machine and to the MemoryHotplugState We use the machine internally either way, so let's just pass it in then. Signed-off-by: David Hildenbrand Message-Id: <20180423165126.15441-5-david@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'hw/i386/pc.c') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e337c6552d..e94e63dc6c 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1715,7 +1715,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev, goto out; } - pc_dimm_memory_plug(dev, MACHINE(pcms)->device_memory, align, &local_err); + pc_dimm_memory_plug(dev, MACHINE(pcms), align, &local_err); if (local_err) { goto out; } @@ -1775,7 +1775,7 @@ static void pc_dimm_unplug(HotplugHandler *hotplug_dev, goto out; } - pc_dimm_memory_unplug(dev, MACHINE(pcms)->device_memory); + pc_dimm_memory_unplug(dev, MACHINE(pcms)); object_unparent(OBJECT(dev)); out: -- cgit v1.2.1 From f2ffbe2b7dd05a563fe81066440629824192b15a Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Mon, 23 Apr 2018 18:51:24 +0200 Subject: pc: rename "hotplug memory" terminology to "device memory" Let's make it clear that we are dealing with device memory. That it can be used for memory hotplug is just a special case. Signed-off-by: David Hildenbrand Message-Id: <20180423165126.15441-10-david@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Eduardo Habkost --- hw/i386/pc.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'hw/i386/pc.c') diff --git a/hw/i386/pc.c b/hw/i386/pc.c index e94e63dc6c..868893d0a1 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1374,11 +1374,10 @@ void pc_memory_init(PCMachineState *pcms, /* always allocate the device memory information */ machine->device_memory = g_malloc0(sizeof(*machine->device_memory)); - /* initialize hotplug memory address space */ + /* initialize device memory address space */ if (pcmc->has_reserved_memory && (machine->ram_size < machine->maxram_size)) { - ram_addr_t hotplug_mem_size = - machine->maxram_size - machine->ram_size; + ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size; if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) { error_report("unsupported amount of memory slots: %"PRIu64, @@ -1397,19 +1396,19 @@ void pc_memory_init(PCMachineState *pcms, ROUND_UP(0x100000000ULL + pcms->above_4g_mem_size, 1ULL << 30); if (pcmc->enforce_aligned_dimm) { - /* size hotplug region assuming 1G page max alignment per slot */ - hotplug_mem_size += (1ULL << 30) * machine->ram_slots; + /* size device region assuming 1G page max alignment per slot */ + device_mem_size += (1ULL << 30) * machine->ram_slots; } - if ((machine->device_memory->base + hotplug_mem_size) < - hotplug_mem_size) { + if ((machine->device_memory->base + device_mem_size) < + device_mem_size) { error_report("unsupported amount of maximum memory: " RAM_ADDR_FMT, machine->maxram_size); exit(EXIT_FAILURE); } memory_region_init(&machine->device_memory->mr, OBJECT(pcms), - "hotplug-memory", hotplug_mem_size); + "device-memory", device_mem_size); memory_region_add_subregion(system_memory, machine->device_memory->base, &machine->device_memory->mr); } @@ -2064,9 +2063,9 @@ static HotplugHandler *pc_get_hotpug_handler(MachineState *machine, } static void -pc_machine_get_hotplug_memory_region_size(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) +pc_machine_get_device_memory_region_size(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) { MachineState *ms = MACHINE(obj); int64_t value = memory_region_size(&ms->device_memory->mr); @@ -2373,8 +2372,8 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) nc->nmi_monitor_handler = x86_nmi; mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE; - object_class_property_add(oc, PC_MACHINE_MEMHP_REGION_SIZE, "int", - pc_machine_get_hotplug_memory_region_size, NULL, + object_class_property_add(oc, PC_MACHINE_DEVMEM_REGION_SIZE, "int", + pc_machine_get_device_memory_region_size, NULL, NULL, NULL, &error_abort); object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size", -- cgit v1.2.1