All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug
@ 2014-05-20 15:15 Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 01/31] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
                   ` (30 more replies)
  0 siblings, 31 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

What's new since v8:

 * rebased on top of Marcel's QOMyfing machine work
    depends on patch from qom-next:
     "machine: Conversion of QEMUMachineInitArgs to MachineState"
 * fixed QEMU abort if it's running in daemonized mode
 * fixed leak in memdev backend
 * introduced custom PCMachine
 * DIMM devices are now bus-less and use bus-less hotplug method
 * DIMMDevice: renamed property/field 'start' to 'addr'
 * ACPI tables:
   * avoid punching hotples in PCI CRS by placing
     MEMORY_HOPTLUG_DEVICE on PCI0 bus
 * incorporated most of comments/fixes from reviewers

What's new since v7:

* Per Andreas' suggestion dropped DIMMBus concept.
* Added hotplug binding for bus-less devices
* DIMM device is split to backend and frontend. Therefore following
  command/options were added for supporting it:

  For memory-ram backend:
      CLI: -object-add memory-ram,
          with options: 'id' and 'size'
  For dimm frontend:
      option "size" became readonly, pulling it's size from attached backend
      added option "memdev" for specifying backend by 'id'

* dropped support for 32 bit guests
* failed hotplug action doesn't consume 1 slot anymore
* vaious fixes adressing reviewer's comments most of them in ACPI part
---

This series allows to hotplug 'arbitrary' DIMM devices specifying size,
NUMA node mapping (guest side), slot and address where to map it, at runtime.

Due to ACPI limitation there is need to specify a number of possible
DIMM devices. For this task -m option was extended to support
following format:

  -m [mem=]RamSize[,slots=N,maxmem=M]

To allow memory hotplug user must specify a pair of additional parameters:
    'slots' - number of possible increments
    'maxmem' - max possible total memory size QEMU is allowed to use,
               including RamSize.

minimal monitor command syntax to hotplug DIMM device:

  object_add memory-ram,id=memX,size=1G
  device_add dimm,id=dimmX,memdev=memX

DIMM device provides following properties that could be used with
device_add / -device to alter default behavior:

  id    - unique string identifying device [mandatory]
  slot  - number in range [0-slots) [optional], if not specified
          the first free slot is used
  node  - NUMA node id [optional] (default: 0)
  size  - amount of memory to add, readonly derived from backing memdev
  addr - guest's physical address where to plug DIMM [optional],
          if not specified the first gap in hotplug memory region
          that fits DIMM is used

 -device option could be used for adding potentially hotunplugable DIMMs
and also for specifying hotplugged DIMMs in migration case.

Tested guests:
 - RHEL 6x64
 - Windows 2012DCx64
 - Windows 2008DCx64

Known limitations/bugs/TODOs:
 - hot-remove is not supported, yet
 - max number of supported DIMM devices 256 (due to ACPI object name
   limit), could be increased creating several containers and putting
   DIMMs there. (exercise for future) 
 - e820 table doesn't include DIMM devices added with -device /
   (or after reboot devices added with device_add)
 - Windows 2008 remembers DIMM configuration, so if DIMM with other
   addr/size is added into the same slot, it refuses to use it insisting
   on old mapping.

QEMU git tree for testing is available at:
  https://github.com/imammedo/qemu/commits/memory-hotplug-v9

Example QEMU cmd line:
  qemu-system-x86_64 -enable-kvm -monitor unix:/tmp/mon,server,nowait \ 
     -m 4096,slots=4,maxmem=8G guest.img

PS:
  Windows guest requires SRAT table for hotplug to work so add an extra option:
   -numa node
  to QEMU command line.


Igor Mammedov (30):
  pc: ACPI BIOS: use enum for defining memory affinity flags
  object_add: allow completion handler to get canonical path
  vl.c: daemonize before guest memory allocation
  add memdev backend infrastructure
  vl.c: extend -m option to support options for memory hotplug
  pc: create custom generic PC machine type
  qdev: hotplug for buss-less devices
  qdev: expose DeviceState.hotplugged field as a property
  memory: add memory_region_is_mapped() API
  dimm: do not allow to set already used memdev
  pc: initialize memory hotplug address space
  pc: exit QEMU if number of slots more than supported 256
  pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  pc: add memory hotplug handler to PC_MACHINE
  dimm: add busy address check and address auto-allocation
  dimm: add busy slot check and slot auto-allocation
  acpi: rename cpu_hotplug_defs.h to acpi_defs.h
  acpi: memory hotplug ACPI hardware implementation
  trace: add acpi memory hotplug IO region events
  trace: pc: add DIMM slot & address allocation
  acpi:piix4: allow plug/unlug callbacks handle not only PCI devices
  acpi:piix4: add memory hotplug handling
  pc: ich9 lpc: make it work with global/compat properties
  acpi:ich9: add memory hotplug handling
  pc: migrate piix4 & ich9 MemHotplugState
  pc: add acpi-device link to PCMachineState
  pc: propagate memory hotplug event to ACPI device
  pc: ACPI BIOS: implement memory hotplug interface
  pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35
    machines

Vasilis Liaskovitis (1):
  dimm: implement dimm device abstraction

 backends/Makefile.objs             |    2 +
 backends/hostmem-ram.c             |   54 ++++++++
 backends/hostmem.c                 |  110 ++++++++++++++++
 default-configs/i386-softmmu.mak   |    1 +
 default-configs/x86_64-softmmu.mak |    1 +
 docs/specs/acpi_mem_hotplug.txt    |   44 +++++++
 hw/Makefile.objs                   |    1 +
 hw/acpi/Makefile.objs              |    1 +
 hw/acpi/ich9.c                     |   62 +++++++++
 hw/acpi/memory_hotplug.c           |  187 ++++++++++++++++++++++++++++
 hw/acpi/piix4.c                    |   74 ++++++++++--
 hw/core/qdev.c                     |   30 +++++
 hw/i386/Makefile.objs              |    3 +-
 hw/i386/acpi-build.c               |   72 ++++++++++-
 hw/i386/acpi-dsdt.dsl              |    7 +-
 hw/i386/pc.c                       |  198 +++++++++++++++++++++++++++++-
 hw/i386/pc_piix.c                  |   51 +++++---
 hw/i386/pc_q35.c                   |   25 +++-
 hw/i386/q35-acpi-dsdt.dsl          |    7 +-
 hw/i386/ssdt-mem.dsl               |   77 ++++++++++++
 hw/i386/ssdt-misc.dsl              |  164 ++++++++++++++++++++++++
 hw/isa/lpc_ich9.c                  |   33 +++++-
 hw/mem/Makefile.objs               |    1 +
 hw/mem/dimm.c                      |  240 ++++++++++++++++++++++++++++++++++++
 hw/mips/mips_malta.c               |    2 +-
 include/exec/memory.h              |    8 ++
 include/hw/acpi/acpi.h             |    6 +
 include/hw/acpi/acpi_defs.h        |   57 +++++++++
 include/hw/acpi/cpu_hotplug.h      |    2 +-
 include/hw/acpi/cpu_hotplug_defs.h |   33 -----
 include/hw/acpi/ich9.h             |    4 +
 include/hw/acpi/memory_hotplug.h   |   37 ++++++
 include/hw/boards.h                |   11 ++-
 include/hw/i386/pc.h               |   63 +++++++++-
 include/hw/mem/dimm.h              |   80 ++++++++++++
 include/sysemu/hostmem.h           |   60 +++++++++
 memory.c                           |   15 ++-
 qemu-options.hx                    |    9 +-
 qmp.c                              |   11 ++-
 trace-events                       |   17 +++
 vl.c                               |   64 +++++++++-
 41 files changed, 1820 insertions(+), 104 deletions(-)
 create mode 100644 backends/hostmem-ram.c
 create mode 100644 backends/hostmem.c
 create mode 100644 docs/specs/acpi_mem_hotplug.txt
 create mode 100644 hw/acpi/memory_hotplug.c
 create mode 100644 hw/i386/ssdt-mem.dsl
 create mode 100644 hw/mem/Makefile.objs
 create mode 100644 hw/mem/dimm.c
 create mode 100644 include/hw/acpi/acpi_defs.h
 delete mode 100644 include/hw/acpi/cpu_hotplug_defs.h
 create mode 100644 include/hw/acpi/memory_hotplug.h
 create mode 100644 include/hw/mem/dimm.h
 create mode 100644 include/sysemu/hostmem.h

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 01/31] pc: ACPI BIOS: use enum for defining memory affinity flags
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 02/31] object_add: allow completion handler to get canonical path Igor Mammedov
                   ` (29 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

replace magic numbers with enum describing Flags field of
memory affinity in SRAT table.

MemoryAffinityFlags enum will define flags decribed by:
 ACPI spec 5.0, "5.2.16.2 Memory Affinity Structure",
 "Table 5-69 Flags - Memory Affinity Structure"

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 9fac589..34c0f42 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1132,15 +1132,22 @@ build_hpet(GArray *table_data, GArray *linker)
                  (void *)hpet, "HPET", sizeof(*hpet), 1);
 }
 
+typedef enum {
+    MEM_AFFINITY_NOFLAGS      = 0,
+    MEM_AFFINITY_ENABLED      = (1 << 0),
+    MEM_AFFINITY_HOTPLUGGABLE = (1 << 1),
+    MEM_AFFINITY_NON_VOLATILE = (1 << 2),
+} MemoryAffinityFlags;
+
 static void
-acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem,
-                       uint64_t base, uint64_t len, int node, int enabled)
+acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
+                       uint64_t len, int node, MemoryAffinityFlags flags)
 {
     numamem->type = ACPI_SRAT_MEMORY;
     numamem->length = sizeof(*numamem);
     memset(numamem->proximity, 0, 4);
     numamem->proximity[0] = node;
-    numamem->flags = cpu_to_le32(!!enabled);
+    numamem->flags = cpu_to_le32(flags);
     numamem->base_addr = cpu_to_le64(base);
     numamem->range_length = cpu_to_le64(len);
 }
@@ -1188,7 +1195,7 @@ build_srat(GArray *table_data, GArray *linker,
     numa_start = table_data->len;
 
     numamem = acpi_data_push(table_data, sizeof *numamem);
-    acpi_build_srat_memory(numamem, 0, 640*1024, 0, 1);
+    acpi_build_srat_memory(numamem, 0, 640*1024, 0, MEM_AFFINITY_ENABLED);
     next_base = 1024 * 1024;
     for (i = 1; i < guest_info->numa_nodes + 1; ++i) {
         mem_base = next_base;
@@ -1204,19 +1211,21 @@ build_srat(GArray *table_data, GArray *linker,
             mem_len -= next_base - guest_info->ram_size_below_4g;
             if (mem_len > 0) {
                 numamem = acpi_data_push(table_data, sizeof *numamem);
-                acpi_build_srat_memory(numamem, mem_base, mem_len, i-1, 1);
+                acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
+                                       MEM_AFFINITY_ENABLED);
             }
             mem_base = 1ULL << 32;
             mem_len = next_base - guest_info->ram_size_below_4g;
             next_base += (1ULL << 32) - guest_info->ram_size_below_4g;
         }
         numamem = acpi_data_push(table_data, sizeof *numamem);
-        acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1, 1);
+        acpi_build_srat_memory(numamem, mem_base, mem_len, i - 1,
+                               MEM_AFFINITY_ENABLED);
     }
     slots = (table_data->len - numa_start) / sizeof *numamem;
     for (; slots < guest_info->numa_nodes + 2; slots++) {
         numamem = acpi_data_push(table_data, sizeof *numamem);
-        acpi_build_srat_memory(numamem, 0, 0, 0, 0);
+        acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
     }
 
     build_header(linker, table_data,
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 02/31] object_add: allow completion handler to get canonical path
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 01/31] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 03/31] vl.c: daemonize before guest memory allocation Igor Mammedov
                   ` (28 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Add object to /objects before calling user_creatable_complete()
handler, so that object might be able to call
object_get_canonical_path() in its completion handler.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 qmp.c |   11 ++++++++---
 vl.c  |    9 +++++----
 2 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/qmp.c b/qmp.c
index a7f432b..b722dbe 100644
--- a/qmp.c
+++ b/qmp.c
@@ -565,13 +565,18 @@ void object_add(const char *type, const char *id, const QDict *qdict,
         }
     }
 
-    user_creatable_complete(obj, &local_err);
+    object_property_add_child(container_get(object_get_root(), "/objects"),
+                              id, obj, &local_err);
     if (local_err) {
         goto out;
     }
 
-    object_property_add_child(container_get(object_get_root(), "/objects"),
-                              id, obj, &local_err);
+    user_creatable_complete(obj, &local_err);
+    if (local_err) {
+        object_property_del(container_get(object_get_root(), "/objects"),
+                            id, &error_abort);
+        goto out;
+    }
 out:
     if (local_err) {
         error_propagate(errp, local_err);
diff --git a/vl.c b/vl.c
index 2de90fb..cda6220 100644
--- a/vl.c
+++ b/vl.c
@@ -2932,14 +2932,15 @@ static int object_create(QemuOpts *opts, void *opaque)
         goto out;
     }
 
+    object_property_add_child(container_get(object_get_root(), "/objects"),
+                              id, obj, &local_err);
+
     user_creatable_complete(obj, &local_err);
     if (local_err) {
+        object_property_del(container_get(object_get_root(), "/objects"),
+                            id, &error_abort);
         goto out;
     }
-
-    object_property_add_child(container_get(object_get_root(), "/objects"),
-                              id, obj, &local_err);
-
 out:
     object_unref(obj);
     if (local_err) {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 03/31] vl.c: daemonize before guest memory allocation
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 01/31] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 02/31] object_add: allow completion handler to get canonical path Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 04/31] add memdev backend infrastructure Igor Mammedov
                   ` (27 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

memory allocated for guest before QEMU is daemonized and then mapped
later in guest's address space after it is daemonized, leads to EPT
violation and QEMU aborts.

To avoid this and similar issues switch to daemonized mode early
before processing applying/processing other options.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
I haven't digged in kvm itself yet why EPT violation happens,
but fix on QEMU side looks trivial so it won't hurt to use it anyway.

there is simpler reporoducer without migration, start guest with
 '-object memory-ram,id=foo,size=1G'
when guest is up and running hotplug dimm device using 'foo' memdev
as backend.
---
 vl.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/vl.c b/vl.c
index cda6220..8fd4ed9 100644
--- a/vl.c
+++ b/vl.c
@@ -3963,6 +3963,8 @@ int main(int argc, char **argv, char **envp)
     }
     loc_set_none();
 
+    os_daemonize();
+
     if (qemu_init_main_loop()) {
         fprintf(stderr, "qemu_init_main_loop failed\n");
         exit(1);
@@ -4200,8 +4202,6 @@ int main(int argc, char **argv, char **envp)
     }
 #endif
 
-    os_daemonize();
-
     if (pid_file && qemu_create_pidfile(pid_file) != 0) {
         os_pidfile_error();
         exit(1);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 04/31] add memdev backend infrastructure
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (2 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 03/31] vl.c: daemonize before guest memory allocation Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
                   ` (26 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Provides framework for splitting host RAM allocation/
policies into a separate backend that could be used
by devices.

Initially only legacy RAM backend is provided, which
uses memory_region_init_ram() allocator and compatible
with every CLI option that affects memory_region_init_ram().

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
v3:
 - fix path leak & use object_get_canonical_path_component()
   for getting object name
v2:
 - reuse UserCreatable interface instead of custom callbacks

hostmem-ram: fix string leak

Signed-off-by: Igor Mammedov <imammedo@redhat.com>

object_get_canonical_path_component

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 backends/Makefile.objs   |    2 +
 backends/hostmem-ram.c   |   54 ++++++++++++++++++++++
 backends/hostmem.c       |  110 ++++++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/hostmem.h |   60 +++++++++++++++++++++++++
 4 files changed, 226 insertions(+), 0 deletions(-)
 create mode 100644 backends/hostmem-ram.c
 create mode 100644 backends/hostmem.c
 create mode 100644 include/sysemu/hostmem.h

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 591ddcf..7fb7acd 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -6,3 +6,5 @@ common-obj-$(CONFIG_BRLAPI) += baum.o
 baum.o-cflags := $(SDL_CFLAGS)
 
 common-obj-$(CONFIG_TPM) += tpm.o
+
+common-obj-y += hostmem.o hostmem-ram.o
diff --git a/backends/hostmem-ram.c b/backends/hostmem-ram.c
new file mode 100644
index 0000000..cbf7e5a
--- /dev/null
+++ b/backends/hostmem-ram.c
@@ -0,0 +1,54 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ *   Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "qom/object_interfaces.h"
+
+#define TYPE_MEMORY_BACKEND_RAM "memory-ram"
+
+
+static void
+ram_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(uc);
+    char *path;
+
+    if (!backend->size) {
+        error_setg(errp, "can't create backend with size 0");
+        return;
+    }
+
+    path = object_get_canonical_path_component(OBJECT(backend));
+    memory_region_init_ram(&backend->mr, OBJECT(backend), path,
+                           backend->size);
+    g_free(path);
+}
+
+static void
+ram_backend_class_init(ObjectClass *oc, void *data)
+{
+    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+    ucc->complete = ram_backend_memory_init;
+}
+
+static const TypeInfo ram_backend_info = {
+    .name = TYPE_MEMORY_BACKEND_RAM,
+    .parent = TYPE_MEMORY_BACKEND,
+    .class_init = ram_backend_class_init,
+};
+
+static void register_types(void)
+{
+    type_register_static(&ram_backend_info);
+}
+
+type_init(register_types);
diff --git a/backends/hostmem.c b/backends/hostmem.c
new file mode 100644
index 0000000..0bd3900
--- /dev/null
+++ b/backends/hostmem.c
@@ -0,0 +1,110 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ *   Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "sysemu/hostmem.h"
+#include "sysemu/sysemu.h"
+#include "qapi/visitor.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/config-file.h"
+#include "qom/object_interfaces.h"
+
+static void
+hostmemory_backend_get_size(Object *obj, Visitor *v, void *opaque,
+                            const char *name, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+    uint64_t value = backend->size;
+
+    visit_type_size(v, &value, name, errp);
+}
+
+static void
+hostmemory_backend_set_size(Object *obj, Visitor *v, void *opaque,
+                            const char *name, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+    uint64_t value;
+
+    if (memory_region_size(&backend->mr)) {
+        error_setg(errp, "cannot change property value\n");
+        return;
+    }
+
+    visit_type_size(v, &value, name, errp);
+    if (error_is_set(errp)) {
+        return;
+    }
+    if (!value) {
+        error_setg(errp, "Property '%s.%s' doesn't take value '%" PRIu64 "'",
+                   object_get_typename(obj), name , value);
+        return;
+    }
+    backend->size = value;
+}
+
+static void hostmemory_backend_initfn(Object *obj)
+{
+    object_property_add(obj, "size", "int",
+                        hostmemory_backend_get_size,
+                        hostmemory_backend_set_size, NULL, NULL, NULL);
+}
+
+static void hostmemory_backend_finalize(Object *obj)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+    if (memory_region_size(&backend->mr)) {
+        memory_region_destroy(&backend->mr);
+    }
+}
+
+static void
+hostmemory_backend_memory_init(UserCreatable *uc, Error **errp)
+{
+    error_setg(errp, "memory_init is not implemented for type [%s]",
+               object_get_typename(OBJECT(uc)));
+}
+
+MemoryRegion *
+host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
+{
+    return memory_region_size(&backend->mr) ? &backend->mr : NULL;
+}
+
+static void
+hostmemory_backend_class_init(ObjectClass *oc, void *data)
+{
+    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+    ucc->complete = hostmemory_backend_memory_init;
+}
+
+static const TypeInfo hostmemory_backend_info = {
+    .name = TYPE_MEMORY_BACKEND,
+    .parent = TYPE_OBJECT,
+    .abstract = true,
+    .class_size = sizeof(HostMemoryBackendClass),
+    .class_init = hostmemory_backend_class_init,
+    .instance_size = sizeof(HostMemoryBackend),
+    .instance_init = hostmemory_backend_initfn,
+    .instance_finalize = hostmemory_backend_finalize,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void register_types(void)
+{
+    type_register_static(&hostmemory_backend_info);
+}
+
+type_init(register_types);
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
new file mode 100644
index 0000000..bc3ffb3
--- /dev/null
+++ b/include/sysemu/hostmem.h
@@ -0,0 +1,60 @@
+/*
+ * QEMU Host Memory Backend
+ *
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ *   Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef QEMU_RAM_H
+#define QEMU_RAM_H
+
+#include "qom/object.h"
+#include "qapi/error.h"
+#include "exec/memory.h"
+#include "qemu/option.h"
+
+#define TYPE_MEMORY_BACKEND "memory"
+#define MEMORY_BACKEND(obj) \
+    OBJECT_CHECK(HostMemoryBackend, (obj), TYPE_MEMORY_BACKEND)
+#define MEMORY_BACKEND_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(HostMemoryBackendClass, (obj), TYPE_MEMORY_BACKEND)
+#define MEMORY_BACKEND_CLASS(klass) \
+    OBJECT_CLASS_CHECK(HostMemoryBackendClass, (klass), TYPE_MEMORY_BACKEND)
+
+typedef struct HostMemoryBackend HostMemoryBackend;
+typedef struct HostMemoryBackendClass HostMemoryBackendClass;
+
+/**
+ * HostMemoryBackendClass:
+ * @parent_class: opaque parent class container
+ */
+struct HostMemoryBackendClass {
+    ObjectClass parent_class;
+};
+
+/**
+ * @HostMemoryBackend
+ *
+ * @parent: opaque parent object container
+ * @size: amount of memory backend provides
+ * @id: unique identification string in memdev namespace
+ * @mr: MemoryRegion representing host memory belonging to backend
+ */
+struct HostMemoryBackend {
+    /* private */
+    Object parent;
+
+    /* protected */
+    uint64_t size;
+
+    MemoryRegion mr;
+};
+
+MemoryRegion *host_memory_backend_get_memory(HostMemoryBackend *backend,
+                                             Error **errp);
+
+#endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (3 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 04/31] add memdev backend infrastructure Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-21  8:10   ` Michael S. Tsirkin
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 06/31] pc: create custom generic PC machine type Igor Mammedov
                   ` (25 subsequent siblings)
  30 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Add following parameters:
  "slots" - total number of hotplug memory slots
  "maxmem" - maximum possible memory

"slots" and "maxmem" should go in pair and "maxmem" should be greater
than "mem" for memory hotplug to be enabled.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v4:
 - store maxmem & slots values in MachineState
v3:
 - store maxmem & slots values in QEMUMachineInitArgs
v2:
 - rebased on top of the latest "vl: convert -m to QemuOpts"
---
 include/hw/boards.h |    3 ++-
 qemu-options.hx     |    9 ++++++---
 vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index b62de4a..f6fbbe1 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -8,7 +8,6 @@
 #include "hw/qdev.h"
 #include "qom/object.h"
 
-
 typedef struct MachineState MachineState;
 
 typedef void QEMUMachineInitFunc(MachineState *ms);
@@ -113,6 +112,8 @@ struct MachineState {
     char *firmware;
 
     ram_addr_t ram_size;
+    ram_addr_t maxram_size;
+    uint64_t   ram_slots;
     const char *boot_order;
     const char *kernel_filename;
     const char *kernel_cmdline;
diff --git a/qemu-options.hx b/qemu-options.hx
index 781af14..c6411c4 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
 ETEXI
 
 DEF("m", HAS_ARG, QEMU_OPTION_m,
-    "-m [size=]megs\n"
+    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
     "                configure guest RAM\n"
     "                size: initial amount of guest memory (default: "
-    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
+    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
+    "                slots: number of hotplug slots (default: none)\n"
+    "                maxmem: maximum amount of guest memory (default: none)\n",
     QEMU_ARCH_ALL)
 STEXI
 @item -m [size=]@var{megs}
 @findex -m
 Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
 a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
-gigabytes respectively.
+gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
+to set amount of hotluggable memory slots and possible maximum amount of memory.
 ETEXI
 
 DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
diff --git a/vl.c b/vl.c
index 8fd4ed9..9fb6fa4 100644
--- a/vl.c
+++ b/vl.c
@@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
             .name = "size",
             .type = QEMU_OPT_SIZE,
         },
+        {
+            .name = "slots",
+            .type = QEMU_OPT_NUMBER,
+        },
+        {
+            .name = "maxmem",
+            .type = QEMU_OPT_SIZE,
+        },
         { /* end of list */ }
     },
 };
@@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
     const char *trace_file = NULL;
     const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
                                         1024 * 1024;
+    ram_addr_t maxram_size = default_ram_size;
+    uint64_t ram_slots = 0;
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
@@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
             case QEMU_OPTION_m: {
                 uint64_t sz;
                 const char *mem_str;
+                const char *maxmem_str, *slots_str;
 
                 opts = qemu_opts_parse(qemu_find_opts("memory"),
                                        optarg, 1);
@@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
                     error_report("ram size too large");
                     exit(EXIT_FAILURE);
                 }
+
+                maxmem_str = qemu_opt_get(opts, "maxmem");
+                slots_str = qemu_opt_get(opts, "slots");
+                if (maxmem_str && slots_str) {
+                    uint64_t slots;
+
+                    sz = qemu_opt_get_size(opts, "maxmem", 0);
+                    if (sz < ram_size) {
+                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
+                                "(%" PRIu64 ") <= initial memory (%"
+                                PRIu64 ")\n", sz, ram_size);
+                        exit(EXIT_FAILURE);
+                    }
+
+                    slots = qemu_opt_get_number(opts, "slots", 0);
+                    if ((sz > ram_size) && !slots) {
+                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
+                                "(%" PRIu64 ") more than initial memory (%"
+                                PRIu64 ") but no hotplug slots where "
+                                "specified\n", sz, ram_size);
+                        exit(EXIT_FAILURE);
+                    }
+
+                    if ((sz <= ram_size) && slots) {
+                        fprintf(stderr, "qemu: invalid -m option value:  %"
+                                PRIu64 " hotplug slots where specified but "
+                                "maxmem (%" PRIu64 ") <= initial memory (%"
+                                PRIu64 ")\n", slots, sz, ram_size);
+                        exit(EXIT_FAILURE);
+                    }
+                    maxram_size = sz;
+                    ram_slots = slots;
+                } else if ((!maxmem_str && slots_str) ||
+                           (maxmem_str && !slots_str)) {
+                    fprintf(stderr, "qemu: invalid -m option value: missing "
+                            "'%s' option\n", slots_str ? "maxmem" : "slots");
+                    exit(EXIT_FAILURE);
+                }
                 break;
             }
 #ifdef CONFIG_TPM
@@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
     qdev_machine_init();
 
     current_machine->ram_size = ram_size;
+    current_machine->maxram_size = maxram_size;
+    current_machine->ram_slots = ram_slots;
     current_machine->boot_order = boot_order;
     current_machine->kernel_filename = kernel_filename;
     current_machine->kernel_cmdline = kernel_cmdline;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 06/31] pc: create custom generic PC machine type
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (4 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:55   ` Marcel Apfelbaum
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 07/31] qdev: hotplug for buss-less devices Igor Mammedov
                   ` (24 subsequent siblings)
  30 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

it will be used for PC specific options/variables

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c         |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/i386/pc_piix.c    |   36 +++++++++++++++---------------
 hw/i386/pc_q35.c     |   12 +++++-----
 include/hw/i386/pc.h |   24 +++++++++++++++++++++
 4 files changed, 105 insertions(+), 24 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e6369d5..f6781d8 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1459,3 +1459,60 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
         gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
     }
 }
+
+static void pc_generic_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    QEMUMachine *qm = data;
+
+    mc->name = qm->name;
+    mc->alias = qm->alias;
+    mc->desc = qm->desc;
+    mc->init = qm->init;
+    mc->reset = qm->reset;
+    mc->hot_add_cpu = qm->hot_add_cpu;
+    mc->kvm_type = qm->kvm_type;
+    mc->block_default_type = qm->block_default_type;
+    mc->max_cpus = qm->max_cpus;
+    mc->no_serial = qm->no_serial;
+    mc->no_parallel = qm->no_parallel;
+    mc->use_virtcon = qm->use_virtcon;
+    mc->use_sclp = qm->use_sclp;
+    mc->no_floppy = qm->no_floppy;
+    mc->no_cdrom = qm->no_cdrom;
+    mc->no_sdcard = qm->no_sdcard;
+    mc->is_default = qm->is_default;
+    mc->default_machine_opts = qm->default_machine_opts;
+    mc->default_boot_order = qm->default_boot_order;
+    mc->compat_props = qm->compat_props;
+    mc->hw_version = qm->hw_version;
+}
+
+void qemu_register_pc_machine(QEMUMachine *m)
+{
+    char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL);
+    TypeInfo ti = {
+        .name       = name,
+        .parent     = TYPE_PC_MACHINE,
+        .class_init = pc_generic_machine_class_init,
+        .class_data = (void *)m,
+    };
+
+    type_register(&ti);
+    g_free(name);
+}
+
+static const TypeInfo pc_machine_info = {
+    .name = TYPE_PC_MACHINE,
+    .parent = TYPE_MACHINE,
+    .abstract = true,
+    .instance_size = sizeof(PCMachineState),
+    .class_size = sizeof(PCMachineClass),
+};
+
+static void pc_machine_register_types(void)
+{
+    type_register_static(&pc_machine_info);
+}
+
+type_init(pc_machine_register_types)
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a48e263..abb599b 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -843,25 +843,25 @@ static QEMUMachine xenfv_machine = {
 
 static void pc_machine_init(void)
 {
-    qemu_register_machine(&pc_i440fx_machine_v2_1);
-    qemu_register_machine(&pc_i440fx_machine_v2_0);
-    qemu_register_machine(&pc_i440fx_machine_v1_7);
-    qemu_register_machine(&pc_i440fx_machine_v1_6);
-    qemu_register_machine(&pc_i440fx_machine_v1_5);
-    qemu_register_machine(&pc_i440fx_machine_v1_4);
-    qemu_register_machine(&pc_machine_v1_3);
-    qemu_register_machine(&pc_machine_v1_2);
-    qemu_register_machine(&pc_machine_v1_1);
-    qemu_register_machine(&pc_machine_v1_0);
-    qemu_register_machine(&pc_machine_v0_15);
-    qemu_register_machine(&pc_machine_v0_14);
-    qemu_register_machine(&pc_machine_v0_13);
-    qemu_register_machine(&pc_machine_v0_12);
-    qemu_register_machine(&pc_machine_v0_11);
-    qemu_register_machine(&pc_machine_v0_10);
-    qemu_register_machine(&isapc_machine);
+    qemu_register_pc_machine(&pc_i440fx_machine_v2_1);
+    qemu_register_pc_machine(&pc_i440fx_machine_v2_0);
+    qemu_register_pc_machine(&pc_i440fx_machine_v1_7);
+    qemu_register_pc_machine(&pc_i440fx_machine_v1_6);
+    qemu_register_pc_machine(&pc_i440fx_machine_v1_5);
+    qemu_register_pc_machine(&pc_i440fx_machine_v1_4);
+    qemu_register_pc_machine(&pc_machine_v1_3);
+    qemu_register_pc_machine(&pc_machine_v1_2);
+    qemu_register_pc_machine(&pc_machine_v1_1);
+    qemu_register_pc_machine(&pc_machine_v1_0);
+    qemu_register_pc_machine(&pc_machine_v0_15);
+    qemu_register_pc_machine(&pc_machine_v0_14);
+    qemu_register_pc_machine(&pc_machine_v0_13);
+    qemu_register_pc_machine(&pc_machine_v0_12);
+    qemu_register_pc_machine(&pc_machine_v0_11);
+    qemu_register_pc_machine(&pc_machine_v0_10);
+    qemu_register_pc_machine(&isapc_machine);
 #ifdef CONFIG_XEN
-    qemu_register_machine(&xenfv_machine);
+    qemu_register_pc_machine(&xenfv_machine);
 #endif
 }
 
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index b3c02c1..d211393 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -384,12 +384,12 @@ static QEMUMachine pc_q35_machine_v1_4 = {
 
 static void pc_q35_machine_init(void)
 {
-    qemu_register_machine(&pc_q35_machine_v2_1);
-    qemu_register_machine(&pc_q35_machine_v2_0);
-    qemu_register_machine(&pc_q35_machine_v1_7);
-    qemu_register_machine(&pc_q35_machine_v1_6);
-    qemu_register_machine(&pc_q35_machine_v1_5);
-    qemu_register_machine(&pc_q35_machine_v1_4);
+    qemu_register_pc_machine(&pc_q35_machine_v2_1);
+    qemu_register_pc_machine(&pc_q35_machine_v2_0);
+    qemu_register_pc_machine(&pc_q35_machine_v1_7);
+    qemu_register_pc_machine(&pc_q35_machine_v1_6);
+    qemu_register_pc_machine(&pc_q35_machine_v1_5);
+    qemu_register_pc_machine(&pc_q35_machine_v1_4);
 }
 
 machine_init(pc_q35_machine_init);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 32a7687..c7b053c 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -12,9 +12,33 @@
 #include "qemu/bitmap.h"
 #include "sysemu/sysemu.h"
 #include "hw/pci/pci.h"
+#include "hw/boards.h"
 
 #define HPET_INTCAP "hpet-intcap"
 
+struct PCMachineState {
+    /*< private >*/
+    MachineState parent_obj;
+};
+
+struct PCMachineClass {
+    /*< private >*/
+    MachineClass parent_class;
+};
+
+typedef struct PCMachineState PCMachineState;
+typedef struct PCMachineClass PCMachineClass;
+
+#define TYPE_PC_MACHINE "generic-pc-machine"
+#define PC_MACHINE(obj) \
+    OBJECT_CHECK(PCMachineState, (obj), TYPE_PC_MACHINE)
+#define PC_MACHINE_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(PCMachineClass, (obj), TYPE_PC_MACHINE)
+#define PC_MACHINE_CLASS(klass) \
+    OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
+
+void qemu_register_pc_machine(QEMUMachine *m);
+
 /* PC-style peripherals (also used by other machines).  */
 
 typedef struct PcPciInfo {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 07/31] qdev: hotplug for buss-less devices
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (5 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 06/31] pc: create custom generic PC machine type Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 08/31] qdev: expose DeviceState.hotplugged field as a property Igor Mammedov
                   ` (23 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Adds get_hotplug_handler() method to machine, and
makes bus-less device to use it during hotplug
as a means to discover hotplug handler controller.
Returned controller is used to permorm a hotplug
action.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/core/qdev.c      |   13 +++++++++++++
 include/hw/boards.h |    8 ++++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 936eae6..b4585f2 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -34,6 +34,7 @@
 #include "qapi/qmp/qjson.h"
 #include "monitor/monitor.h"
 #include "hw/hotplug.h"
+#include "hw/boards.h"
 
 int qdev_hotplug = 0;
 static bool qdev_hot_added = false;
@@ -761,6 +762,18 @@ static void device_set_realized(Object *obj, bool value, Error **errp)
             local_err == NULL) {
             hotplug_handler_plug(dev->parent_bus->hotplug_handler,
                                  dev, &local_err);
+        } else if (local_err == NULL &&
+                   object_dynamic_cast(qdev_get_machine(), TYPE_MACHINE)) {
+            HotplugHandler *hotplug_ctrl;
+            MachineState *machine = MACHINE(qdev_get_machine());
+            MachineClass *mc = MACHINE_GET_CLASS(machine);
+
+            if (mc->get_hotplug_handler) {
+                hotplug_ctrl = mc->get_hotplug_handler(machine, dev);
+                if (hotplug_ctrl) {
+                    hotplug_handler_plug(hotplug_ctrl, dev, &local_err);
+                }
+            }
         }
 
         if (qdev_get_vmsd(dev) && local_err == NULL) {
diff --git a/include/hw/boards.h b/include/hw/boards.h
index f6fbbe1..e4cce46 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -60,6 +60,11 @@ extern MachineState *current_machine;
 /**
  * MachineClass:
  * @qemu_machine: #QEMUMachine
+ * @get_hotplug_handler: this function is called during bus-less
+ *    device hotplug. If defined it returns pointer to an instance
+ *    of HotplugHandler object, which handles hotplug operation
+ *    for a given @dev. It may return NULL if @dev doesn't require
+ *    any actions to be performed by hotplug handler.
  */
 struct MachineClass {
     /*< private >*/
@@ -89,6 +94,9 @@ struct MachineClass {
     const char *default_boot_order;
     GlobalProperty *compat_props;
     const char *hw_version;
+
+    HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
+                                           DeviceState *dev);
 };
 
 /**
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 08/31] qdev: expose DeviceState.hotplugged field as a property
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (6 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 07/31] qdev: hotplug for buss-less devices Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 09/31] dimm: implement dimm device abstraction Igor Mammedov
                   ` (22 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

so that management could detect via QOM interface if device was
hotplugged

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
 - fix typo in commit message (afaerber)
---
 hw/core/qdev.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index b4585f2..8f2d227 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -826,6 +826,20 @@ static bool device_get_hotpluggable(Object *obj, Error **errp)
                                 dev->parent_bus->allow_hotplug);
 }
 
+static bool device_get_hotplugged(Object *obj, Error **err)
+{
+    DeviceState *dev = DEVICE(obj);
+
+    return dev->hotplugged;
+}
+
+static void device_set_hotplugged(Object *obj, bool value, Error **err)
+{
+    DeviceState *dev = DEVICE(obj);
+
+    dev->hotplugged = value;
+}
+
 static void device_initfn(Object *obj)
 {
     DeviceState *dev = DEVICE(obj);
@@ -844,6 +858,9 @@ static void device_initfn(Object *obj)
                              device_get_realized, device_set_realized, NULL);
     object_property_add_bool(obj, "hotpluggable",
                              device_get_hotpluggable, NULL, NULL);
+    object_property_add_bool(obj, "hotplugged",
+                             device_get_hotplugged, device_set_hotplugged,
+                             &error_abort);
 
     class = object_get_class(OBJECT(dev));
     do {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 09/31] dimm: implement dimm device abstraction
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (7 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 08/31] qdev: expose DeviceState.hotplugged field as a property Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 10/31] memory: add memory_region_is_mapped() API Igor Mammedov
                   ` (21 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

From: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>

Each hotplug-able memory slot is a DimmDevice.
A hot-add operation for a DIMM:
- creates a new DimmDevice and makes hotplug controller to map it into
  guest address space

Hotplug operations are done through normal device_add commands.
For migration case, all hotplugged DIMMs on source should be specified
on target's command line using '-device' option with properties set to
the same values as on source.

To simplify review, patch introduces only DimmDevice QOM skeleton that
will be extended by following patches to implement actual memory hotplug
and related functions.

Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v4:
  drop DimmBus in favor of bus-less device hotplug
  rename property/field 'start' to 'addr'
  use defines for property names
v3:
  pc: compile memhotplug on i386 target too
v2:
  fix typo s/DimmBus/DimmDevice/ in doc comment
  s/klass/oc/;s/*/parent_obj/;a/gtk-doc markup/
---
 default-configs/i386-softmmu.mak   |    1 +
 default-configs/x86_64-softmmu.mak |    1 +
 hw/Makefile.objs                   |    1 +
 hw/mem/Makefile.objs               |    1 +
 hw/mem/dimm.c                      |  103 ++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h              |   73 +++++++++++++++++++++++++
 6 files changed, 180 insertions(+), 0 deletions(-)
 create mode 100644 hw/mem/Makefile.objs
 create mode 100644 hw/mem/dimm.c
 create mode 100644 include/hw/mem/dimm.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 37ef90f..8e08841 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -44,3 +44,4 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_ICC_BUS=y
 CONFIG_PVPANIC=y
+CONFIG_MEM_HOTPLUG=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 31bddce..66557ac 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -44,3 +44,4 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_ICC_BUS=y
 CONFIG_PVPANIC=y
+CONFIG_MEM_HOTPLUG=y
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index d178b65..52a1464 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -29,6 +29,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += usb/
 devices-dirs-$(CONFIG_VIRTIO) += virtio/
 devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
 devices-dirs-$(CONFIG_SOFTMMU) += xen/
+devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
 devices-dirs-y += core/
 common-obj-y += $(devices-dirs-y)
 obj-y += $(devices-dirs-y)
diff --git a/hw/mem/Makefile.objs b/hw/mem/Makefile.objs
new file mode 100644
index 0000000..7563ef5
--- /dev/null
+++ b/hw/mem/Makefile.objs
@@ -0,0 +1 @@
+common-obj-$(CONFIG_MEM_HOTPLUG) += dimm.o
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
new file mode 100644
index 0000000..bb81679
--- /dev/null
+++ b/hw/mem/dimm.c
@@ -0,0 +1,103 @@
+/*
+ * Dimm device for Memory Hotplug
+ *
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
+ */
+
+#include "hw/mem/dimm.h"
+#include "qemu/config-file.h"
+#include "qapi/visitor.h"
+
+static Property dimm_properties[] = {
+    DEFINE_PROP_UINT64(DIMM_ADDR_PROP, DimmDevice, addr, 0),
+    DEFINE_PROP_UINT32(DIMM_NODE_PROP, DimmDevice, node, 0),
+    DEFINE_PROP_INT32(DIMM_SLOT_PROP, DimmDevice, slot, DIMM_UNASSIGNED_SLOT),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void dimm_get_size(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    int64_t value;
+    MemoryRegion *mr;
+    DimmDevice *dimm = DIMM(obj);
+
+    mr = host_memory_backend_get_memory(dimm->hostmem, errp);
+    value = memory_region_size(mr);
+
+    visit_type_int(v, &value, name, errp);
+}
+
+static void dimm_initfn(Object *obj)
+{
+    DimmDevice *dimm = DIMM(obj);
+
+    object_property_add(obj, DIMM_SIZE_PROP, "int", dimm_get_size,
+                        NULL, NULL, NULL, &error_abort);
+    object_property_add_link(obj, DIMM_MEMDEV_PROP, TYPE_MEMORY_BACKEND,
+                             (Object **)&dimm->hostmem,
+                             qdev_prop_allow_set_link_before_realize,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                             &error_abort);
+}
+
+static void dimm_realize(DeviceState *dev, Error **errp)
+{
+    DimmDevice *dimm = DIMM(dev);
+
+    if (!dimm->hostmem) {
+        error_setg(errp, "'" DIMM_MEMDEV_PROP "' property is not set");
+        return;
+    }
+
+    if (!dev->id) {
+        error_setg(errp, "'id' property is not set");
+        return;
+    }
+}
+
+static MemoryRegion *dimm_get_memory_region(DimmDevice *dimm)
+{
+    return host_memory_backend_get_memory(dimm->hostmem, &error_abort);
+}
+
+static void dimm_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+    DimmDeviceClass *ddc = DIMM_CLASS(oc);
+
+    dc->realize = dimm_realize;
+    dc->props = dimm_properties;
+
+    ddc->get_memory_region = dimm_get_memory_region;
+}
+
+static TypeInfo dimm_info = {
+    .name          = TYPE_DIMM,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(DimmDevice),
+    .instance_init = dimm_initfn,
+    .class_init    = dimm_class_init,
+    .class_size    = sizeof(DimmDeviceClass),
+};
+
+static void dimm_register_types(void)
+{
+    type_register_static(&dimm_info);
+}
+
+type_init(dimm_register_types)
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
new file mode 100644
index 0000000..8839fb9
--- /dev/null
+++ b/include/hw/mem/dimm.h
@@ -0,0 +1,73 @@
+/*
+ * DIMM device
+ *
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * Authors:
+ *  Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
+ *  Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_DIMM_H
+#define QEMU_DIMM_H
+
+#include "exec/memory.h"
+#include "sysemu/hostmem.h"
+#include "hw/qdev.h"
+
+#define DEFAULT_DIMMSIZE (1024*1024*1024)
+
+#define TYPE_DIMM "dimm"
+#define DIMM(obj) \
+    OBJECT_CHECK(DimmDevice, (obj), TYPE_DIMM)
+#define DIMM_CLASS(oc) \
+    OBJECT_CLASS_CHECK(DimmDeviceClass, (oc), TYPE_DIMM)
+#define DIMM_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(DimmDeviceClass, (obj), TYPE_DIMM)
+
+#define DIMM_ADDR_PROP "addr"
+#define DIMM_SLOT_PROP "slot"
+#define DIMM_NODE_PROP "node"
+#define DIMM_SIZE_PROP "size"
+#define DIMM_MEMDEV_PROP "memdev"
+
+#define DIMM_UNASSIGNED_SLOT -1
+
+/**
+ * DimmDevice:
+ * @addr: starting guest physical address, where @DimmDevice is mapped.
+ *         Default value: 0, means that address is auto-allocated.
+ * @node: numa node to which @DimmDevice is attached.
+ * @slot: slot number into which @DimmDevice is plugged in.
+ *        Default value: -1, means that slot is auto-allocated.
+ * @hostmem: host memory backend providing memory for @DimmDevice
+ */
+typedef struct DimmDevice {
+    /* private */
+    DeviceState parent_obj;
+
+    /* public */
+    ram_addr_t addr;
+    uint32_t node;
+    int32_t slot;
+    HostMemoryBackend *hostmem;
+} DimmDevice;
+
+/**
+ * DimmDeviceClass:
+ * @get_memory_region: returns #MemoryRegion associated with @dimm
+ */
+typedef struct DimmDeviceClass {
+    /* private */
+    DeviceClass parent_class;
+
+    /* public */
+    MemoryRegion *(*get_memory_region)(DimmDevice *dimm);
+} DimmDeviceClass;
+
+#endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 10/31] memory: add memory_region_is_mapped() API
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (8 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 09/31] dimm: implement dimm device abstraction Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 11/31] dimm: do not allow to set already used memdev Igor Mammedov
                   ` (20 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

which allows to check if MemoryRegion is already mapped.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 include/exec/memory.h |    8 ++++++++
 memory.c              |   15 ++++++++++++++-
 2 files changed, 22 insertions(+), 1 deletions(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index 1d55ad9..ab11c32 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -848,6 +848,14 @@ void memory_region_set_alias_offset(MemoryRegion *mr,
 bool memory_region_present(MemoryRegion *parent, hwaddr addr);
 
 /**
+ * memory_region_is_mapped: returns true if #MemoryRegion is mapped
+ * into any address space.
+ *
+ * @mr: a #MemoryRegion which should be checked if it's mapped
+ */
+bool memory_region_is_mapped(MemoryRegion *mr);
+
+/**
  * memory_region_find: translate an address/size relative to a
  * MemoryRegion into a #MemoryRegionSection.
  *
diff --git a/memory.c b/memory.c
index 3f1df23..f4d8e69 100644
--- a/memory.c
+++ b/memory.c
@@ -492,7 +492,7 @@ static AddressSpace *memory_region_to_address_space(MemoryRegion *mr)
             return as;
         }
     }
-    abort();
+    return NULL;
 }
 
 /* Render a memory region into the global view.  Ranges in @view obscure
@@ -1569,6 +1569,16 @@ bool memory_region_present(MemoryRegion *parent, hwaddr addr)
     return true;
 }
 
+bool memory_region_is_mapped(MemoryRegion *mr)
+{
+    mr = memory_region_find(mr, 0, 1).mr;
+    if (!mr) {
+        return false;
+    }
+    memory_region_unref(mr);
+    return true;
+}
+
 MemoryRegionSection memory_region_find(MemoryRegion *mr,
                                        hwaddr addr, uint64_t size)
 {
@@ -1586,6 +1596,9 @@ MemoryRegionSection memory_region_find(MemoryRegion *mr,
     }
 
     as = memory_region_to_address_space(root);
+    if (!as) {
+        return ret;
+    }
     range = addrrange_make(int128_make64(addr), int128_make64(size));
 
     view = address_space_get_flatview(as);
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 11/31] dimm: do not allow to set already used memdev
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (9 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 10/31] memory: add memory_region_is_mapped() API Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 12/31] pc: initialize memory hotplug address space Igor Mammedov
                   ` (19 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

using the same memdev backend more than once will cause
assersion at MemoryRegion mapping time becase it's already
mapped. Prevent it by checking that associated MemoryRegion
is not mapped.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/mem/dimm.c |   17 ++++++++++++++++-
 1 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index bb81679..713ded5 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -42,6 +42,21 @@ static void dimm_get_size(Object *obj, Visitor *v, void *opaque,
     visit_type_int(v, &value, name, errp);
 }
 
+static void dimm_check_memdev_is_busy(Object *obj, const char *name,
+                                      Object *val, Error **errp)
+{
+    MemoryRegion *mr;
+
+    mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), errp);
+    if (memory_region_is_mapped(mr)) {
+        char *path = object_get_canonical_path_component(val);
+        error_setg(errp, "can't use already busy memdev: %s", path);
+        g_free(path);
+    } else {
+        qdev_prop_allow_set_link_before_realize(obj, name, val, errp);
+    }
+}
+
 static void dimm_initfn(Object *obj)
 {
     DimmDevice *dimm = DIMM(obj);
@@ -50,7 +65,7 @@ static void dimm_initfn(Object *obj)
                         NULL, NULL, NULL, &error_abort);
     object_property_add_link(obj, DIMM_MEMDEV_PROP, TYPE_MEMORY_BACKEND,
                              (Object **)&dimm->hostmem,
-                             qdev_prop_allow_set_link_before_realize,
+                             dimm_check_memdev_is_busy,
                              OBJ_PROP_LINK_UNREF_ON_RELEASE,
                              &error_abort);
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 12/31] pc: initialize memory hotplug address space
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (10 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 11/31] dimm: do not allow to set already used memdev Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 13/31] pc: exit QEMU if number of slots more than supported 256 Igor Mammedov
                   ` (18 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

initialize and map hotplug memory address space container
into guest's RAM address space.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
  * fix uint64_t overflow reported by Hu Tao
  * rebase on top of Marcel's patch
      "machine: Conversion of QEMUMachineInitArgs to MachineState"
---
 hw/i386/pc.c         |   26 ++++++++++++++++++++++++--
 include/hw/i386/pc.h |   10 ++++++++++
 2 files changed, 34 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f6781d8..f94cfd9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1201,6 +1201,9 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
     MemoryRegion *ram, *option_rom_mr;
     MemoryRegion *ram_below_4g, *ram_above_4g;
     FWCfgState *fw_cfg;
+    ram_addr_t ram_size = below_4g_mem_size + above_4g_mem_size;
+    MachineState *machine = MACHINE(qdev_get_machine());
+    PCMachineState *pcms = PC_MACHINE(machine);
 
     linux_boot = (kernel_filename != NULL);
 
@@ -1209,8 +1212,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
      * with older qemus that used qemu_ram_alloc().
      */
     ram = g_malloc(sizeof(*ram));
-    memory_region_init_ram(ram, NULL, "pc.ram",
-                           below_4g_mem_size + above_4g_mem_size);
+    memory_region_init_ram(ram, NULL, "pc.ram", ram_size);
     vmstate_register_ram_global(ram);
     *ram_memory = ram;
     ram_below_4g = g_malloc(sizeof(*ram_below_4g));
@@ -1227,6 +1229,26 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
         e820_add_entry(0x100000000ULL, above_4g_mem_size, E820_RAM);
     }
 
+    /* initialize hotplug memory address space */
+    if (ram_size < machine->maxram_size) {
+        ram_addr_t hotplug_mem_size =
+            machine->maxram_size - ram_size;
+
+        pcms->hotplug_memory_base =
+            ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
+
+        if ((pcms->hotplug_memory_base + hotplug_mem_size) <
+            hotplug_mem_size) {
+            error_report("unsupported amount of maximum memory: %"PRIu64,
+                         machine->maxram_size);
+            exit(EXIT_FAILURE);
+        }
+
+        memory_region_init(&pcms->hotplug_memory, OBJECT(pcms),
+                           "hotplug-memory", hotplug_mem_size);
+        memory_region_add_subregion(system_memory, pcms->hotplug_memory_base,
+                                    &pcms->hotplug_memory);
+    }
 
     /* Initialize PC system firmware */
     pc_system_firmware_init(rom_memory, guest_info->isapc_ram_fw);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c7b053c..3ae6c56 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -16,9 +16,19 @@
 
 #define HPET_INTCAP "hpet-intcap"
 
+/**
+ * PCMachineState:
+ * @hotplug_memory_base: address in guest RAM address space where hotplug memory
+ * address space begins.
+ * @hotplug_memory: hotplug memory addess space container
+ */
 struct PCMachineState {
     /*< private >*/
     MachineState parent_obj;
+
+    /* <public> */
+    ram_addr_t hotplug_memory_base;
+    MemoryRegion hotplug_memory;
 };
 
 struct PCMachineClass {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 13/31] pc: exit QEMU if number of slots more than supported 256
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (11 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 12/31] pc: initialize memory hotplug address space Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 14/31] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
                   ` (17 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

... which is imposed by current naming scheme of ACPI memory devices.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
 * use define for amount of supported slots, requested by Eduardo Habkost
---
 hw/i386/pc.c           |    6 ++++++
 include/hw/acpi/acpi.h |    6 ++++++
 2 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index f94cfd9..5522503 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1234,6 +1234,12 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
         ram_addr_t hotplug_mem_size =
             machine->maxram_size - ram_size;
 
+        if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
+            error_report("unsupported amount of memory slots: %"PRIu64,
+                         machine->ram_slots);
+            exit(EXIT_FAILURE);
+        }
+
         pcms->hotplug_memory_base =
             ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
 
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index a9fae9d..e93de6c 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -26,6 +26,12 @@
 #include "exec/memory.h"
 #include "hw/irq.h"
 
+/*
+ * current device naming scheme supports
+ * only upto 256 memory devices
+ */
+#define ACPI_MAX_RAM_SLOTS 256
+
 /* from linux include/acpi/actype.h */
 /* Default ACPI register widths */
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 14/31] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (12 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 13/31] pc: exit QEMU if number of slots more than supported 256 Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 15/31] pc: add memory hotplug handler to PC_MACHINE Igor Mammedov
                   ` (16 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

'etc/reserved-memory-end' will allow QEMU to tell BIOS where PCI
BARs mapping could safely start in high memory.

Allowing BIOS to start mapping 64-bit PCI BARs at address where it
wouldn't conflict with other mappings QEMU might place before it.

That permits QEMU to reserve extra address space before
64-bit PCI hole for memory hotplug.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
Seabios part is already commited: 0f474d07d
---
 hw/i386/pc.c         |    9 ++++++++-
 hw/i386/pc_piix.c    |    3 +++
 hw/i386/pc_q35.c     |    3 +++
 include/hw/i386/pc.h |    1 +
 4 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5522503..5be7b33 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1230,7 +1230,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
     }
 
     /* initialize hotplug memory address space */
-    if (ram_size < machine->maxram_size) {
+    if (guest_info->has_reserved_memory &&
+        (ram_size < machine->maxram_size)) {
         ram_addr_t hotplug_mem_size =
             machine->maxram_size - ram_size;
 
@@ -1270,6 +1271,12 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
     fw_cfg = bochs_bios_init();
     rom_set_fw(fw_cfg);
 
+    if (guest_info->has_reserved_memory && pcms->hotplug_memory_base) {
+        uint64_t *val = g_malloc(sizeof(*val));
+        *val = cpu_to_le64(ROUND_UP(pcms->hotplug_memory_base, 0x1ULL << 30));
+        fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
+    }
+
     if (linux_boot) {
         load_linux(fw_cfg, kernel_filename, initrd_filename, kernel_cmdline, below_4g_mem_size);
     }
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index abb599b..e133b6a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -67,6 +67,7 @@ static bool smbios_legacy_mode;
  * pages in the host.
  */
 static bool gigabyte_align = true;
+static bool has_reserved_memory = true;
 
 /* PC hardware initialisation */
 static void pc_init1(MachineState *machine,
@@ -143,6 +144,7 @@ static void pc_init1(MachineState *machine,
 
     guest_info->has_pci_info = has_pci_info;
     guest_info->isapc_ram_fw = !pci_enabled;
+    guest_info->has_reserved_memory = has_reserved_memory;
 
     if (smbios_defaults) {
         MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -267,6 +269,7 @@ static void pc_init_pci(MachineState *machine)
 static void pc_compat_2_0(MachineState *machine)
 {
     smbios_legacy_mode = true;
+    has_reserved_memory = false;
 }
 
 static void pc_compat_1_7(MachineState *machine)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index d211393..0e77476 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -57,6 +57,7 @@ static bool smbios_legacy_mode;
  * pages in the host.
  */
 static bool gigabyte_align = true;
+static bool has_reserved_memory = true;
 
 /* PC hardware initialisation */
 static void pc_q35_init(MachineState *machine)
@@ -130,6 +131,7 @@ static void pc_q35_init(MachineState *machine)
     guest_info->has_pci_info = has_pci_info;
     guest_info->isapc_ram_fw = false;
     guest_info->has_acpi_build = has_acpi_build;
+    guest_info->has_reserved_memory = has_reserved_memory;
 
     if (smbios_defaults) {
         MachineClass *mc = MACHINE_GET_CLASS(machine);
@@ -245,6 +247,7 @@ static void pc_q35_init(MachineState *machine)
 static void pc_compat_2_0(MachineState *machine)
 {
     smbios_legacy_mode = true;
+    has_reserved_memory = false;
 }
 
 static void pc_compat_1_7(MachineState *machine)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3ae6c56..3fed471 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -77,6 +77,7 @@ struct PcGuestInfo {
     uint64_t *node_cpu;
     FWCfgState *fw_cfg;
     bool has_acpi_build;
+    bool has_reserved_memory;
 };
 
 /* parallel.c */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 15/31] pc: add memory hotplug handler to PC_MACHINE
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (13 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 14/31] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 16/31] dimm: add busy address check and address auto-allocation Igor Mammedov
                   ` (15 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

that will perform mapping of DIMM device into guest's RAM address space

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c         |   59 ++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/i386/pc.h |    8 ++++++
 2 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 5be7b33..868af17 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -58,6 +58,7 @@
 #include "hw/boards.h"
 #include "hw/pci/pci_host.h"
 #include "acpi-build.h"
+#include "hw/mem/dimm.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -1537,12 +1538,70 @@ void qemu_register_pc_machine(QEMUMachine *m)
     g_free(name);
 }
 
+static void pc_dimm_plug(HotplugHandler *hotplug_dev,
+                         DeviceState *dev, Error **errp)
+{
+    Error *local_err = NULL;
+    PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+    DimmDevice *dimm = DIMM(dev);
+    DimmDeviceClass *ddc = DIMM_GET_CLASS(dimm);
+    MemoryRegion *mr = ddc->get_memory_region(dimm);
+    ram_addr_t addr = object_property_get_int(OBJECT(dimm), DIMM_ADDR_PROP,
+                                              &local_err);
+    if (local_err) {
+        goto out;
+    }
+
+    memory_region_add_subregion(&pcms->hotplug_memory,
+                                addr - pcms->hotplug_memory_base, mr);
+    vmstate_register_ram(mr, dev);
+out:
+    error_propagate(errp, local_err);
+}
+
+static void pc_machine_device_plug_cb(HotplugHandler *hotplug_dev,
+                                      DeviceState *dev, Error **errp)
+{
+    if (object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
+        pc_dimm_plug(hotplug_dev, dev, errp);
+    }
+}
+
+static HotplugHandler *pc_get_hotpug_handler(MachineState *machine,
+                                             DeviceState *dev)
+{
+    PCMachineClass *pcmc = PC_MACHINE_GET_CLASS(machine);
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
+        return HOTPLUG_HANDLER(machine);
+    }
+
+    return pcmc->get_hotplug_handler ?
+        pcmc->get_hotplug_handler(machine, dev) : NULL;
+}
+
+static void pc_machine_class_init(ObjectClass *oc, void *data)
+{
+    MachineClass *mc = MACHINE_CLASS(oc);
+    PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);
+    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
+
+    pcmc->get_hotplug_handler = mc->get_hotplug_handler;
+    mc->get_hotplug_handler = pc_get_hotpug_handler;
+    hc->plug = pc_machine_device_plug_cb;
+}
+
 static const TypeInfo pc_machine_info = {
     .name = TYPE_PC_MACHINE,
     .parent = TYPE_MACHINE,
     .abstract = true,
     .instance_size = sizeof(PCMachineState),
     .class_size = sizeof(PCMachineClass),
+    .class_init = pc_machine_class_init,
+    .interfaces = (InterfaceInfo[]) {
+         { TYPE_HOTPLUG_HANDLER },
+         { }
+    },
 };
 
 static void pc_machine_register_types(void)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 3fed471..e541c51 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -31,9 +31,17 @@ struct PCMachineState {
     MemoryRegion hotplug_memory;
 };
 
+/**
+ * PCMachineClass:
+ * @get_hotplug_handler: pointer to parent class callback @get_hotplug_handler
+ */
 struct PCMachineClass {
     /*< private >*/
     MachineClass parent_class;
+
+    /*< public >*/
+    HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
+                                           DeviceState *dev);
 };
 
 typedef struct PCMachineState PCMachineState;
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 16/31] dimm: add busy address check and address auto-allocation
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (14 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 15/31] pc: add memory hotplug handler to PC_MACHINE Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 17/31] dimm: add busy slot check and slot auto-allocation Igor Mammedov
                   ` (14 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

- if 'addr' property is not specified on -device/device_add command,
treat default value as request for assigning DimmDevice to
the first free memory region.

- if 'addr' is provided with -device/device_add command, attempt to
use it or fail command if it's already occupied or falls inside
of an existing DimmDevice memory region.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com>
---
v2:
  * abort if hotplug address-space size is too big,
        reported by Hu Tao
  * do not reset previous error in dimm_get_free_addr(),
        fixed by Tang Chen
---
 hw/i386/pc.c          |    9 ++++++
 hw/mem/dimm.c         |   76 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h |    5 +++
 3 files changed, 90 insertions(+), 0 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 868af17..42f41df 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1552,6 +1552,15 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
         goto out;
     }
 
+    addr = dimm_get_free_addr(pcms->hotplug_memory_base,
+                              memory_region_size(&pcms->hotplug_memory),
+                              !addr ? NULL : &addr,
+                              memory_region_size(mr), &local_err);
+    if (local_err) {
+        goto out;
+    }
+    object_property_set_int(OBJECT(dev), addr, DIMM_ADDR_PROP, &local_err);
+
     memory_region_add_subregion(&pcms->hotplug_memory,
                                 addr - pcms->hotplug_memory_base, mr);
     vmstate_register_ram(mr, dev);
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 713ded5..1c726c6 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -21,6 +21,82 @@
 #include "hw/mem/dimm.h"
 #include "qemu/config-file.h"
 #include "qapi/visitor.h"
+#include "qemu/range.h"
+
+static gint dimm_addr_sort(gconstpointer a, gconstpointer b)
+{
+    DimmDevice *x = DIMM(a);
+    DimmDevice *y = DIMM(b);
+
+    return x->addr - y->addr;
+}
+
+static int dimm_built_list(Object *obj, void *opaque)
+{
+    GSList **list = opaque;
+
+    if (object_dynamic_cast(obj, TYPE_DIMM)) {
+        DeviceState *dev = DEVICE(obj);
+        if (dev->realized) { /* only realized DIMMs matter */
+            *list = g_slist_insert_sorted(*list, dev, dimm_addr_sort);
+        }
+    }
+
+    object_child_foreach(obj, dimm_built_list, opaque);
+    return 0;
+}
+
+uint64_t dimm_get_free_addr(uint64_t address_space_start,
+                            uint64_t address_space_size,
+                            uint64_t *hint, uint64_t size,
+                            Error **errp)
+{
+    GSList *list = NULL, *item;
+    uint64_t new_addr, ret = 0;
+    uint64_t address_space_end = address_space_start + address_space_size;
+
+    assert(address_space_end > address_space_size);
+    object_child_foreach(qdev_get_machine(), dimm_built_list, &list);
+
+    if (hint) {
+        new_addr = *hint;
+    } else {
+        new_addr = address_space_start;
+    }
+
+    /* find address range that will fit new DIMM */
+    for (item = list; item; item = g_slist_next(item)) {
+        DimmDevice *dimm = item->data;
+        uint64_t dimm_size = object_property_get_int(OBJECT(dimm),
+                                                     DIMM_SIZE_PROP,
+                                                     errp);
+        if (errp && *errp) {
+            goto out;
+        }
+
+        if (ranges_overlap(dimm->addr, dimm_size, new_addr, size)) {
+            if (hint) {
+                DeviceState *d = DEVICE(dimm);
+                error_setg(errp, "address range conflicts with '%s'", d->id);
+                goto out;
+            }
+            new_addr = dimm->addr + dimm_size;
+        }
+    }
+    ret = new_addr;
+
+    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);
+    } else if ((new_addr + size) > address_space_end) {
+        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
+                   "] beyond 0x%" PRIx64, new_addr, size, address_space_end);
+    }
+
+out:
+    g_slist_free(list);
+    return ret;
+}
 
 static Property dimm_properties[] = {
     DEFINE_PROP_UINT64(DIMM_ADDR_PROP, DimmDevice, addr, 0),
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 8839fb9..55bdfb2 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -70,4 +70,9 @@ typedef struct DimmDeviceClass {
     MemoryRegion *(*get_memory_region)(DimmDevice *dimm);
 } DimmDeviceClass;
 
+
+uint64_t dimm_get_free_addr(uint64_t address_space_start,
+                            uint64_t address_space_size,
+                            uint64_t *hint, uint64_t size,
+                            Error **errp);
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 17/31] dimm: add busy slot check and slot auto-allocation
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (15 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 16/31] dimm: add busy address check and address auto-allocation Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 18/31] acpi: rename cpu_hotplug_defs.h to acpi_defs.h Igor Mammedov
                   ` (13 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

- if slot property is not specified on -device/device_add command,
treat default value as request for assigning DimmDevice to
the first free slot.

- if slot is provided with -device/device_add command, attempt to
use it or fail command if it's already occupied.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c          |   21 +++++++++++++++++++++
 hw/mem/dimm.c         |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h |    2 ++
 3 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 42f41df..aee8dfb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1541,8 +1541,10 @@ void qemu_register_pc_machine(QEMUMachine *m)
 static void pc_dimm_plug(HotplugHandler *hotplug_dev,
                          DeviceState *dev, Error **errp)
 {
+    int slot;
     Error *local_err = NULL;
     PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+    MachineState *machine = MACHINE(hotplug_dev);
     DimmDevice *dimm = DIMM(dev);
     DimmDeviceClass *ddc = DIMM_GET_CLASS(dimm);
     MemoryRegion *mr = ddc->get_memory_region(dimm);
@@ -1559,7 +1561,26 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     if (local_err) {
         goto out;
     }
+
     object_property_set_int(OBJECT(dev), addr, DIMM_ADDR_PROP, &local_err);
+    if (local_err) {
+        goto out;
+    }
+
+    slot = object_property_get_int(OBJECT(dev), DIMM_SLOT_PROP, &local_err);
+    if (local_err) {
+        goto out;
+    }
+
+    slot = dimm_get_free_slot(slot == DIMM_UNASSIGNED_SLOT ? NULL : &slot,
+                              machine->ram_slots, &local_err);
+    if (local_err) {
+        goto out;
+    }
+    object_property_set_int(OBJECT(dev), slot, DIMM_SLOT_PROP, &local_err);
+    if (local_err) {
+        goto out;
+    }
 
     memory_region_add_subregion(&pcms->hotplug_memory,
                                 addr - pcms->hotplug_memory_base, mr);
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 1c726c6..a189b59 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -23,6 +23,52 @@
 #include "qapi/visitor.h"
 #include "qemu/range.h"
 
+static int dimm_slot2bitmap(Object *obj, void *opaque)
+{
+    unsigned long *bitmap = opaque;
+
+    if (object_dynamic_cast(obj, TYPE_DIMM)) {
+        DeviceState *dev = DEVICE(obj);
+        if (dev->realized) { /* count only realized DIMMs */
+            DimmDevice *d = DIMM(obj);
+            set_bit(d->slot, bitmap);
+        }
+    }
+
+    object_child_foreach(obj, dimm_slot2bitmap, opaque);
+    return 0;
+}
+
+int dimm_get_free_slot(const int *hint, int max_slots, Error **errp)
+{
+    unsigned long *bitmap = bitmap_new(max_slots);
+    int slot = 0;
+
+    object_child_foreach(qdev_get_machine(), dimm_slot2bitmap, bitmap);
+
+    /* check if requested slot is not occupied */
+    if (hint) {
+        if (*hint >= max_slots) {
+            error_setg(errp, "invalid slot# %d, should be less than %d",
+                       *hint, max_slots);
+        } else if (!test_bit(*hint, bitmap)) {
+            slot = *hint;
+        } else {
+            error_setg(errp, "slot %d is busy", *hint);
+        }
+        goto out;
+    }
+
+    /* search for free slot */
+    slot = find_first_zero_bit(bitmap, max_slots);
+    if (slot == max_slots) {
+        error_setg(errp, "no free slots available");
+    }
+out:
+    g_free(bitmap);
+    return slot;
+}
+
 static gint dimm_addr_sort(gconstpointer a, gconstpointer b)
 {
     DimmDevice *x = DIMM(a);
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 55bdfb2..1be8fb2 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -75,4 +75,6 @@ uint64_t dimm_get_free_addr(uint64_t address_space_start,
                             uint64_t address_space_size,
                             uint64_t *hint, uint64_t size,
                             Error **errp);
+
+int dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 18/31] acpi: rename cpu_hotplug_defs.h to acpi_defs.h
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (16 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 17/31] dimm: add busy slot check and slot auto-allocation Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:35   ` Michael S. Tsirkin
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 19/31] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
                   ` (12 subsequent siblings)
  30 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

to make it more generic, so it could be used for memory hotplug
as well.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-dsdt.dsl              |    2 +-
 hw/i386/q35-acpi-dsdt.dsl          |    2 +-
 include/hw/acpi/acpi_defs.h        |   33 +++++++++++++++++++++++++++++++++
 include/hw/acpi/cpu_hotplug.h      |    2 +-
 include/hw/acpi/cpu_hotplug_defs.h |   33 ---------------------------------
 5 files changed, 36 insertions(+), 36 deletions(-)
 create mode 100644 include/hw/acpi/acpi_defs.h
 delete mode 100644 include/hw/acpi/cpu_hotplug_defs.h

diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
index 0a1e252..f93353f 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -306,7 +306,7 @@ DefinitionBlock (
         }
     }
 
-#include "hw/acpi/cpu_hotplug_defs.h"
+#include "hw/acpi/acpi_defs.h"
 #define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE
 #include "acpi-dsdt-cpu-hotplug.dsl"
 
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
index f4d2a2d..3838fc7 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -402,7 +402,7 @@ DefinitionBlock (
         define_gsi_link(GSIH, 0, 0x17)
     }
 
-#include "hw/acpi/cpu_hotplug_defs.h"
+#include "hw/acpi/acpi_defs.h"
 #define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE
 #include "acpi-dsdt-cpu-hotplug.dsl"
 
diff --git a/include/hw/acpi/acpi_defs.h b/include/hw/acpi/acpi_defs.h
new file mode 100644
index 0000000..0692b3b
--- /dev/null
+++ b/include/hw/acpi/acpi_defs.h
@@ -0,0 +1,33 @@
+/*
+ * QEMU ACPI hotplug utilities shared defines
+ *
+ * Copyright (C) 2014 Red Hat Inc
+ *
+ * Authors:
+ *   Igor Mammedov <imammedo@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef ACPI_DEFS_H
+#define ACPI_DEFS_H
+
+/*
+ * ONLY DEFINEs are permited in this file since it's shared
+ * between C and ASL code.
+ */
+#define ACPI_CPU_HOTPLUG_STATUS 4
+
+/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
+ * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
+ */
+#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
+
+/* 256 CPU IDs, 8 bits per entry: */
+#define ACPI_GPE_PROC_LEN 32
+
+#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
+#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
+#define ACPI_CPU_HOTPLUG_BASE_PROP "cpu-hotplug-io-base"
+
+#endif
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 4576400..1562ce8 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -13,7 +13,7 @@
 #define ACPI_HOTPLUG_H
 
 #include "hw/acpi/acpi.h"
-#include "hw/acpi/cpu_hotplug_defs.h"
+#include "hw/acpi/acpi_defs.h"
 
 typedef struct AcpiCpuHotplug {
     MemoryRegion io;
diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h
deleted file mode 100644
index ce41e4c..0000000
--- a/include/hw/acpi/cpu_hotplug_defs.h
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * QEMU ACPI hotplug utilities shared defines
- *
- * Copyright (C) 2013 Red Hat Inc
- *
- * Authors:
- *   Igor Mammedov <imammedo@redhat.com>
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- */
-#ifndef ACPI_HOTPLUG_DEFS_H
-#define ACPI_HOTPLUG_DEFS_H
-
-/*
- * ONLY DEFINEs are permited in this file since it's shared
- * between C and ASL code.
- */
-#define ACPI_CPU_HOTPLUG_STATUS 4
-
-/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
- * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
- */
-#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
-
-/* 256 CPU IDs, 8 bits per entry: */
-#define ACPI_GPE_PROC_LEN 32
-
-#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
-#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
-#define ACPI_CPU_HOTPLUG_BASE_PROP "cpu-hotplug-io-base"
-
-#endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 19/31] acpi: memory hotplug ACPI hardware implementation
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (17 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 18/31] acpi: rename cpu_hotplug_defs.h to acpi_defs.h Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 20/31] trace: add acpi memory hotplug IO region events Igor Mammedov
                   ` (11 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

- implements QEMU hardware part of memory hotplug protocol
  described at "docs/specs/acpi_mem_hotplug.txt"
- handles only memory add notification event for now

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 docs/specs/acpi_mem_hotplug.txt  |   44 +++++++++++
 hw/acpi/Makefile.objs            |    1 +
 hw/acpi/memory_hotplug.c         |  147 ++++++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi_defs.h      |    3 +
 include/hw/acpi/memory_hotplug.h |   29 ++++++++
 5 files changed, 224 insertions(+), 0 deletions(-)
 create mode 100644 docs/specs/acpi_mem_hotplug.txt
 create mode 100644 hw/acpi/memory_hotplug.c
 create mode 100644 include/hw/acpi/memory_hotplug.h

diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
new file mode 100644
index 0000000..1290994
--- /dev/null
+++ b/docs/specs/acpi_mem_hotplug.txt
@@ -0,0 +1,44 @@
+QEMU<->ACPI BIOS memory hotplug interface
+--------------------------------------
+
+ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
+events.
+
+Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
+---------------------------------------------------------------
+0xa00:
+  read access:
+      [0x0-0x3] Lo part of memory device phys address
+      [0x4-0x7] Hi part of memory device phys address
+      [0x8-0xb] Lo part of memory device size in bytes
+      [0xc-0xf] Hi part of memory device size in bytes
+      [0x10-0x13] Memory device proximity domain
+      [0x14] Memory device status fields
+          bits:
+              0: Device is enabled and may be used by guest
+              1: Device insert event, used to distinguish device for which
+                 no device check event to OSPM was issued.
+                 It's valid only when bit 1 is set.
+              2-7: reserved and should be ignored by OSPM
+      [0x15-0x17] reserved
+
+  write access:
+      [0x0-0x3] Memory device slot selector, selects active memory device.
+                All following accesses to other registers in 0xa00-0xa17
+                region will read/store data from/to selected memory device.
+      [0x4-0x7] OST event code reported by OSPM
+      [0x8-0xb] OST status code reported by OSPM
+      [0xc-0x13] reserved, writes into it are ignored
+      [0x14] Memory device control fields
+          bits:
+              0: reserved, OSPM must clear it before writing to register
+              1: if set to 1 clears device insert event, set by OSPM
+                 after it has emitted device check event for the
+                 selected memory device
+              2-7: reserved, OSPM must clear them before writing to register
+
+Selecting memory device slot beyond present range has no effect on platform:
+   - write accesses to memory hot-plug registers not documented above are
+     ignored
+   - read accesses to memory hot-plug registers not documented above return
+     all bits set to 1.
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 397d32b..004e1b2 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -1 +1,2 @@
 common-obj-$(CONFIG_ACPI) += core.o piix4.o ich9.o pcihp.o cpu_hotplug.o
+common-obj-$(CONFIG_ACPI) += memory_hotplug.o
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
new file mode 100644
index 0000000..15d8f57
--- /dev/null
+++ b/hw/acpi/memory_hotplug.c
@@ -0,0 +1,147 @@
+#include "hw/acpi/memory_hotplug.h"
+#include "hw/acpi/acpi_defs.h"
+#include "hw/mem/dimm.h"
+#include "hw/boards.h"
+
+static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
+                                         unsigned int size)
+{
+    uint32_t val = 0;
+    MemHotplugState *mem_st = opaque;
+    MemStatus *mdev;
+
+    if (mem_st->selector >= mem_st->dev_count) {
+        return 0;
+    }
+
+    mdev = &mem_st->devs[mem_st->selector];
+    switch (addr) {
+    case 0x0: /* Lo part of phys address where DIMM is mapped */
+        val = object_property_get_int(OBJECT(mdev->dimm), DIMM_ADDR_PROP, NULL);
+        break;
+    case 0x4: /* Hi part of phys address where DIMM is mapped */
+        val = object_property_get_int(OBJECT(mdev->dimm), DIMM_ADDR_PROP,
+                                      NULL) >> 32;
+        break;
+    case 0x8: /* Lo part of DIMM size */
+        val = object_property_get_int(OBJECT(mdev->dimm), DIMM_SIZE_PROP, NULL);
+        break;
+    case 0xc: /* Hi part of DIMM size */
+        val = object_property_get_int(OBJECT(mdev->dimm), DIMM_SIZE_PROP,
+                                      NULL) >> 32;
+        break;
+    case 0x10: /* node proximity for _PXM method */
+        val = object_property_get_int(OBJECT(mdev->dimm), DIMM_NODE_PROP, NULL);
+        break;
+    case 0x14: /* pack and return is_* fields */
+        val |= mdev->is_enabled   ? 1 : 0;
+        val |= mdev->is_inserting ? 2 : 0;
+        break;
+    default:
+        val = ~0;
+        break;
+    }
+    return val;
+}
+
+static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
+                                      unsigned int size)
+{
+    MemHotplugState *mem_st = opaque;
+    MemStatus *mdev;
+
+    if (!mem_st->dev_count) {
+        return;
+    }
+
+    if (addr) {
+        if (mem_st->selector >= mem_st->dev_count) {
+            return;
+        }
+    }
+
+    switch (addr) {
+    case 0x0: /* DIMM slot selector */
+        mem_st->selector = data;
+        break;
+    case 0x4: /* _OST event  */
+        mdev = &mem_st->devs[mem_st->selector];
+        if (data == 1) {
+            /* TODO: handle device insert OST event */
+        } else if (data == 3) {
+            /* TODO: handle device remove OST event */
+        }
+        mdev->ost_event = data;
+        break;
+    case 0x8: /* _OST status */
+        mdev = &mem_st->devs[mem_st->selector];
+        mdev->ost_status = data;
+        /* TODO: report async error */
+        /* TODO: implement memory removal on guest signal */
+        break;
+    case 0x14:
+        mdev = &mem_st->devs[mem_st->selector];
+        if (data & 2) { /* clear insert event */
+            mdev->is_inserting  = false;
+        }
+        break;
+    }
+
+}
+static const MemoryRegionOps acpi_memory_hotplug_ops = {
+    .read = acpi_memory_hotplug_read,
+    .write = acpi_memory_hotplug_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
+                              MemHotplugState *state)
+{
+    MachineState *machine = MACHINE(qdev_get_machine());
+
+    state->dev_count = machine->ram_slots;
+    if (!state->dev_count) {
+        return;
+    }
+
+    state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
+    memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state,
+                          "apci-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
+    memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io);
+}
+
+void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
+                         DeviceState *dev, Error **errp)
+{
+    MemStatus *mdev;
+    Error *local_err = NULL;
+    int slot = object_property_get_int(OBJECT(dev), "slot", &local_err);
+
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    if (slot >= mem_st->dev_count) {
+        char *dev_path = object_get_canonical_path(OBJECT(dev));
+        error_setg(errp, "acpi_memory_plug_cb: "
+                   "device [%s] returned invalid memory slot[%d]",
+                    dev_path, slot);
+        g_free(dev_path);
+        return;
+    }
+
+    mdev = &mem_st->devs[slot];
+    mdev->dimm = dev;
+    mdev->is_enabled = true;
+    mdev->is_inserting = true;
+
+    /* do ACPI magic */
+    ar->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
+    acpi_update_sci(ar, irq);
+    return;
+}
diff --git a/include/hw/acpi/acpi_defs.h b/include/hw/acpi/acpi_defs.h
index 0692b3b..4222d07 100644
--- a/include/hw/acpi/acpi_defs.h
+++ b/include/hw/acpi/acpi_defs.h
@@ -30,4 +30,7 @@
 #define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
 #define ACPI_CPU_HOTPLUG_BASE_PROP "cpu-hotplug-io-base"
 
+#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
+#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
+
 #endif
diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
new file mode 100644
index 0000000..8f90f72
--- /dev/null
+++ b/include/hw/acpi/memory_hotplug.h
@@ -0,0 +1,29 @@
+#ifndef QEMU_HW_ACPI_MEMORY_HOTPLUG_H
+#define QEMU_HW_ACPI_MEMORY_HOTPLUG_H
+
+#include "hw/qdev-core.h"
+#include "hw/acpi/acpi.h"
+
+#define ACPI_MEMORY_HOTPLUG_STATUS 8
+
+typedef struct MemStatus {
+    DeviceState *dimm;
+    bool is_enabled;
+    bool is_inserting;
+    uint32_t ost_event;
+    uint32_t ost_status;
+} MemStatus;
+
+typedef struct MemHotplugState {
+    MemoryRegion io;
+    uint32_t selector;
+    uint32_t dev_count;
+    MemStatus *devs;
+} MemHotplugState;
+
+void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
+                              MemHotplugState *state);
+
+void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
+                         DeviceState *dev, Error **errp);
+#endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 20/31] trace: add acpi memory hotplug IO region events
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (18 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 19/31] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 21/31] trace: pc: add DIMM slot & address allocation Igor Mammedov
                   ` (10 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Add events for tracing accesses to memory hotplug IO ports.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/memory_hotplug.c |   13 +++++++++++++
 trace-events             |   13 +++++++++++++
 2 files changed, 26 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 15d8f57..79158f1 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -2,6 +2,7 @@
 #include "hw/acpi/acpi_defs.h"
 #include "hw/mem/dimm.h"
 #include "hw/boards.h"
+#include "trace.h"
 
 static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
                                          unsigned int size)
@@ -11,6 +12,7 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
     MemStatus *mdev;
 
     if (mem_st->selector >= mem_st->dev_count) {
+        trace_mhp_acpi_invalid_slot_selected(mem_st->selector);
         return 0;
     }
 
@@ -18,24 +20,30 @@ static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
     switch (addr) {
     case 0x0: /* Lo part of phys address where DIMM is mapped */
         val = object_property_get_int(OBJECT(mdev->dimm), DIMM_ADDR_PROP, NULL);
+        trace_mhp_acpi_read_addr_lo(mem_st->selector, val);
         break;
     case 0x4: /* Hi part of phys address where DIMM is mapped */
         val = object_property_get_int(OBJECT(mdev->dimm), DIMM_ADDR_PROP,
                                       NULL) >> 32;
+        trace_mhp_acpi_read_addr_hi(mem_st->selector, val);
         break;
     case 0x8: /* Lo part of DIMM size */
         val = object_property_get_int(OBJECT(mdev->dimm), DIMM_SIZE_PROP, NULL);
+        trace_mhp_acpi_read_size_lo(mem_st->selector, val);
         break;
     case 0xc: /* Hi part of DIMM size */
         val = object_property_get_int(OBJECT(mdev->dimm), DIMM_SIZE_PROP,
                                       NULL) >> 32;
+        trace_mhp_acpi_read_size_hi(mem_st->selector, val);
         break;
     case 0x10: /* node proximity for _PXM method */
         val = object_property_get_int(OBJECT(mdev->dimm), DIMM_NODE_PROP, NULL);
+        trace_mhp_acpi_read_pxm(mem_st->selector, val);
         break;
     case 0x14: /* pack and return is_* fields */
         val |= mdev->is_enabled   ? 1 : 0;
         val |= mdev->is_inserting ? 2 : 0;
+        trace_mhp_acpi_read_flags(mem_st->selector, val);
         break;
     default:
         val = ~0;
@@ -56,6 +64,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
 
     if (addr) {
         if (mem_st->selector >= mem_st->dev_count) {
+            trace_mhp_acpi_invalid_slot_selected(mem_st->selector);
             return;
         }
     }
@@ -63,6 +72,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
     switch (addr) {
     case 0x0: /* DIMM slot selector */
         mem_st->selector = data;
+        trace_mhp_acpi_write_slot(mem_st->selector);
         break;
     case 0x4: /* _OST event  */
         mdev = &mem_st->devs[mem_st->selector];
@@ -72,10 +82,12 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
             /* TODO: handle device remove OST event */
         }
         mdev->ost_event = data;
+        trace_mhp_acpi_write_ost_ev(mem_st->selector, mdev->ost_event);
         break;
     case 0x8: /* _OST status */
         mdev = &mem_st->devs[mem_st->selector];
         mdev->ost_status = data;
+        trace_mhp_acpi_write_ost_status(mem_st->selector, mdev->ost_status);
         /* TODO: report async error */
         /* TODO: implement memory removal on guest signal */
         break;
@@ -83,6 +95,7 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
         mdev = &mem_st->devs[mem_st->selector];
         if (data & 2) { /* clear insert event */
             mdev->is_inserting  = false;
+            trace_mhp_acpi_clear_insert_evt(mem_st->selector);
         }
         break;
     }
diff --git a/trace-events b/trace-events
index b6d289d..4f4c58f 100644
--- a/trace-events
+++ b/trace-events
@@ -1252,3 +1252,16 @@ xen_pv_mmio_write(uint64_t addr) "WARNING: write to Xen PV Device MMIO space (ad
 # hw/pci/pci_host.c
 pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x -> 0x%x"
 pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, unsigned val) "%s %02u:%u @0x%x <- 0x%x"
+
+#hw/acpi/memory_hotplug.c
+mhp_acpi_invalid_slot_selected(uint32_t slot) "0x%"PRIx32
+mhp_acpi_read_addr_lo(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr lo: 0x%"PRIx32
+mhp_acpi_read_addr_hi(uint32_t slot, uint32_t addr) "slot[0x%"PRIx32"] addr hi: 0x%"PRIx32
+mhp_acpi_read_size_lo(uint32_t slot, uint32_t size) "slot[0x%"PRIx32"] size lo: 0x%"PRIx32
+mhp_acpi_read_size_hi(uint32_t slot, uint32_t size) "slot[0x%"PRIx32"] size hi: 0x%"PRIx32
+mhp_acpi_read_pxm(uint32_t slot, uint32_t pxm) "slot[0x%"PRIx32"] proximity: 0x%"PRIx32
+mhp_acpi_read_flags(uint32_t slot, uint32_t flags) "slot[0x%"PRIx32"] flags: 0x%"PRIx32
+mhp_acpi_write_slot(uint32_t slot) "set active slot: 0x%"PRIx32
+mhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "slot[0x%"PRIx32"] OST EVENT: 0x%"PRIx32
+mhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "slot[0x%"PRIx32"] OST STATUS: 0x%"PRIx32
+mhp_acpi_clear_insert_evt(uint32_t slot) "slot[0x%"PRIx32"] clear insert event"
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 21/31] trace: pc: add DIMM slot & address allocation
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (19 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 20/31] trace: add acpi memory hotplug IO region events Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 24/31] pc: ich9 lpc: make it work with global/compat properties Igor Mammedov
                   ` (9 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Add mhp_pc_dimm_assigned_slot & mhp_pc_dimm_assigned_address
events to trace which address and slot where assigned to
plugged in DIMM device on target-i386 machine.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c |    3 +++
 trace-events |    4 ++++
 2 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index aee8dfb..b6c0ef9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -59,6 +59,7 @@
 #include "hw/pci/pci_host.h"
 #include "acpi-build.h"
 #include "hw/mem/dimm.h"
+#include "trace.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -1566,6 +1567,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     if (local_err) {
         goto out;
     }
+    trace_mhp_pc_dimm_assigned_address(addr);
 
     slot = object_property_get_int(OBJECT(dev), DIMM_SLOT_PROP, &local_err);
     if (local_err) {
@@ -1581,6 +1583,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     if (local_err) {
         goto out;
     }
+    trace_mhp_pc_dimm_assigned_slot(slot);
 
     memory_region_add_subregion(&pcms->hotplug_memory,
                                 addr - pcms->hotplug_memory_base, mr);
diff --git a/trace-events b/trace-events
index 4f4c58f..d78f103 100644
--- a/trace-events
+++ b/trace-events
@@ -1265,3 +1265,7 @@ mhp_acpi_write_slot(uint32_t slot) "set active slot: 0x%"PRIx32
 mhp_acpi_write_ost_ev(uint32_t slot, uint32_t ev) "slot[0x%"PRIx32"] OST EVENT: 0x%"PRIx32
 mhp_acpi_write_ost_status(uint32_t slot, uint32_t st) "slot[0x%"PRIx32"] OST STATUS: 0x%"PRIx32
 mhp_acpi_clear_insert_evt(uint32_t slot) "slot[0x%"PRIx32"] clear insert event"
+
+#hw/i386/pc.c
+mhp_pc_dimm_assigned_slot(int slot) "0x%d"
+mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 24/31] pc: ich9 lpc: make it work with global/compat properties
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (20 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 21/31] trace: pc: add DIMM slot & address allocation Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 29/31] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
                   ` (8 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Propeties of object should be available after its instances_init()
callback is finished and not added in PCIDeviceClass.init which is
roughly corresponds to realize() method.
Moving properties adding into instances_init will fix missing
property error when global/compat property mechanism is used.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/isa/lpc_ich9.c |   15 ++++++++++-----
 1 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 51ce12d..46de3b6 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -563,7 +563,14 @@ static void ich9_lpc_add_properties(ICH9LPCState *lpc)
     ich9_pm_add_properties(OBJECT(lpc), &lpc->pm, NULL);
 }
 
-static int ich9_lpc_initfn(PCIDevice *d)
+static void ich9_lpc_initfn(Object *obj)
+{
+    ICH9LPCState *lpc = ICH9_LPC_DEVICE(obj);
+
+    ich9_lpc_add_properties(lpc);
+}
+
+static int ich9_lpc_init(PCIDevice *d)
 {
     ICH9LPCState *lpc = ICH9_LPC_DEVICE(d);
     ISABus *isa_bus;
@@ -589,9 +596,6 @@ static int ich9_lpc_initfn(PCIDevice *d)
     memory_region_add_subregion_overlap(pci_address_space_io(d),
                                         ICH9_RST_CNT_IOPORT, &lpc->rst_cnt_mem,
                                         1);
-
-    ich9_lpc_add_properties(lpc);
-
     return 0;
 }
 
@@ -642,7 +646,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
 
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
     dc->reset = ich9_lpc_reset;
-    k->init = ich9_lpc_initfn;
+    k->init = ich9_lpc_init;
     dc->vmsd = &vmstate_ich9_lpc;
     k->config_write = ich9_lpc_config_write;
     dc->desc = "ICH9 LPC bridge";
@@ -661,6 +665,7 @@ static const TypeInfo ich9_lpc_info = {
     .name       = TYPE_ICH9_LPC_DEVICE,
     .parent     = TYPE_PCI_DEVICE,
     .instance_size = sizeof(struct ICH9LPCState),
+    .instance_init = ich9_lpc_initfn,
     .class_init  = ich9_lpc_class_init,
 };
 
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 29/31] pc: ACPI BIOS: implement memory hotplug interface
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (21 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 24/31] pc: ich9 lpc: make it work with global/compat properties Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
                   ` (7 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

- provides static SSDT object for memory hotplug that can handle
  upto 4095 hotplugable memory slots
- SSDT template for memory devices and runtime generator
  of them in SSDT table.

Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
 * use define for amount of supported slots, requested by Eduardo Habkost
 * use defines in ASL code to make names more decriptive, requested by Michael S. Tsirkin
 * drop unneeded "Serialized" attr in ASL code
 * put memory ctrl ACPI device under PCI bus to avoid punching holes in its _CRS
---
 hw/i386/Makefile.objs       |    3 +-
 hw/i386/acpi-build.c        |   35 +++++++++
 hw/i386/ssdt-mem.dsl        |   77 ++++++++++++++++++++
 hw/i386/ssdt-misc.dsl       |  164 +++++++++++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi_defs.h |   21 ++++++
 5 files changed, 299 insertions(+), 1 deletions(-)
 create mode 100644 hw/i386/ssdt-mem.dsl

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index f66c349..a65473c 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -9,7 +9,8 @@ obj-y += acpi-build.o
 obj-y += bios-linker-loader.o
 hw/i386/acpi-build.o: hw/i386/acpi-build.c hw/i386/acpi-dsdt.hex \
 	hw/i386/ssdt-proc.hex hw/i386/ssdt-pcihp.hex hw/i386/ssdt-misc.hex \
-	hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex
+	hw/i386/acpi-dsdt.hex hw/i386/q35-acpi-dsdt.hex \
+	hw/i386/q35-acpi-dsdt.hex hw/i386/ssdt-mem.hex
 
 iasl-option=$(shell if test -z "`$(1) $(2) 2>&1 > /dev/null`" \
     ; then echo "$(2)"; else echo "$(3)"; fi ;)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 34c0f42..58e7306 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -37,6 +37,7 @@
 #include "bios-linker-loader.h"
 #include "hw/loader.h"
 #include "hw/isa/isa.h"
+#include "hw/acpi/memory_hotplug.h"
 
 /* Supported chipsets: */
 #include "hw/acpi/piix4.h"
@@ -667,6 +668,14 @@ static inline char acpi_get_hex(uint32_t val)
 #define ACPI_PCIQXL_SIZEOF (*ssdt_pciqxl_end - *ssdt_pciqxl_start)
 #define ACPI_PCIQXL_AML (ssdp_pcihp_aml + *ssdt_pciqxl_start)
 
+#include "hw/i386/ssdt-mem.hex"
+
+/* 0x5B 0x82 DeviceOp PkgLength NameString DimmID */
+#define ACPI_MEM_OFFSET_HEX (*ssdt_mem_name - *ssdt_mem_start + 2)
+#define ACPI_MEM_OFFSET_ID (*ssdt_mem_id - *ssdt_mem_start + 7)
+#define ACPI_MEM_SIZEOF (*ssdt_mem_end - *ssdt_mem_start)
+#define ACPI_MEM_AML (ssdm_mem_aml + *ssdt_mem_start)
+
 #define ACPI_SSDT_SIGNATURE 0x54445353 /* SSDT */
 #define ACPI_SSDT_HEADER_LENGTH 36
 
@@ -1003,6 +1012,8 @@ build_ssdt(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
            PcPciInfo *pci, PcGuestInfo *guest_info)
 {
+    MachineState *machine = MACHINE(qdev_get_machine());
+    uint32_t nr_mem = machine->ram_slots;
     unsigned acpi_cpus = guest_info->apic_id_limit;
     int ssdt_start = table_data->len;
     uint8_t *ssdt_ptr;
@@ -1031,6 +1042,9 @@ build_ssdt(GArray *table_data, GArray *linker,
     ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
                       ssdt_isa_pest[0], 16, misc->pvpanic_port);
 
+    ACPI_BUILD_SET_LE(ssdt_ptr, sizeof(ssdp_misc_aml),
+                      ssdt_mctrl_nr_slots[0], 32, nr_mem);
+
     {
         GArray *sb_scope = build_alloc_array();
         uint8_t op = 0x10; /* ScopeOp */
@@ -1084,6 +1098,27 @@ build_ssdt(GArray *table_data, GArray *linker,
             build_free_array(package);
         }
 
+        if (nr_mem) {
+            assert(nr_mem <= ACPI_MAX_RAM_SLOTS);
+            /* build memory devices */
+            for (i = 0; i < nr_mem; i++) {
+                char id[3];
+                uint8_t *mem = acpi_data_push(sb_scope, ACPI_MEM_SIZEOF);
+
+                snprintf(id, sizeof(id), "%02X", i);
+                memcpy(mem, ACPI_MEM_AML, ACPI_MEM_SIZEOF);
+                memcpy(mem + ACPI_MEM_OFFSET_HEX, id, 2);
+                memcpy(mem + ACPI_MEM_OFFSET_ID, id, 2);
+            }
+
+            /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {
+             *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
+             */
+            build_append_notify_method(sb_scope,
+                                       stringify(MEMORY_SLOT_NOTIFY_METHOD),
+                                       "MP%0.02X", nr_mem);
+        }
+
         {
             AcpiBuildPciBusHotplugState hotplug_state;
             Object *pci_host;
diff --git a/hw/i386/ssdt-mem.dsl b/hw/i386/ssdt-mem.dsl
new file mode 100644
index 0000000..d3cfaf0
--- /dev/null
+++ b/hw/i386/ssdt-mem.dsl
@@ -0,0 +1,77 @@
+/*
+ * Memory hotplug ACPI DSDT static objects definitions
+ *
+ * Copyright ProfitBricks GmbH 2012
+ * Copyright (C) 2013 Red Hat Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>
+ */
+
+/* This file is the basis for the ssdt_mem[] variable in src/acpi.c.
+ * It defines the contents of the memory device object.  At
+ * runtime, a dynamically generated SSDT will contain one copy of this
+ * AML snippet for every possible memory device in the system.  The
+ * objects will be placed in the \_SB_ namespace.
+ *
+ * In addition to the aml code generated from this file, the
+ * src/acpi.c file creates a MTFY method with an entry for each memdevice:
+ *     Method(MTFY, 2) {
+ *         If (LEqual(Arg0, 0x00)) { Notify(MP00, Arg1) }
+ *         If (LEqual(Arg0, 0x01)) { Notify(MP01, Arg1) }
+ *         ...
+ *     }
+ */
+#include "hw/acpi/acpi_defs.h"
+
+ACPI_EXTRACT_ALL_CODE ssdm_mem_aml
+
+DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
+{
+
+    External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_CRS_METHOD, MethodObj)
+    External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD, MethodObj)
+    External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_OST_METHOD, MethodObj)
+    External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD, MethodObj)
+
+    Scope(\_SB) {
+/*  v------------------ DO NOT EDIT ------------------v */
+        ACPI_EXTRACT_DEVICE_START ssdt_mem_start
+        ACPI_EXTRACT_DEVICE_END ssdt_mem_end
+        ACPI_EXTRACT_DEVICE_STRING ssdt_mem_name
+        Device(MPAA) {
+            ACPI_EXTRACT_NAME_STRING ssdt_mem_id
+            Name(_UID, "0xAA")
+/*  ^------------------ DO NOT EDIT ------------------^
+ * Don't change the above without also updating the C code.
+ */
+            Name(_HID, EISAID("PNP0C80"))
+
+            Method(_CRS, 0) {
+                Return(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_CRS_METHOD(_UID))
+            }
+
+            Method(_STA, 0) {
+                Return(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_STATUS_METHOD(_UID))
+            }
+
+            Method(_PXM, 0) {
+                Return(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_PROXIMITY_METHOD(_UID))
+            }
+
+            Method(_OST, 3) {
+                \_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_OST_METHOD(_UID, Arg0, Arg1, Arg2)
+            }
+        }
+    }
+}
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
index a4484b8..7aa92d7 100644
--- a/hw/i386/ssdt-misc.dsl
+++ b/hw/i386/ssdt-misc.dsl
@@ -12,6 +12,7 @@
  * You should have received a copy of the GNU General Public License along
  * with this program; if not, see <http://www.gnu.org/licenses/>.
  */
+#include "hw/acpi/acpi_defs.h"
 
 ACPI_EXTRACT_ALL_CODE ssdp_misc_aml
 
@@ -116,4 +117,167 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
             }
         }
     }
+
+    External(MEMORY_SLOT_NOTIFY_METHOD, MethodObj)
+    Scope(\_SB.PCI0) {
+        Device(MEMORY_HOPTLUG_DEVICE) {
+            Name(_HID, "PNP0A06")
+            Name(_UID, "Memory hotplug resources")
+
+            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
+            Name(MEMORY_SLOTS_NUMBER, 0x12345678)
+
+            /* Memory hotplug IO registers */
+            OperationRegion(MEMORY_HOTPLUG_IO_REGION, SystemIO,
+                            ACPI_MEMORY_HOTPLUG_BASE,
+                            ACPI_MEMORY_HOTPLUG_IO_LEN)
+
+            Name(_CRS, ResourceTemplate() {
+                IO(Decode16, ACPI_MEMORY_HOTPLUG_BASE, ACPI_MEMORY_HOTPLUG_BASE,
+                   0, ACPI_MEMORY_HOTPLUG_IO_LEN, IO)
+            })
+
+            Method(_STA, 0) {
+                If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
+                    Return(0x0)
+                }
+                /* present, functioning, decoding, not shown in UI */
+                Return(0xB)
+            }
+
+            Field(MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
+                MEMORY_SLOT_ADDR_LOW, 32,  // read only
+                MEMORY_SLOT_ADDR_HIGH, 32, // read only
+                MEMORY_SLOT_SIZE_LOW, 32,  // read only
+                MEMORY_SLOT_SIZE_HIGH, 32, // read only
+                MEMORY_SLOT_PROXIMITY, 32, // read only
+            }
+            Field(MEMORY_HOTPLUG_IO_REGION, ByteAcc, NoLock, Preserve) {
+                Offset(20),
+                MEMORY_SLOT_ENABLED,  1, // 1 if enabled, read only
+                MEMORY_SLOT_INSERT_EVENT, 1, // (read) 1 if has a insert event. (write) 1 to clear event
+            }
+
+            Mutex (MEMORY_SLOT_LOCK, 0)
+            Field (MEMORY_HOTPLUG_IO_REGION, DWordAcc, NoLock, Preserve) {
+                MEMORY_SLOT_SLECTOR, 32,  // DIMM selector, write only
+                MEMORY_SLOT_OST_EVENT, 32,  // _OST event code, write only
+                MEMORY_SLOT_OST_STATUS, 32,  // _OST status code, write only
+            }
+
+            Method(MEMORY_SLOT_SCAN_METHOD, 0) {
+                If (LEqual(MEMORY_SLOTS_NUMBER, Zero)) {
+                     Return(Zero)
+                }
+
+                Store(Zero, Local0) // Mem devs iterrator
+                Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
+                while (LLess(Local0, MEMORY_SLOTS_NUMBER)) {
+                    Store(Local0, MEMORY_SLOT_SLECTOR) // select Local0 DIMM
+                    If (LEqual(MEMORY_SLOT_INSERT_EVENT, One)) { // Memory device needs check
+                        MEMORY_SLOT_NOTIFY_METHOD(Local0, 1)
+                        Store(1, MEMORY_SLOT_INSERT_EVENT)
+                    }
+                    // TODO: handle memory eject request
+                    Add(Local0, One, Local0) // goto next DIMM
+                }
+                Release(MEMORY_SLOT_LOCK)
+                Return(One)
+            }
+
+            Method(MEMORY_SLOT_STATUS_METHOD, 1) {
+                Store(Zero, Local0)
+
+                Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
+                Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
+
+                If (LEqual(MEMORY_SLOT_ENABLED, One)) {
+                    Store(0xF, Local0)
+                }
+
+                Release(MEMORY_SLOT_LOCK)
+                Return(Local0)
+            }
+
+            Method(MEMORY_SLOT_CRS_METHOD, 1, Serialized) {
+                Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
+                Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
+
+                Name(MR64, ResourceTemplate() {
+                    QWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
+                    Cacheable, ReadWrite,
+                    0x0000000000000000,        // Address Space Granularity
+                    0x0000000000000000,        // Address Range Minimum
+                    0xFFFFFFFFFFFFFFFE,        // Address Range Maximum
+                    0x0000000000000000,        // Address Translation Offset
+                    0xFFFFFFFFFFFFFFFF,        // Address Length
+                    ,, MW64, AddressRangeMemory, TypeStatic)
+                })
+
+                CreateDWordField(MR64, 14, MINL)
+                CreateDWordField(MR64, 18, MINH)
+                CreateDWordField(MR64, 38, LENL)
+                CreateDWordField(MR64, 42, LENH)
+                CreateDWordField(MR64, 22, MAXL)
+                CreateDWordField(MR64, 26, MAXH)
+
+                Store(MEMORY_SLOT_ADDR_HIGH, MINH)
+                Store(MEMORY_SLOT_ADDR_LOW, MINL)
+                Store(MEMORY_SLOT_SIZE_HIGH, LENH)
+                Store(MEMORY_SLOT_SIZE_LOW, LENL)
+
+                // 64-bit math: MAX = MIN + LEN - 1
+                Add(MINL, LENL, MAXL)
+                Add(MINH, LENH, MAXH)
+                If (LLess(MAXL, MINL)) {
+                    Add(MAXH, One, MAXH)
+                }
+                If (LLess(MAXL, One)) {
+                    Subtract(MAXH, One, MAXH)
+                }
+                Subtract(MAXL, One, MAXL)
+
+                If (LEqual(MAXH, Zero)){
+                    Name(MR32, ResourceTemplate() {
+                        DWordMemory(ResourceProducer, PosDecode, MinFixed, MaxFixed,
+                        Cacheable, ReadWrite,
+                        0x00000000,        // Address Space Granularity
+                        0x00000000,        // Address Range Minimum
+                        0xFFFFFFFE,        // Address Range Maximum
+                        0x00000000,        // Address Translation Offset
+                        0xFFFFFFFF,        // Address Length
+                        ,, MW32, AddressRangeMemory, TypeStatic)
+                    })
+                    CreateDWordField(MR32, MW32._MIN, MIN)
+                    CreateDWordField(MR32, MW32._MAX, MAX)
+                    CreateDWordField(MR32, MW32._LEN, LEN)
+                    Store(MINL, MIN)
+                    Store(MAXL, MAX)
+                    Store(LENL, LEN)
+
+                    Release(MEMORY_SLOT_LOCK)
+                    Return(MR32)
+                }
+
+                Release(MEMORY_SLOT_LOCK)
+                Return(MR64)
+            }
+
+            Method(MEMORY_SLOT_PROXIMITY_METHOD, 1) {
+                Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
+                Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
+                Store(MEMORY_SLOT_PROXIMITY, Local0)
+                Release(MEMORY_SLOT_LOCK)
+                Return(Local0)
+            }
+
+            Method(MEMORY_SLOT_OST_METHOD, 4) {
+                Acquire(MEMORY_SLOT_LOCK, 0xFFFF)
+                Store(ToInteger(Arg0), MEMORY_SLOT_SLECTOR) // select DIMM
+                Store(Arg1, MEMORY_SLOT_OST_EVENT)
+                Store(Arg2, MEMORY_SLOT_OST_STATUS)
+                Release(MEMORY_SLOT_LOCK)
+            }
+        } // Device()
+    } // Scope()
 }
diff --git a/include/hw/acpi/acpi_defs.h b/include/hw/acpi/acpi_defs.h
index 4222d07..87e9cd7 100644
--- a/include/hw/acpi/acpi_defs.h
+++ b/include/hw/acpi/acpi_defs.h
@@ -33,4 +33,25 @@
 #define ACPI_MEMORY_HOTPLUG_IO_LEN 24
 #define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
 
+#define MEMORY_HOPTLUG_DEVICE        MHPD
+#define MEMORY_SLOTS_NUMBER          MDNR
+#define MEMORY_HOTPLUG_IO_REGION     HPMR
+#define MEMORY_SLOT_ADDR_LOW         MRBL
+#define MEMORY_SLOT_ADDR_HIGH        MRBH
+#define MEMORY_SLOT_SIZE_LOW         MRLL
+#define MEMORY_SLOT_SIZE_HIGH        MRLH
+#define MEMORY_SLOT_PROXIMITY        MPX
+#define MEMORY_SLOT_ENABLED          MES
+#define MEMORY_SLOT_INSERT_EVENT     MINS
+#define MEMORY_SLOT_SLECTOR          MSEL
+#define MEMORY_SLOT_OST_EVENT        MOEV
+#define MEMORY_SLOT_OST_STATUS       MOSC
+#define MEMORY_SLOT_LOCK             MLCK
+#define MEMORY_SLOT_STATUS_METHOD    MRST
+#define MEMORY_SLOT_CRS_METHOD       MCRS
+#define MEMORY_SLOT_OST_METHOD       MOST
+#define MEMORY_SLOT_PROXIMITY_METHOD MPXM
+#define MEMORY_SLOT_NOTIFY_METHOD    MTFY
+#define MEMORY_SLOT_SCAN_METHOD      MSCN
+
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (22 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 29/31] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-20 15:38   ` Michael S. Tsirkin
  2014-05-21  8:05   ` Michael S. Tsirkin
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 31/31] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
                   ` (6 subsequent siblings)
  30 siblings, 2 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

Needed for Windows to use hotplugged memory device, otherwise
it complains that server is not configured for memory hotplug.
Tests shows that aftewards it uses dynamically provided
proximity value from _PXM() method if available.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-build.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 58e7306..97e3a82 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
     uint64_t curnode;
     int srat_start, numa_start, slots;
     uint64_t mem_len, mem_base, next_base;
+    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
+    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
 
     srat_start = table_data->len;
 
@@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
         acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
     }
 
+    /*
+     * Fake entry required by Windows to enable memory hotplug in OS.
+     * Individual DIMM devices override proximity set here via _PXM method,
+     * which returns associated with it NUMA node id.
+     */
+    if (hotplug_as_size) {
+        numamem = acpi_data_push(table_data, sizeof *numamem);
+        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
+                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
+                               MEM_AFFINITY_ENABLED);
+    }
+
     build_header(linker, table_data,
                  (void *)(table_data->data + srat_start),
                  "SRAT",
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 31/31] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (23 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
@ 2014-05-20 15:15 ` Igor Mammedov
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 22/31] acpi:piix4: allow plug/unlug callbacks handle not only PCI devices Igor Mammedov
                   ` (5 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 15:15 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, tangchen, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, rth, agraf, andrey,
	vasilis.liaskovitis, pbonzini, afaerber, aurelien

also make handler edge based to avoid losing events, the same as
it has been done for PCI and CPU hotplug handlers.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
 * use memory hotplug crtl located under PCI0
---
 hw/i386/acpi-dsdt.dsl     |    5 ++++-
 hw/i386/q35-acpi-dsdt.dsl |    5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
index f93353f..e54045e 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -314,6 +314,7 @@ DefinitionBlock (
 /****************************************************************
  * General purpose events
  ****************************************************************/
+    External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
 
     Scope(\_GPE) {
         Name(_HID, "ACPI0006")
@@ -330,7 +331,9 @@ DefinitionBlock (
             // CPU hotplug event
             \_SB.PRSC()
         }
-        Method(_L03) {
+        Method(_E03) {
+            // Memory hotplug event
+            \_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
         }
         Method(_L04) {
         }
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
index 3838fc7..a0d289c 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -410,6 +410,7 @@ DefinitionBlock (
 /****************************************************************
  * General purpose events
  ****************************************************************/
+    External(\_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD, MethodObj)
 
     Scope(\_GPE) {
         Name(_HID, "ACPI0006")
@@ -422,7 +423,9 @@ DefinitionBlock (
             // CPU hotplug event
             \_SB.PRSC()
         }
-        Method(_L03) {
+        Method(_E03) {
+            // Memory hotplug event
+            \_SB.PCI0.MEMORY_HOPTLUG_DEVICE.MEMORY_SLOT_SCAN_METHOD()
         }
         Method(_L04) {
         }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 18/31] acpi: rename cpu_hotplug_defs.h to acpi_defs.h
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 18/31] acpi: rename cpu_hotplug_defs.h to acpi_defs.h Igor Mammedov
@ 2014-05-20 15:35   ` Michael S. Tsirkin
  2014-05-20 16:03     ` Igor Mammedov
  0 siblings, 1 reply; 54+ messages in thread
From: Michael S. Tsirkin @ 2014-05-20 15:35 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Tue, May 20, 2014 at 05:15:21PM +0200, Igor Mammedov wrote:
> to make it more generic, so it could be used for memory hotplug
> as well.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

These are actually qemu pc specific hotplug registers,
this name makes one think these are generic defines.
How about ./include/hw/acpi/pc-hotplug.h ?

> ---
>  hw/i386/acpi-dsdt.dsl              |    2 +-
>  hw/i386/q35-acpi-dsdt.dsl          |    2 +-
>  include/hw/acpi/acpi_defs.h        |   33 +++++++++++++++++++++++++++++++++
>  include/hw/acpi/cpu_hotplug.h      |    2 +-
>  include/hw/acpi/cpu_hotplug_defs.h |   33 ---------------------------------
>  5 files changed, 36 insertions(+), 36 deletions(-)
>  create mode 100644 include/hw/acpi/acpi_defs.h
>  delete mode 100644 include/hw/acpi/cpu_hotplug_defs.h
> 
> diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
> index 0a1e252..f93353f 100644
> --- a/hw/i386/acpi-dsdt.dsl
> +++ b/hw/i386/acpi-dsdt.dsl
> @@ -306,7 +306,7 @@ DefinitionBlock (
>          }
>      }
>  
> -#include "hw/acpi/cpu_hotplug_defs.h"
> +#include "hw/acpi/acpi_defs.h"
>  #define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE
>  #include "acpi-dsdt-cpu-hotplug.dsl"
>  
> diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
> index f4d2a2d..3838fc7 100644
> --- a/hw/i386/q35-acpi-dsdt.dsl
> +++ b/hw/i386/q35-acpi-dsdt.dsl
> @@ -402,7 +402,7 @@ DefinitionBlock (
>          define_gsi_link(GSIH, 0, 0x17)
>      }
>  
> -#include "hw/acpi/cpu_hotplug_defs.h"
> +#include "hw/acpi/acpi_defs.h"
>  #define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE
>  #include "acpi-dsdt-cpu-hotplug.dsl"
>  
> diff --git a/include/hw/acpi/acpi_defs.h b/include/hw/acpi/acpi_defs.h
> new file mode 100644
> index 0000000..0692b3b
> --- /dev/null
> +++ b/include/hw/acpi/acpi_defs.h
> @@ -0,0 +1,33 @@
> +/*
> + * QEMU ACPI hotplug utilities shared defines
> + *
> + * Copyright (C) 2014 Red Hat Inc
> + *
> + * Authors:
> + *   Igor Mammedov <imammedo@redhat.com>
> + *
> + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> + * See the COPYING file in the top-level directory.
> + */
> +#ifndef ACPI_DEFS_H
> +#define ACPI_DEFS_H
> +
> +/*
> + * ONLY DEFINEs are permited in this file since it's shared
> + * between C and ASL code.
> + */
> +#define ACPI_CPU_HOTPLUG_STATUS 4
> +
> +/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
> + * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
> + */
> +#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
> +
> +/* 256 CPU IDs, 8 bits per entry: */
> +#define ACPI_GPE_PROC_LEN 32
> +
> +#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
> +#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
> +#define ACPI_CPU_HOTPLUG_BASE_PROP "cpu-hotplug-io-base"
> +
> +#endif
> diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
> index 4576400..1562ce8 100644
> --- a/include/hw/acpi/cpu_hotplug.h
> +++ b/include/hw/acpi/cpu_hotplug.h
> @@ -13,7 +13,7 @@
>  #define ACPI_HOTPLUG_H
>  
>  #include "hw/acpi/acpi.h"
> -#include "hw/acpi/cpu_hotplug_defs.h"
> +#include "hw/acpi/acpi_defs.h"
>  
>  typedef struct AcpiCpuHotplug {
>      MemoryRegion io;
> diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h
> deleted file mode 100644
> index ce41e4c..0000000
> --- a/include/hw/acpi/cpu_hotplug_defs.h
> +++ /dev/null
> @@ -1,33 +0,0 @@
> -/*
> - * QEMU ACPI hotplug utilities shared defines
> - *
> - * Copyright (C) 2013 Red Hat Inc
> - *
> - * Authors:
> - *   Igor Mammedov <imammedo@redhat.com>
> - *
> - * This work is licensed under the terms of the GNU GPL, version 2 or later.
> - * See the COPYING file in the top-level directory.
> - */
> -#ifndef ACPI_HOTPLUG_DEFS_H
> -#define ACPI_HOTPLUG_DEFS_H
> -
> -/*
> - * ONLY DEFINEs are permited in this file since it's shared
> - * between C and ASL code.
> - */
> -#define ACPI_CPU_HOTPLUG_STATUS 4
> -
> -/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
> - * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
> - */
> -#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
> -
> -/* 256 CPU IDs, 8 bits per entry: */
> -#define ACPI_GPE_PROC_LEN 32
> -
> -#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
> -#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
> -#define ACPI_CPU_HOTPLUG_BASE_PROP "cpu-hotplug-io-base"
> -
> -#endif
> -- 
> 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
@ 2014-05-20 15:38   ` Michael S. Tsirkin
  2014-05-21  7:56     ` Igor Mammedov
  2014-05-21  8:05   ` Michael S. Tsirkin
  1 sibling, 1 reply; 54+ messages in thread
From: Michael S. Tsirkin @ 2014-05-20 15:38 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> Needed for Windows to use hotplugged memory device, otherwise
> it complains that server is not configured for memory hotplug.
> Tests shows that aftewards it uses dynamically provided
> proximity value from _PXM() method if available.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/i386/acpi-build.c |   14 ++++++++++++++
>  1 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 58e7306..97e3a82 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
>      uint64_t curnode;
>      int srat_start, numa_start, slots;
>      uint64_t mem_len, mem_base, next_base;
> +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
>  
>      srat_start = table_data->len;
>  
> @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
>          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
>      }
>  
> +    /*
> +     * Fake entry required by Windows to enable memory hotplug in OS.
> +     * Individual DIMM devices override proximity set here via _PXM method,
> +     * which returns associated with it NUMA node id.

Failed to parse this last sentence. what returns what associated with
what? Maybe split to 3-4 short sentences.

> +     */
> +    if (hotplug_as_size) {
> +        numamem = acpi_data_push(table_data, sizeof *numamem);
> +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> +                               MEM_AFFINITY_ENABLED);
> +    }
> +
>      build_header(linker, table_data,
>                   (void *)(table_data->data + srat_start),
>                   "SRAT",
> -- 
> 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 06/31] pc: create custom generic PC machine type
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 06/31] pc: create custom generic PC machine type Igor Mammedov
@ 2014-05-20 15:55   ` Marcel Apfelbaum
  2014-05-21  7:30     ` Igor Mammedov
  0 siblings, 1 reply; 54+ messages in thread
From: Marcel Apfelbaum @ 2014-05-20 15:55 UTC (permalink / raw)
  To: Igor Mammedov, Andreas Färber
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, qemu-devel, agraf,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, david,
	lersek, ehabkost, stefanha, cornelia.huck, tangchen, rth, andrey,
	vasilis.liaskovitis, pbonzini, aurelien

On Tue, 2014-05-20 at 17:15 +0200, Igor Mammedov wrote:
> it will be used for PC specific options/variables
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/i386/pc.c         |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  hw/i386/pc_piix.c    |   36 +++++++++++++++---------------
>  hw/i386/pc_q35.c     |   12 +++++-----
>  include/hw/i386/pc.h |   24 +++++++++++++++++++++
>  4 files changed, 105 insertions(+), 24 deletions(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index e6369d5..f6781d8 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1459,3 +1459,60 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
>          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
>      }
>  }
> +
> +static void pc_generic_machine_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    QEMUMachine *qm = data;
> +
> +    mc->name = qm->name;
> +    mc->alias = qm->alias;
> +    mc->desc = qm->desc;
> +    mc->init = qm->init;
> +    mc->reset = qm->reset;
> +    mc->hot_add_cpu = qm->hot_add_cpu;
> +    mc->kvm_type = qm->kvm_type;
> +    mc->block_default_type = qm->block_default_type;
> +    mc->max_cpus = qm->max_cpus;
> +    mc->no_serial = qm->no_serial;
> +    mc->no_parallel = qm->no_parallel;
> +    mc->use_virtcon = qm->use_virtcon;
> +    mc->use_sclp = qm->use_sclp;
> +    mc->no_floppy = qm->no_floppy;
> +    mc->no_cdrom = qm->no_cdrom;
> +    mc->no_sdcard = qm->no_sdcard;
> +    mc->is_default = qm->is_default;
> +    mc->default_machine_opts = qm->default_machine_opts;
> +    mc->default_boot_order = qm->default_boot_order;
> +    mc->compat_props = qm->compat_props;
> +    mc->hw_version = qm->hw_version;
> +}
Hi Igor,
This conflicts with the latest "machine as QOM object" series in which
MachineClass does not have a pointer to QEMUMachine and
pc_generic_machine_class_init is not needed anymore.

If your series will come first we will have a re-base problem on
Andreas's QOM's queue.
Andreas, what's the best practice here?

> +
> +void qemu_register_pc_machine(QEMUMachine *m)
> +{
> +    char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL);
> +    TypeInfo ti = {
> +        .name       = name,
> +        .parent     = TYPE_PC_MACHINE,
> +        .class_init = pc_generic_machine_class_init,
> +        .class_data = (void *)m,
> +    };
> +
> +    type_register(&ti);
> +    g_free(name);
> +}
> +
> +static const TypeInfo pc_machine_info = {
> +    .name = TYPE_PC_MACHINE,
> +    .parent = TYPE_MACHINE,
> +    .abstract = true,
> +    .instance_size = sizeof(PCMachineState),
> +    .class_size = sizeof(PCMachineClass),
> +};
> +
> +static void pc_machine_register_types(void)
> +{
> +    type_register_static(&pc_machine_info);
> +}
> +
> +type_init(pc_machine_register_types)
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index a48e263..abb599b 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -843,25 +843,25 @@ static QEMUMachine xenfv_machine = {
>  
>  static void pc_machine_init(void)
>  {
> -    qemu_register_machine(&pc_i440fx_machine_v2_1);
> -    qemu_register_machine(&pc_i440fx_machine_v2_0);
> -    qemu_register_machine(&pc_i440fx_machine_v1_7);
> -    qemu_register_machine(&pc_i440fx_machine_v1_6);
> -    qemu_register_machine(&pc_i440fx_machine_v1_5);
> -    qemu_register_machine(&pc_i440fx_machine_v1_4);
> -    qemu_register_machine(&pc_machine_v1_3);
> -    qemu_register_machine(&pc_machine_v1_2);
> -    qemu_register_machine(&pc_machine_v1_1);
> -    qemu_register_machine(&pc_machine_v1_0);
> -    qemu_register_machine(&pc_machine_v0_15);
> -    qemu_register_machine(&pc_machine_v0_14);
> -    qemu_register_machine(&pc_machine_v0_13);
> -    qemu_register_machine(&pc_machine_v0_12);
> -    qemu_register_machine(&pc_machine_v0_11);
> -    qemu_register_machine(&pc_machine_v0_10);
> -    qemu_register_machine(&isapc_machine);
> +    qemu_register_pc_machine(&pc_i440fx_machine_v2_1);
> +    qemu_register_pc_machine(&pc_i440fx_machine_v2_0);
> +    qemu_register_pc_machine(&pc_i440fx_machine_v1_7);
> +    qemu_register_pc_machine(&pc_i440fx_machine_v1_6);
> +    qemu_register_pc_machine(&pc_i440fx_machine_v1_5);
> +    qemu_register_pc_machine(&pc_i440fx_machine_v1_4);
> +    qemu_register_pc_machine(&pc_machine_v1_3);
> +    qemu_register_pc_machine(&pc_machine_v1_2);
> +    qemu_register_pc_machine(&pc_machine_v1_1);
> +    qemu_register_pc_machine(&pc_machine_v1_0);
> +    qemu_register_pc_machine(&pc_machine_v0_15);
> +    qemu_register_pc_machine(&pc_machine_v0_14);
> +    qemu_register_pc_machine(&pc_machine_v0_13);
> +    qemu_register_pc_machine(&pc_machine_v0_12);
> +    qemu_register_pc_machine(&pc_machine_v0_11);
> +    qemu_register_pc_machine(&pc_machine_v0_10);
> +    qemu_register_pc_machine(&isapc_machine);
>  #ifdef CONFIG_XEN
> -    qemu_register_machine(&xenfv_machine);
> +    qemu_register_pc_machine(&xenfv_machine);
>  #endif
>  }
>  
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index b3c02c1..d211393 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -384,12 +384,12 @@ static QEMUMachine pc_q35_machine_v1_4 = {
>  
>  static void pc_q35_machine_init(void)
>  {
> -    qemu_register_machine(&pc_q35_machine_v2_1);
> -    qemu_register_machine(&pc_q35_machine_v2_0);
> -    qemu_register_machine(&pc_q35_machine_v1_7);
> -    qemu_register_machine(&pc_q35_machine_v1_6);
> -    qemu_register_machine(&pc_q35_machine_v1_5);
> -    qemu_register_machine(&pc_q35_machine_v1_4);
> +    qemu_register_pc_machine(&pc_q35_machine_v2_1);
> +    qemu_register_pc_machine(&pc_q35_machine_v2_0);
> +    qemu_register_pc_machine(&pc_q35_machine_v1_7);
> +    qemu_register_pc_machine(&pc_q35_machine_v1_6);
> +    qemu_register_pc_machine(&pc_q35_machine_v1_5);
> +    qemu_register_pc_machine(&pc_q35_machine_v1_4);
>  }
>  
>  machine_init(pc_q35_machine_init);
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 32a7687..c7b053c 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -12,9 +12,33 @@
>  #include "qemu/bitmap.h"
>  #include "sysemu/sysemu.h"
>  #include "hw/pci/pci.h"
> +#include "hw/boards.h"
>  
>  #define HPET_INTCAP "hpet-intcap"
>  
> +struct PCMachineState {
> +    /*< private >*/
> +    MachineState parent_obj;
> +};
> +
> +struct PCMachineClass {
> +    /*< private >*/
> +    MachineClass parent_class;
> +};
> +
> +typedef struct PCMachineState PCMachineState;
> +typedef struct PCMachineClass PCMachineClass;
> +
> +#define TYPE_PC_MACHINE "generic-pc-machine"
I'll name it pc-machine, without introducing the "generic"
code word, but maybe is just me.

Thanks,
Marcel

> +#define PC_MACHINE(obj) \
> +    OBJECT_CHECK(PCMachineState, (obj), TYPE_PC_MACHINE)
> +#define PC_MACHINE_GET_CLASS(obj) \
> +    OBJECT_GET_CLASS(PCMachineClass, (obj), TYPE_PC_MACHINE)
> +#define PC_MACHINE_CLASS(klass) \
> +    OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
> +
> +void qemu_register_pc_machine(QEMUMachine *m);
> +
>  /* PC-style peripherals (also used by other machines).  */
>  
>  typedef struct PcPciInfo {

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 18/31] acpi: rename cpu_hotplug_defs.h to acpi_defs.h
  2014-05-20 15:35   ` Michael S. Tsirkin
@ 2014-05-20 16:03     ` Igor Mammedov
  0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-20 16:03 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Tue, 20 May 2014 18:35:33 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Tue, May 20, 2014 at 05:15:21PM +0200, Igor Mammedov wrote:
> > to make it more generic, so it could be used for memory hotplug
> > as well.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> These are actually qemu pc specific hotplug registers,
> this name makes one think these are generic defines.
> How about ./include/hw/acpi/pc-hotplug.h ?
sure

> 
> > ---
> >  hw/i386/acpi-dsdt.dsl              |    2 +-
> >  hw/i386/q35-acpi-dsdt.dsl          |    2 +-
> >  include/hw/acpi/acpi_defs.h        |   33 +++++++++++++++++++++++++++++++++
> >  include/hw/acpi/cpu_hotplug.h      |    2 +-
> >  include/hw/acpi/cpu_hotplug_defs.h |   33 ---------------------------------
> >  5 files changed, 36 insertions(+), 36 deletions(-)
> >  create mode 100644 include/hw/acpi/acpi_defs.h
> >  delete mode 100644 include/hw/acpi/cpu_hotplug_defs.h
> > 
> > diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
> > index 0a1e252..f93353f 100644
> > --- a/hw/i386/acpi-dsdt.dsl
> > +++ b/hw/i386/acpi-dsdt.dsl
> > @@ -306,7 +306,7 @@ DefinitionBlock (
> >          }
> >      }
> >  
> > -#include "hw/acpi/cpu_hotplug_defs.h"
> > +#include "hw/acpi/acpi_defs.h"
> >  #define CPU_STATUS_BASE PIIX4_CPU_HOTPLUG_IO_BASE
> >  #include "acpi-dsdt-cpu-hotplug.dsl"
> >  
> > diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
> > index f4d2a2d..3838fc7 100644
> > --- a/hw/i386/q35-acpi-dsdt.dsl
> > +++ b/hw/i386/q35-acpi-dsdt.dsl
> > @@ -402,7 +402,7 @@ DefinitionBlock (
> >          define_gsi_link(GSIH, 0, 0x17)
> >      }
> >  
> > -#include "hw/acpi/cpu_hotplug_defs.h"
> > +#include "hw/acpi/acpi_defs.h"
> >  #define CPU_STATUS_BASE ICH9_CPU_HOTPLUG_IO_BASE
> >  #include "acpi-dsdt-cpu-hotplug.dsl"
> >  
> > diff --git a/include/hw/acpi/acpi_defs.h b/include/hw/acpi/acpi_defs.h
> > new file mode 100644
> > index 0000000..0692b3b
> > --- /dev/null
> > +++ b/include/hw/acpi/acpi_defs.h
> > @@ -0,0 +1,33 @@
> > +/*
> > + * QEMU ACPI hotplug utilities shared defines
> > + *
> > + * Copyright (C) 2014 Red Hat Inc
> > + *
> > + * Authors:
> > + *   Igor Mammedov <imammedo@redhat.com>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +#ifndef ACPI_DEFS_H
> > +#define ACPI_DEFS_H
> > +
> > +/*
> > + * ONLY DEFINEs are permited in this file since it's shared
> > + * between C and ASL code.
> > + */
> > +#define ACPI_CPU_HOTPLUG_STATUS 4
> > +
> > +/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
> > + * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
> > + */
> > +#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
> > +
> > +/* 256 CPU IDs, 8 bits per entry: */
> > +#define ACPI_GPE_PROC_LEN 32
> > +
> > +#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
> > +#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
> > +#define ACPI_CPU_HOTPLUG_BASE_PROP "cpu-hotplug-io-base"
> > +
> > +#endif
> > diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
> > index 4576400..1562ce8 100644
> > --- a/include/hw/acpi/cpu_hotplug.h
> > +++ b/include/hw/acpi/cpu_hotplug.h
> > @@ -13,7 +13,7 @@
> >  #define ACPI_HOTPLUG_H
> >  
> >  #include "hw/acpi/acpi.h"
> > -#include "hw/acpi/cpu_hotplug_defs.h"
> > +#include "hw/acpi/acpi_defs.h"
> >  
> >  typedef struct AcpiCpuHotplug {
> >      MemoryRegion io;
> > diff --git a/include/hw/acpi/cpu_hotplug_defs.h b/include/hw/acpi/cpu_hotplug_defs.h
> > deleted file mode 100644
> > index ce41e4c..0000000
> > --- a/include/hw/acpi/cpu_hotplug_defs.h
> > +++ /dev/null
> > @@ -1,33 +0,0 @@
> > -/*
> > - * QEMU ACPI hotplug utilities shared defines
> > - *
> > - * Copyright (C) 2013 Red Hat Inc
> > - *
> > - * Authors:
> > - *   Igor Mammedov <imammedo@redhat.com>
> > - *
> > - * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > - * See the COPYING file in the top-level directory.
> > - */
> > -#ifndef ACPI_HOTPLUG_DEFS_H
> > -#define ACPI_HOTPLUG_DEFS_H
> > -
> > -/*
> > - * ONLY DEFINEs are permited in this file since it's shared
> > - * between C and ASL code.
> > - */
> > -#define ACPI_CPU_HOTPLUG_STATUS 4
> > -
> > -/* Limit for CPU arch IDs for CPU hotplug. All hotpluggable CPUs should
> > - * have CPUClass.get_arch_id() < ACPI_CPU_HOTPLUG_ID_LIMIT.
> > - */
> > -#define ACPI_CPU_HOTPLUG_ID_LIMIT 256
> > -
> > -/* 256 CPU IDs, 8 bits per entry: */
> > -#define ACPI_GPE_PROC_LEN 32
> > -
> > -#define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
> > -#define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
> > -#define ACPI_CPU_HOTPLUG_BASE_PROP "cpu-hotplug-io-base"
> > -
> > -#endif
> > -- 
> > 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 06/31] pc: create custom generic PC machine type
  2014-05-20 15:55   ` Marcel Apfelbaum
@ 2014-05-21  7:30     ` Igor Mammedov
  0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21  7:30 UTC (permalink / raw)
  To: Marcel Apfelbaum
  Cc: peter.maydell, alex, mst, aik, hutao, mjt, qemu-devel, agraf,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, david,
	lersek, ehabkost, stefanha, cornelia.huck, tangchen, rth, andrey,
	vasilis.liaskovitis, pbonzini, Andreas Färber, aurelien

On Tue, 20 May 2014 18:55:32 +0300
Marcel Apfelbaum <marcel.a@redhat.com> wrote:

> On Tue, 2014-05-20 at 17:15 +0200, Igor Mammedov wrote:
> > it will be used for PC specific options/variables
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/i386/pc.c         |   57 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  hw/i386/pc_piix.c    |   36 +++++++++++++++---------------
> >  hw/i386/pc_q35.c     |   12 +++++-----
> >  include/hw/i386/pc.h |   24 +++++++++++++++++++++
> >  4 files changed, 105 insertions(+), 24 deletions(-)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index e6369d5..f6781d8 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1459,3 +1459,60 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name)
> >          gsi_state->ioapic_irq[i] = qdev_get_gpio_in(dev, i);
> >      }
> >  }
> > +
> > +static void pc_generic_machine_class_init(ObjectClass *oc, void *data)
> > +{
> > +    MachineClass *mc = MACHINE_CLASS(oc);
> > +    QEMUMachine *qm = data;
> > +
> > +    mc->name = qm->name;
> > +    mc->alias = qm->alias;
> > +    mc->desc = qm->desc;
> > +    mc->init = qm->init;
> > +    mc->reset = qm->reset;
> > +    mc->hot_add_cpu = qm->hot_add_cpu;
> > +    mc->kvm_type = qm->kvm_type;
> > +    mc->block_default_type = qm->block_default_type;
> > +    mc->max_cpus = qm->max_cpus;
> > +    mc->no_serial = qm->no_serial;
> > +    mc->no_parallel = qm->no_parallel;
> > +    mc->use_virtcon = qm->use_virtcon;
> > +    mc->use_sclp = qm->use_sclp;
> > +    mc->no_floppy = qm->no_floppy;
> > +    mc->no_cdrom = qm->no_cdrom;
> > +    mc->no_sdcard = qm->no_sdcard;
> > +    mc->is_default = qm->is_default;
> > +    mc->default_machine_opts = qm->default_machine_opts;
> > +    mc->default_boot_order = qm->default_boot_order;
> > +    mc->compat_props = qm->compat_props;
> > +    mc->hw_version = qm->hw_version;
> > +}
> Hi Igor,
> This conflicts with the latest "machine as QOM object" series in which
> MachineClass does not have a pointer to QEMUMachine and
> pc_generic_machine_class_init is not needed anymore.
I'm not sure with what it conflicts, this patch is rebased on top of
https://github.com/afaerber/qemu-cpu/commit/33ead66c86c96e37d141cfcfda5664b2fa0408fd
from qom-next queue, which drops QEMUMachineInitArgs but QEMUMachine is still exists/used.

MachineClass does not have a pointer to QEMUMachine so we have to
initialize MachineClass fields directly /that's what's changed from previous version/

If there will be more patches about Machine conversion in qom-next before
next series respin, I'll rebase it on top them.
> 
> If your series will come first we will have a re-base problem on
> Andreas's QOM's queue.
> Andreas, what's the best practice here?
> 
> > +
> > +void qemu_register_pc_machine(QEMUMachine *m)
> > +{
> > +    char *name = g_strconcat(m->name, TYPE_MACHINE_SUFFIX, NULL);
> > +    TypeInfo ti = {
> > +        .name       = name,
> > +        .parent     = TYPE_PC_MACHINE,
> > +        .class_init = pc_generic_machine_class_init,
> > +        .class_data = (void *)m,
> > +    };
> > +
> > +    type_register(&ti);
> > +    g_free(name);
> > +}
> > +
> > +static const TypeInfo pc_machine_info = {
> > +    .name = TYPE_PC_MACHINE,
> > +    .parent = TYPE_MACHINE,
> > +    .abstract = true,
> > +    .instance_size = sizeof(PCMachineState),
> > +    .class_size = sizeof(PCMachineClass),
> > +};
> > +
> > +static void pc_machine_register_types(void)
> > +{
> > +    type_register_static(&pc_machine_info);
> > +}
> > +
> > +type_init(pc_machine_register_types)
> > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> > index a48e263..abb599b 100644
> > --- a/hw/i386/pc_piix.c
> > +++ b/hw/i386/pc_piix.c
> > @@ -843,25 +843,25 @@ static QEMUMachine xenfv_machine = {
> >  
> >  static void pc_machine_init(void)
> >  {
> > -    qemu_register_machine(&pc_i440fx_machine_v2_1);
> > -    qemu_register_machine(&pc_i440fx_machine_v2_0);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_7);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_6);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_5);
> > -    qemu_register_machine(&pc_i440fx_machine_v1_4);
> > -    qemu_register_machine(&pc_machine_v1_3);
> > -    qemu_register_machine(&pc_machine_v1_2);
> > -    qemu_register_machine(&pc_machine_v1_1);
> > -    qemu_register_machine(&pc_machine_v1_0);
> > -    qemu_register_machine(&pc_machine_v0_15);
> > -    qemu_register_machine(&pc_machine_v0_14);
> > -    qemu_register_machine(&pc_machine_v0_13);
> > -    qemu_register_machine(&pc_machine_v0_12);
> > -    qemu_register_machine(&pc_machine_v0_11);
> > -    qemu_register_machine(&pc_machine_v0_10);
> > -    qemu_register_machine(&isapc_machine);
> > +    qemu_register_pc_machine(&pc_i440fx_machine_v2_1);
> > +    qemu_register_pc_machine(&pc_i440fx_machine_v2_0);
> > +    qemu_register_pc_machine(&pc_i440fx_machine_v1_7);
> > +    qemu_register_pc_machine(&pc_i440fx_machine_v1_6);
> > +    qemu_register_pc_machine(&pc_i440fx_machine_v1_5);
> > +    qemu_register_pc_machine(&pc_i440fx_machine_v1_4);
> > +    qemu_register_pc_machine(&pc_machine_v1_3);
> > +    qemu_register_pc_machine(&pc_machine_v1_2);
> > +    qemu_register_pc_machine(&pc_machine_v1_1);
> > +    qemu_register_pc_machine(&pc_machine_v1_0);
> > +    qemu_register_pc_machine(&pc_machine_v0_15);
> > +    qemu_register_pc_machine(&pc_machine_v0_14);
> > +    qemu_register_pc_machine(&pc_machine_v0_13);
> > +    qemu_register_pc_machine(&pc_machine_v0_12);
> > +    qemu_register_pc_machine(&pc_machine_v0_11);
> > +    qemu_register_pc_machine(&pc_machine_v0_10);
> > +    qemu_register_pc_machine(&isapc_machine);
> >  #ifdef CONFIG_XEN
> > -    qemu_register_machine(&xenfv_machine);
> > +    qemu_register_pc_machine(&xenfv_machine);
> >  #endif
> >  }
> >  
> > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > index b3c02c1..d211393 100644
> > --- a/hw/i386/pc_q35.c
> > +++ b/hw/i386/pc_q35.c
> > @@ -384,12 +384,12 @@ static QEMUMachine pc_q35_machine_v1_4 = {
> >  
> >  static void pc_q35_machine_init(void)
> >  {
> > -    qemu_register_machine(&pc_q35_machine_v2_1);
> > -    qemu_register_machine(&pc_q35_machine_v2_0);
> > -    qemu_register_machine(&pc_q35_machine_v1_7);
> > -    qemu_register_machine(&pc_q35_machine_v1_6);
> > -    qemu_register_machine(&pc_q35_machine_v1_5);
> > -    qemu_register_machine(&pc_q35_machine_v1_4);
> > +    qemu_register_pc_machine(&pc_q35_machine_v2_1);
> > +    qemu_register_pc_machine(&pc_q35_machine_v2_0);
> > +    qemu_register_pc_machine(&pc_q35_machine_v1_7);
> > +    qemu_register_pc_machine(&pc_q35_machine_v1_6);
> > +    qemu_register_pc_machine(&pc_q35_machine_v1_5);
> > +    qemu_register_pc_machine(&pc_q35_machine_v1_4);
> >  }
> >  
> >  machine_init(pc_q35_machine_init);
> > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > index 32a7687..c7b053c 100644
> > --- a/include/hw/i386/pc.h
> > +++ b/include/hw/i386/pc.h
> > @@ -12,9 +12,33 @@
> >  #include "qemu/bitmap.h"
> >  #include "sysemu/sysemu.h"
> >  #include "hw/pci/pci.h"
> > +#include "hw/boards.h"
> >  
> >  #define HPET_INTCAP "hpet-intcap"
> >  
> > +struct PCMachineState {
> > +    /*< private >*/
> > +    MachineState parent_obj;
> > +};
> > +
> > +struct PCMachineClass {
> > +    /*< private >*/
> > +    MachineClass parent_class;
> > +};
> > +
> > +typedef struct PCMachineState PCMachineState;
> > +typedef struct PCMachineClass PCMachineClass;
> > +
> > +#define TYPE_PC_MACHINE "generic-pc-machine"
> I'll name it pc-machine, without introducing the "generic"
> code word, but maybe is just me.
> 
> Thanks,
> Marcel
> 
> > +#define PC_MACHINE(obj) \
> > +    OBJECT_CHECK(PCMachineState, (obj), TYPE_PC_MACHINE)
> > +#define PC_MACHINE_GET_CLASS(obj) \
> > +    OBJECT_GET_CLASS(PCMachineClass, (obj), TYPE_PC_MACHINE)
> > +#define PC_MACHINE_CLASS(klass) \
> > +    OBJECT_CLASS_CHECK(PCMachineClass, (klass), TYPE_PC_MACHINE)
> > +
> > +void qemu_register_pc_machine(QEMUMachine *m);
> > +
> >  /* PC-style peripherals (also used by other machines).  */
> >  
> >  typedef struct PcPciInfo {
> 
> 
> 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-20 15:38   ` Michael S. Tsirkin
@ 2014-05-21  7:56     ` Igor Mammedov
  2014-05-21  8:02       ` Michael S. Tsirkin
  0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21  7:56 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Tue, 20 May 2014 18:38:15 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> > Needed for Windows to use hotplugged memory device, otherwise
> > it complains that server is not configured for memory hotplug.
> > Tests shows that aftewards it uses dynamically provided
> > proximity value from _PXM() method if available.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/i386/acpi-build.c |   14 ++++++++++++++
> >  1 files changed, 14 insertions(+), 0 deletions(-)
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 58e7306..97e3a82 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
> >      uint64_t curnode;
> >      int srat_start, numa_start, slots;
> >      uint64_t mem_len, mem_base, next_base;
> > +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> > +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
> >  
> >      srat_start = table_data->len;
> >  
> > @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
> >          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
> >      }
> >  
> > +    /*
> > +     * Fake entry required by Windows to enable memory hotplug in OS.
> > +     * Individual DIMM devices override proximity set here via _PXM method,
> > +     * which returns associated with it NUMA node id.
> 
> Failed to parse this last sentence. what returns what associated with
> what? Maybe split to 3-4 short sentences.
How about:
"
Entry is required for Windows to enable memory hotplug in OS.
Memory devices may override proximity set by this entry,
providing _PXM method if necessary.
"

> 
> > +     */
> > +    if (hotplug_as_size) {
> > +        numamem = acpi_data_push(table_data, sizeof *numamem);
> > +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> > +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> > +                               MEM_AFFINITY_ENABLED);
> > +    }
> > +
> >      build_header(linker, table_data,
> >                   (void *)(table_data->data + srat_start),
> >                   "SRAT",
> > -- 
> > 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-21  7:56     ` Igor Mammedov
@ 2014-05-21  8:02       ` Michael S. Tsirkin
  0 siblings, 0 replies; 54+ messages in thread
From: Michael S. Tsirkin @ 2014-05-21  8:02 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Wed, May 21, 2014 at 09:56:13AM +0200, Igor Mammedov wrote:
> On Tue, 20 May 2014 18:38:15 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> > > Needed for Windows to use hotplugged memory device, otherwise
> > > it complains that server is not configured for memory hotplug.
> > > Tests shows that aftewards it uses dynamically provided
> > > proximity value from _PXM() method if available.
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > >  hw/i386/acpi-build.c |   14 ++++++++++++++
> > >  1 files changed, 14 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index 58e7306..97e3a82 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
> > >      uint64_t curnode;
> > >      int srat_start, numa_start, slots;
> > >      uint64_t mem_len, mem_base, next_base;
> > > +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> > > +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
> > >  
> > >      srat_start = table_data->len;
> > >  
> > > @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
> > >          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
> > >      }
> > >  
> > > +    /*
> > > +     * Fake entry required by Windows to enable memory hotplug in OS.
> > > +     * Individual DIMM devices override proximity set here via _PXM method,
> > > +     * which returns associated with it NUMA node id.
> > 
> > Failed to parse this last sentence. what returns what associated with
> > what? Maybe split to 3-4 short sentences.
> How about:
> "
> Entry is required for Windows to enable memory hotplug in OS.
> Memory devices may override proximity set by this entry,
> providing _PXM method if necessary.
> "

Sounds good, thanks.

> > 
> > > +     */
> > > +    if (hotplug_as_size) {
> > > +        numamem = acpi_data_push(table_data, sizeof *numamem);
> > > +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> > > +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> > > +                               MEM_AFFINITY_ENABLED);
> > > +    }
> > > +
> > >      build_header(linker, table_data,
> > >                   (void *)(table_data->data + srat_start),
> > >                   "SRAT",
> > > -- 
> > > 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
  2014-05-20 15:38   ` Michael S. Tsirkin
@ 2014-05-21  8:05   ` Michael S. Tsirkin
  2014-05-21 11:22     ` Igor Mammedov
  1 sibling, 1 reply; 54+ messages in thread
From: Michael S. Tsirkin @ 2014-05-21  8:05 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> Needed for Windows to use hotplugged memory device, otherwise
> it complains that server is not configured for memory hotplug.
> Tests shows that aftewards it uses dynamically provided
> proximity value from _PXM() method if available.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/i386/acpi-build.c |   14 ++++++++++++++
>  1 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 58e7306..97e3a82 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
>      uint64_t curnode;
>      int srat_start, numa_start, slots;
>      uint64_t mem_len, mem_base, next_base;
> +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
>  
>      srat_start = table_data->len;
>

Please don't abbreviate address space as "as". If you abbreviate as as
as it can be misunderstood for the English as which stands for as.
You see how confusing this can be :)
How about hotplug_memory_max_size?

Also, it would be a bit more elegant to make this a read-only property
of the machine.
  
> @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
>          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
>      }
>  
> +    /*
> +     * Fake entry required by Windows to enable memory hotplug in OS.
> +     * Individual DIMM devices override proximity set here via _PXM method,
> +     * which returns associated with it NUMA node id.
> +     */
> +    if (hotplug_as_size) {
> +        numamem = acpi_data_push(table_data, sizeof *numamem);
> +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> +                               MEM_AFFINITY_ENABLED);
> +    }
> +
>      build_header(linker, table_data,
>                   (void *)(table_data->data + srat_start),
>                   "SRAT",
> -- 
> 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
@ 2014-05-21  8:10   ` Michael S. Tsirkin
  2014-05-21  8:26     ` Igor Mammedov
  2014-05-21  8:27     ` Andrey Korolyov
  0 siblings, 2 replies; 54+ messages in thread
From: Michael S. Tsirkin @ 2014-05-21  8:10 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Tue, May 20, 2014 at 05:15:08PM +0200, Igor Mammedov wrote:
> Add following parameters:
>   "slots" - total number of hotplug memory slots
>   "maxmem" - maximum possible memory
> 
> "slots" and "maxmem" should go in pair and "maxmem" should be greater
> than "mem" for memory hotplug to be enabled.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

Also, it's a bug to mix this with a compat machine type, right?
Maybe best to fail initialization if users try this.

> ---
> v4:
>  - store maxmem & slots values in MachineState
> v3:
>  - store maxmem & slots values in QEMUMachineInitArgs
> v2:
>  - rebased on top of the latest "vl: convert -m to QemuOpts"
> ---
>  include/hw/boards.h |    3 ++-
>  qemu-options.hx     |    9 ++++++---
>  vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 59 insertions(+), 4 deletions(-)
> 
> diff --git a/include/hw/boards.h b/include/hw/boards.h
> index b62de4a..f6fbbe1 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -8,7 +8,6 @@
>  #include "hw/qdev.h"
>  #include "qom/object.h"
>  
> -
>  typedef struct MachineState MachineState;
>  
>  typedef void QEMUMachineInitFunc(MachineState *ms);
> @@ -113,6 +112,8 @@ struct MachineState {
>      char *firmware;
>  
>      ram_addr_t ram_size;
> +    ram_addr_t maxram_size;
> +    uint64_t   ram_slots;
>      const char *boot_order;
>      const char *kernel_filename;
>      const char *kernel_cmdline;
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 781af14..c6411c4 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
>  ETEXI
>  
>  DEF("m", HAS_ARG, QEMU_OPTION_m,
> -    "-m [size=]megs\n"
> +    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
>      "                configure guest RAM\n"
>      "                size: initial amount of guest memory (default: "
> -    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
> +    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
> +    "                slots: number of hotplug slots (default: none)\n"
> +    "                maxmem: maximum amount of guest memory (default: none)\n",
>      QEMU_ARCH_ALL)
>  STEXI
>  @item -m [size=]@var{megs}
>  @findex -m
>  Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
>  a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
> -gigabytes respectively.
> +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
> +to set amount of hotluggable memory slots and possible maximum amount of memory.
>  ETEXI
>  
>  DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
> diff --git a/vl.c b/vl.c
> index 8fd4ed9..9fb6fa4 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
>              .name = "size",
>              .type = QEMU_OPT_SIZE,
>          },
> +        {
> +            .name = "slots",
> +            .type = QEMU_OPT_NUMBER,
> +        },
> +        {
> +            .name = "maxmem",
> +            .type = QEMU_OPT_SIZE,
> +        },
>          { /* end of list */ }
>      },
>  };
> @@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
>      const char *trace_file = NULL;
>      const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
>                                          1024 * 1024;
> +    ram_addr_t maxram_size = default_ram_size;
> +    uint64_t ram_slots = 0;
>  
>      atexit(qemu_run_exit_notifiers);
>      error_set_progname(argv[0]);
> @@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
>              case QEMU_OPTION_m: {
>                  uint64_t sz;
>                  const char *mem_str;
> +                const char *maxmem_str, *slots_str;
>  
>                  opts = qemu_opts_parse(qemu_find_opts("memory"),
>                                         optarg, 1);
> @@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
>                      error_report("ram size too large");
>                      exit(EXIT_FAILURE);
>                  }
> +
> +                maxmem_str = qemu_opt_get(opts, "maxmem");
> +                slots_str = qemu_opt_get(opts, "slots");
> +                if (maxmem_str && slots_str) {
> +                    uint64_t slots;
> +
> +                    sz = qemu_opt_get_size(opts, "maxmem", 0);
> +                    if (sz < ram_size) {
> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> +                                "(%" PRIu64 ") <= initial memory (%"
> +                                PRIu64 ")\n", sz, ram_size);
> +                        exit(EXIT_FAILURE);
> +                    }
> +
> +                    slots = qemu_opt_get_number(opts, "slots", 0);
> +                    if ((sz > ram_size) && !slots) {
> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> +                                "(%" PRIu64 ") more than initial memory (%"
> +                                PRIu64 ") but no hotplug slots where "
> +                                "specified\n", sz, ram_size);
> +                        exit(EXIT_FAILURE);
> +                    }
> +
> +                    if ((sz <= ram_size) && slots) {
> +                        fprintf(stderr, "qemu: invalid -m option value:  %"
> +                                PRIu64 " hotplug slots where specified but "
> +                                "maxmem (%" PRIu64 ") <= initial memory (%"
> +                                PRIu64 ")\n", slots, sz, ram_size);
> +                        exit(EXIT_FAILURE);
> +                    }
> +                    maxram_size = sz;
> +                    ram_slots = slots;
> +                } else if ((!maxmem_str && slots_str) ||
> +                           (maxmem_str && !slots_str)) {
> +                    fprintf(stderr, "qemu: invalid -m option value: missing "
> +                            "'%s' option\n", slots_str ? "maxmem" : "slots");
> +                    exit(EXIT_FAILURE);
> +                }
>                  break;
>              }
>  #ifdef CONFIG_TPM
> @@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
>      qdev_machine_init();
>  
>      current_machine->ram_size = ram_size;
> +    current_machine->maxram_size = maxram_size;
> +    current_machine->ram_slots = ram_slots;
>      current_machine->boot_order = boot_order;
>      current_machine->kernel_filename = kernel_filename;
>      current_machine->kernel_cmdline = kernel_cmdline;
> -- 
> 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-21  8:10   ` Michael S. Tsirkin
@ 2014-05-21  8:26     ` Igor Mammedov
  2014-05-21  8:27     ` Andrey Korolyov
  1 sibling, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21  8:26 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, agraf, kraxel,
	pasteka, s.priebe, agarcia, armbru, aliguori, david, lersek,
	ehabkost, marcel.a, stefanha, cornelia.huck, tangchen, rth,
	andrey, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Wed, 21 May 2014 11:10:28 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Tue, May 20, 2014 at 05:15:08PM +0200, Igor Mammedov wrote:
> > Add following parameters:
> >   "slots" - total number of hotplug memory slots
> >   "maxmem" - maximum possible memory
> > 
> > "slots" and "maxmem" should go in pair and "maxmem" should be greater
> > than "mem" for memory hotplug to be enabled.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> Also, it's a bug to mix this with a compat machine type, right?
> Maybe best to fail initialization if users try this.
I'll add PC specific patch for this.

> 
> > ---
> > v4:
> >  - store maxmem & slots values in MachineState
> > v3:
> >  - store maxmem & slots values in QEMUMachineInitArgs
> > v2:
> >  - rebased on top of the latest "vl: convert -m to QemuOpts"
> > ---
> >  include/hw/boards.h |    3 ++-
> >  qemu-options.hx     |    9 ++++++---
> >  vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 59 insertions(+), 4 deletions(-)
> > 
> > diff --git a/include/hw/boards.h b/include/hw/boards.h
> > index b62de4a..f6fbbe1 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -8,7 +8,6 @@
> >  #include "hw/qdev.h"
> >  #include "qom/object.h"
> >  
> > -
> >  typedef struct MachineState MachineState;
> >  
> >  typedef void QEMUMachineInitFunc(MachineState *ms);
> > @@ -113,6 +112,8 @@ struct MachineState {
> >      char *firmware;
> >  
> >      ram_addr_t ram_size;
> > +    ram_addr_t maxram_size;
> > +    uint64_t   ram_slots;
> >      const char *boot_order;
> >      const char *kernel_filename;
> >      const char *kernel_cmdline;
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 781af14..c6411c4 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
> >  ETEXI
> >  
> >  DEF("m", HAS_ARG, QEMU_OPTION_m,
> > -    "-m [size=]megs\n"
> > +    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
> >      "                configure guest RAM\n"
> >      "                size: initial amount of guest memory (default: "
> > -    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
> > +    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
> > +    "                slots: number of hotplug slots (default: none)\n"
> > +    "                maxmem: maximum amount of guest memory (default: none)\n",
> >      QEMU_ARCH_ALL)
> >  STEXI
> >  @item -m [size=]@var{megs}
> >  @findex -m
> >  Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
> >  a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
> > -gigabytes respectively.
> > +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
> > +to set amount of hotluggable memory slots and possible maximum amount of memory.
> >  ETEXI
> >  
> >  DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
> > diff --git a/vl.c b/vl.c
> > index 8fd4ed9..9fb6fa4 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
> >              .name = "size",
> >              .type = QEMU_OPT_SIZE,
> >          },
> > +        {
> > +            .name = "slots",
> > +            .type = QEMU_OPT_NUMBER,
> > +        },
> > +        {
> > +            .name = "maxmem",
> > +            .type = QEMU_OPT_SIZE,
> > +        },
> >          { /* end of list */ }
> >      },
> >  };
> > @@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
> >      const char *trace_file = NULL;
> >      const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
> >                                          1024 * 1024;
> > +    ram_addr_t maxram_size = default_ram_size;
> > +    uint64_t ram_slots = 0;
> >  
> >      atexit(qemu_run_exit_notifiers);
> >      error_set_progname(argv[0]);
> > @@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
> >              case QEMU_OPTION_m: {
> >                  uint64_t sz;
> >                  const char *mem_str;
> > +                const char *maxmem_str, *slots_str;
> >  
> >                  opts = qemu_opts_parse(qemu_find_opts("memory"),
> >                                         optarg, 1);
> > @@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
> >                      error_report("ram size too large");
> >                      exit(EXIT_FAILURE);
> >                  }
> > +
> > +                maxmem_str = qemu_opt_get(opts, "maxmem");
> > +                slots_str = qemu_opt_get(opts, "slots");
> > +                if (maxmem_str && slots_str) {
> > +                    uint64_t slots;
> > +
> > +                    sz = qemu_opt_get_size(opts, "maxmem", 0);
> > +                    if (sz < ram_size) {
> > +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> > +                                "(%" PRIu64 ") <= initial memory (%"
> > +                                PRIu64 ")\n", sz, ram_size);
> > +                        exit(EXIT_FAILURE);
> > +                    }
> > +
> > +                    slots = qemu_opt_get_number(opts, "slots", 0);
> > +                    if ((sz > ram_size) && !slots) {
> > +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> > +                                "(%" PRIu64 ") more than initial memory (%"
> > +                                PRIu64 ") but no hotplug slots where "
> > +                                "specified\n", sz, ram_size);
> > +                        exit(EXIT_FAILURE);
> > +                    }
> > +
> > +                    if ((sz <= ram_size) && slots) {
> > +                        fprintf(stderr, "qemu: invalid -m option value:  %"
> > +                                PRIu64 " hotplug slots where specified but "
> > +                                "maxmem (%" PRIu64 ") <= initial memory (%"
> > +                                PRIu64 ")\n", slots, sz, ram_size);
> > +                        exit(EXIT_FAILURE);
> > +                    }
> > +                    maxram_size = sz;
> > +                    ram_slots = slots;
> > +                } else if ((!maxmem_str && slots_str) ||
> > +                           (maxmem_str && !slots_str)) {
> > +                    fprintf(stderr, "qemu: invalid -m option value: missing "
> > +                            "'%s' option\n", slots_str ? "maxmem" : "slots");
> > +                    exit(EXIT_FAILURE);
> > +                }
> >                  break;
> >              }
> >  #ifdef CONFIG_TPM
> > @@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
> >      qdev_machine_init();
> >  
> >      current_machine->ram_size = ram_size;
> > +    current_machine->maxram_size = maxram_size;
> > +    current_machine->ram_slots = ram_slots;
> >      current_machine->boot_order = boot_order;
> >      current_machine->kernel_filename = kernel_filename;
> >      current_machine->kernel_cmdline = kernel_cmdline;
> > -- 
> > 1.7.1

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-21  8:10   ` Michael S. Tsirkin
  2014-05-21  8:26     ` Igor Mammedov
@ 2014-05-21  8:27     ` Andrey Korolyov
  2014-05-21  8:55       ` Igor Mammedov
  1 sibling, 1 reply; 54+ messages in thread
From: Andrey Korolyov @ 2014-05-21  8:27 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, alex, aik, hutao, Michael Tokarev, qemu-devel,
	agraf, kraxel, pasteka, Stefan Priebe - Profihost AG, agarcia,
	armbru, aliguori, david, lersek, ehabkost, marcel.a, stefanha,
	Igor Mammedov, cornelia.huck, tangchen, rth, vasilis.liaskovitis,
	Paolo Bonzini, afaerber, aurelien

On Wed, May 21, 2014 at 12:10 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> On Tue, May 20, 2014 at 05:15:08PM +0200, Igor Mammedov wrote:
>> Add following parameters:
>>   "slots" - total number of hotplug memory slots
>>   "maxmem" - maximum possible memory
>>
>> "slots" and "maxmem" should go in pair and "maxmem" should be greater
>> than "mem" for memory hotplug to be enabled.
>>
>> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>
> Also, it's a bug to mix this with a compat machine type, right?
> Maybe best to fail initialization if users try this.
>
>> ---
>> v4:
>>  - store maxmem & slots values in MachineState
>> v3:
>>  - store maxmem & slots values in QEMUMachineInitArgs
>> v2:
>>  - rebased on top of the latest "vl: convert -m to QemuOpts"
>> ---
>>  include/hw/boards.h |    3 ++-
>>  qemu-options.hx     |    9 ++++++---
>>  vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  3 files changed, 59 insertions(+), 4 deletions(-)
>>
>> diff --git a/include/hw/boards.h b/include/hw/boards.h
>> index b62de4a..f6fbbe1 100644
>> --- a/include/hw/boards.h
>> +++ b/include/hw/boards.h
>> @@ -8,7 +8,6 @@
>>  #include "hw/qdev.h"
>>  #include "qom/object.h"
>>
>> -
>>  typedef struct MachineState MachineState;
>>
>>  typedef void QEMUMachineInitFunc(MachineState *ms);
>> @@ -113,6 +112,8 @@ struct MachineState {
>>      char *firmware;
>>
>>      ram_addr_t ram_size;
>> +    ram_addr_t maxram_size;
>> +    uint64_t   ram_slots;
>>      const char *boot_order;
>>      const char *kernel_filename;
>>      const char *kernel_cmdline;
>> diff --git a/qemu-options.hx b/qemu-options.hx
>> index 781af14..c6411c4 100644
>> --- a/qemu-options.hx
>> +++ b/qemu-options.hx
>> @@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
>>  ETEXI
>>
>>  DEF("m", HAS_ARG, QEMU_OPTION_m,
>> -    "-m [size=]megs\n"
>> +    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
>>      "                configure guest RAM\n"
>>      "                size: initial amount of guest memory (default: "
>> -    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
>> +    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
>> +    "                slots: number of hotplug slots (default: none)\n"
>> +    "                maxmem: maximum amount of guest memory (default: none)\n",
>>      QEMU_ARCH_ALL)
>>  STEXI
>>  @item -m [size=]@var{megs}
>>  @findex -m
>>  Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
>>  a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
>> -gigabytes respectively.
>> +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
>> +to set amount of hotluggable memory slots and possible maximum amount of memory.
>>  ETEXI
>>
>>  DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
>> diff --git a/vl.c b/vl.c
>> index 8fd4ed9..9fb6fa4 100644
>> --- a/vl.c
>> +++ b/vl.c
>> @@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
>>              .name = "size",
>>              .type = QEMU_OPT_SIZE,
>>          },
>> +        {
>> +            .name = "slots",
>> +            .type = QEMU_OPT_NUMBER,
>> +        },
>> +        {
>> +            .name = "maxmem",
>> +            .type = QEMU_OPT_SIZE,
>> +        },
>>          { /* end of list */ }
>>      },
>>  };
>> @@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
>>      const char *trace_file = NULL;
>>      const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
>>                                          1024 * 1024;
>> +    ram_addr_t maxram_size = default_ram_size;
>> +    uint64_t ram_slots = 0;
>>
>>      atexit(qemu_run_exit_notifiers);
>>      error_set_progname(argv[0]);
>> @@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
>>              case QEMU_OPTION_m: {
>>                  uint64_t sz;
>>                  const char *mem_str;
>> +                const char *maxmem_str, *slots_str;
>>
>>                  opts = qemu_opts_parse(qemu_find_opts("memory"),
>>                                         optarg, 1);
>> @@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
>>                      error_report("ram size too large");
>>                      exit(EXIT_FAILURE);
>>                  }
>> +
>> +                maxmem_str = qemu_opt_get(opts, "maxmem");
>> +                slots_str = qemu_opt_get(opts, "slots");
>> +                if (maxmem_str && slots_str) {
>> +                    uint64_t slots;
>> +
>> +                    sz = qemu_opt_get_size(opts, "maxmem", 0);
>> +                    if (sz < ram_size) {
>> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
>> +                                "(%" PRIu64 ") <= initial memory (%"
>> +                                PRIu64 ")\n", sz, ram_size);
>> +                        exit(EXIT_FAILURE);
>> +                    }
>> +
>> +                    slots = qemu_opt_get_number(opts, "slots", 0);
>> +                    if ((sz > ram_size) && !slots) {
>> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
>> +                                "(%" PRIu64 ") more than initial memory (%"
>> +                                PRIu64 ") but no hotplug slots where "
>> +                                "specified\n", sz, ram_size);
>> +                        exit(EXIT_FAILURE);
>> +                    }
>> +
>> +                    if ((sz <= ram_size) && slots) {
>> +                        fprintf(stderr, "qemu: invalid -m option value:  %"
>> +                                PRIu64 " hotplug slots where specified but "
>> +                                "maxmem (%" PRIu64 ") <= initial memory (%"
>> +                                PRIu64 ")\n", slots, sz, ram_size);
>> +                        exit(EXIT_FAILURE);
>> +                    }
>> +                    maxram_size = sz;
>> +                    ram_slots = slots;
>> +                } else if ((!maxmem_str && slots_str) ||
>> +                           (maxmem_str && !slots_str)) {
>> +                    fprintf(stderr, "qemu: invalid -m option value: missing "
>> +                            "'%s' option\n", slots_str ? "maxmem" : "slots");
>> +                    exit(EXIT_FAILURE);
>> +                }
>>                  break;
>>              }
>>  #ifdef CONFIG_TPM
>> @@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
>>      qdev_machine_init();
>>
>>      current_machine->ram_size = ram_size;
>> +    current_machine->maxram_size = maxram_size;
>> +    current_machine->ram_slots = ram_slots;
>>      current_machine->boot_order = boot_order;
>>      current_machine->kernel_filename = kernel_filename;
>>      current_machine->kernel_cmdline = kernel_cmdline;
>> --
>> 1.7.1

May be I am adding very userish opinion, but ability to specify slot
state via cmdline explicitly, like in
https://github.com/vliaskov/qemu-kvm/tree/memhp-v5-wip, looks better
in sight of thoughts of future integration in libvirt and for unplug
option (where knowledge of which regions are offlined is necessary to
do the job).

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-21  8:27     ` Andrey Korolyov
@ 2014-05-21  8:55       ` Igor Mammedov
  2014-05-21  9:12         ` Andrey Korolyov
  0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21  8:55 UTC (permalink / raw)
  To: Andrey Korolyov
  Cc: peter.maydell, alex, Michael S. Tsirkin, aik, hutao,
	Michael Tokarev, qemu-devel, agraf, kraxel, pasteka,
	Stefan Priebe - Profihost AG, agarcia, armbru, aliguori, david,
	lersek, ehabkost, marcel.a, stefanha, cornelia.huck, tangchen,
	rth, vasilis.liaskovitis, Paolo Bonzini, afaerber, aurelien

On Wed, 21 May 2014 12:27:05 +0400
Andrey Korolyov <andrey@xdel.ru> wrote:

> On Wed, May 21, 2014 at 12:10 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> > On Tue, May 20, 2014 at 05:15:08PM +0200, Igor Mammedov wrote:
> >> Add following parameters:
> >>   "slots" - total number of hotplug memory slots
> >>   "maxmem" - maximum possible memory
> >>
> >> "slots" and "maxmem" should go in pair and "maxmem" should be greater
> >> than "mem" for memory hotplug to be enabled.
> >>
> >> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> >
> > Also, it's a bug to mix this with a compat machine type, right?
> > Maybe best to fail initialization if users try this.
> >
> >> ---
> >> v4:
> >>  - store maxmem & slots values in MachineState
> >> v3:
> >>  - store maxmem & slots values in QEMUMachineInitArgs
> >> v2:
> >>  - rebased on top of the latest "vl: convert -m to QemuOpts"
> >> ---
> >>  include/hw/boards.h |    3 ++-
> >>  qemu-options.hx     |    9 ++++++---
> >>  vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  3 files changed, 59 insertions(+), 4 deletions(-)
> >>
> >> diff --git a/include/hw/boards.h b/include/hw/boards.h
> >> index b62de4a..f6fbbe1 100644
> >> --- a/include/hw/boards.h
> >> +++ b/include/hw/boards.h
> >> @@ -8,7 +8,6 @@
> >>  #include "hw/qdev.h"
> >>  #include "qom/object.h"
> >>
> >> -
> >>  typedef struct MachineState MachineState;
> >>
> >>  typedef void QEMUMachineInitFunc(MachineState *ms);
> >> @@ -113,6 +112,8 @@ struct MachineState {
> >>      char *firmware;
> >>
> >>      ram_addr_t ram_size;
> >> +    ram_addr_t maxram_size;
> >> +    uint64_t   ram_slots;
> >>      const char *boot_order;
> >>      const char *kernel_filename;
> >>      const char *kernel_cmdline;
> >> diff --git a/qemu-options.hx b/qemu-options.hx
> >> index 781af14..c6411c4 100644
> >> --- a/qemu-options.hx
> >> +++ b/qemu-options.hx
> >> @@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
> >>  ETEXI
> >>
> >>  DEF("m", HAS_ARG, QEMU_OPTION_m,
> >> -    "-m [size=]megs\n"
> >> +    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
> >>      "                configure guest RAM\n"
> >>      "                size: initial amount of guest memory (default: "
> >> -    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
> >> +    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
> >> +    "                slots: number of hotplug slots (default: none)\n"
> >> +    "                maxmem: maximum amount of guest memory (default: none)\n",
> >>      QEMU_ARCH_ALL)
> >>  STEXI
> >>  @item -m [size=]@var{megs}
> >>  @findex -m
> >>  Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
> >>  a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
> >> -gigabytes respectively.
> >> +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
> >> +to set amount of hotluggable memory slots and possible maximum amount of memory.
> >>  ETEXI
> >>
> >>  DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
> >> diff --git a/vl.c b/vl.c
> >> index 8fd4ed9..9fb6fa4 100644
> >> --- a/vl.c
> >> +++ b/vl.c
> >> @@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
> >>              .name = "size",
> >>              .type = QEMU_OPT_SIZE,
> >>          },
> >> +        {
> >> +            .name = "slots",
> >> +            .type = QEMU_OPT_NUMBER,
> >> +        },
> >> +        {
> >> +            .name = "maxmem",
> >> +            .type = QEMU_OPT_SIZE,
> >> +        },
> >>          { /* end of list */ }
> >>      },
> >>  };
> >> @@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
> >>      const char *trace_file = NULL;
> >>      const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
> >>                                          1024 * 1024;
> >> +    ram_addr_t maxram_size = default_ram_size;
> >> +    uint64_t ram_slots = 0;
> >>
> >>      atexit(qemu_run_exit_notifiers);
> >>      error_set_progname(argv[0]);
> >> @@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
> >>              case QEMU_OPTION_m: {
> >>                  uint64_t sz;
> >>                  const char *mem_str;
> >> +                const char *maxmem_str, *slots_str;
> >>
> >>                  opts = qemu_opts_parse(qemu_find_opts("memory"),
> >>                                         optarg, 1);
> >> @@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
> >>                      error_report("ram size too large");
> >>                      exit(EXIT_FAILURE);
> >>                  }
> >> +
> >> +                maxmem_str = qemu_opt_get(opts, "maxmem");
> >> +                slots_str = qemu_opt_get(opts, "slots");
> >> +                if (maxmem_str && slots_str) {
> >> +                    uint64_t slots;
> >> +
> >> +                    sz = qemu_opt_get_size(opts, "maxmem", 0);
> >> +                    if (sz < ram_size) {
> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> >> +                                "(%" PRIu64 ") <= initial memory (%"
> >> +                                PRIu64 ")\n", sz, ram_size);
> >> +                        exit(EXIT_FAILURE);
> >> +                    }
> >> +
> >> +                    slots = qemu_opt_get_number(opts, "slots", 0);
> >> +                    if ((sz > ram_size) && !slots) {
> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> >> +                                "(%" PRIu64 ") more than initial memory (%"
> >> +                                PRIu64 ") but no hotplug slots where "
> >> +                                "specified\n", sz, ram_size);
> >> +                        exit(EXIT_FAILURE);
> >> +                    }
> >> +
> >> +                    if ((sz <= ram_size) && slots) {
> >> +                        fprintf(stderr, "qemu: invalid -m option value:  %"
> >> +                                PRIu64 " hotplug slots where specified but "
> >> +                                "maxmem (%" PRIu64 ") <= initial memory (%"
> >> +                                PRIu64 ")\n", slots, sz, ram_size);
> >> +                        exit(EXIT_FAILURE);
> >> +                    }
> >> +                    maxram_size = sz;
> >> +                    ram_slots = slots;
> >> +                } else if ((!maxmem_str && slots_str) ||
> >> +                           (maxmem_str && !slots_str)) {
> >> +                    fprintf(stderr, "qemu: invalid -m option value: missing "
> >> +                            "'%s' option\n", slots_str ? "maxmem" : "slots");
> >> +                    exit(EXIT_FAILURE);
> >> +                }
> >>                  break;
> >>              }
> >>  #ifdef CONFIG_TPM
> >> @@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
> >>      qdev_machine_init();
> >>
> >>      current_machine->ram_size = ram_size;
> >> +    current_machine->maxram_size = maxram_size;
> >> +    current_machine->ram_slots = ram_slots;
> >>      current_machine->boot_order = boot_order;
> >>      current_machine->kernel_filename = kernel_filename;
> >>      current_machine->kernel_cmdline = kernel_cmdline;
> >> --
> >> 1.7.1
> 
> May be I am adding very userish opinion, but ability to specify slot
> state via cmdline explicitly, like in
> https://github.com/vliaskov/qemu-kvm/tree/memhp-v5-wip, looks better
> in sight of thoughts of future integration in libvirt and for unplug
> option (where knowledge of which regions are offlined is necessary to
> do the job).
slots are 'not populated' by default, and if specific slot should be
populated then it should have corresponding "-device dimm,slot=XXX"
on QEMU CLI.
There is not much point to specify on CLI not present DIMMs, that way
it would be less confusing and user won't have to worry about not
present DIMMs options at startup (slot/size/addr/node). That makes
VM configuration flexible and allows user to decide parameters at runtime.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-21  8:55       ` Igor Mammedov
@ 2014-05-21  9:12         ` Andrey Korolyov
  2014-05-21  9:52           ` Igor Mammedov
  0 siblings, 1 reply; 54+ messages in thread
From: Andrey Korolyov @ 2014-05-21  9:12 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Maydell, alex, Michael S. Tsirkin, aik, hutao,
	Michael Tokarev, qemu-devel, Alexander Graf, Gerd Hoffmann,
	pasteka, Stefan Priebe - Profihost AG, agarcia, armbru, aliguori,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, vasilis.liaskovitis, Paolo Bonzini, afaerber,
	aurelien

On Wed, May 21, 2014 at 12:55 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> On Wed, 21 May 2014 12:27:05 +0400
> Andrey Korolyov <andrey@xdel.ru> wrote:
>
>> On Wed, May 21, 2014 at 12:10 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> > On Tue, May 20, 2014 at 05:15:08PM +0200, Igor Mammedov wrote:
>> >> Add following parameters:
>> >>   "slots" - total number of hotplug memory slots
>> >>   "maxmem" - maximum possible memory
>> >>
>> >> "slots" and "maxmem" should go in pair and "maxmem" should be greater
>> >> than "mem" for memory hotplug to be enabled.
>> >>
>> >> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>> >
>> > Also, it's a bug to mix this with a compat machine type, right?
>> > Maybe best to fail initialization if users try this.
>> >
>> >> ---
>> >> v4:
>> >>  - store maxmem & slots values in MachineState
>> >> v3:
>> >>  - store maxmem & slots values in QEMUMachineInitArgs
>> >> v2:
>> >>  - rebased on top of the latest "vl: convert -m to QemuOpts"
>> >> ---
>> >>  include/hw/boards.h |    3 ++-
>> >>  qemu-options.hx     |    9 ++++++---
>> >>  vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
>> >>  3 files changed, 59 insertions(+), 4 deletions(-)
>> >>
>> >> diff --git a/include/hw/boards.h b/include/hw/boards.h
>> >> index b62de4a..f6fbbe1 100644
>> >> --- a/include/hw/boards.h
>> >> +++ b/include/hw/boards.h
>> >> @@ -8,7 +8,6 @@
>> >>  #include "hw/qdev.h"
>> >>  #include "qom/object.h"
>> >>
>> >> -
>> >>  typedef struct MachineState MachineState;
>> >>
>> >>  typedef void QEMUMachineInitFunc(MachineState *ms);
>> >> @@ -113,6 +112,8 @@ struct MachineState {
>> >>      char *firmware;
>> >>
>> >>      ram_addr_t ram_size;
>> >> +    ram_addr_t maxram_size;
>> >> +    uint64_t   ram_slots;
>> >>      const char *boot_order;
>> >>      const char *kernel_filename;
>> >>      const char *kernel_cmdline;
>> >> diff --git a/qemu-options.hx b/qemu-options.hx
>> >> index 781af14..c6411c4 100644
>> >> --- a/qemu-options.hx
>> >> +++ b/qemu-options.hx
>> >> @@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
>> >>  ETEXI
>> >>
>> >>  DEF("m", HAS_ARG, QEMU_OPTION_m,
>> >> -    "-m [size=]megs\n"
>> >> +    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
>> >>      "                configure guest RAM\n"
>> >>      "                size: initial amount of guest memory (default: "
>> >> -    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
>> >> +    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
>> >> +    "                slots: number of hotplug slots (default: none)\n"
>> >> +    "                maxmem: maximum amount of guest memory (default: none)\n",
>> >>      QEMU_ARCH_ALL)
>> >>  STEXI
>> >>  @item -m [size=]@var{megs}
>> >>  @findex -m
>> >>  Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
>> >>  a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
>> >> -gigabytes respectively.
>> >> +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
>> >> +to set amount of hotluggable memory slots and possible maximum amount of memory.
>> >>  ETEXI
>> >>
>> >>  DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
>> >> diff --git a/vl.c b/vl.c
>> >> index 8fd4ed9..9fb6fa4 100644
>> >> --- a/vl.c
>> >> +++ b/vl.c
>> >> @@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
>> >>              .name = "size",
>> >>              .type = QEMU_OPT_SIZE,
>> >>          },
>> >> +        {
>> >> +            .name = "slots",
>> >> +            .type = QEMU_OPT_NUMBER,
>> >> +        },
>> >> +        {
>> >> +            .name = "maxmem",
>> >> +            .type = QEMU_OPT_SIZE,
>> >> +        },
>> >>          { /* end of list */ }
>> >>      },
>> >>  };
>> >> @@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
>> >>      const char *trace_file = NULL;
>> >>      const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
>> >>                                          1024 * 1024;
>> >> +    ram_addr_t maxram_size = default_ram_size;
>> >> +    uint64_t ram_slots = 0;
>> >>
>> >>      atexit(qemu_run_exit_notifiers);
>> >>      error_set_progname(argv[0]);
>> >> @@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
>> >>              case QEMU_OPTION_m: {
>> >>                  uint64_t sz;
>> >>                  const char *mem_str;
>> >> +                const char *maxmem_str, *slots_str;
>> >>
>> >>                  opts = qemu_opts_parse(qemu_find_opts("memory"),
>> >>                                         optarg, 1);
>> >> @@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
>> >>                      error_report("ram size too large");
>> >>                      exit(EXIT_FAILURE);
>> >>                  }
>> >> +
>> >> +                maxmem_str = qemu_opt_get(opts, "maxmem");
>> >> +                slots_str = qemu_opt_get(opts, "slots");
>> >> +                if (maxmem_str && slots_str) {
>> >> +                    uint64_t slots;
>> >> +
>> >> +                    sz = qemu_opt_get_size(opts, "maxmem", 0);
>> >> +                    if (sz < ram_size) {
>> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
>> >> +                                "(%" PRIu64 ") <= initial memory (%"
>> >> +                                PRIu64 ")\n", sz, ram_size);
>> >> +                        exit(EXIT_FAILURE);
>> >> +                    }
>> >> +
>> >> +                    slots = qemu_opt_get_number(opts, "slots", 0);
>> >> +                    if ((sz > ram_size) && !slots) {
>> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
>> >> +                                "(%" PRIu64 ") more than initial memory (%"
>> >> +                                PRIu64 ") but no hotplug slots where "
>> >> +                                "specified\n", sz, ram_size);
>> >> +                        exit(EXIT_FAILURE);
>> >> +                    }
>> >> +
>> >> +                    if ((sz <= ram_size) && slots) {
>> >> +                        fprintf(stderr, "qemu: invalid -m option value:  %"
>> >> +                                PRIu64 " hotplug slots where specified but "
>> >> +                                "maxmem (%" PRIu64 ") <= initial memory (%"
>> >> +                                PRIu64 ")\n", slots, sz, ram_size);
>> >> +                        exit(EXIT_FAILURE);
>> >> +                    }
>> >> +                    maxram_size = sz;
>> >> +                    ram_slots = slots;
>> >> +                } else if ((!maxmem_str && slots_str) ||
>> >> +                           (maxmem_str && !slots_str)) {
>> >> +                    fprintf(stderr, "qemu: invalid -m option value: missing "
>> >> +                            "'%s' option\n", slots_str ? "maxmem" : "slots");
>> >> +                    exit(EXIT_FAILURE);
>> >> +                }
>> >>                  break;
>> >>              }
>> >>  #ifdef CONFIG_TPM
>> >> @@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
>> >>      qdev_machine_init();
>> >>
>> >>      current_machine->ram_size = ram_size;
>> >> +    current_machine->maxram_size = maxram_size;
>> >> +    current_machine->ram_slots = ram_slots;
>> >>      current_machine->boot_order = boot_order;
>> >>      current_machine->kernel_filename = kernel_filename;
>> >>      current_machine->kernel_cmdline = kernel_cmdline;
>> >> --
>> >> 1.7.1
>>
>> May be I am adding very userish opinion, but ability to specify slot
>> state via cmdline explicitly, like in
>> https://github.com/vliaskov/qemu-kvm/tree/memhp-v5-wip, looks better
>> in sight of thoughts of future integration in libvirt and for unplug
>> option (where knowledge of which regions are offlined is necessary to
>> do the job).
> slots are 'not populated' by default, and if specific slot should be
> populated then it should have corresponding "-device dimm,slot=XXX"
> on QEMU CLI.
> There is not much point to specify on CLI not present DIMMs, that way
> it would be less confusing and user won't have to worry about not
> present DIMMs options at startup (slot/size/addr/node). That makes
> VM configuration flexible and allows user to decide parameters at runtime.
>

Ok, so on updating memory configuration we`ll have to (un)plug the
device and update inactive libvirt config for appropriate part in
current notation by some kind of mighty mechanism from above.
Unplugging will work well but with helper from the upper-level
orchestrator, I think that doing boot param injection in
non-direct-booted kernel for declaration of ZONE_MOVABLE and doing
appropriate calculation for the config is too hard and complex for
role which libvirt currently holds, so current approach is acceptable
there too. There are two paths - simplify dimm management as much as
possible and therefore do not rely on logic inside libvirt, or build
very monstrous and complex, but self-sufficient (in libvirt scope)
interface for dimm operations. With those selections, I`d vote for
first of course.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-21  9:12         ` Andrey Korolyov
@ 2014-05-21  9:52           ` Igor Mammedov
  2014-05-21 10:04             ` Andrey Korolyov
  0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21  9:52 UTC (permalink / raw)
  To: Andrey Korolyov
  Cc: Peter Maydell, alex, Michael S. Tsirkin, aik, hutao,
	Michael Tokarev, qemu-devel, Alexander Graf, Gerd Hoffmann,
	pasteka, Stefan Priebe - Profihost AG, agarcia, armbru, aliguori,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, vasilis.liaskovitis, Paolo Bonzini, afaerber,
	aurelien

On Wed, 21 May 2014 13:12:13 +0400
Andrey Korolyov <andrey@xdel.ru> wrote:

> On Wed, May 21, 2014 at 12:55 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> > On Wed, 21 May 2014 12:27:05 +0400
> > Andrey Korolyov <andrey@xdel.ru> wrote:
> >
> >> On Wed, May 21, 2014 at 12:10 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
> >> > On Tue, May 20, 2014 at 05:15:08PM +0200, Igor Mammedov wrote:
> >> >> Add following parameters:
> >> >>   "slots" - total number of hotplug memory slots
> >> >>   "maxmem" - maximum possible memory
> >> >>
> >> >> "slots" and "maxmem" should go in pair and "maxmem" should be greater
> >> >> than "mem" for memory hotplug to be enabled.
> >> >>
> >> >> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> >> >
> >> > Also, it's a bug to mix this with a compat machine type, right?
> >> > Maybe best to fail initialization if users try this.
> >> >
> >> >> ---
> >> >> v4:
> >> >>  - store maxmem & slots values in MachineState
> >> >> v3:
> >> >>  - store maxmem & slots values in QEMUMachineInitArgs
> >> >> v2:
> >> >>  - rebased on top of the latest "vl: convert -m to QemuOpts"
> >> >> ---
> >> >>  include/hw/boards.h |    3 ++-
> >> >>  qemu-options.hx     |    9 ++++++---
> >> >>  vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >> >>  3 files changed, 59 insertions(+), 4 deletions(-)
> >> >>
> >> >> diff --git a/include/hw/boards.h b/include/hw/boards.h
> >> >> index b62de4a..f6fbbe1 100644
> >> >> --- a/include/hw/boards.h
> >> >> +++ b/include/hw/boards.h
> >> >> @@ -8,7 +8,6 @@
> >> >>  #include "hw/qdev.h"
> >> >>  #include "qom/object.h"
> >> >>
> >> >> -
> >> >>  typedef struct MachineState MachineState;
> >> >>
> >> >>  typedef void QEMUMachineInitFunc(MachineState *ms);
> >> >> @@ -113,6 +112,8 @@ struct MachineState {
> >> >>      char *firmware;
> >> >>
> >> >>      ram_addr_t ram_size;
> >> >> +    ram_addr_t maxram_size;
> >> >> +    uint64_t   ram_slots;
> >> >>      const char *boot_order;
> >> >>      const char *kernel_filename;
> >> >>      const char *kernel_cmdline;
> >> >> diff --git a/qemu-options.hx b/qemu-options.hx
> >> >> index 781af14..c6411c4 100644
> >> >> --- a/qemu-options.hx
> >> >> +++ b/qemu-options.hx
> >> >> @@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
> >> >>  ETEXI
> >> >>
> >> >>  DEF("m", HAS_ARG, QEMU_OPTION_m,
> >> >> -    "-m [size=]megs\n"
> >> >> +    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
> >> >>      "                configure guest RAM\n"
> >> >>      "                size: initial amount of guest memory (default: "
> >> >> -    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
> >> >> +    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
> >> >> +    "                slots: number of hotplug slots (default: none)\n"
> >> >> +    "                maxmem: maximum amount of guest memory (default: none)\n",
> >> >>      QEMU_ARCH_ALL)
> >> >>  STEXI
> >> >>  @item -m [size=]@var{megs}
> >> >>  @findex -m
> >> >>  Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
> >> >>  a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
> >> >> -gigabytes respectively.
> >> >> +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
> >> >> +to set amount of hotluggable memory slots and possible maximum amount of memory.
> >> >>  ETEXI
> >> >>
> >> >>  DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
> >> >> diff --git a/vl.c b/vl.c
> >> >> index 8fd4ed9..9fb6fa4 100644
> >> >> --- a/vl.c
> >> >> +++ b/vl.c
> >> >> @@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
> >> >>              .name = "size",
> >> >>              .type = QEMU_OPT_SIZE,
> >> >>          },
> >> >> +        {
> >> >> +            .name = "slots",
> >> >> +            .type = QEMU_OPT_NUMBER,
> >> >> +        },
> >> >> +        {
> >> >> +            .name = "maxmem",
> >> >> +            .type = QEMU_OPT_SIZE,
> >> >> +        },
> >> >>          { /* end of list */ }
> >> >>      },
> >> >>  };
> >> >> @@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
> >> >>      const char *trace_file = NULL;
> >> >>      const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
> >> >>                                          1024 * 1024;
> >> >> +    ram_addr_t maxram_size = default_ram_size;
> >> >> +    uint64_t ram_slots = 0;
> >> >>
> >> >>      atexit(qemu_run_exit_notifiers);
> >> >>      error_set_progname(argv[0]);
> >> >> @@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
> >> >>              case QEMU_OPTION_m: {
> >> >>                  uint64_t sz;
> >> >>                  const char *mem_str;
> >> >> +                const char *maxmem_str, *slots_str;
> >> >>
> >> >>                  opts = qemu_opts_parse(qemu_find_opts("memory"),
> >> >>                                         optarg, 1);
> >> >> @@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
> >> >>                      error_report("ram size too large");
> >> >>                      exit(EXIT_FAILURE);
> >> >>                  }
> >> >> +
> >> >> +                maxmem_str = qemu_opt_get(opts, "maxmem");
> >> >> +                slots_str = qemu_opt_get(opts, "slots");
> >> >> +                if (maxmem_str && slots_str) {
> >> >> +                    uint64_t slots;
> >> >> +
> >> >> +                    sz = qemu_opt_get_size(opts, "maxmem", 0);
> >> >> +                    if (sz < ram_size) {
> >> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> >> >> +                                "(%" PRIu64 ") <= initial memory (%"
> >> >> +                                PRIu64 ")\n", sz, ram_size);
> >> >> +                        exit(EXIT_FAILURE);
> >> >> +                    }
> >> >> +
> >> >> +                    slots = qemu_opt_get_number(opts, "slots", 0);
> >> >> +                    if ((sz > ram_size) && !slots) {
> >> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
> >> >> +                                "(%" PRIu64 ") more than initial memory (%"
> >> >> +                                PRIu64 ") but no hotplug slots where "
> >> >> +                                "specified\n", sz, ram_size);
> >> >> +                        exit(EXIT_FAILURE);
> >> >> +                    }
> >> >> +
> >> >> +                    if ((sz <= ram_size) && slots) {
> >> >> +                        fprintf(stderr, "qemu: invalid -m option value:  %"
> >> >> +                                PRIu64 " hotplug slots where specified but "
> >> >> +                                "maxmem (%" PRIu64 ") <= initial memory (%"
> >> >> +                                PRIu64 ")\n", slots, sz, ram_size);
> >> >> +                        exit(EXIT_FAILURE);
> >> >> +                    }
> >> >> +                    maxram_size = sz;
> >> >> +                    ram_slots = slots;
> >> >> +                } else if ((!maxmem_str && slots_str) ||
> >> >> +                           (maxmem_str && !slots_str)) {
> >> >> +                    fprintf(stderr, "qemu: invalid -m option value: missing "
> >> >> +                            "'%s' option\n", slots_str ? "maxmem" : "slots");
> >> >> +                    exit(EXIT_FAILURE);
> >> >> +                }
> >> >>                  break;
> >> >>              }
> >> >>  #ifdef CONFIG_TPM
> >> >> @@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
> >> >>      qdev_machine_init();
> >> >>
> >> >>      current_machine->ram_size = ram_size;
> >> >> +    current_machine->maxram_size = maxram_size;
> >> >> +    current_machine->ram_slots = ram_slots;
> >> >>      current_machine->boot_order = boot_order;
> >> >>      current_machine->kernel_filename = kernel_filename;
> >> >>      current_machine->kernel_cmdline = kernel_cmdline;
> >> >> --
> >> >> 1.7.1
> >>
> >> May be I am adding very userish opinion, but ability to specify slot
> >> state via cmdline explicitly, like in
> >> https://github.com/vliaskov/qemu-kvm/tree/memhp-v5-wip, looks better
> >> in sight of thoughts of future integration in libvirt and for unplug
> >> option (where knowledge of which regions are offlined is necessary to
> >> do the job).
> > slots are 'not populated' by default, and if specific slot should be
> > populated then it should have corresponding "-device dimm,slot=XXX"
> > on QEMU CLI.
> > There is not much point to specify on CLI not present DIMMs, that way
> > it would be less confusing and user won't have to worry about not
> > present DIMMs options at startup (slot/size/addr/node). That makes
> > VM configuration flexible and allows user to decide parameters at runtime.
> >
> 
> Ok, so on updating memory configuration we`ll have to (un)plug the
> device and update inactive libvirt config for appropriate part in
> current notation by some kind of mighty mechanism from above.
It's general (un)plug problem affecting all hotpluggable devices.
Currently libvirt works ok with hotplugging split device model
(backend/frontend) /i.e. dimm device uses the same model as net devices/

Libvirt has notion of "--persistent/transient" for some devices
so it could be reused for memory device as well to decide what to do
with it.
 
> Unplugging will work well but with helper from the upper-level
> orchestrator,
What do you mean under helping?

> I think that doing boot param injection in
> non-direct-booted kernel for declaration of ZONE_MOVABLE and doing
> appropriate calculation for the config is too hard and complex for
> role which libvirt currently holds, so current approach is acceptable
> there too.
There shouldn't be need for libvirt to care about above stuff at all.

It's linux thing that should be fixed there and not in libvirt.
ACPI memory device provides all necessary info for doing it.
i.e. if memory device is removable (has _EJ method) then OSPM
should put it in movable zone or not attempt to eject it if
it's not in movable zone.


> There are two paths - simplify dimm management as much as
> possible and therefore do not rely on logic inside libvirt, or build
> very monstrous and complex, but self-sufficient (in libvirt scope)
> interface for dimm operations. With those selections, I`d vote for
> first of course.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug
  2014-05-21  9:52           ` Igor Mammedov
@ 2014-05-21 10:04             ` Andrey Korolyov
  0 siblings, 0 replies; 54+ messages in thread
From: Andrey Korolyov @ 2014-05-21 10:04 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Maydell, alex, Michael S. Tsirkin, aik, hutao,
	Michael Tokarev, qemu-devel, Alexander Graf, Gerd Hoffmann,
	pasteka, Stefan Priebe - Profihost AG, agarcia, armbru, aliguori,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, vasilis.liaskovitis, Paolo Bonzini, afaerber,
	aurelien

On Wed, May 21, 2014 at 1:52 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> On Wed, 21 May 2014 13:12:13 +0400
> Andrey Korolyov <andrey@xdel.ru> wrote:
>
>> On Wed, May 21, 2014 at 12:55 PM, Igor Mammedov <imammedo@redhat.com> wrote:
>> > On Wed, 21 May 2014 12:27:05 +0400
>> > Andrey Korolyov <andrey@xdel.ru> wrote:
>> >
>> >> On Wed, May 21, 2014 at 12:10 PM, Michael S. Tsirkin <mst@redhat.com> wrote:
>> >> > On Tue, May 20, 2014 at 05:15:08PM +0200, Igor Mammedov wrote:
>> >> >> Add following parameters:
>> >> >>   "slots" - total number of hotplug memory slots
>> >> >>   "maxmem" - maximum possible memory
>> >> >>
>> >> >> "slots" and "maxmem" should go in pair and "maxmem" should be greater
>> >> >> than "mem" for memory hotplug to be enabled.
>> >> >>
>> >> >> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>> >> >
>> >> > Also, it's a bug to mix this with a compat machine type, right?
>> >> > Maybe best to fail initialization if users try this.
>> >> >
>> >> >> ---
>> >> >> v4:
>> >> >>  - store maxmem & slots values in MachineState
>> >> >> v3:
>> >> >>  - store maxmem & slots values in QEMUMachineInitArgs
>> >> >> v2:
>> >> >>  - rebased on top of the latest "vl: convert -m to QemuOpts"
>> >> >> ---
>> >> >>  include/hw/boards.h |    3 ++-
>> >> >>  qemu-options.hx     |    9 ++++++---
>> >> >>  vl.c                |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++
>> >> >>  3 files changed, 59 insertions(+), 4 deletions(-)
>> >> >>
>> >> >> diff --git a/include/hw/boards.h b/include/hw/boards.h
>> >> >> index b62de4a..f6fbbe1 100644
>> >> >> --- a/include/hw/boards.h
>> >> >> +++ b/include/hw/boards.h
>> >> >> @@ -8,7 +8,6 @@
>> >> >>  #include "hw/qdev.h"
>> >> >>  #include "qom/object.h"
>> >> >>
>> >> >> -
>> >> >>  typedef struct MachineState MachineState;
>> >> >>
>> >> >>  typedef void QEMUMachineInitFunc(MachineState *ms);
>> >> >> @@ -113,6 +112,8 @@ struct MachineState {
>> >> >>      char *firmware;
>> >> >>
>> >> >>      ram_addr_t ram_size;
>> >> >> +    ram_addr_t maxram_size;
>> >> >> +    uint64_t   ram_slots;
>> >> >>      const char *boot_order;
>> >> >>      const char *kernel_filename;
>> >> >>      const char *kernel_cmdline;
>> >> >> diff --git a/qemu-options.hx b/qemu-options.hx
>> >> >> index 781af14..c6411c4 100644
>> >> >> --- a/qemu-options.hx
>> >> >> +++ b/qemu-options.hx
>> >> >> @@ -210,17 +210,20 @@ use is discouraged as it may be removed from future versions.
>> >> >>  ETEXI
>> >> >>
>> >> >>  DEF("m", HAS_ARG, QEMU_OPTION_m,
>> >> >> -    "-m [size=]megs\n"
>> >> >> +    "-m[emory] [size=]megs[,slots=n,maxmem=size]\n"
>> >> >>      "                configure guest RAM\n"
>> >> >>      "                size: initial amount of guest memory (default: "
>> >> >> -    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
>> >> >> +    stringify(DEFAULT_RAM_SIZE) "MiB)\n"
>> >> >> +    "                slots: number of hotplug slots (default: none)\n"
>> >> >> +    "                maxmem: maximum amount of guest memory (default: none)\n",
>> >> >>      QEMU_ARCH_ALL)
>> >> >>  STEXI
>> >> >>  @item -m [size=]@var{megs}
>> >> >>  @findex -m
>> >> >>  Set virtual RAM size to @var{megs} megabytes. Default is 128 MiB.  Optionally,
>> >> >>  a suffix of ``M'' or ``G'' can be used to signify a value in megabytes or
>> >> >> -gigabytes respectively.
>> >> >> +gigabytes respectively. Optional pair @var{slots}, @var{maxmem} could be used
>> >> >> +to set amount of hotluggable memory slots and possible maximum amount of memory.
>> >> >>  ETEXI
>> >> >>
>> >> >>  DEF("mem-path", HAS_ARG, QEMU_OPTION_mempath,
>> >> >> diff --git a/vl.c b/vl.c
>> >> >> index 8fd4ed9..9fb6fa4 100644
>> >> >> --- a/vl.c
>> >> >> +++ b/vl.c
>> >> >> @@ -520,6 +520,14 @@ static QemuOptsList qemu_mem_opts = {
>> >> >>              .name = "size",
>> >> >>              .type = QEMU_OPT_SIZE,
>> >> >>          },
>> >> >> +        {
>> >> >> +            .name = "slots",
>> >> >> +            .type = QEMU_OPT_NUMBER,
>> >> >> +        },
>> >> >> +        {
>> >> >> +            .name = "maxmem",
>> >> >> +            .type = QEMU_OPT_SIZE,
>> >> >> +        },
>> >> >>          { /* end of list */ }
>> >> >>      },
>> >> >>  };
>> >> >> @@ -2989,6 +2997,8 @@ int main(int argc, char **argv, char **envp)
>> >> >>      const char *trace_file = NULL;
>> >> >>      const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
>> >> >>                                          1024 * 1024;
>> >> >> +    ram_addr_t maxram_size = default_ram_size;
>> >> >> +    uint64_t ram_slots = 0;
>> >> >>
>> >> >>      atexit(qemu_run_exit_notifiers);
>> >> >>      error_set_progname(argv[0]);
>> >> >> @@ -3324,6 +3334,7 @@ int main(int argc, char **argv, char **envp)
>> >> >>              case QEMU_OPTION_m: {
>> >> >>                  uint64_t sz;
>> >> >>                  const char *mem_str;
>> >> >> +                const char *maxmem_str, *slots_str;
>> >> >>
>> >> >>                  opts = qemu_opts_parse(qemu_find_opts("memory"),
>> >> >>                                         optarg, 1);
>> >> >> @@ -3365,6 +3376,44 @@ int main(int argc, char **argv, char **envp)
>> >> >>                      error_report("ram size too large");
>> >> >>                      exit(EXIT_FAILURE);
>> >> >>                  }
>> >> >> +
>> >> >> +                maxmem_str = qemu_opt_get(opts, "maxmem");
>> >> >> +                slots_str = qemu_opt_get(opts, "slots");
>> >> >> +                if (maxmem_str && slots_str) {
>> >> >> +                    uint64_t slots;
>> >> >> +
>> >> >> +                    sz = qemu_opt_get_size(opts, "maxmem", 0);
>> >> >> +                    if (sz < ram_size) {
>> >> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
>> >> >> +                                "(%" PRIu64 ") <= initial memory (%"
>> >> >> +                                PRIu64 ")\n", sz, ram_size);
>> >> >> +                        exit(EXIT_FAILURE);
>> >> >> +                    }
>> >> >> +
>> >> >> +                    slots = qemu_opt_get_number(opts, "slots", 0);
>> >> >> +                    if ((sz > ram_size) && !slots) {
>> >> >> +                        fprintf(stderr, "qemu: invalid -m option value: maxmem "
>> >> >> +                                "(%" PRIu64 ") more than initial memory (%"
>> >> >> +                                PRIu64 ") but no hotplug slots where "
>> >> >> +                                "specified\n", sz, ram_size);
>> >> >> +                        exit(EXIT_FAILURE);
>> >> >> +                    }
>> >> >> +
>> >> >> +                    if ((sz <= ram_size) && slots) {
>> >> >> +                        fprintf(stderr, "qemu: invalid -m option value:  %"
>> >> >> +                                PRIu64 " hotplug slots where specified but "
>> >> >> +                                "maxmem (%" PRIu64 ") <= initial memory (%"
>> >> >> +                                PRIu64 ")\n", slots, sz, ram_size);
>> >> >> +                        exit(EXIT_FAILURE);
>> >> >> +                    }
>> >> >> +                    maxram_size = sz;
>> >> >> +                    ram_slots = slots;
>> >> >> +                } else if ((!maxmem_str && slots_str) ||
>> >> >> +                           (maxmem_str && !slots_str)) {
>> >> >> +                    fprintf(stderr, "qemu: invalid -m option value: missing "
>> >> >> +                            "'%s' option\n", slots_str ? "maxmem" : "slots");
>> >> >> +                    exit(EXIT_FAILURE);
>> >> >> +                }
>> >> >>                  break;
>> >> >>              }
>> >> >>  #ifdef CONFIG_TPM
>> >> >> @@ -4422,6 +4471,8 @@ int main(int argc, char **argv, char **envp)
>> >> >>      qdev_machine_init();
>> >> >>
>> >> >>      current_machine->ram_size = ram_size;
>> >> >> +    current_machine->maxram_size = maxram_size;
>> >> >> +    current_machine->ram_slots = ram_slots;
>> >> >>      current_machine->boot_order = boot_order;
>> >> >>      current_machine->kernel_filename = kernel_filename;
>> >> >>      current_machine->kernel_cmdline = kernel_cmdline;
>> >> >> --
>> >> >> 1.7.1
>> >>
>> >> May be I am adding very userish opinion, but ability to specify slot
>> >> state via cmdline explicitly, like in
>> >> https://github.com/vliaskov/qemu-kvm/tree/memhp-v5-wip, looks better
>> >> in sight of thoughts of future integration in libvirt and for unplug
>> >> option (where knowledge of which regions are offlined is necessary to
>> >> do the job).
>> > slots are 'not populated' by default, and if specific slot should be
>> > populated then it should have corresponding "-device dimm,slot=XXX"
>> > on QEMU CLI.
>> > There is not much point to specify on CLI not present DIMMs, that way
>> > it would be less confusing and user won't have to worry about not
>> > present DIMMs options at startup (slot/size/addr/node). That makes
>> > VM configuration flexible and allows user to decide parameters at runtime.
>> >
>>
>> Ok, so on updating memory configuration we`ll have to (un)plug the
>> device and update inactive libvirt config for appropriate part in
>> current notation by some kind of mighty mechanism from above.
> It's general (un)plug problem affecting all hotpluggable devices.
> Currently libvirt works ok with hotplugging split device model
> (backend/frontend) /i.e. dimm device uses the same model as net devices/
>
> Libvirt has notion of "--persistent/transient" for some devices
> so it could be reused for memory device as well to decide what to do
> with it.
>

Yes, I meant it, may be a bit unclear.

>> Unplugging will work well but with helper from the upper-level
>> orchestrator,
> What do you mean under helping?

Something should tell virtualized environment to offline regions which
are about to be unplugged and check if offline request completed
successfully, most probably it`ll be an extension for qga, I
referenced it as help from above in case if agent will not implement
this method. I am not aware of any implementation of ACPI notification
methods with same functionality, it`ll remove userspace feedback loop
completely.

>
>> I think that doing boot param injection in
>> non-direct-booted kernel for declaration of ZONE_MOVABLE and doing
>> appropriate calculation for the config is too hard and complex for
>> role which libvirt currently holds, so current approach is acceptable
>> there too.
> There shouldn't be need for libvirt to care about above stuff at all.
>
> It's linux thing that should be fixed there and not in libvirt.
> ACPI memory device provides all necessary info for doing it.
> i.e. if memory device is removable (has _EJ method) then OSPM
> should put it in movable zone or not attempt to eject it if
> it's not in movable zone.
>
>

Last time I tried, linux kernel was unable to do this automatically. I
had not poked yet very recent kernels, so it may work now.

>> There are two paths - simplify dimm management as much as
>> possible and therefore do not rely on logic inside libvirt, or build
>> very monstrous and complex, but self-sufficient (in libvirt scope)
>> interface for dimm operations. With those selections, I`d vote for
>> first of course.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-21  8:05   ` Michael S. Tsirkin
@ 2014-05-21 11:22     ` Igor Mammedov
  2014-05-21 12:44       ` Michael S. Tsirkin
  0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 11:22 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, tangchen,
	kraxel, pasteka, s.priebe, agarcia, agraf, aliguori, david,
	lersek, ehabkost, marcel.a, stefanha, cornelia.huck, rth, andrey,
	armbru, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Wed, 21 May 2014 11:05:58 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> > Needed for Windows to use hotplugged memory device, otherwise
> > it complains that server is not configured for memory hotplug.
> > Tests shows that aftewards it uses dynamically provided
> > proximity value from _PXM() method if available.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/i386/acpi-build.c |   14 ++++++++++++++
> >  1 files changed, 14 insertions(+), 0 deletions(-)
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 58e7306..97e3a82 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
> >      uint64_t curnode;
> >      int srat_start, numa_start, slots;
> >      uint64_t mem_len, mem_base, next_base;
> > +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> > +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
> >  
> >      srat_start = table_data->len;
> >
> 
> Please don't abbreviate address space as "as". If you abbreviate as as
> as it can be misunderstood for the English as which stands for as.
> You see how confusing this can be :)
> How about hotplug_memory_max_size?
Ok, but ^^ is a bit ambiguous, hot about:
hotplugabble_address_space_size

> 
> Also, it would be a bit more elegant to make this a read-only property
> of the machine.
I'm not sure about exposing it as property since
  - it's internal to implementation and mgmt doesn't need to know about it at all
    so hiding it from QOM view might be a good idea
  - field is shared by PC machines and used only in PC code which runs only
    for a specific instance
So using property here loos like over-engineering for now.

However,
I don't feel strong about it and if you insist I'll make it a property.


> > @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
> >          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
> >      }
> >  
> > +    /*
> > +     * Fake entry required by Windows to enable memory hotplug in OS.
> > +     * Individual DIMM devices override proximity set here via _PXM method,
> > +     * which returns associated with it NUMA node id.
> > +     */
> > +    if (hotplug_as_size) {
> > +        numamem = acpi_data_push(table_data, sizeof *numamem);
> > +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> > +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> > +                               MEM_AFFINITY_ENABLED);
> > +    }
> > +
> >      build_header(linker, table_data,
> >                   (void *)(table_data->data + srat_start),
> >                   "SRAT",
> > -- 
> > 1.7.1
> 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 22/31] acpi:piix4: allow plug/unlug callbacks handle not only PCI devices
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (24 preceding siblings ...)
  2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 31/31] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
@ 2014-05-21 11:29 ` Igor Mammedov
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 23/31] acpi:piix4: add memory hotplug handling Igor Mammedov
                   ` (4 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 11:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, jan.kiszka, mjt, lcapitulino,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, agraf, andrey, vasilis.liaskovitis, pbonzini,
	afaerber, aurelien

... and report error if plugged in device is not supported.
Later these callbacks will be used by memory hotplug.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/piix4.c |   31 ++++++++++++++++++++++---------
 1 files changed, 22 insertions(+), 9 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 67dc075..4341f82 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -310,19 +310,32 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
     acpi_pm1_evt_power_down(&s->ar);
 }
 
-static void piix4_pci_device_plug_cb(HotplugHandler *hotplug_dev,
-                                     DeviceState *dev, Error **errp)
+static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
+                                 DeviceState *dev, Error **errp)
 {
     PIIX4PMState *s = PIIX4_PM(hotplug_dev);
-    acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev, errp);
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
+                                  errp);
+    } else {
+        error_setg(errp, "acpi: device plug request for not supported device"
+                   " type: %s", object_get_typename(OBJECT(dev)));
+    }
 }
 
-static void piix4_pci_device_unplug_cb(HotplugHandler *hotplug_dev,
-                                       DeviceState *dev, Error **errp)
+static void piix4_device_unplug_cb(HotplugHandler *hotplug_dev,
+                                   DeviceState *dev, Error **errp)
 {
     PIIX4PMState *s = PIIX4_PM(hotplug_dev);
-    acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
-                                errp);
+
+    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+        acpi_pcihp_device_unplug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
+                                    errp);
+    } else {
+        error_setg(errp, "acpi: device unplug request for not supported device"
+                   " type: %s", object_get_typename(OBJECT(dev)));
+    }
 }
 
 static void piix4_update_bus_hotplug(PCIBus *pci_bus, void *opaque)
@@ -553,8 +566,8 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
      */
     dc->cannot_instantiate_with_device_add_yet = true;
     dc->hotpluggable = false;
-    hc->plug = piix4_pci_device_plug_cb;
-    hc->unplug = piix4_pci_device_unplug_cb;
+    hc->plug = piix4_device_plug_cb;
+    hc->unplug = piix4_device_unplug_cb;
 }
 
 static const TypeInfo piix4_pm_info = {
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 23/31] acpi:piix4: add memory hotplug handling
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (25 preceding siblings ...)
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 22/31] acpi:piix4: allow plug/unlug callbacks handle not only PCI devices Igor Mammedov
@ 2014-05-21 11:29 ` Igor Mammedov
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 25/31] acpi:ich9: " Igor Mammedov
                   ` (3 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 11:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, jan.kiszka, mjt, lcapitulino,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, agraf, andrey, vasilis.liaskovitis, pbonzini,
	afaerber, aurelien

Add memory hotplug initialization/handling to PIIX4_PM device
and enable it by default for post 2.0 machine types

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/piix4.c                  |   15 ++++++++++++++-
 include/hw/acpi/memory_hotplug.h |    1 +
 include/hw/i386/pc.h             |    5 +++++
 3 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 4341f82..056a7bc 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -33,6 +33,8 @@
 #include "hw/acpi/pcihp.h"
 #include "hw/acpi/cpu_hotplug.h"
 #include "hw/hotplug.h"
+#include "hw/mem/dimm.h"
+#include "hw/acpi/memory_hotplug.h"
 
 //#define DEBUG
 
@@ -81,6 +83,8 @@ typedef struct PIIX4PMState {
 
     AcpiCpuHotplug gpe_cpu;
     Notifier cpu_added_notifier;
+
+    MemHotplugState acpi_memory_hotplug;
 } PIIX4PMState;
 
 #define TYPE_PIIX4_PM "PIIX4_PM"
@@ -315,7 +319,10 @@ static void piix4_device_plug_cb(HotplugHandler *hotplug_dev,
 {
     PIIX4PMState *s = PIIX4_PM(hotplug_dev);
 
-    if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+    if (s->acpi_memory_hotplug.is_enabled &&
+        object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
+        acpi_memory_plug_cb(&s->ar, s->irq, &s->acpi_memory_hotplug, dev, errp);
+    } else if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
         acpi_pcihp_device_plug_cb(&s->ar, s->irq, &s->acpi_pci_hotplug, dev,
                                   errp);
     } else {
@@ -533,6 +540,10 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                         PIIX4_CPU_HOTPLUG_IO_BASE);
     s->cpu_added_notifier.notify = piix4_cpu_added_req;
     qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
+
+    if (s->acpi_memory_hotplug.is_enabled) {
+        acpi_memory_hotplug_init(parent, OBJECT(s), &s->acpi_memory_hotplug);
+    }
 }
 
 static Property piix4_pm_properties[] = {
@@ -542,6 +553,8 @@ static Property piix4_pm_properties[] = {
     DEFINE_PROP_UINT8(ACPI_PM_PROP_S4_VAL, PIIX4PMState, s4_val, 2),
     DEFINE_PROP_BOOL("acpi-pci-hotplug-with-bridge-support", PIIX4PMState,
                      use_acpi_pci_hotplug, true),
+    DEFINE_PROP_BOOL("memory-hotplug-support", PIIX4PMState,
+                     acpi_memory_hotplug.is_enabled, true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
index 8f90f72..912c53f 100644
--- a/include/hw/acpi/memory_hotplug.h
+++ b/include/hw/acpi/memory_hotplug.h
@@ -15,6 +15,7 @@ typedef struct MemStatus {
 } MemStatus;
 
 typedef struct MemHotplugState {
+    bool is_enabled; /* true if memory hotplug is supported */
     MemoryRegion io;
     uint32_t selector;
     uint32_t dev_count;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index e541c51..34c3a63 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -314,6 +314,11 @@ bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
             .driver   = "apic",\
             .property = "version",\
             .value    = stringify(0x11),\
+        },\
+        {\
+            .driver   = "PIIX4_PM",\
+            .property = "memory-hotplug-support",\
+            .value    = "off",\
         }
 
 #define PC_COMPAT_1_7 \
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 25/31] acpi:ich9: add memory hotplug handling
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (26 preceding siblings ...)
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 23/31] acpi:piix4: add memory hotplug handling Igor Mammedov
@ 2014-05-21 11:29 ` Igor Mammedov
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 26/31] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
                   ` (2 subsequent siblings)
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 11:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, jan.kiszka, mjt, lcapitulino,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, agraf, andrey, vasilis.liaskovitis, pbonzini,
	afaerber, aurelien

Add memory hotplug initialization/handling to ICH9 LPC device
and enable it by default for post 2.0 machine types

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/ich9.c         |   38 ++++++++++++++++++++++++++++++++++++++
 hw/isa/lpc_ich9.c      |   20 ++++++++++++++++++++
 include/hw/acpi/ich9.h |    4 ++++
 include/hw/i386/pc.h   |    7 ++++++-
 4 files changed, 68 insertions(+), 1 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 0afac42..86c45ba 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -34,6 +34,7 @@
 #include "exec/address-spaces.h"
 
 #include "hw/i386/ich9.h"
+#include "hw/mem/dimm.h"
 
 //#define DEBUG
 
@@ -224,6 +225,11 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
                         &pm->gpe_cpu, ICH9_CPU_HOTPLUG_IO_BASE);
     pm->cpu_added_notifier.notify = ich9_cpu_added_req;
     qemu_register_cpu_added_notifier(&pm->cpu_added_notifier);
+
+    if (pm->acpi_memory_hotplug.is_enabled) {
+        acpi_memory_hotplug_init(pci_address_space_io(lpc_pci), OBJECT(lpc_pci),
+                                 &pm->acpi_memory_hotplug);
+    }
 }
 
 static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v,
@@ -236,9 +242,25 @@ static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v,
     visit_type_uint32(v, &value, name, errp);
 }
 
+static bool ich9_pm_get_memory_hotplug_support(Object *obj, Error **errp)
+{
+    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+    return s->pm.acpi_memory_hotplug.is_enabled;
+}
+
+static void ich9_pm_set_memory_hotplug_support(Object *obj, bool value,
+                                               Error **errp)
+{
+    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+    s->pm.acpi_memory_hotplug.is_enabled = value;
+}
+
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
 {
     static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
+    pm->acpi_memory_hotplug.is_enabled = true;
 
     object_property_add_uint32_ptr(obj, ACPI_PM_PROP_PM_IO_BASE,
                                    &pm->pm_io_base, errp);
@@ -247,4 +269,20 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
                         NULL, NULL, pm, NULL);
     object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
                                    &gpe0_len, errp);
+    object_property_add_bool(obj, "memory-hotplug-support",
+                             ich9_pm_get_memory_hotplug_support,
+                             ich9_pm_set_memory_hotplug_support,
+                             NULL);
+}
+
+void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp)
+{
+    if (pm->acpi_memory_hotplug.is_enabled &&
+        object_dynamic_cast(OBJECT(dev), TYPE_DIMM)) {
+        acpi_memory_plug_cb(&pm->acpi_regs, pm->irq, &pm->acpi_memory_hotplug,
+                            dev, errp);
+    } else {
+        error_setg(errp, "acpi: device plug request for not supported device"
+                   " type: %s", object_get_typename(OBJECT(dev)));
+    }
 }
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 46de3b6..2adf29a 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -599,6 +599,19 @@ static int ich9_lpc_init(PCIDevice *d)
     return 0;
 }
 
+static void ich9_device_plug_cb(HotplugHandler *hotplug_dev,
+                                DeviceState *dev, Error **errp)
+{
+    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+
+    ich9_pm_device_plug_cb(&lpc->pm, dev, errp);
+}
+
+static void ich9_device_unplug_cb(HotplugHandler *hotplug_dev,
+                                  DeviceState *dev, Error **errp)
+{
+}
+
 static bool ich9_rst_cnt_needed(void *opaque)
 {
     ICH9LPCState *lpc = opaque;
@@ -643,6 +656,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass);
 
     set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
     dc->reset = ich9_lpc_reset;
@@ -659,6 +673,8 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
      * pc_q35_init()
      */
     dc->cannot_instantiate_with_device_add_yet = true;
+    hc->plug = ich9_device_plug_cb;
+    hc->unplug = ich9_device_unplug_cb;
 }
 
 static const TypeInfo ich9_lpc_info = {
@@ -667,6 +683,10 @@ static const TypeInfo ich9_lpc_info = {
     .instance_size = sizeof(struct ICH9LPCState),
     .instance_init = ich9_lpc_initfn,
     .class_init  = ich9_lpc_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_HOTPLUG_HANDLER },
+        { }
+    }
 };
 
 static void ich9_lpc_register(void)
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 104f419..1977f1b 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -23,6 +23,7 @@
 
 #include "hw/acpi/acpi.h"
 #include "hw/acpi/cpu_hotplug.h"
+#include "hw/acpi/memory_hotplug.h"
 
 typedef struct ICH9LPCPMRegs {
     /*
@@ -46,6 +47,8 @@ typedef struct ICH9LPCPMRegs {
 
     AcpiCpuHotplug gpe_cpu;
     Notifier cpu_added_notifier;
+
+    MemHotplugState acpi_memory_hotplug;
 } ICH9LPCPMRegs;
 
 void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
@@ -55,4 +58,5 @@ extern const VMStateDescription vmstate_ich9_pm;
 
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp);
 
+void ich9_pm_device_plug_cb(ICH9LPCPMRegs *pm, DeviceState *dev, Error **errp);
 #endif /* HW_ACPI_ICH9_H */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 34c3a63..cecd4c2 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -286,7 +286,12 @@ int e820_get_num_entries(void);
 bool e820_get_entry(int, uint32_t, uint64_t *, uint64_t *);
 
 #define PC_Q35_COMPAT_2_0 \
-        PC_COMPAT_2_0
+        PC_COMPAT_2_0, \
+        {\
+            .driver   = "ICH9 LPC",\
+            .property = "memory-hotplug-support",\
+            .value    = "off",\
+        }
 
 #define PC_Q35_COMPAT_1_7 \
         PC_COMPAT_1_7, \
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 26/31] pc: migrate piix4 & ich9 MemHotplugState
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (27 preceding siblings ...)
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 25/31] acpi:ich9: " Igor Mammedov
@ 2014-05-21 11:29 ` Igor Mammedov
  2014-05-23 15:11   ` Andrey Korolyov
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 27/31] pc: add acpi-device link to PCMachineState Igor Mammedov
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 28/31] pc: propagate memory hotplug event to ACPI device Igor Mammedov
  30 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 11:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, jan.kiszka, mjt, lcapitulino,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, agraf, andrey, vasilis.liaskovitis, pbonzini,
	afaerber, aurelien

Adds an optional subsection that allows to migrate current
state of acpi_memory_hotplug of ACPI PM device.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
  * use subsection, requested by pbonzini
---
 hw/acpi/ich9.c                   |   24 ++++++++++++++++++++++++
 hw/acpi/memory_hotplug.c         |   27 +++++++++++++++++++++++++++
 hw/acpi/piix4.c                  |   24 ++++++++++++++++++++++++
 include/hw/acpi/memory_hotplug.h |    7 +++++++
 4 files changed, 82 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 86c45ba..f021b33 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -140,6 +140,23 @@ static int ich9_pm_post_load(void *opaque, int version_id)
      .offset     = vmstate_offset_pointer(_state, _field, uint8_t),  \
  }
 
+static bool vmstate_test_use_memhp(void *opaque)
+{
+    ICH9LPCPMRegs *s = opaque;
+    return s->acpi_memory_hotplug.is_enabled;
+}
+
+static const VMStateDescription vmstate_memhp_state = {
+    .name = "ich9_pm/memhp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, ICH9LPCPMRegs),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 const VMStateDescription vmstate_ich9_pm = {
     .name = "ich9_pm",
     .version_id = 1,
@@ -157,6 +174,13 @@ const VMStateDescription vmstate_ich9_pm = {
         VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
         VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection[]) {
+        {
+            .vmsd = &vmstate_memhp_state,
+            .needed = vmstate_test_use_memhp,
+        },
+        VMSTATE_END_OF_LIST()
     }
 };
 
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 79158f1..98a3d8c 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -158,3 +158,30 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
     acpi_update_sci(ar, irq);
     return;
 }
+
+static const VMStateDescription vmstate_memhp_sts = {
+    .name = "memory hotplug device state",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_BOOL(is_enabled, MemStatus),
+        VMSTATE_BOOL(is_inserting, MemStatus),
+        VMSTATE_UINT32(ost_event, MemStatus),
+        VMSTATE_UINT32(ost_status, MemStatus),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+const VMStateDescription vmstate_memory_hotplug = {
+    .name = "memory hotplug state",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_UINT32(selector, MemHotplugState),
+        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs, MemHotplugState, dev_count,
+                                             vmstate_memhp_sts, MemStatus),
+        VMSTATE_END_OF_LIST()
+    }
+};
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 056a7bc..c220715 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -250,6 +250,23 @@ static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id)
     return !s->use_acpi_pci_hotplug;
 }
 
+static bool vmstate_test_use_memhp(void *opaque)
+{
+    PIIX4PMState *s = opaque;
+    return s->acpi_memory_hotplug.is_enabled;
+}
+
+static const VMStateDescription vmstate_memhp_state = {
+    .name = "piix4_pm/memhp",
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .minimum_version_id_old = 1,
+    .fields      = (VMStateField[]) {
+        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, PIIX4PMState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
 /* qemu-kvm 1.2 uses version 3 but advertised as 2
  * To support incoming qemu-kvm 1.2 migration, change version_id
  * and minimum_version_id to 2 below (which breaks migration from
@@ -281,6 +298,13 @@ static const VMStateDescription vmstate_acpi = {
         VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
                             vmstate_test_use_acpi_pci_hotplug),
         VMSTATE_END_OF_LIST()
+    },
+    .subsections = (VMStateSubsection[]) {
+        {
+            .vmsd = &vmstate_memhp_state,
+            .needed = vmstate_test_use_memhp,
+        },
+        VMSTATE_END_OF_LIST()
     }
 };
 
diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
index 912c53f..4588459 100644
--- a/include/hw/acpi/memory_hotplug.h
+++ b/include/hw/acpi/memory_hotplug.h
@@ -3,6 +3,7 @@
 
 #include "hw/qdev-core.h"
 #include "hw/acpi/acpi.h"
+#include "migration/vmstate.h"
 
 #define ACPI_MEMORY_HOTPLUG_STATUS 8
 
@@ -27,4 +28,10 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
 
 void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
                          DeviceState *dev, Error **errp);
+
+extern const VMStateDescription vmstate_memory_hotplug;
+#define VMSTATE_MEMORY_HOTPLUG(memhp, state) \
+    VMSTATE_STRUCT(memhp, state, 1, \
+                   vmstate_memory_hotplug, MemHotplugState)
+
 #endif
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 27/31] pc: add acpi-device link to PCMachineState
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (28 preceding siblings ...)
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 26/31] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
@ 2014-05-21 11:29 ` Igor Mammedov
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 28/31] pc: propagate memory hotplug event to ACPI device Igor Mammedov
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 11:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, jan.kiszka, mjt, lcapitulino,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, agraf, andrey, vasilis.liaskovitis, pbonzini,
	afaerber, aurelien

the link will used later to access device implementing
ACPI functions instead of adhoc lookup in QOM tree.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/piix4.c      |    6 +++++-
 hw/i386/pc_piix.c    |   12 +++++++++++-
 hw/i386/pc_q35.c     |   10 ++++++++++
 hw/mips/mips_malta.c |    2 +-
 include/hw/i386/pc.h |    8 +++++++-
 5 files changed, 34 insertions(+), 4 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index c220715..227ea30 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -485,13 +485,17 @@ Object *piix4_pm_find(void)
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int kvm_enabled, FWCfgState *fw_cfg)
+                      int kvm_enabled, FWCfgState *fw_cfg,
+                      DeviceState **piix4_pm)
 {
     DeviceState *dev;
     PIIX4PMState *s;
 
     dev = DEVICE(pci_create(bus, devfn, TYPE_PIIX4_PM));
     qdev_prop_set_uint32(dev, "smb_io_base", smb_io_base);
+    if (piix4_pm) {
+        *piix4_pm = dev;
+    }
 
     s = PIIX4_PM(dev);
     s->irq = sci_irq;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index e133b6a..a13e8d6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -74,6 +74,7 @@ static void pc_init1(MachineState *machine,
                      int pci_enabled,
                      int kvmclock_enabled)
 {
+    PCMachineState *pc_machine = PC_MACHINE(machine);
     MemoryRegion *system_memory = get_system_memory();
     MemoryRegion *system_io = get_system_io();
     int i;
@@ -246,14 +247,23 @@ static void pc_init1(MachineState *machine,
     }
 
     if (pci_enabled && acpi_enabled) {
+        DeviceState *piix4_pm;
         I2CBus *smbus;
 
         smi_irq = qemu_allocate_irqs(pc_acpi_smi_interrupt, first_cpu, 1);
         /* TODO: Populate SPD eeprom data.  */
         smbus = piix4_pm_init(pci_bus, piix3_devfn + 3, 0xb100,
                               gsi[9], *smi_irq,
-                              kvm_enabled(), fw_cfg);
+                              kvm_enabled(), fw_cfg, &piix4_pm);
         smbus_eeprom_init(smbus, 8, NULL, 0);
+
+        object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
+                                 TYPE_HOTPLUG_HANDLER,
+                                 (Object **)&pc_machine->acpi_dev,
+                                 object_property_allow_set_link,
+                                 OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+        object_property_set_link(OBJECT(machine), OBJECT(piix4_pm),
+                                 PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
     }
 
     if (pci_enabled) {
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 0e77476..629eb2d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -62,6 +62,7 @@ static bool has_reserved_memory = true;
 /* PC hardware initialisation */
 static void pc_q35_init(MachineState *machine)
 {
+    PCMachineState *pc_machine = PC_MACHINE(machine);
     ram_addr_t below_4g_mem_size, above_4g_mem_size;
     Q35PCIHost *q35_host;
     PCIHostState *phb;
@@ -178,6 +179,15 @@ static void pc_q35_init(MachineState *machine)
     lpc = pci_create_simple_multifunction(host_bus, PCI_DEVFN(ICH9_LPC_DEV,
                                           ICH9_LPC_FUNC), true,
                                           TYPE_ICH9_LPC_DEVICE);
+
+    object_property_add_link(OBJECT(machine), PC_MACHINE_ACPI_DEVICE_PROP,
+                             TYPE_HOTPLUG_HANDLER,
+                             (Object **)&pc_machine->acpi_dev,
+                             object_property_allow_set_link,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE, &error_abort);
+    object_property_set_link(OBJECT(machine), OBJECT(lpc),
+                             PC_MACHINE_ACPI_DEVICE_PROP, &error_abort);
+
     ich9_lpc = ICH9_LPC_DEVICE(lpc);
     ich9_lpc->pic = gsi;
     ich9_lpc->ioapic = gsi_state->ioapic_irq;
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index 9fe775e..6685c7e 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -1104,7 +1104,7 @@ void mips_malta_init(MachineState *machine)
     pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
     pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
     smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
-                          isa_get_irq(NULL, 9), NULL, 0, NULL);
+                          isa_get_irq(NULL, 9), NULL, 0, NULL, NULL);
     smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
     g_free(smbus_eeprom_buf);
     pit = pit_init(isa_bus, 0x40, 0, NULL);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index cecd4c2..26526a8 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -21,6 +21,7 @@
  * @hotplug_memory_base: address in guest RAM address space where hotplug memory
  * address space begins.
  * @hotplug_memory: hotplug memory addess space container
+ * @acpi_dev: link to ACPI PM device that performs ACPI hotplug handling
  */
 struct PCMachineState {
     /*< private >*/
@@ -29,8 +30,12 @@ struct PCMachineState {
     /* <public> */
     ram_addr_t hotplug_memory_base;
     MemoryRegion hotplug_memory;
+
+    HotplugHandler *acpi_dev;
 };
 
+#define PC_MACHINE_ACPI_DEVICE_PROP "acpi-device"
+
 /**
  * PCMachineClass:
  * @get_hotplug_handler: pointer to parent class callback @get_hotplug_handler
@@ -210,7 +215,8 @@ void ioapic_init_gsi(GSIState *gsi_state, const char *parent_name);
 
 I2CBus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base,
                       qemu_irq sci_irq, qemu_irq smi_irq,
-                      int kvm_enabled, FWCfgState *fw_cfg);
+                      int kvm_enabled, FWCfgState *fw_cfg,
+                      DeviceState **piix4_pm);
 void piix4_smbus_register_device(SMBusDevice *dev, uint8_t addr);
 
 /* hpet.c */
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [Qemu-devel] [PATCH v2 28/31] pc: propagate memory hotplug event to ACPI device
  2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
                   ` (29 preceding siblings ...)
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 27/31] pc: add acpi-device link to PCMachineState Igor Mammedov
@ 2014-05-21 11:29 ` Igor Mammedov
  30 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 11:29 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, alex, mst, aik, jan.kiszka, mjt, lcapitulino,
	kraxel, pasteka, s.priebe, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, agraf, andrey, vasilis.liaskovitis, pbonzini,
	afaerber, aurelien

Notify PIIX4_PM/ICH9LPC device about hotplug event,
so that it would send SCI to guest notifying about
newly added memory.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
v2:
  * fix memory leak, reported by pbonzini
  * use link to ACPI device instead of looking it up in QOM tree
---
 hw/i386/pc.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b6c0ef9..ba4d15f 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1543,6 +1543,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
                          DeviceState *dev, Error **errp)
 {
     int slot;
+    HotplugHandlerClass *hhc;
     Error *local_err = NULL;
     PCMachineState *pcms = PC_MACHINE(hotplug_dev);
     MachineState *machine = MACHINE(hotplug_dev);
@@ -1585,9 +1586,18 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     }
     trace_mhp_pc_dimm_assigned_slot(slot);
 
+    if (!pcms->acpi_dev) {
+        error_setg(&local_err,
+                   "memory hotplug is not enabled: missing acpi device");
+        goto out;
+    }
+
     memory_region_add_subregion(&pcms->hotplug_memory,
                                 addr - pcms->hotplug_memory_base, mr);
     vmstate_register_ram(mr, dev);
+
+    hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);
+    hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &local_err);
 out:
     error_propagate(errp, local_err);
 }
-- 
1.7.1

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-21 11:22     ` Igor Mammedov
@ 2014-05-21 12:44       ` Michael S. Tsirkin
  2014-05-21 13:56         ` Igor Mammedov
  0 siblings, 1 reply; 54+ messages in thread
From: Michael S. Tsirkin @ 2014-05-21 12:44 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, tangchen,
	kraxel, pasteka, s.priebe, agarcia, agraf, aliguori, david,
	lersek, ehabkost, marcel.a, stefanha, cornelia.huck, rth, andrey,
	armbru, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Wed, May 21, 2014 at 01:22:23PM +0200, Igor Mammedov wrote:
> On Wed, 21 May 2014 11:05:58 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> > > Needed for Windows to use hotplugged memory device, otherwise
> > > it complains that server is not configured for memory hotplug.
> > > Tests shows that aftewards it uses dynamically provided
> > > proximity value from _PXM() method if available.
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > >  hw/i386/acpi-build.c |   14 ++++++++++++++
> > >  1 files changed, 14 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > index 58e7306..97e3a82 100644
> > > --- a/hw/i386/acpi-build.c
> > > +++ b/hw/i386/acpi-build.c
> > > @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
> > >      uint64_t curnode;
> > >      int srat_start, numa_start, slots;
> > >      uint64_t mem_len, mem_base, next_base;
> > > +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> > > +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
> > >  
> > >      srat_start = table_data->len;
> > >
> > 
> > Please don't abbreviate address space as "as". If you abbreviate as as
> > as it can be misunderstood for the English as which stands for as.
> > You see how confusing this can be :)
> > How about hotplug_memory_max_size?
> Ok, but ^^ is a bit ambiguous, hot about:
> hotplugabble_address_space_size

Fine with me.

> > 
> > Also, it would be a bit more elegant to make this a read-only property
> > of the machine.
> I'm not sure about exposing it as property since
>   - it's internal to implementation and mgmt doesn't need to know about it at all
>     so hiding it from QOM view might be a good idea
>   - field is shared by PC machines and used only in PC code which runs only
>     for a specific instance
> So using property here loos like over-engineering for now.
> 
> However,
> I don't feel strong about it and if you insist I'll make it a property.
> 

If it's a property ACPI unit tests can poke at it.
I do not feel strongly about it, it's just an idea.
And BTW, it would be nice to have some unit tests
for the new functionality.

> > > @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
> > >          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
> > >      }
> > >  
> > > +    /*
> > > +     * Fake entry required by Windows to enable memory hotplug in OS.
> > > +     * Individual DIMM devices override proximity set here via _PXM method,
> > > +     * which returns associated with it NUMA node id.
> > > +     */
> > > +    if (hotplug_as_size) {
> > > +        numamem = acpi_data_push(table_data, sizeof *numamem);
> > > +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> > > +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> > > +                               MEM_AFFINITY_ENABLED);
> > > +    }
> > > +
> > >      build_header(linker, table_data,
> > >                   (void *)(table_data->data + srat_start),
> > >                   "SRAT",
> > > -- 
> > > 1.7.1
> > 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-21 12:44       ` Michael S. Tsirkin
@ 2014-05-21 13:56         ` Igor Mammedov
  2014-05-21 15:01           ` Michael S. Tsirkin
  0 siblings, 1 reply; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 13:56 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, tangchen,
	kraxel, pasteka, s.priebe, agarcia, agraf, aliguori, david,
	lersek, ehabkost, marcel.a, stefanha, cornelia.huck, rth, andrey,
	armbru, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Wed, 21 May 2014 15:44:07 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, May 21, 2014 at 01:22:23PM +0200, Igor Mammedov wrote:
> > On Wed, 21 May 2014 11:05:58 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> > > > Needed for Windows to use hotplugged memory device, otherwise
> > > > it complains that server is not configured for memory hotplug.
> > > > Tests shows that aftewards it uses dynamically provided
> > > > proximity value from _PXM() method if available.
> > > > 
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > ---
> > > >  hw/i386/acpi-build.c |   14 ++++++++++++++
> > > >  1 files changed, 14 insertions(+), 0 deletions(-)
> > > > 
> > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > index 58e7306..97e3a82 100644
> > > > --- a/hw/i386/acpi-build.c
> > > > +++ b/hw/i386/acpi-build.c
> > > > @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
> > > >      uint64_t curnode;
> > > >      int srat_start, numa_start, slots;
> > > >      uint64_t mem_len, mem_base, next_base;
> > > > +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> > > > +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
> > > >  
> > > >      srat_start = table_data->len;
> > > >
> > > 
> > > Please don't abbreviate address space as "as". If you abbreviate as as
> > > as it can be misunderstood for the English as which stands for as.
> > > You see how confusing this can be :)
> > > How about hotplug_memory_max_size?
> > Ok, but ^^ is a bit ambiguous, hot about:
> > hotplugabble_address_space_size
> 
> Fine with me.
> 
> > > 
> > > Also, it would be a bit more elegant to make this a read-only property
> > > of the machine.
> > I'm not sure about exposing it as property since
> >   - it's internal to implementation and mgmt doesn't need to know about it at all
> >     so hiding it from QOM view might be a good idea
> >   - field is shared by PC machines and used only in PC code which runs only
> >     for a specific instance
> > So using property here loos like over-engineering for now.
> > 
> > However,
> > I don't feel strong about it and if you insist I'll make it a property.
> > 
> 
> If it's a property ACPI unit tests can poke at it.
> I do not feel strongly about it, it's just an idea.
np, I'll add it.

> And BTW, it would be nice to have some unit tests
> for the new functionality.
That's on my TODO list but after hot-add feature is complete.
Feature works but to make it more usable I need first to take
care about:
 - mgmt interface
 - e820/smbios integration

> 
> > > > @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
> > > >          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
> > > >      }
> > > >  
> > > > +    /*
> > > > +     * Fake entry required by Windows to enable memory hotplug in OS.
> > > > +     * Individual DIMM devices override proximity set here via _PXM method,
> > > > +     * which returns associated with it NUMA node id.
> > > > +     */
> > > > +    if (hotplug_as_size) {
> > > > +        numamem = acpi_data_push(table_data, sizeof *numamem);
> > > > +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> > > > +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> > > > +                               MEM_AFFINITY_ENABLED);
> > > > +    }
> > > > +
> > > >      build_header(linker, table_data,
> > > >                   (void *)(table_data->data + srat_start),
> > > >                   "SRAT",
> > > > -- 
> > > > 1.7.1
> > > 
> 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-21 13:56         ` Igor Mammedov
@ 2014-05-21 15:01           ` Michael S. Tsirkin
  2014-05-21 15:17             ` Igor Mammedov
  0 siblings, 1 reply; 54+ messages in thread
From: Michael S. Tsirkin @ 2014-05-21 15:01 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, tangchen,
	kraxel, pasteka, s.priebe, agarcia, agraf, aliguori, david,
	lersek, ehabkost, marcel.a, stefanha, cornelia.huck, rth, andrey,
	armbru, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Wed, May 21, 2014 at 03:56:55PM +0200, Igor Mammedov wrote:
> On Wed, 21 May 2014 15:44:07 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Wed, May 21, 2014 at 01:22:23PM +0200, Igor Mammedov wrote:
> > > On Wed, 21 May 2014 11:05:58 +0300
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> > > > > Needed for Windows to use hotplugged memory device, otherwise
> > > > > it complains that server is not configured for memory hotplug.
> > > > > Tests shows that aftewards it uses dynamically provided
> > > > > proximity value from _PXM() method if available.
> > > > > 
> > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > ---
> > > > >  hw/i386/acpi-build.c |   14 ++++++++++++++
> > > > >  1 files changed, 14 insertions(+), 0 deletions(-)
> > > > > 
> > > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > > index 58e7306..97e3a82 100644
> > > > > --- a/hw/i386/acpi-build.c
> > > > > +++ b/hw/i386/acpi-build.c
> > > > > @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
> > > > >      uint64_t curnode;
> > > > >      int srat_start, numa_start, slots;
> > > > >      uint64_t mem_len, mem_base, next_base;
> > > > > +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> > > > > +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
> > > > >  
> > > > >      srat_start = table_data->len;
> > > > >
> > > > 
> > > > Please don't abbreviate address space as "as". If you abbreviate as as
> > > > as it can be misunderstood for the English as which stands for as.
> > > > You see how confusing this can be :)
> > > > How about hotplug_memory_max_size?
> > > Ok, but ^^ is a bit ambiguous, hot about:
> > > hotplugabble_address_space_size
> > 
> > Fine with me.
> > 
> > > > 
> > > > Also, it would be a bit more elegant to make this a read-only property
> > > > of the machine.
> > > I'm not sure about exposing it as property since
> > >   - it's internal to implementation and mgmt doesn't need to know about it at all
> > >     so hiding it from QOM view might be a good idea
> > >   - field is shared by PC machines and used only in PC code which runs only
> > >     for a specific instance
> > > So using property here loos like over-engineering for now.
> > > 
> > > However,
> > > I don't feel strong about it and if you insist I'll make it a property.
> > > 
> > 
> > If it's a property ACPI unit tests can poke at it.
> > I do not feel strongly about it, it's just an idea.
> np, I'll add it.
> 
> > And BTW, it would be nice to have some unit tests
> > for the new functionality.
> That's on my TODO list but after hot-add feature is complete.
> Feature works but to make it more usable I need first to take
> care about:
>  - mgmt interface
>  - e820/smbios integration

OK so you want to defer merging these bits until this integration is
done? Maybe at least infrastructure patches (currently 1-28) can go in
meanwhile?

> > 
> > > > > @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
> > > > >          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
> > > > >      }
> > > > >  
> > > > > +    /*
> > > > > +     * Fake entry required by Windows to enable memory hotplug in OS.
> > > > > +     * Individual DIMM devices override proximity set here via _PXM method,
> > > > > +     * which returns associated with it NUMA node id.
> > > > > +     */
> > > > > +    if (hotplug_as_size) {
> > > > > +        numamem = acpi_data_push(table_data, sizeof *numamem);
> > > > > +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> > > > > +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> > > > > +                               MEM_AFFINITY_ENABLED);
> > > > > +    }
> > > > > +
> > > > >      build_header(linker, table_data,
> > > > >                   (void *)(table_data->data + srat_start),
> > > > >                   "SRAT",
> > > > > -- 
> > > > > 1.7.1
> > > > 
> > 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-21 15:01           ` Michael S. Tsirkin
@ 2014-05-21 15:17             ` Igor Mammedov
  0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-21 15:17 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, alex, aik, hutao, mjt, qemu-devel, tangchen,
	kraxel, pasteka, s.priebe, agarcia, agraf, aliguori, david,
	lersek, ehabkost, marcel.a, stefanha, cornelia.huck, rth, andrey,
	armbru, vasilis.liaskovitis, pbonzini, afaerber, aurelien

On Wed, 21 May 2014 18:01:45 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Wed, May 21, 2014 at 03:56:55PM +0200, Igor Mammedov wrote:
> > On Wed, 21 May 2014 15:44:07 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Wed, May 21, 2014 at 01:22:23PM +0200, Igor Mammedov wrote:
> > > > On Wed, 21 May 2014 11:05:58 +0300
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Tue, May 20, 2014 at 05:15:33PM +0200, Igor Mammedov wrote:
> > > > > > Needed for Windows to use hotplugged memory device, otherwise
> > > > > > it complains that server is not configured for memory hotplug.
> > > > > > Tests shows that aftewards it uses dynamically provided
> > > > > > proximity value from _PXM() method if available.
> > > > > > 
> > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > > ---
> > > > > >  hw/i386/acpi-build.c |   14 ++++++++++++++
> > > > > >  1 files changed, 14 insertions(+), 0 deletions(-)
> > > > > > 
> > > > > > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > > > > > index 58e7306..97e3a82 100644
> > > > > > --- a/hw/i386/acpi-build.c
> > > > > > +++ b/hw/i386/acpi-build.c
> > > > > > @@ -1199,6 +1199,8 @@ build_srat(GArray *table_data, GArray *linker,
> > > > > >      uint64_t curnode;
> > > > > >      int srat_start, numa_start, slots;
> > > > > >      uint64_t mem_len, mem_base, next_base;
> > > > > > +    PCMachineState *pcms = PC_MACHINE(qdev_get_machine());
> > > > > > +    ram_addr_t hotplug_as_size = memory_region_size(&pcms->hotplug_memory);
> > > > > >  
> > > > > >      srat_start = table_data->len;
> > > > > >
> > > > > 
> > > > > Please don't abbreviate address space as "as". If you abbreviate as as
> > > > > as it can be misunderstood for the English as which stands for as.
> > > > > You see how confusing this can be :)
> > > > > How about hotplug_memory_max_size?
> > > > Ok, but ^^ is a bit ambiguous, hot about:
> > > > hotplugabble_address_space_size
> > > 
> > > Fine with me.
> > > 
> > > > > 
> > > > > Also, it would be a bit more elegant to make this a read-only property
> > > > > of the machine.
> > > > I'm not sure about exposing it as property since
> > > >   - it's internal to implementation and mgmt doesn't need to know about it at all
> > > >     so hiding it from QOM view might be a good idea
> > > >   - field is shared by PC machines and used only in PC code which runs only
> > > >     for a specific instance
> > > > So using property here loos like over-engineering for now.
> > > > 
> > > > However,
> > > > I don't feel strong about it and if you insist I'll make it a property.
> > > > 
> > > 
> > > If it's a property ACPI unit tests can poke at it.
> > > I do not feel strongly about it, it's just an idea.
> > np, I'll add it.
> > 
> > > And BTW, it would be nice to have some unit tests
> > > for the new functionality.
> > That's on my TODO list but after hot-add feature is complete.
> > Feature works but to make it more usable I need first to take
> > care about:
> >  - mgmt interface
> >  - e820/smbios integration
> 
> OK so you want to defer merging these bits until this integration is
> done? Maybe at least infrastructure patches (currently 1-28) can go in
> meanwhile?
nope,
it would be better to merge all patches in this series first and
then on top of it, I'll do HMP/QAPI + e802/smbios patches + tests

> 
> > > 
> > > > > > @@ -1263,6 +1265,18 @@ build_srat(GArray *table_data, GArray *linker,
> > > > > >          acpi_build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS);
> > > > > >      }
> > > > > >  
> > > > > > +    /*
> > > > > > +     * Fake entry required by Windows to enable memory hotplug in OS.
> > > > > > +     * Individual DIMM devices override proximity set here via _PXM method,
> > > > > > +     * which returns associated with it NUMA node id.
> > > > > > +     */
> > > > > > +    if (hotplug_as_size) {
> > > > > > +        numamem = acpi_data_push(table_data, sizeof *numamem);
> > > > > > +        acpi_build_srat_memory(numamem, pcms->hotplug_memory_base,
> > > > > > +                               hotplug_as_size, 0, MEM_AFFINITY_HOTPLUGGABLE |
> > > > > > +                               MEM_AFFINITY_ENABLED);
> > > > > > +    }
> > > > > > +
> > > > > >      build_header(linker, table_data,
> > > > > >                   (void *)(table_data->data + srat_start),
> > > > > >                   "SRAT",
> > > > > > -- 
> > > > > > 1.7.1
> > > > > 
> > > 
> 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 26/31] pc: migrate piix4 & ich9 MemHotplugState
  2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 26/31] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
@ 2014-05-23 15:11   ` Andrey Korolyov
  2014-05-23 15:41     ` Igor Mammedov
  0 siblings, 1 reply; 54+ messages in thread
From: Andrey Korolyov @ 2014-05-23 15:11 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Maydell, alex, Michael S. Tsirkin, aik, jan.kiszka,
	Michael Tokarev, qemu-devel, lcapitulino, Gerd Hoffmann, pasteka,
	Stefan Priebe - Profihost AG, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, Alexander Graf, vasilis.liaskovitis,
	Paolo Bonzini, afaerber, aurelien

On Wed, May 21, 2014 at 3:29 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> Adds an optional subsection that allows to migrate current
> state of acpi_memory_hotplug of ACPI PM device.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
> v2:
>   * use subsection, requested by pbonzini
> ---
>  hw/acpi/ich9.c                   |   24 ++++++++++++++++++++++++
>  hw/acpi/memory_hotplug.c         |   27 +++++++++++++++++++++++++++
>  hw/acpi/piix4.c                  |   24 ++++++++++++++++++++++++
>  include/hw/acpi/memory_hotplug.h |    7 +++++++
>  4 files changed, 82 insertions(+), 0 deletions(-)
>
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index 86c45ba..f021b33 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -140,6 +140,23 @@ static int ich9_pm_post_load(void *opaque, int version_id)
>       .offset     = vmstate_offset_pointer(_state, _field, uint8_t),  \
>   }
>
> +static bool vmstate_test_use_memhp(void *opaque)
> +{
> +    ICH9LPCPMRegs *s = opaque;
> +    return s->acpi_memory_hotplug.is_enabled;
> +}
> +
> +static const VMStateDescription vmstate_memhp_state = {
> +    .name = "ich9_pm/memhp",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .minimum_version_id_old = 1,
> +    .fields      = (VMStateField[]) {
> +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, ICH9LPCPMRegs),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
>  const VMStateDescription vmstate_ich9_pm = {
>      .name = "ich9_pm",
>      .version_id = 1,
> @@ -157,6 +174,13 @@ const VMStateDescription vmstate_ich9_pm = {
>          VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
>          VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
>          VMSTATE_END_OF_LIST()
> +    },
> +    .subsections = (VMStateSubsection[]) {
> +        {
> +            .vmsd = &vmstate_memhp_state,
> +            .needed = vmstate_test_use_memhp,
> +        },
> +        VMSTATE_END_OF_LIST()
>      }
>  };
>
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index 79158f1..98a3d8c 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -158,3 +158,30 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
>      acpi_update_sci(ar, irq);
>      return;
>  }
> +
> +static const VMStateDescription vmstate_memhp_sts = {
> +    .name = "memory hotplug device state",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .minimum_version_id_old = 1,
> +    .fields      = (VMStateField[]) {
> +        VMSTATE_BOOL(is_enabled, MemStatus),
> +        VMSTATE_BOOL(is_inserting, MemStatus),
> +        VMSTATE_UINT32(ost_event, MemStatus),
> +        VMSTATE_UINT32(ost_status, MemStatus),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
> +const VMStateDescription vmstate_memory_hotplug = {
> +    .name = "memory hotplug state",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .minimum_version_id_old = 1,
> +    .fields      = (VMStateField[]) {
> +        VMSTATE_UINT32(selector, MemHotplugState),
> +        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs, MemHotplugState, dev_count,
> +                                             vmstate_memhp_sts, MemStatus),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> index 056a7bc..c220715 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -250,6 +250,23 @@ static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id)
>      return !s->use_acpi_pci_hotplug;
>  }
>
> +static bool vmstate_test_use_memhp(void *opaque)
> +{
> +    PIIX4PMState *s = opaque;
> +    return s->acpi_memory_hotplug.is_enabled;
> +}
> +
> +static const VMStateDescription vmstate_memhp_state = {
> +    .name = "piix4_pm/memhp",
> +    .version_id = 1,
> +    .minimum_version_id = 1,
> +    .minimum_version_id_old = 1,
> +    .fields      = (VMStateField[]) {
> +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, PIIX4PMState),
> +        VMSTATE_END_OF_LIST()
> +    }
> +};
> +
>  /* qemu-kvm 1.2 uses version 3 but advertised as 2
>   * To support incoming qemu-kvm 1.2 migration, change version_id
>   * and minimum_version_id to 2 below (which breaks migration from
> @@ -281,6 +298,13 @@ static const VMStateDescription vmstate_acpi = {
>          VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
>                              vmstate_test_use_acpi_pci_hotplug),
>          VMSTATE_END_OF_LIST()
> +    },
> +    .subsections = (VMStateSubsection[]) {
> +        {
> +            .vmsd = &vmstate_memhp_state,
> +            .needed = vmstate_test_use_memhp,
> +        },
> +        VMSTATE_END_OF_LIST()
>      }
>  };
>
> diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
> index 912c53f..4588459 100644
> --- a/include/hw/acpi/memory_hotplug.h
> +++ b/include/hw/acpi/memory_hotplug.h
> @@ -3,6 +3,7 @@
>
>  #include "hw/qdev-core.h"
>  #include "hw/acpi/acpi.h"
> +#include "migration/vmstate.h"
>
>  #define ACPI_MEMORY_HOTPLUG_STATUS 8
>
> @@ -27,4 +28,10 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
>
>  void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
>                           DeviceState *dev, Error **errp);
> +
> +extern const VMStateDescription vmstate_memory_hotplug;
> +#define VMSTATE_MEMORY_HOTPLUG(memhp, state) \
> +    VMSTATE_STRUCT(memhp, state, 1, \
> +                   vmstate_memory_hotplug, MemHotplugState)
> +
>  #endif
> --
> 1.7.1
>

As I just wrote to Igor, there is a need to preserve dimm states
across p2p migration (like one in libvirt), or live migration will be
not possible with changed dimm configuration at all. Otherwise
patchset works very well - I am not able to found any other flaws in
functionality. If reviewers consider to postpone this functionality -
memhp is still very useable and long-demanded option, so patchset is
self-sufficient.

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [Qemu-devel] [PATCH v2 26/31] pc: migrate piix4 & ich9 MemHotplugState
  2014-05-23 15:11   ` Andrey Korolyov
@ 2014-05-23 15:41     ` Igor Mammedov
  0 siblings, 0 replies; 54+ messages in thread
From: Igor Mammedov @ 2014-05-23 15:41 UTC (permalink / raw)
  To: Andrey Korolyov
  Cc: Peter Maydell, alex, Michael S. Tsirkin, aik, jan.kiszka,
	Michael Tokarev, qemu-devel, lcapitulino, Gerd Hoffmann, pasteka,
	Stefan Priebe - Profihost AG, agarcia, armbru, aliguori, hutao,
	david, lersek, ehabkost, marcel.a, stefanha, cornelia.huck,
	tangchen, rth, Alexander Graf, vasilis.liaskovitis,
	Paolo Bonzini, afaerber, aurelien

On Fri, 23 May 2014 19:11:49 +0400
Andrey Korolyov <andrey@xdel.ru> wrote:

> On Wed, May 21, 2014 at 3:29 PM, Igor Mammedov <imammedo@redhat.com> wrote:
> > Adds an optional subsection that allows to migrate current
> > state of acpi_memory_hotplug of ACPI PM device.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> > v2:
> >   * use subsection, requested by pbonzini
> > ---
> >  hw/acpi/ich9.c                   |   24 ++++++++++++++++++++++++
> >  hw/acpi/memory_hotplug.c         |   27 +++++++++++++++++++++++++++
> >  hw/acpi/piix4.c                  |   24 ++++++++++++++++++++++++
> >  include/hw/acpi/memory_hotplug.h |    7 +++++++
> >  4 files changed, 82 insertions(+), 0 deletions(-)
> >
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index 86c45ba..f021b33 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -140,6 +140,23 @@ static int ich9_pm_post_load(void *opaque, int version_id)
> >       .offset     = vmstate_offset_pointer(_state, _field, uint8_t),  \
> >   }
> >
> > +static bool vmstate_test_use_memhp(void *opaque)
> > +{
> > +    ICH9LPCPMRegs *s = opaque;
> > +    return s->acpi_memory_hotplug.is_enabled;
> > +}
> > +
> > +static const VMStateDescription vmstate_memhp_state = {
> > +    .name = "ich9_pm/memhp",
> > +    .version_id = 1,
> > +    .minimum_version_id = 1,
> > +    .minimum_version_id_old = 1,
> > +    .fields      = (VMStateField[]) {
> > +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, ICH9LPCPMRegs),
> > +        VMSTATE_END_OF_LIST()
> > +    }
> > +};
> > +
> >  const VMStateDescription vmstate_ich9_pm = {
> >      .name = "ich9_pm",
> >      .version_id = 1,
> > @@ -157,6 +174,13 @@ const VMStateDescription vmstate_ich9_pm = {
> >          VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
> >          VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
> >          VMSTATE_END_OF_LIST()
> > +    },
> > +    .subsections = (VMStateSubsection[]) {
> > +        {
> > +            .vmsd = &vmstate_memhp_state,
> > +            .needed = vmstate_test_use_memhp,
> > +        },
> > +        VMSTATE_END_OF_LIST()
> >      }
> >  };
> >
> > diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> > index 79158f1..98a3d8c 100644
> > --- a/hw/acpi/memory_hotplug.c
> > +++ b/hw/acpi/memory_hotplug.c
> > @@ -158,3 +158,30 @@ void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
> >      acpi_update_sci(ar, irq);
> >      return;
> >  }
> > +
> > +static const VMStateDescription vmstate_memhp_sts = {
> > +    .name = "memory hotplug device state",
> > +    .version_id = 1,
> > +    .minimum_version_id = 1,
> > +    .minimum_version_id_old = 1,
> > +    .fields      = (VMStateField[]) {
> > +        VMSTATE_BOOL(is_enabled, MemStatus),
> > +        VMSTATE_BOOL(is_inserting, MemStatus),
> > +        VMSTATE_UINT32(ost_event, MemStatus),
> > +        VMSTATE_UINT32(ost_status, MemStatus),
> > +        VMSTATE_END_OF_LIST()
> > +    }
> > +};
> > +
> > +const VMStateDescription vmstate_memory_hotplug = {
> > +    .name = "memory hotplug state",
> > +    .version_id = 1,
> > +    .minimum_version_id = 1,
> > +    .minimum_version_id_old = 1,
> > +    .fields      = (VMStateField[]) {
> > +        VMSTATE_UINT32(selector, MemHotplugState),
> > +        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(devs, MemHotplugState, dev_count,
> > +                                             vmstate_memhp_sts, MemStatus),
> > +        VMSTATE_END_OF_LIST()
> > +    }
> > +};
> > diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> > index 056a7bc..c220715 100644
> > --- a/hw/acpi/piix4.c
> > +++ b/hw/acpi/piix4.c
> > @@ -250,6 +250,23 @@ static bool vmstate_test_no_use_acpi_pci_hotplug(void *opaque, int version_id)
> >      return !s->use_acpi_pci_hotplug;
> >  }
> >
> > +static bool vmstate_test_use_memhp(void *opaque)
> > +{
> > +    PIIX4PMState *s = opaque;
> > +    return s->acpi_memory_hotplug.is_enabled;
> > +}
> > +
> > +static const VMStateDescription vmstate_memhp_state = {
> > +    .name = "piix4_pm/memhp",
> > +    .version_id = 1,
> > +    .minimum_version_id = 1,
> > +    .minimum_version_id_old = 1,
> > +    .fields      = (VMStateField[]) {
> > +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug, PIIX4PMState),
> > +        VMSTATE_END_OF_LIST()
> > +    }
> > +};
> > +
> >  /* qemu-kvm 1.2 uses version 3 but advertised as 2
> >   * To support incoming qemu-kvm 1.2 migration, change version_id
> >   * and minimum_version_id to 2 below (which breaks migration from
> > @@ -281,6 +298,13 @@ static const VMStateDescription vmstate_acpi = {
> >          VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
> >                              vmstate_test_use_acpi_pci_hotplug),
> >          VMSTATE_END_OF_LIST()
> > +    },
> > +    .subsections = (VMStateSubsection[]) {
> > +        {
> > +            .vmsd = &vmstate_memhp_state,
> > +            .needed = vmstate_test_use_memhp,
> > +        },
> > +        VMSTATE_END_OF_LIST()
> >      }
> >  };
> >
> > diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
> > index 912c53f..4588459 100644
> > --- a/include/hw/acpi/memory_hotplug.h
> > +++ b/include/hw/acpi/memory_hotplug.h
> > @@ -3,6 +3,7 @@
> >
> >  #include "hw/qdev-core.h"
> >  #include "hw/acpi/acpi.h"
> > +#include "migration/vmstate.h"
> >
> >  #define ACPI_MEMORY_HOTPLUG_STATUS 8
> >
> > @@ -27,4 +28,10 @@ void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner,
> >
> >  void acpi_memory_plug_cb(ACPIREGS *ar, qemu_irq irq, MemHotplugState *mem_st,
> >                           DeviceState *dev, Error **errp);
> > +
> > +extern const VMStateDescription vmstate_memory_hotplug;
> > +#define VMSTATE_MEMORY_HOTPLUG(memhp, state) \
> > +    VMSTATE_STRUCT(memhp, state, 1, \
> > +                   vmstate_memory_hotplug, MemHotplugState)
> > +
> >  #endif
> > --
> > 1.7.1
> >
> 
> As I just wrote to Igor, there is a need to preserve dimm states
> across p2p migration (like one in libvirt), or live migration will be
> not possible with changed dimm configuration at all. Otherwise
In my tests live migration works just fine if done manually (i.e without
libvirt). To work target has to be started with all already present dimm
devices on source (cold/hot-plugged on QEMU CLI using -device dimm,...)

> patchset works very well - I am not able to found any other flaws in
> functionality. If reviewers consider to postpone this functionality -
> memhp is still very useable and long-demanded option, so patchset is
> self-sufficient.

Thanks for feedback and testing!

-- 
Regards,
  Igor

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2014-05-23 15:43 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-05-20 15:15 [Qemu-devel] [PATCH v2 00/31] pc: ACPI memory hotplug Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 01/31] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 02/31] object_add: allow completion handler to get canonical path Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 03/31] vl.c: daemonize before guest memory allocation Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 04/31] add memdev backend infrastructure Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 05/31] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
2014-05-21  8:10   ` Michael S. Tsirkin
2014-05-21  8:26     ` Igor Mammedov
2014-05-21  8:27     ` Andrey Korolyov
2014-05-21  8:55       ` Igor Mammedov
2014-05-21  9:12         ` Andrey Korolyov
2014-05-21  9:52           ` Igor Mammedov
2014-05-21 10:04             ` Andrey Korolyov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 06/31] pc: create custom generic PC machine type Igor Mammedov
2014-05-20 15:55   ` Marcel Apfelbaum
2014-05-21  7:30     ` Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 07/31] qdev: hotplug for buss-less devices Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 08/31] qdev: expose DeviceState.hotplugged field as a property Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 09/31] dimm: implement dimm device abstraction Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 10/31] memory: add memory_region_is_mapped() API Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 11/31] dimm: do not allow to set already used memdev Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 12/31] pc: initialize memory hotplug address space Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 13/31] pc: exit QEMU if number of slots more than supported 256 Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 14/31] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 15/31] pc: add memory hotplug handler to PC_MACHINE Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 16/31] dimm: add busy address check and address auto-allocation Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 17/31] dimm: add busy slot check and slot auto-allocation Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 18/31] acpi: rename cpu_hotplug_defs.h to acpi_defs.h Igor Mammedov
2014-05-20 15:35   ` Michael S. Tsirkin
2014-05-20 16:03     ` Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 19/31] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 20/31] trace: add acpi memory hotplug IO region events Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 21/31] trace: pc: add DIMM slot & address allocation Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 24/31] pc: ich9 lpc: make it work with global/compat properties Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 29/31] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 30/31] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
2014-05-20 15:38   ` Michael S. Tsirkin
2014-05-21  7:56     ` Igor Mammedov
2014-05-21  8:02       ` Michael S. Tsirkin
2014-05-21  8:05   ` Michael S. Tsirkin
2014-05-21 11:22     ` Igor Mammedov
2014-05-21 12:44       ` Michael S. Tsirkin
2014-05-21 13:56         ` Igor Mammedov
2014-05-21 15:01           ` Michael S. Tsirkin
2014-05-21 15:17             ` Igor Mammedov
2014-05-20 15:15 ` [Qemu-devel] [PATCH v2 31/31] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 22/31] acpi:piix4: allow plug/unlug callbacks handle not only PCI devices Igor Mammedov
2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 23/31] acpi:piix4: add memory hotplug handling Igor Mammedov
2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 25/31] acpi:ich9: " Igor Mammedov
2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 26/31] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
2014-05-23 15:11   ` Andrey Korolyov
2014-05-23 15:41     ` Igor Mammedov
2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 27/31] pc: add acpi-device link to PCMachineState Igor Mammedov
2014-05-21 11:29 ` [Qemu-devel] [PATCH v2 28/31] pc: propagate memory hotplug event to ACPI device Igor Mammedov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.