All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
@ 2014-04-04 13:36 Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 01/35] qemu-option: introduce qemu_find_opts_singleton Igor Mammedov
                   ` (37 more replies)
  0 siblings, 38 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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
  start - 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 255 (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
   start/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-v8

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 (34):
  vl: convert -m to QemuOpts
  object_add: allow completion handler to get canonical path
  add memdev backend infrastructure
  vl.c: extend -m option to support options for memory hotplug
  add pc-{i440fx,q35}-2.1 machine types
  pc: create custom generic PC machine type
  qdev: hotplug for buss-less devices
  qdev: expose DeviceState.hotplugged field as a property
  dimm: implement dimm device abstraction
  memory: add memory_region_is_mapped() API
  dimm: do not allow to set already busy memdev
  pc: initialize memory hotplug address space
  pc: exit QEMU if slots > 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: add DIMM slot & address allocation for target-i386
  acpi:piix4: make plug/unlug callbacks generic
  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: propagate memory hotplug event to ACPI device
  pc: ACPI BIOS: punch holes in PCI0._CRS for memory hotplug IO region
  pc: ACPI BIOS: name CPU hotplug ACPI0004 device
  pc: ACPI BIOS: implement memory hotplug interface
  pc: ACPI BIOS: use enum for defining memory affinity flags
  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
  pc: ACPI BIOS: update pregenerated ACPI table blobs

Paolo Bonzini (1):
  qemu-option: introduce qemu_find_opts_singleton

 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                      |  46 ++
 hw/acpi/memory_hotplug.c            | 184 ++++++++
 hw/acpi/piix4.c                     |  52 ++-
 hw/core/qdev.c                      |  30 ++
 hw/i386/Makefile.objs               |   3 +-
 hw/i386/acpi-build.c                |  74 +++-
 hw/i386/acpi-dsdt-cpu-hotplug.dsl   |   1 +
 hw/i386/acpi-dsdt.dsl               |  17 +-
 hw/i386/acpi-dsdt.hex.generated     | 102 ++++-
 hw/i386/pc.c                        | 165 +++++++-
 hw/i386/pc_piix.c                   |  64 ++-
 hw/i386/pc_q35.c                    |  38 +-
 hw/i386/q35-acpi-dsdt.dsl           |  17 +-
 hw/i386/q35-acpi-dsdt.hex.generated | 104 ++++-
 hw/i386/ssdt-mem.dsl                |  75 ++++
 hw/i386/ssdt-mem.hex.generated      | 197 +++++++++
 hw/i386/ssdt-misc.dsl               | 163 ++++++++
 hw/i386/ssdt-misc.hex.generated     | 809 +++++++++++++++++++++++++++++++++++-
 hw/isa/lpc_ich9.c                   |  33 +-
 hw/mem/Makefile.objs                |   1 +
 hw/mem/dimm.c                       | 234 +++++++++++
 include/exec/memory.h               |   8 +
 include/hw/acpi/acpi_defs.h         |  35 ++
 include/hw/acpi/cpu_hotplug.h       |   2 +-
 include/hw/acpi/cpu_hotplug_defs.h  |  32 --
 include/hw/acpi/ich9.h              |   4 +
 include/hw/acpi/memory_hotplug.h    |  37 ++
 include/hw/boards.h                 |  10 +
 include/hw/i386/pc.h                |  59 +++
 include/hw/mem/dimm.h               |  72 ++++
 include/qemu/config-file.h          |   2 +
 include/sysemu/hostmem.h            |  60 +++
 memory.c                            |  15 +-
 qemu-options.hx                     |  14 +-
 qmp.c                               |  11 +-
 trace-events                        |  17 +
 util/qemu-config.c                  |  14 +
 vl.c                                | 145 +++++--
 46 files changed, 2987 insertions(+), 173 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/i386/ssdt-mem.hex.generated
 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

-- 
1.9.0

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

* [Qemu-devel] [PATCH 01/35] qemu-option: introduce qemu_find_opts_singleton
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 02/35] vl: convert -m to QemuOpts Igor Mammedov
                   ` (36 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

From: Paolo Bonzini <pbonzini@redhat.com>

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 include/qemu/config-file.h |  2 ++
 util/qemu-config.c         | 14 ++++++++++++++
 vl.c                       | 11 +----------
 3 files changed, 17 insertions(+), 10 deletions(-)

diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index dbd97c4..d4ba20e 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -8,6 +8,8 @@
 
 QemuOptsList *qemu_find_opts(const char *group);
 QemuOptsList *qemu_find_opts_err(const char *group, Error **errp);
+QemuOpts *qemu_find_opts_singleton(const char *group);
+
 void qemu_add_opts(QemuOptsList *list);
 void qemu_add_drive_opts(QemuOptsList *list);
 int qemu_set_option(const char *str);
diff --git a/util/qemu-config.c b/util/qemu-config.c
index f610101..60051df 100644
--- a/util/qemu-config.c
+++ b/util/qemu-config.c
@@ -39,6 +39,20 @@ QemuOptsList *qemu_find_opts(const char *group)
     return ret;
 }
 
+QemuOpts *qemu_find_opts_singleton(const char *group)
+{
+    QemuOptsList *list;
+    QemuOpts *opts;
+
+    list = qemu_find_opts(group);
+    assert(list);
+    opts = qemu_opts_find(list, NULL);
+    if (!opts) {
+        opts = qemu_opts_create(list, NULL, 0, &error_abort);
+    }
+    return opts;
+}
+
 static CommandLineParameterInfoList *query_option_descs(const QemuOptDesc *desc)
 {
     CommandLineParameterInfoList *param_list = NULL, *entry;
diff --git a/vl.c b/vl.c
index 9975e5a..1dd6319 100644
--- a/vl.c
+++ b/vl.c
@@ -517,16 +517,7 @@ static QemuOptsList qemu_name_opts = {
  */
 QemuOpts *qemu_get_machine_opts(void)
 {
-    QemuOptsList *list;
-    QemuOpts *opts;
-
-    list = qemu_find_opts("machine");
-    assert(list);
-    opts = qemu_opts_find(list, NULL);
-    if (!opts) {
-        opts = qemu_opts_create(list, NULL, 0, &error_abort);
-    }
-    return opts;
+    return qemu_find_opts_singleton("machine");
 }
 
 const char *qemu_get_vm_name(void)
-- 
1.9.0

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

* [Qemu-devel] [PATCH 02/35] vl: convert -m to QemuOpts
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 01/35] qemu-option: introduce qemu_find_opts_singleton Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 03/35] object_add: allow completion handler to get canonical path Igor Mammedov
                   ` (35 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

Adds option to -m
 "size" - startup memory amount

For compatibility with legacy CLI if suffix-less number is passed,
it assumes amount in Mb.

Otherwise user is free to use suffixed number using suffixes b,k/K,M,G

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 qemu-options.hx |  9 +++++---
 vl.c            | 71 +++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 2d33815..a5a412e 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -210,10 +210,13 @@ use is discouraged as it may be removed from future versions.
 ETEXI
 
 DEF("m", HAS_ARG, QEMU_OPTION_m,
-    "-m megs         set virtual RAM size to megs MB [default="
-    stringify(DEFAULT_RAM_SIZE) "]\n", QEMU_ARCH_ALL)
+    "-m [size=]megs\n"
+    "                configure guest RAM\n"
+    "                size: initial amount of guest memory (default: "
+    stringify(DEFAULT_RAM_SIZE) "MiB)\n",
+    QEMU_ARCH_ALL)
 STEXI
-@item -m @var{megs}
+@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
diff --git a/vl.c b/vl.c
index 1dd6319..67fd5bb 100644
--- a/vl.c
+++ b/vl.c
@@ -510,6 +510,20 @@ static QemuOptsList qemu_name_opts = {
     },
 };
 
+static QemuOptsList qemu_mem_opts = {
+    .name = "memory",
+    .implied_opt_name = "size",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
+    .merge_lists = true,
+    .desc = {
+        {
+            .name = "size",
+            .type = QEMU_OPT_SIZE,
+        },
+        { /* end of list */ }
+    },
+};
+
 /**
  * Get machine options
  *
@@ -2955,6 +2969,8 @@ int main(int argc, char **argv, char **envp)
     };
     const char *trace_events = NULL;
     const char *trace_file = NULL;
+    const ram_addr_t default_ram_size = (ram_addr_t)DEFAULT_RAM_SIZE *
+                                        1024 * 1024;
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
@@ -2978,6 +2994,7 @@ int main(int argc, char **argv, char **envp)
     qemu_add_opts(&qemu_trace_opts);
     qemu_add_opts(&qemu_option_rom_opts);
     qemu_add_opts(&qemu_machine_opts);
+    qemu_add_opts(&qemu_mem_opts);
     qemu_add_opts(&qemu_smp_opts);
     qemu_add_opts(&qemu_boot_opts);
     qemu_add_opts(&qemu_sandbox_opts);
@@ -3002,7 +3019,7 @@ int main(int argc, char **argv, char **envp)
     module_call_init(MODULE_INIT_MACHINE);
     machine_class = find_default_machine();
     cpu_model = NULL;
-    ram_size = 0;
+    ram_size = default_ram_size;
     snapshot = 0;
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
@@ -3289,20 +3306,48 @@ int main(int argc, char **argv, char **envp)
                 exit(0);
                 break;
             case QEMU_OPTION_m: {
-                int64_t value;
                 uint64_t sz;
-                char *end;
+                const char *mem_str;
 
-                value = strtosz(optarg, &end);
-                if (value < 0 || *end) {
-                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
-                    exit(1);
+                opts = qemu_opts_parse(qemu_find_opts("memory"),
+                                       optarg, 1);
+                if (!opts) {
+                    exit(EXIT_FAILURE);
+                }
+
+                mem_str = qemu_opt_get(opts, "size");
+                if (!mem_str) {
+                    error_report("invalid -m option, missing 'size' option");
+                    exit(EXIT_FAILURE);
+                }
+                if (!*mem_str) {
+                    error_report("missing 'size' option value");
+                    exit(EXIT_FAILURE);
+                }
+
+                sz = qemu_opt_get_size(opts, "size", ram_size);
+
+                /* Fix up legacy suffix-less format */
+                if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+                    uint64_t overflow_check = sz;
+
+                    sz <<= 20;
+                    if ((sz >> 20) != overflow_check) {
+                        error_report("too large 'size' option value");
+                        exit(EXIT_FAILURE);
+                    }
+                }
+
+                /* backward compatibility behaviour for case "-m 0" */
+                if (sz == 0) {
+                    sz = default_ram_size;
                 }
-                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+
+                sz = QEMU_ALIGN_UP(sz, 8192);
                 ram_size = sz;
                 if (ram_size != sz) {
-                    fprintf(stderr, "qemu: ram size too large\n");
-                    exit(1);
+                    error_report("ram size too large");
+                    exit(EXIT_FAILURE);
                 }
                 break;
             }
@@ -4145,10 +4190,8 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
-    /* init the memory */
-    if (ram_size == 0) {
-        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
-    }
+    /* store value for the future use */
+    qemu_opt_set_number(qemu_find_opts_singleton("memory"), "size", ram_size);
 
     if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
         != 0) {
-- 
1.9.0

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

* [Qemu-devel] [PATCH 03/35] object_add: allow completion handler to get canonical path
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 01/35] qemu-option: introduce qemu_find_opts_singleton Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 02/35] vl: convert -m to QemuOpts Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 04/35] add memdev backend infrastructure Igor Mammedov
                   ` (34 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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  | 12 ++++++++----
 2 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/qmp.c b/qmp.c
index 87a28f7..ac8693d 100644
--- a/qmp.c
+++ b/qmp.c
@@ -564,13 +564,18 @@ void object_add(const char *type, const char *id, const QDict *qdict,
         goto out;
     }
 
-    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 67fd5bb..2181b41 100644
--- a/vl.c
+++ b/vl.c
@@ -2914,14 +2914,18 @@ static int object_create(QemuOpts *opts, void *opaque)
         goto out;
     }
 
-    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:
     object_unref(obj);
     if (local_err) {
-- 
1.9.0

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

* [Qemu-devel] [PATCH 04/35] add memdev backend infrastructure
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (2 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 03/35] object_add: allow completion handler to get canonical path Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 05/35] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
                   ` (33 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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>
---
 backends/Makefile.objs   |   2 +
 backends/hostmem-ram.c   |  54 +++++++++++++++++++++++
 backends/hostmem.c       | 110 +++++++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/hostmem.h |  60 ++++++++++++++++++++++++++
 4 files changed, 226 insertions(+)
 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 42557d5..e6bdc11 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -6,3 +6,5 @@ common-obj-$(CONFIG_BRLAPI) += baum.o
 $(obj)/baum.o: QEMU_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.9.0

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

* [Qemu-devel] [PATCH 05/35] vl.c: extend -m option to support options for memory hotplug
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (3 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 04/35] add memdev backend infrastructure Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 06/35] add pc-{i440fx,q35}-2.1 machine types Igor Mammedov
                   ` (32 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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>
---
 include/hw/boards.h |  2 ++
 qemu-options.hx     |  9 ++++++---
 vl.c                | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index dd2c70d..3567190 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -10,6 +10,8 @@
 typedef struct QEMUMachineInitArgs {
     const QEMUMachine *machine;
     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 a5a412e..7934147 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 2181b41..8f7b04e 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 */ }
     },
 };
@@ -2975,6 +2983,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]);
@@ -3312,6 +3322,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);
@@ -3353,6 +3364,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
@@ -4411,6 +4460,8 @@ int main(int argc, char **argv, char **envp)
 
     QEMUMachineInitArgs args = { .machine = machine,
                                  .ram_size = ram_size,
+                                 .maxram_size = maxram_size,
+                                 .ram_slots = ram_slots,
                                  .boot_order = boot_order,
                                  .kernel_filename = kernel_filename,
                                  .kernel_cmdline = kernel_cmdline,
-- 
1.9.0

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

* [Qemu-devel] [PATCH 06/35] add pc-{i440fx,q35}-2.1 machine types
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (4 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 05/35] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 07/35] pc: create custom generic PC machine type Igor Mammedov
                   ` (31 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc_piix.c | 23 +++++++++++++++++++++--
 hw/i386/pc_q35.c  | 21 ++++++++++++++++++++-
 2 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 7930a26..f0dc4d1 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -262,8 +262,13 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
     pc_init1(args, 1, 1);
 }
 
+static void pc_compat_2_0(QEMUMachineInitArgs *args)
+{
+}
+
 static void pc_compat_1_7(QEMUMachineInitArgs *args)
 {
+    pc_compat_2_0(args);
     smbios_type1_defaults = false;
     gigabyte_align = false;
     option_rom_has_mr = true;
@@ -303,6 +308,12 @@ static void pc_compat_1_2(QEMUMachineInitArgs *args)
     x86_cpu_compat_disable_kvm_features(FEAT_KVM, KVM_FEATURE_PV_EOI);
 }
 
+static void pc_init_pci_2_0(QEMUMachineInitArgs *args)
+{
+    pc_compat_2_0(args);
+    pc_init_pci(args);
+}
+
 static void pc_init_pci_1_7(QEMUMachineInitArgs *args)
 {
     pc_compat_1_7(args);
@@ -383,6 +394,14 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
     .desc = "Standard PC (i440FX + PIIX, 1996)", \
     .hot_add_cpu = pc_hot_add_cpu
 
+static QEMUMachine pc_i440fx_machine_v2_1 = {
+    PC_I440FX_MACHINE_OPTIONS,
+    .name = "pc-i440fx-2.1",
+    .alias = "pc",
+    .init = pc_init_pci,
+    .is_default = 1,
+};
+
 #define PC_I440FX_2_0_MACHINE_OPTIONS                           \
     PC_I440FX_MACHINE_OPTIONS,                                  \
     .default_machine_opts = "firmware=bios-256k.bin"
@@ -391,8 +410,7 @@ static QEMUMachine pc_i440fx_machine_v2_0 = {
     PC_I440FX_2_0_MACHINE_OPTIONS,
     .name = "pc-i440fx-2.0",
     .alias = "pc",
-    .init = pc_init_pci,
-    .is_default = 1,
+    .init = pc_init_pci_2_0,
 };
 
 #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
@@ -817,6 +835,7 @@ 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);
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c844dc2..5ad31a5 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -240,8 +240,13 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     }
 }
 
+static void pc_compat_2_0(QEMUMachineInitArgs *args)
+{
+}
+
 static void pc_compat_1_7(QEMUMachineInitArgs *args)
 {
+    pc_compat_2_0(args);
     smbios_type1_defaults = false;
     gigabyte_align = false;
     option_rom_has_mr = true;
@@ -268,6 +273,12 @@ static void pc_compat_1_4(QEMUMachineInitArgs *args)
     x86_cpu_compat_set_features("Westmere", FEAT_1_ECX, 0, CPUID_EXT_PCLMULQDQ);
 }
 
+static void pc_q35_init_2_0(QEMUMachineInitArgs *args)
+{
+    pc_compat_2_0(args);
+    pc_q35_init(args);
+}
+
 static void pc_q35_init_1_7(QEMUMachineInitArgs *args)
 {
     pc_compat_1_7(args);
@@ -297,6 +308,13 @@ static void pc_q35_init_1_4(QEMUMachineInitArgs *args)
     .desc = "Standard PC (Q35 + ICH9, 2009)", \
     .hot_add_cpu = pc_hot_add_cpu
 
+static QEMUMachine pc_q35_machine_v2_1 = {
+    PC_Q35_MACHINE_OPTIONS,
+    .name = "pc-q35-2.1",
+    .alias = "q35",
+    .init = pc_q35_init,
+};
+
 #define PC_Q35_2_0_MACHINE_OPTIONS                      \
     PC_Q35_MACHINE_OPTIONS,                             \
     .default_machine_opts = "firmware=bios-256k.bin"
@@ -305,7 +323,7 @@ static QEMUMachine pc_q35_machine_v2_0 = {
     PC_Q35_2_0_MACHINE_OPTIONS,
     .name = "pc-q35-2.0",
     .alias = "q35",
-    .init = pc_q35_init,
+    .init = pc_q35_init_2_0,
 };
 
 #define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
@@ -358,6 +376,7 @@ 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);
-- 
1.9.0

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

* [Qemu-devel] [PATCH 07/35] pc: create custom generic PC machine type
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (5 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 06/35] add pc-{i440fx,q35}-2.1 machine types Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices Igor Mammedov
                   ` (30 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

it will be used for PC specific options/variables

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

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 14f0d91..32b4003 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1429,3 +1429,39 @@ 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);
+
+    mc->qemu_machine = data;
+}
+
+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 f0dc4d1..62f750d 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -835,25 +835,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 5ad31a5..ee68de7 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -376,12 +376,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 9010246..b3bc0f7 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.9.0

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

* [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (6 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 07/35] pc: create custom generic PC machine type Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-07  2:26   ` Alexey Kardashevskiy
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 09/35] qdev: expose DeviceState.hotplugged field as a property Igor Mammedov
                   ` (29 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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(+)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 60f9df1..50bb8f5 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 **err)
             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 3567190..67750b5 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -73,6 +73,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 >*/
@@ -80,6 +85,9 @@ struct MachineClass {
     /*< public >*/
 
     QEMUMachine *qemu_machine;
+
+    HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
+                                           DeviceState *dev);
 };
 
 /**
-- 
1.9.0

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

* [Qemu-devel] [PATCH 09/35] qdev: expose DeviceState.hotplugged field as a property
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (7 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 10/35] dimm: implement dimm device abstraction Igor Mammedov
                   ` (28 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/core/qdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 50bb8f5..a278380 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -826,6 +826,20 @@ static bool device_get_hotpluggable(Object *obj, Error **err)
                                 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.9.0

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

* [Qemu-devel] [PATCH 10/35] dimm: implement dimm device abstraction
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (8 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 09/35] qdev: expose DeviceState.hotplugged field as a property Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 11/35] memory: add memory_region_is_mapped() API Igor Mammedov
                   ` (27 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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>
---
 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              |  65 +++++++++++++++++++++++
 6 files changed, 172 insertions(+)
 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..76f2a11
--- /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("start", DimmDevice, start, 0),
+    DEFINE_PROP_UINT32("node", DimmDevice, node, 0),
+    DEFINE_PROP_INT32("slot", DimmDevice, slot, -1),
+    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, "size", "int", dimm_get_size,
+                        NULL, NULL, NULL, &error_abort);
+    object_property_add_link(obj, "memdev", 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, "'memdev' 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..4bbf0ed
--- /dev/null
+++ b/include/hw/mem/dimm.h
@@ -0,0 +1,65 @@
+/*
+ * 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)
+
+/**
+ * DimmDevice:
+ * @start: 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 start;
+    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.9.0

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

* [Qemu-devel] [PATCH 11/35] memory: add memory_region_is_mapped() API
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (9 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 10/35] dimm: implement dimm device abstraction Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 12/35] dimm: do not allow to set already busy memdev Igor Mammedov
                   ` (26 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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 deletion(-)

diff --git a/include/exec/memory.h b/include/exec/memory.h
index c084db2..200d3c5 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.9.0

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

* [Qemu-devel] [PATCH 12/35] dimm: do not allow to set already busy memdev
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (10 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 11/35] memory: add memory_region_is_mapped() API Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space Igor Mammedov
                   ` (25 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 76f2a11..65d4cd0 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, "memdev", 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.9.0

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

* [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (11 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 12/35] dimm: do not allow to set already busy memdev Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 14/35] pc: exit QEMU if slots > 256 Igor Mammedov
                   ` (24 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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

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

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 32b4003..69e4225 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1171,6 +1171,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);
 
@@ -1179,8 +1182,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));
@@ -1197,6 +1199,19 @@ 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->init_args.maxram_size) {
+        ram_addr_t hotplug_mem_size =
+            machine->init_args.maxram_size - ram_size;
+
+        pcms->hotplug_memory_base =
+            ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
+
+        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 b3bc0f7..a1f21ba 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.9.0

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

* [Qemu-devel] [PATCH 14/35] pc: exit QEMU if slots > 256
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (12 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 17:14   ` Eduardo Habkost
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 15/35] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
                   ` (23 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

... which is current ACPI implementation limit.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 69e4225..6fe1803 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1204,6 +1204,12 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
         ram_addr_t hotplug_mem_size =
             machine->init_args.maxram_size - ram_size;
 
+        if (machine->init_args.ram_slots > 256) {
+            error_report("unsupported amount of memory slots: %"PRIu64,
+                         machine->init_args.ram_slots);
+            exit(EXIT_FAILURE);
+        }
+
         pcms->hotplug_memory_base =
             ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
 
-- 
1.9.0

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

* [Qemu-devel] [PATCH 15/35] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (13 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 14/35] pc: exit QEMU if slots > 256 Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 16/35] pc: add memory hotplug handler to PC_MACHINE Igor Mammedov
                   ` (22 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

'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>
---
 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 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6fe1803..b164e37 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1200,7 +1200,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
     }
 
     /* initialize hotplug memory address space */
-    if (ram_size < machine->init_args.maxram_size) {
+    if (guest_info->has_reserved_memory &&
+        (ram_size < machine->init_args.maxram_size)) {
         ram_addr_t hotplug_mem_size =
             machine->init_args.maxram_size - ram_size;
 
@@ -1233,6 +1234,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 62f750d..098fbfc 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -66,6 +66,7 @@ static bool smbios_type1_defaults = true;
  * pages in the host.
  */
 static bool gigabyte_align = true;
+static bool has_reserved_memory = true;
 
 /* PC hardware initialisation */
 static void pc_init1(QEMUMachineInitArgs *args,
@@ -142,6 +143,7 @@ static void pc_init1(QEMUMachineInitArgs *args,
 
     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_type1_defaults) {
         /* These values are guest ABI, do not change */
@@ -264,6 +266,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
 
 static void pc_compat_2_0(QEMUMachineInitArgs *args)
 {
+    has_reserved_memory = false;
 }
 
 static void pc_compat_1_7(QEMUMachineInitArgs *args)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index ee68de7..89fd4b4 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -56,6 +56,7 @@ static bool smbios_type1_defaults = true;
  * pages in the host.
  */
 static bool gigabyte_align = true;
+static bool has_reserved_memory = true;
 
 /* PC hardware initialisation */
 static void pc_q35_init(QEMUMachineInitArgs *args)
@@ -129,6 +130,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     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_type1_defaults) {
         /* These values are guest ABI, do not change */
@@ -242,6 +244,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 
 static void pc_compat_2_0(QEMUMachineInitArgs *args)
 {
+    has_reserved_memory = false;
 }
 
 static void pc_compat_1_7(QEMUMachineInitArgs *args)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index a1f21ba..36f2f52 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.9.0

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

* [Qemu-devel] [PATCH 16/35] pc: add memory hotplug handler to PC_MACHINE
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (14 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 15/35] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 17/35] dimm: add busy address check and address auto-allocation Igor Mammedov
                   ` (21 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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         | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/i386/pc.h |  8 ++++++++
 2 files changed, 60 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index b164e37..4038e2c 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
@@ -1479,12 +1480,63 @@ void qemu_register_pc_machine(QEMUMachine *m)
     g_free(name);
 }
 
+static void pc_dimm_plug(HotplugHandler *hotplug_dev,
+                         DeviceState *dev, Error **errp)
+{
+    PCMachineState *pcms = PC_MACHINE(hotplug_dev);
+    DimmDevice *dimm = DIMM(dev);
+    DimmDeviceClass *ddc = DIMM_GET_CLASS(dimm);
+    MemoryRegion *mr = ddc->get_memory_region(dimm);
+
+    memory_region_add_subregion(&pcms->hotplug_memory,
+                                dimm->start - pcms->hotplug_memory_base,
+                                mr);
+    vmstate_register_ram(mr, dev);
+}
+
+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 36f2f52..059e137 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.9.0

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

* [Qemu-devel] [PATCH 17/35] dimm: add busy address check and address auto-allocation
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (15 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 16/35] pc: add memory hotplug handler to PC_MACHINE Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-05-07  9:58   ` Tang Chen
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 18/35] dimm: add busy slot check and slot auto-allocation Igor Mammedov
                   ` (20 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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

- if 'start' 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>
---
 hw/i386/pc.c          | 16 +++++++++++-
 hw/mem/dimm.c         | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h |  5 ++++
 3 files changed, 89 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4038e2c..29382ec 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1483,15 +1483,29 @@ void qemu_register_pc_machine(QEMUMachine *m)
 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 = dimm->start;
+
+    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, "start", &local_err);
 
     memory_region_add_subregion(&pcms->hotplug_memory,
-                                dimm->start - pcms->hotplug_memory_base,
+                                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,
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 65d4cd0..a10bd07 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -21,6 +21,75 @@
 #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->start - y->start;
+}
+
+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_start, ret;
+    uint64_t address_space_end = address_space_start + address_space_size;
+
+    object_child_foreach(qdev_get_machine(), dimm_built_list, &list);
+
+    if (hint) {
+        new_start = *hint;
+    } else {
+        new_start = 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),
+                             "size", &error_abort);
+        if (ranges_overlap(dimm->start, dimm_size, new_start, size)) {
+            if (hint) {
+                DeviceState *d = DEVICE(dimm);
+                error_setg(errp, "address range conflicts with '%s'", d->id);
+                break;
+            }
+            new_start = dimm->start + dimm_size;
+        }
+    }
+    ret = new_start;
+
+    g_slist_free(list);
+
+    if (new_start < address_space_start) {
+        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
+                   "] at 0x%" PRIx64, new_start, size, address_space_start);
+    } else if ((new_start + size) > address_space_end) {
+        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
+                   "] beyond 0x%" PRIx64, new_start, size, address_space_end);
+    }
+    return ret;
+}
 
 static Property dimm_properties[] = {
     DEFINE_PROP_UINT64("start", DimmDevice, start, 0),
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 4bbf0ed..d6e4d65 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -62,4 +62,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.9.0

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

* [Qemu-devel] [PATCH 18/35] dimm: add busy slot check and slot auto-allocation
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (16 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 17/35] dimm: add busy address check and address auto-allocation Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 19/35] acpi: rename cpu_hotplug_defs.h to acpi_defs.h Igor Mammedov
                   ` (19 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

- 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          | 15 +++++++++++++++
 hw/mem/dimm.c         | 47 +++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h |  2 ++
 3 files changed, 64 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 29382ec..e3e63bb 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1489,6 +1489,8 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     DimmDeviceClass *ddc = DIMM_GET_CLASS(dimm);
     MemoryRegion *mr = ddc->get_memory_region(dimm);
     ram_addr_t addr = dimm->start;
+    MachineState *machine = MACHINE(hotplug_dev);
+    int slot = dimm->slot;
 
     addr = dimm_get_free_addr(pcms->hotplug_memory_base,
                               memory_region_size(&pcms->hotplug_memory),
@@ -1498,6 +1500,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
         goto out;
     }
     object_property_set_int(OBJECT(dev), addr, "start", &local_err);
+    if (local_err) {
+        goto out;
+    }
+
+    slot = dimm_get_free_slot(slot < 0 ? NULL : &slot,
+                              machine->init_args.ram_slots, &local_err);
+    if (local_err) {
+        goto out;
+    }
+    object_property_set_int(OBJECT(dev), slot, "slot", &local_err);
+    if (local_err) {
+        goto out;
+    }
 
     memory_region_add_subregion(&pcms->hotplug_memory,
                                 addr - pcms->hotplug_memory_base,
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index a10bd07..16fdf62 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -23,6 +23,53 @@
 #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);
+        }
+        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 d6e4d65..fa27208 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -67,4 +67,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.9.0

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

* [Qemu-devel] [PATCH 19/35] acpi: rename cpu_hotplug_defs.h to acpi_defs.h
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (17 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 18/35] dimm: add busy slot check and slot auto-allocation Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
                   ` (18 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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        | 32 ++++++++++++++++++++++++++++++++
 include/hw/acpi/cpu_hotplug.h      |  2 +-
 include/hw/acpi/cpu_hotplug_defs.h | 32 --------------------------------
 5 files changed, 35 insertions(+), 35 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..36b831f
--- /dev/null
+++ b/include/hw/acpi/acpi_defs.h
@@ -0,0 +1,32 @@
+/*
+ * 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
+
+#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 9f33663..0000000
--- a/include/hw/acpi/cpu_hotplug_defs.h
+++ /dev/null
@@ -1,32 +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
-
-#endif
-- 
1.9.0

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

* [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (18 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 19/35] acpi: rename cpu_hotplug_defs.h to acpi_defs.h Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-05-05 12:20   ` Vasilis Liaskovitis
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 21/35] trace: add acpi memory hotplug IO region events Igor Mammedov
                   ` (17 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

- 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         | 144 +++++++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi_defs.h      |   3 +
 include/hw/acpi/memory_hotplug.h |  29 ++++++++
 5 files changed, 221 insertions(+)
 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..b0292c8
--- /dev/null
+++ b/hw/acpi/memory_hotplug.c
@@ -0,0 +1,144 @@
+#include "hw/acpi/memory_hotplug.h"
+#include "hw/acpi/acpi_defs.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), "start", NULL);
+        break;
+    case 0x4: /* Hi part of phys address where DIMM is mapped */
+        val = object_property_get_int(OBJECT(mdev->dimm), "start", NULL) >> 32;
+        break;
+    case 0x8: /* Lo part of DIMM size */
+        val = object_property_get_int(OBJECT(mdev->dimm), "size", NULL);
+        break;
+    case 0xc: /* Hi part of DIMM size */
+        val = object_property_get_int(OBJECT(mdev->dimm), "size", NULL) >> 32;
+        break;
+    case 0x10: /* node proximity for _PXM method */
+        val = object_property_get_int(OBJECT(mdev->dimm), "node", 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->init_args.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 36b831f..a6e7219 100644
--- a/include/hw/acpi/acpi_defs.h
+++ b/include/hw/acpi/acpi_defs.h
@@ -29,4 +29,7 @@
 #define ICH9_CPU_HOTPLUG_IO_BASE 0x0CD8
 #define PIIX4_CPU_HOTPLUG_IO_BASE 0xaf00
 
+#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.9.0

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

* [Qemu-devel] [PATCH 21/35] trace: add acpi memory hotplug IO region events
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (19 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 22/35] trace: add DIMM slot & address allocation for target-i386 Igor Mammedov
                   ` (16 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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(+)

diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index b0292c8..a5c3ef4 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -1,6 +1,7 @@
 #include "hw/acpi/memory_hotplug.h"
 #include "hw/acpi/acpi_defs.h"
 #include "hw/boards.h"
+#include "trace.h"
 
 static uint64_t acpi_memory_hotplug_read(void *opaque, hwaddr addr,
                                          unsigned int size)
@@ -10,6 +11,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;
     }
 
@@ -17,22 +19,28 @@ 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), "start", 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), "start", 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), "size", 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), "size", 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), "node", 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;
@@ -53,6 +61,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;
         }
     }
@@ -60,6 +69,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];
@@ -69,10 +79,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;
@@ -80,6 +92,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 9303245..3dce60c 100644
--- a/trace-events
+++ b/trace-events
@@ -1222,3 +1222,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.9.0

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

* [Qemu-devel] [PATCH 22/35] trace: add DIMM slot & address allocation for target-i386
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (20 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 21/35] trace: add acpi memory hotplug IO region events Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic Igor Mammedov
                   ` (15 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e3e63bb..734c6ee 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
@@ -1503,6 +1504,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     if (local_err) {
         goto out;
     }
+    trace_mhp_pc_dimm_assigned_address(dimm->start);
 
     slot = dimm_get_free_slot(slot < 0 ? NULL : &slot,
                               machine->init_args.ram_slots, &local_err);
@@ -1513,6 +1515,7 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     if (local_err) {
         goto out;
     }
+    trace_mhp_pc_dimm_assigned_slot(dimm->slot);
 
     memory_region_add_subregion(&pcms->hotplug_memory,
                                 addr - pcms->hotplug_memory_base,
diff --git a/trace-events b/trace-events
index 3dce60c..9384b7d 100644
--- a/trace-events
+++ b/trace-events
@@ -1235,3 +1235,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.9.0

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

* [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (21 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 22/35] trace: add DIMM slot & address allocation for target-i386 Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-07 11:32   ` Michael S. Tsirkin
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 24/35] acpi:piix4: add memory hotplug handling Igor Mammedov
                   ` (14 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
 1 file 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.9.0

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

* [Qemu-devel] [PATCH 24/35] acpi:piix4: add memory hotplug handling
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (22 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 25/35] pc: ich9 lpc: make it work with global/compat properties Igor Mammedov
                   ` (13 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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 ++++++++++++++-
 hw/i386/pc_piix.c                |  4 ++++
 include/hw/acpi/memory_hotplug.h |  1 +
 include/hw/i386/pc.h             |  8 ++++++++
 4 files changed, 27 insertions(+), 1 deletion(-)

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/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 098fbfc..1329a50 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -414,6 +414,10 @@ static QEMUMachine pc_i440fx_machine_v2_0 = {
     .name = "pc-i440fx-2.0",
     .alias = "pc",
     .init = pc_init_pci_2_0,
+    .compat_props = (GlobalProperty[]) {
+        PC_COMPAT_2_0,
+        { /* end of list */ }
+    },
 };
 
 #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
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 059e137..630bdb2 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -303,7 +303,15 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
         PC_COMPAT_1_4, \
         PC_Q35_COMPAT_1_5
 
+#define PC_COMPAT_2_0 \
+        {\
+            .driver   = "PIIX4_PM",\
+            .property = "memory-hotplug-support",\
+            .value    = "off",\
+        }
+
 #define PC_COMPAT_1_7 \
+        PC_COMPAT_2_0, \
         {\
             .driver   = TYPE_USB_DEVICE,\
             .property = "msos-desc",\
-- 
1.9.0

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

* [Qemu-devel] [PATCH 25/35] pc: ich9 lpc: make it work with global/compat properties
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (23 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 24/35] acpi:piix4: add memory hotplug handling Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 26/35] acpi:ich9: add memory hotplug handling Igor Mammedov
                   ` (12 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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 file 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.9.0

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

* [Qemu-devel] [PATCH 26/35] acpi:ich9: add memory hotplug handling
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (24 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 25/35] pc: ich9 lpc: make it work with global/compat properties Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 27/35] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
                   ` (11 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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/i386/pc_q35.c       |  4 ++++
 hw/isa/lpc_ich9.c      | 20 ++++++++++++++++++++
 include/hw/acpi/ich9.h |  4 ++++
 include/hw/i386/pc.h   |  8 ++++++++
 5 files changed, 74 insertions(+)

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/i386/pc_q35.c b/hw/i386/pc_q35.c
index 89fd4b4..f9b74d5 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -327,6 +327,10 @@ static QEMUMachine pc_q35_machine_v2_0 = {
     .name = "pc-q35-2.0",
     .alias = "q35",
     .init = pc_q35_init_2_0,
+    .compat_props = (GlobalProperty[]) {
+        PC_Q35_COMPAT_2_0,
+        { /* end of list */ }
+    },
 };
 
 #define PC_Q35_1_7_MACHINE_OPTIONS PC_Q35_MACHINE_OPTIONS
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 630bdb2..88efdaa 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -283,6 +283,14 @@ uint16_t pvpanic_port(void);
 
 int e820_add_entry(uint64_t, uint64_t, uint32_t);
 
+#define PC_Q35_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.9.0

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

* [Qemu-devel] [PATCH 27/35] pc: migrate piix4 & ich9 MemHotplugState
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (25 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 26/35] acpi:ich9: add memory hotplug handling Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 14:16   ` Paolo Bonzini
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device Igor Mammedov
                   ` (10 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/ich9.c                   |  8 ++++++++
 hw/acpi/memory_hotplug.c         | 27 +++++++++++++++++++++++++++
 hw/acpi/piix4.c                  |  8 ++++++++
 include/hw/acpi/memory_hotplug.h |  7 +++++++
 4 files changed, 50 insertions(+)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 86c45ba..e566f7e 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -140,6 +140,12 @@ 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, int version_id)
+{
+    ICH9LPCPMRegs *s = opaque;
+    return s->acpi_memory_hotplug.is_enabled;
+}
+
 const VMStateDescription vmstate_ich9_pm = {
     .name = "ich9_pm",
     .version_id = 1,
@@ -156,6 +162,8 @@ const VMStateDescription vmstate_ich9_pm = {
         VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs),
         VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
         VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
+        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug,
+                               ICH9LPCPMRegs, vmstate_test_use_memhp),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index a5c3ef4..7d33cd7 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -155,3 +155,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..3028eb6 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -250,6 +250,12 @@ 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, int version_id)
+{
+    PIIX4PMState *s = opaque;
+    return s->acpi_memory_hotplug.is_enabled;
+}
+
 /* 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
@@ -280,6 +286,8 @@ static const VMStateDescription vmstate_acpi = {
             struct AcpiPciHpPciStatus),
         VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
                             vmstate_test_use_acpi_pci_hotplug),
+        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug,
+                               PIIX4PMState, 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..7251dd0 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, test_memhp_fn) \
+    VMSTATE_STRUCT_TEST(memhp, state, test_memhp_fn, 1, \
+                        vmstate_memory_hotplug, MemHotplugState)
+
 #endif
-- 
1.9.0

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

* [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (26 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 27/35] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 14:02   ` Paolo Bonzini
                     ` (2 more replies)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 29/35] pc: ACPI BIOS: punch holes in PCI0._CRS for memory hotplug IO region Igor Mammedov
                   ` (9 subsequent siblings)
  37 siblings, 3 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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>
---
 hw/i386/pc.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 734c6ee..ee5cf88 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -60,6 +60,8 @@
 #include "acpi-build.h"
 #include "hw/mem/dimm.h"
 #include "trace.h"
+#include "hw/acpi/piix4.h"
+#include "hw/i386/ich9.h"
 
 /* debug PC/ISA interrupts */
 //#define DEBUG_IRQ
@@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
 static void pc_dimm_plug(HotplugHandler *hotplug_dev,
                          DeviceState *dev, Error **errp)
 {
+    Object *acpi_dev;
+    HotplugHandlerClass *hhc;
     Error *local_err = NULL;
     PCMachineState *pcms = PC_MACHINE(hotplug_dev);
     DimmDevice *dimm = DIMM(dev);
@@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
     }
     trace_mhp_pc_dimm_assigned_slot(dimm->slot);
 
+    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
+    if (!acpi_dev) {
+        error_setg(&local_err,
+                   "memory hotplug is not enabled: missing acpi device");
+        return;
+    }
+
+    hhc = HOTPLUG_HANDLER_GET_CLASS(acpi_dev);
     memory_region_add_subregion(&pcms->hotplug_memory,
                                 addr - pcms->hotplug_memory_base,
                                 mr);
     vmstate_register_ram(mr, dev);
+    hhc->plug(HOTPLUG_HANDLER(acpi_dev), dev, &local_err);
 
 out:
     error_propagate(errp, local_err);
-- 
1.9.0

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

* [Qemu-devel] [PATCH 29/35] pc: ACPI BIOS: punch holes in PCI0._CRS for memory hotplug IO region
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (27 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 30/35] pc: ACPI BIOS: name CPU hotplug ACPI0004 device Igor Mammedov
                   ` (8 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

... to make sure that IO range used by memory hotlug won't be used by PCI
devices.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-dsdt.dsl     | 10 +++++++++-
 hw/i386/q35-acpi-dsdt.dsl | 10 +++++++++-
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/hw/i386/acpi-dsdt.dsl b/hw/i386/acpi-dsdt.dsl
index f93353f..b846195 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -39,9 +39,17 @@ DefinitionBlock (
      WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
          0x0000, \
          0x0000, \
+         0x09FF, \
+         0x0000, \
+         0x0A00, \
+         ,, , TypeStatic) \
+     /* 0xa00-0xa17 hole for memory hotplug, include/hw/acpi/memory_hotplug.h:ACPI_MEMORY_HOTPLUG_BASE */ \
+     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
+         0x0000, \
+         0x0A18, \
          0x0CF7, \
          0x0000, \
-         0x0CF8, \
+         0x02E0, \
          ,, , TypeStatic) \
      WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
          0x0000, \
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
index 3838fc7..766e96d 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -52,9 +52,17 @@ DefinitionBlock (
      WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
          0x0000, \
          0x0000, \
+         0x09FF, \
+         0x0000, \
+         0x0A00, \
+         ,, , TypeStatic) \
+     /* 0xa00-0xa17 hole for memory hotplug, include/hw/acpi/memory_hotplug.h:ACPI_MEMORY_HOTPLUG_BASE */ \
+     WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
+         0x0000, \
+         0x0A18, \
          0x0CD7, \
          0x0000, \
-         0x0CD8, \
+         0x02C0, \
          ,, , TypeStatic) \
      /* 0xcd8-0xcf7 hole for CPU hotplug, hw/acpi/ich9.c:ICH9_PROC_BASE */ \
      WordIO(ResourceProducer, MinFixed, MaxFixed, PosDecode, EntireRange, \
-- 
1.9.0

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

* [Qemu-devel] [PATCH 30/35] pc: ACPI BIOS: name CPU hotplug ACPI0004 device
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (28 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 29/35] pc: ACPI BIOS: punch holes in PCI0._CRS for memory hotplug IO region Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-06  9:18   ` Michael S. Tsirkin
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 31/35] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
                   ` (7 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

Following patches will add another ACPI0004 device
to the same scope, and that will make Windows BSOD
because it thinks that the second ACPI0004 device
is duplicate.
Adding to device unique _UID, fixes issue and allows
Windows to distinguish devices with the same _HID

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-dsdt-cpu-hotplug.dsl | 1 +
 1 file changed, 1 insertion(+)

diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
index dee4843..81fb876 100644
--- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
+++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
@@ -94,6 +94,7 @@ Scope(\_SB) {
 
     Device(CPU_HOTPLUG_RESOURCE_DEVICE) {
         Name(_HID, "ACPI0004")
+        Name(_UID, "CPU hotplug resources")
 
         Name(_CRS, ResourceTemplate() {
             IO(Decode16, CPU_STATUS_BASE, CPU_STATUS_BASE, 0, CPU_STATUS_LEN)
-- 
1.9.0

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

* [Qemu-devel] [PATCH 31/35] pc: ACPI BIOS: implement memory hotplug interface
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (29 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 30/35] pc: ACPI BIOS: name CPU hotplug ACPI0004 device Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-06  9:13   ` Michael S. Tsirkin
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 32/35] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
                   ` (6 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

- provides static SSDT object for memory hotplug
- 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>
---
 hw/i386/Makefile.objs |   3 +-
 hw/i386/acpi-build.c  |  37 ++++++++++++
 hw/i386/ssdt-mem.dsl  |  75 +++++++++++++++++++++++
 hw/i386/ssdt-misc.dsl | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 277 insertions(+), 1 deletion(-)
 create mode 100644 hw/i386/ssdt-mem.dsl

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 3df1612..fd04fc2 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 a5d3fbf..6649480 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"
@@ -664,6 +665,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
 
@@ -999,6 +1008,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->init_args.ram_slots;
     unsigned acpi_cpus = guest_info->apic_id_limit;
     int ssdt_start = table_data->len;
     uint8_t *ssdt_ptr;
@@ -1027,6 +1038,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 */
@@ -1080,6 +1094,29 @@ build_ssdt(GArray *table_data, GArray *linker,
             build_free_array(package);
         }
 
+        if (nr_mem) {
+            /*
+             * current device naming scheme dosen't support
+             * more that 256 memory devices
+             */
+            assert(nr_mem <= 256);
+            /* 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(MTFY, 2) {
+             *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
+             */
+            build_append_notify_method(sb_scope, "MTFY", "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..7f68750
--- /dev/null
+++ b/hw/i386/ssdt-mem.dsl
@@ -0,0 +1,75 @@
+/*
+ * 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) }
+ *         ...
+ *     }
+ */
+ACPI_EXTRACT_ALL_CODE ssdm_mem_aml
+
+DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
+{
+
+    External(\_SB.MHPD.MCRS, MethodObj)
+    External(\_SB.MHPD.MRST, MethodObj)
+    External(\_SB.MHPD.MOST, MethodObj)
+    External(\_SB.MHPD.MPXM, 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.MHPD.MCRS(_UID))
+            }
+
+            Method(_STA, 0) {
+                Return(\_SB.MHPD.MRST(_UID))
+            }
+
+            Method(_PXM, 0) {
+                Return(\_SB.MHPD.MPXM(_UID))
+            }
+
+            Method(_OST, 3) {
+                \_SB.MHPD.MOST(_UID, Arg0, Arg1, Arg2)
+            }
+        }
+    }
+}
diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
index a4484b8..d1caaed 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,166 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
             }
         }
     }
+
+    External(MTFY, MethodObj)
+    Scope(\_SB) {
+        Device(MHPD) {
+            Name(_HID, "ACPI0004")
+            Name(_UID, "Memory hotplug resources")
+
+            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
+            Name(MDNR, 0x12345678)
+
+            /* Memory hotplug IO registers */
+            OperationRegion(HPMR, 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(MDNR, Zero)) {
+                    Return(0x0)
+                }
+                /* present, functioning, decoding, not shown in UI */
+                Return(0xB)
+            }
+
+            Field(HPMR, DWordAcc, NoLock, Preserve) {
+                MRBL, 32, // DIMM start addr Low word, read only
+                MRBH, 32, // DIMM start addr Hi word, read only
+                MRLL, 32, // DIMM size Low word, read only
+                MRLH, 32, // DIMM size Hi word, read only
+                MPX, 32,  // DIMM node proximity, read only
+            }
+            Field(HPMR, ByteAcc, NoLock, Preserve) {
+                Offset(20),
+                MES,  1, // 1 if DIMM enabled used by _STA, read only
+                MINS, 1, // (read) 1 if DIMM has a insert event. (write) 1 after MTFY() to clear event
+            }
+
+            Mutex (MLCK, 0)
+            Field (HPMR, DWordAcc, NoLock, Preserve) {
+                MSEL, 32,  // DIMM selector, write only
+                MOEV, 32,  // _OST event code, write only
+                MOSC, 32,  // _OST status code, write only
+            }
+
+            Method(MESC, 0, Serialized) {
+                If (LEqual(MDNR, Zero)) {
+                     Return(Zero)
+                }
+
+                Store(Zero, Local0) // Mem devs iterrator
+                Acquire(MLCK, 0xFFFF)
+                while (LLess(Local0, MDNR)) {
+                    Store(Local0, MSEL) // select Local0 DIMM
+                    If (LEqual(MINS, One)) { // Memory device needs check
+                        MTFY(Local0, 1)
+                        Store(1, MINS)
+                    }
+                    // TODO: handle memory eject request
+                    Add(Local0, One, Local0) // goto next DIMM
+                }
+                Release(MLCK)
+                Return(One)
+            }
+
+            Method(MRST, 1) {
+                Store(Zero, Local0)
+
+                Acquire(MLCK, 0xFFFF)
+                Store(ToInteger(Arg0), MSEL) // select DIMM
+
+                If (LEqual(MES, One)) {
+                    Store(0xF, Local0)
+                }
+
+                Release(MLCK)
+                Return(Local0)
+            }
+
+            Method(MCRS, 1, Serialized) {
+                Acquire(MLCK, 0xFFFF)
+                Store(ToInteger(Arg0), MSEL) // 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(MRBH, MINH)
+                Store(MRBL, MINL)
+                Store(MRLH, LENH)
+                Store(MRLL, 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(MLCK)
+                    Return(MR32)
+                }
+
+                Release(MLCK)
+                Return(MR64)
+            }
+
+            Method(MPXM, 1) {
+                Acquire(MLCK, 0xFFFF)
+                Store(ToInteger(Arg0), MSEL) // select DIMM
+                Store(MPX, Local0)
+                Release(MLCK)
+                Return(Local0)
+            }
+
+            Method(MOST, 4) {
+                Acquire(MLCK, 0xFFFF)
+                Store(ToInteger(Arg0), MSEL) // select DIMM
+                Store(Arg1, MOEV)
+                Store(Arg2, MOSC)
+                Release(MLCK)
+            }
+        } // Device()
+    } // Scope()
 }
-- 
1.9.0

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

* [Qemu-devel] [PATCH 32/35] pc: ACPI BIOS: use enum for defining memory affinity flags
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (30 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 31/35] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
                   ` (5 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 6649480..ef89e99 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1165,15 +1165,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);
 }
@@ -1221,7 +1228,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;
@@ -1237,19 +1244,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.9.0

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

* [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (31 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 32/35] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
       [not found]   ` <20140414072501.GC10931@G08FNSTD100614.fnst.cn.fujitsu.com>
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
                   ` (4 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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 file changed, 14 insertions(+)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index ef89e99..012b100 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1197,6 +1197,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;
 
@@ -1261,6 +1263,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.9.0

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

* [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (32 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
@ 2014-04-04 13:36 ` Igor Mammedov
  2014-05-05 16:25   ` Eric Blake
  2014-04-04 13:37 ` [Qemu-devel] [PATCH 35/35] pc: ACPI BIOS: update pregenerated ACPI table blobs Igor Mammedov
                   ` (3 subsequent siblings)
  37 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:36 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

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

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 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 b846195..d3fb533 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -322,6 +322,7 @@ DefinitionBlock (
 /****************************************************************
  * General purpose events
  ****************************************************************/
+    External(\_SB.MHPD.MESC, MethodObj)
 
     Scope(\_GPE) {
         Name(_HID, "ACPI0006")
@@ -338,7 +339,9 @@ DefinitionBlock (
             // CPU hotplug event
             \_SB.PRSC()
         }
-        Method(_L03) {
+        Method(_E03) {
+            // Memory hotplug event
+            \_SB.MHPD.MESC()
         }
         Method(_L04) {
         }
diff --git a/hw/i386/q35-acpi-dsdt.dsl b/hw/i386/q35-acpi-dsdt.dsl
index 766e96d..a55e34f 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -418,6 +418,7 @@ DefinitionBlock (
 /****************************************************************
  * General purpose events
  ****************************************************************/
+    External(\_SB.MHPD.MESC, MethodObj)
 
     Scope(\_GPE) {
         Name(_HID, "ACPI0006")
@@ -430,7 +431,9 @@ DefinitionBlock (
             // CPU hotplug event
             \_SB.PRSC()
         }
-        Method(_L03) {
+        Method(_E03) {
+            // Memory hotplug event
+            \_SB.MHPD.MESC()
         }
         Method(_L04) {
         }
-- 
1.9.0

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

* [Qemu-devel] [PATCH 35/35] pc: ACPI BIOS: update pregenerated ACPI table blobs
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (33 preceding siblings ...)
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
@ 2014-04-04 13:37 ` Igor Mammedov
       [not found] ` <533EBCB9.3040001@redhat.com>
                   ` (2 subsequent siblings)
  37 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 13:37 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/acpi-dsdt.hex.generated     | 102 ++++-
 hw/i386/q35-acpi-dsdt.hex.generated | 104 ++++-
 hw/i386/ssdt-mem.hex.generated      | 197 +++++++++
 hw/i386/ssdt-misc.hex.generated     | 809 +++++++++++++++++++++++++++++++++++-
 4 files changed, 1162 insertions(+), 50 deletions(-)
 create mode 100644 hw/i386/ssdt-mem.hex.generated

diff --git a/hw/i386/acpi-dsdt.hex.generated b/hw/i386/acpi-dsdt.hex.generated
index 94c6e8e..d956251 100644
--- a/hw/i386/acpi-dsdt.hex.generated
+++ b/hw/i386/acpi-dsdt.hex.generated
@@ -3,12 +3,12 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x53,
 0x44,
 0x54,
-0x85,
+0xc1,
 0x11,
 0x0,
 0x0,
 0x1,
-0x8b,
+0xb4,
 0x42,
 0x58,
 0x50,
@@ -31,9 +31,9 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x14,
+0x2,
+0x14,
 0x20,
 0x10,
 0x49,
@@ -146,7 +146,7 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x1,
 0x10,
 0x4e,
-0x18,
+0x19,
 0x2e,
 0x5f,
 0x53,
@@ -163,9 +163,9 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x53,
 0x11,
 0x42,
+0xb,
 0xa,
-0xa,
-0x9e,
+0xae,
 0x88,
 0xd,
 0x0,
@@ -200,12 +200,28 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x0,
 0x0,
 0x0,
-0xf7,
+0xff,
+0x9,
+0x0,
+0x0,
+0x0,
+0xa,
+0x88,
+0xd,
+0x0,
+0x1,
 0xc,
+0x3,
 0x0,
 0x0,
-0xf8,
+0x18,
+0xa,
+0xf7,
 0xc,
+0x0,
+0x0,
+0xe0,
+0x2,
 0x88,
 0xd,
 0x0,
@@ -395,7 +411,7 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x45,
 0x53,
 0xa,
-0x8c,
+0x9c,
 0x50,
 0x53,
 0x33,
@@ -406,7 +422,7 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x45,
 0x53,
 0xa,
-0x90,
+0xa0,
 0x50,
 0x45,
 0x33,
@@ -417,7 +433,7 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x45,
 0x53,
 0xa,
-0x98,
+0xa8,
 0x50,
 0x4c,
 0x33,
@@ -4010,8 +4026,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x53,
 0x1,
 0x10,
-0x47,
-0x11,
+0x44,
+0x13,
 0x5f,
 0x53,
 0x42,
@@ -4243,7 +4259,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x60,
 0x5b,
 0x82,
-0x2e,
+0x4b,
+0x4,
 0x50,
 0x52,
 0x45,
@@ -4265,6 +4282,34 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x0,
 0x8,
 0x5f,
+0x55,
+0x49,
+0x44,
+0xd,
+0x43,
+0x50,
+0x55,
+0x20,
+0x68,
+0x6f,
+0x74,
+0x70,
+0x6c,
+0x75,
+0x67,
+0x20,
+0x72,
+0x65,
+0x73,
+0x6f,
+0x75,
+0x72,
+0x63,
+0x65,
+0x73,
+0x0,
+0x8,
+0x5f,
 0x43,
 0x52,
 0x53,
@@ -4290,8 +4335,8 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0xa,
 0xb,
 0x10,
-0x42,
-0xc,
+0x41,
+0xd,
 0x5f,
 0x47,
 0x50,
@@ -4394,12 +4439,27 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x53,
 0x43,
 0x14,
-0x6,
+0x15,
 0x5f,
-0x4c,
+0x45,
 0x30,
 0x33,
 0x0,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x4d,
+0x45,
+0x53,
+0x43,
 0x14,
 0x6,
 0x5f,
@@ -4486,5 +4546,5 @@ static unsigned char AcpiDsdtAmlCode[] = {
 0x0
 };
 static unsigned short piix_dsdt_applesmc_sta[] = {
-0x353
+0x363
 };
diff --git a/hw/i386/q35-acpi-dsdt.hex.generated b/hw/i386/q35-acpi-dsdt.hex.generated
index 6c29f3b..8eee22a 100644
--- a/hw/i386/q35-acpi-dsdt.hex.generated
+++ b/hw/i386/q35-acpi-dsdt.hex.generated
@@ -3,12 +3,12 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x53,
 0x44,
 0x54,
-0xd7,
-0x1c,
+0x13,
+0x1d,
 0x0,
 0x0,
 0x1,
-0x3e,
+0x66,
 0x42,
 0x58,
 0x50,
@@ -31,9 +31,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x14,
+0x2,
+0x14,
 0x20,
 0x10,
 0x49,
@@ -361,7 +361,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x6b,
 0x10,
 0x4e,
-0x15,
+0x16,
 0x2e,
 0x5f,
 0x53,
@@ -378,9 +378,9 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x53,
 0x11,
 0x42,
-0x7,
+0x8,
 0xa,
-0x6e,
+0x7e,
 0x88,
 0xd,
 0x0,
@@ -415,12 +415,28 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x0,
 0x0,
 0x0,
-0xd7,
+0xff,
+0x9,
+0x0,
+0x0,
+0x0,
+0xa,
+0x88,
+0xd,
+0x0,
+0x1,
 0xc,
+0x3,
 0x0,
 0x0,
-0xd8,
+0x18,
+0xa,
+0xd7,
 0xc,
+0x0,
+0x0,
+0xc0,
+0x2,
 0x88,
 0xd,
 0x0,
@@ -562,7 +578,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x45,
 0x53,
 0xa,
-0x5c,
+0x6c,
 0x50,
 0x53,
 0x33,
@@ -573,7 +589,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x45,
 0x53,
 0xa,
-0x60,
+0x70,
 0x50,
 0x45,
 0x33,
@@ -584,7 +600,7 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x45,
 0x53,
 0xa,
-0x68,
+0x78,
 0x50,
 0x4c,
 0x33,
@@ -6959,8 +6975,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x53,
 0x1,
 0x10,
-0x47,
-0x11,
+0x44,
+0x13,
 0x5f,
 0x53,
 0x42,
@@ -7192,7 +7208,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x60,
 0x5b,
 0x82,
-0x2e,
+0x4b,
+0x4,
 0x50,
 0x52,
 0x45,
@@ -7214,6 +7231,34 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x0,
 0x8,
 0x5f,
+0x55,
+0x49,
+0x44,
+0xd,
+0x43,
+0x50,
+0x55,
+0x20,
+0x68,
+0x6f,
+0x74,
+0x70,
+0x6c,
+0x75,
+0x67,
+0x20,
+0x72,
+0x65,
+0x73,
+0x6f,
+0x75,
+0x72,
+0x63,
+0x65,
+0x73,
+0x0,
+0x8,
+0x5f,
 0x43,
 0x52,
 0x53,
@@ -7239,8 +7284,8 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0xa,
 0xb,
 0x10,
-0x4f,
-0x8,
+0x4e,
+0x9,
 0x5f,
 0x47,
 0x50,
@@ -7292,12 +7337,27 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x53,
 0x43,
 0x14,
-0x6,
+0x15,
 0x5f,
-0x4c,
+0x45,
 0x30,
 0x33,
 0x0,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x4d,
+0x45,
+0x53,
+0x43,
 0x14,
 0x6,
 0x5f,
@@ -7384,5 +7444,5 @@ static unsigned char Q35AcpiDsdtAmlCode[] = {
 0x0
 };
 static unsigned short q35_dsdt_applesmc_sta[] = {
-0x3fa
+0x40a
 };
diff --git a/hw/i386/ssdt-mem.hex.generated b/hw/i386/ssdt-mem.hex.generated
new file mode 100644
index 0000000..dde2853
--- /dev/null
+++ b/hw/i386/ssdt-mem.hex.generated
@@ -0,0 +1,197 @@
+static unsigned char ssdt_mem_id[] = {
+0x35
+};
+static unsigned char ssdm_mem_aml[] = {
+0x53,
+0x53,
+0x44,
+0x54,
+0xb7,
+0x0,
+0x0,
+0x0,
+0x2,
+0xd6,
+0x42,
+0x58,
+0x50,
+0x43,
+0x0,
+0x0,
+0x43,
+0x53,
+0x53,
+0x44,
+0x54,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x0,
+0x0,
+0x49,
+0x4e,
+0x54,
+0x4c,
+0x14,
+0x2,
+0x14,
+0x20,
+0x10,
+0x42,
+0x9,
+0x5c,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x82,
+0x49,
+0x8,
+0x4d,
+0x50,
+0x41,
+0x41,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xd,
+0x30,
+0x78,
+0x41,
+0x41,
+0x0,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0x80,
+0x14,
+0x1a,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x0,
+0xa4,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x4d,
+0x43,
+0x52,
+0x53,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x14,
+0x1a,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa4,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x4d,
+0x52,
+0x53,
+0x54,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x14,
+0x1a,
+0x5f,
+0x50,
+0x58,
+0x4d,
+0x0,
+0xa4,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x4d,
+0x50,
+0x58,
+0x4d,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x14,
+0x1c,
+0x5f,
+0x4f,
+0x53,
+0x54,
+0x3,
+0x5c,
+0x2f,
+0x3,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x4d,
+0x4f,
+0x53,
+0x54,
+0x5f,
+0x55,
+0x49,
+0x44,
+0x68,
+0x69,
+0x6a
+};
+static unsigned char ssdt_mem_start[] = {
+0x2c
+};
+static unsigned char ssdt_mem_end[] = {
+0xb7
+};
+static unsigned char ssdt_mem_name[] = {
+0x30
+};
diff --git a/hw/i386/ssdt-misc.hex.generated b/hw/i386/ssdt-misc.hex.generated
index 55e3bd2..d81fb12 100644
--- a/hw/i386/ssdt-misc.hex.generated
+++ b/hw/i386/ssdt-misc.hex.generated
@@ -4,6 +4,9 @@ static unsigned char acpi_pci64_length[] = {
 static unsigned char acpi_s4_pkg[] = {
 0x8f
 };
+static unsigned short ssdt_mctrl_nr_slots[] = {
+0x1a6
+};
 static unsigned char acpi_s3_name[] = {
 0x7c
 };
@@ -18,12 +21,12 @@ static unsigned char ssdp_misc_aml[] = {
 0x53,
 0x44,
 0x54,
-0x62,
-0x1,
+0x7a,
+0x4,
 0x0,
 0x0,
 0x1,
-0x76,
+0xc0,
 0x42,
 0x58,
 0x50,
@@ -46,9 +49,9 @@ static unsigned char ssdp_misc_aml[] = {
 0x4e,
 0x54,
 0x4c,
-0x23,
-0x8,
-0x13,
+0x14,
+0x2,
+0x14,
 0x20,
 0x10,
 0x42,
@@ -367,7 +370,799 @@ static unsigned char ssdp_misc_aml[] = {
 0x49,
 0x4f,
 0x4d,
-0x58
+0x58,
+0x10,
+0x47,
+0x31,
+0x5c,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x82,
+0x4e,
+0x30,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xd,
+0x41,
+0x43,
+0x50,
+0x49,
+0x30,
+0x30,
+0x30,
+0x34,
+0x0,
+0x8,
+0x5f,
+0x55,
+0x49,
+0x44,
+0xd,
+0x4d,
+0x65,
+0x6d,
+0x6f,
+0x72,
+0x79,
+0x20,
+0x68,
+0x6f,
+0x74,
+0x70,
+0x6c,
+0x75,
+0x67,
+0x20,
+0x72,
+0x65,
+0x73,
+0x6f,
+0x75,
+0x72,
+0x63,
+0x65,
+0x73,
+0x0,
+0x8,
+0x4d,
+0x44,
+0x4e,
+0x52,
+0xc,
+0x78,
+0x56,
+0x34,
+0x12,
+0x5b,
+0x80,
+0x48,
+0x50,
+0x4d,
+0x52,
+0x1,
+0xb,
+0x0,
+0xa,
+0xa,
+0x18,
+0x8,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x11,
+0xd,
+0xa,
+0xa,
+0x47,
+0x1,
+0x0,
+0xa,
+0x0,
+0xa,
+0x0,
+0x18,
+0x79,
+0x0,
+0x14,
+0x13,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa0,
+0x9,
+0x93,
+0x4d,
+0x44,
+0x4e,
+0x52,
+0x0,
+0xa4,
+0x0,
+0xa4,
+0xa,
+0xb,
+0x5b,
+0x81,
+0x1f,
+0x48,
+0x50,
+0x4d,
+0x52,
+0x3,
+0x4d,
+0x52,
+0x42,
+0x4c,
+0x20,
+0x4d,
+0x52,
+0x42,
+0x48,
+0x20,
+0x4d,
+0x52,
+0x4c,
+0x4c,
+0x20,
+0x4d,
+0x52,
+0x4c,
+0x48,
+0x20,
+0x4d,
+0x50,
+0x58,
+0x5f,
+0x20,
+0x5b,
+0x81,
+0x13,
+0x48,
+0x50,
+0x4d,
+0x52,
+0x1,
+0x0,
+0x40,
+0xa,
+0x4d,
+0x45,
+0x53,
+0x5f,
+0x1,
+0x4d,
+0x49,
+0x4e,
+0x53,
+0x1,
+0x5b,
+0x1,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0x0,
+0x5b,
+0x81,
+0x15,
+0x48,
+0x50,
+0x4d,
+0x52,
+0x3,
+0x4d,
+0x53,
+0x45,
+0x4c,
+0x20,
+0x4d,
+0x4f,
+0x45,
+0x56,
+0x20,
+0x4d,
+0x4f,
+0x53,
+0x43,
+0x20,
+0x14,
+0x4a,
+0x4,
+0x4d,
+0x45,
+0x53,
+0x43,
+0x8,
+0xa0,
+0x9,
+0x93,
+0x4d,
+0x44,
+0x4e,
+0x52,
+0x0,
+0xa4,
+0x0,
+0x70,
+0x0,
+0x60,
+0x5b,
+0x23,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xff,
+0xff,
+0xa2,
+0x25,
+0x95,
+0x60,
+0x4d,
+0x44,
+0x4e,
+0x52,
+0x70,
+0x60,
+0x4d,
+0x53,
+0x45,
+0x4c,
+0xa0,
+0x13,
+0x93,
+0x4d,
+0x49,
+0x4e,
+0x53,
+0x1,
+0x4d,
+0x54,
+0x46,
+0x59,
+0x60,
+0x1,
+0x70,
+0x1,
+0x4d,
+0x49,
+0x4e,
+0x53,
+0x72,
+0x60,
+0x1,
+0x60,
+0x5b,
+0x27,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xa4,
+0x1,
+0x14,
+0x2d,
+0x4d,
+0x52,
+0x53,
+0x54,
+0x1,
+0x70,
+0x0,
+0x60,
+0x5b,
+0x23,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xff,
+0xff,
+0x70,
+0x99,
+0x68,
+0x0,
+0x4d,
+0x53,
+0x45,
+0x4c,
+0xa0,
+0xb,
+0x93,
+0x4d,
+0x45,
+0x53,
+0x5f,
+0x1,
+0x70,
+0xa,
+0xf,
+0x60,
+0x5b,
+0x27,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xa4,
+0x60,
+0x14,
+0x41,
+0x18,
+0x4d,
+0x43,
+0x52,
+0x53,
+0x9,
+0x5b,
+0x23,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xff,
+0xff,
+0x70,
+0x99,
+0x68,
+0x0,
+0x4d,
+0x53,
+0x45,
+0x4c,
+0x8,
+0x4d,
+0x52,
+0x36,
+0x34,
+0x11,
+0x33,
+0xa,
+0x30,
+0x8a,
+0x2b,
+0x0,
+0x0,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xfe,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0xff,
+0x79,
+0x0,
+0x8a,
+0x4d,
+0x52,
+0x36,
+0x34,
+0xa,
+0xe,
+0x4d,
+0x49,
+0x4e,
+0x4c,
+0x8a,
+0x4d,
+0x52,
+0x36,
+0x34,
+0xa,
+0x12,
+0x4d,
+0x49,
+0x4e,
+0x48,
+0x8a,
+0x4d,
+0x52,
+0x36,
+0x34,
+0xa,
+0x26,
+0x4c,
+0x45,
+0x4e,
+0x4c,
+0x8a,
+0x4d,
+0x52,
+0x36,
+0x34,
+0xa,
+0x2a,
+0x4c,
+0x45,
+0x4e,
+0x48,
+0x8a,
+0x4d,
+0x52,
+0x36,
+0x34,
+0xa,
+0x16,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x8a,
+0x4d,
+0x52,
+0x36,
+0x34,
+0xa,
+0x1a,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x70,
+0x4d,
+0x52,
+0x42,
+0x48,
+0x4d,
+0x49,
+0x4e,
+0x48,
+0x70,
+0x4d,
+0x52,
+0x42,
+0x4c,
+0x4d,
+0x49,
+0x4e,
+0x4c,
+0x70,
+0x4d,
+0x52,
+0x4c,
+0x48,
+0x4c,
+0x45,
+0x4e,
+0x48,
+0x70,
+0x4d,
+0x52,
+0x4c,
+0x4c,
+0x4c,
+0x45,
+0x4e,
+0x4c,
+0x72,
+0x4d,
+0x49,
+0x4e,
+0x4c,
+0x4c,
+0x45,
+0x4e,
+0x4c,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x72,
+0x4d,
+0x49,
+0x4e,
+0x48,
+0x4c,
+0x45,
+0x4e,
+0x48,
+0x4d,
+0x41,
+0x58,
+0x48,
+0xa0,
+0x14,
+0x95,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x4d,
+0x49,
+0x4e,
+0x4c,
+0x72,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x1,
+0x4d,
+0x41,
+0x58,
+0x48,
+0xa0,
+0x11,
+0x95,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x1,
+0x74,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x1,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x74,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x1,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0xa0,
+0x44,
+0x7,
+0x93,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x0,
+0x8,
+0x4d,
+0x52,
+0x33,
+0x32,
+0x11,
+0x1f,
+0xa,
+0x1c,
+0x87,
+0x17,
+0x0,
+0x0,
+0xc,
+0x3,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0x0,
+0xfe,
+0xff,
+0xff,
+0xff,
+0x0,
+0x0,
+0x0,
+0x0,
+0xff,
+0xff,
+0xff,
+0xff,
+0x79,
+0x0,
+0x8a,
+0x4d,
+0x52,
+0x33,
+0x32,
+0xa,
+0xa,
+0x4d,
+0x49,
+0x4e,
+0x5f,
+0x8a,
+0x4d,
+0x52,
+0x33,
+0x32,
+0xa,
+0xe,
+0x4d,
+0x41,
+0x58,
+0x5f,
+0x8a,
+0x4d,
+0x52,
+0x33,
+0x32,
+0xa,
+0x16,
+0x4c,
+0x45,
+0x4e,
+0x5f,
+0x70,
+0x4d,
+0x49,
+0x4e,
+0x4c,
+0x4d,
+0x49,
+0x4e,
+0x5f,
+0x70,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x4d,
+0x41,
+0x58,
+0x5f,
+0x70,
+0x4c,
+0x45,
+0x4e,
+0x4c,
+0x4c,
+0x45,
+0x4e,
+0x5f,
+0x5b,
+0x27,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xa4,
+0x4d,
+0x52,
+0x33,
+0x32,
+0x5b,
+0x27,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xa4,
+0x4d,
+0x52,
+0x36,
+0x34,
+0x14,
+0x24,
+0x4d,
+0x50,
+0x58,
+0x4d,
+0x1,
+0x5b,
+0x23,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xff,
+0xff,
+0x70,
+0x99,
+0x68,
+0x0,
+0x4d,
+0x53,
+0x45,
+0x4c,
+0x70,
+0x4d,
+0x50,
+0x58,
+0x5f,
+0x60,
+0x5b,
+0x27,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xa4,
+0x60,
+0x14,
+0x28,
+0x4d,
+0x4f,
+0x53,
+0x54,
+0x4,
+0x5b,
+0x23,
+0x4d,
+0x4c,
+0x43,
+0x4b,
+0xff,
+0xff,
+0x70,
+0x99,
+0x68,
+0x0,
+0x4d,
+0x53,
+0x45,
+0x4c,
+0x70,
+0x69,
+0x4d,
+0x4f,
+0x45,
+0x56,
+0x70,
+0x6a,
+0x4d,
+0x4f,
+0x53,
+0x43,
+0x5b,
+0x27,
+0x4d,
+0x4c,
+0x43,
+0x4b
 };
 static unsigned char ssdt_isa_pest[] = {
 0xd0
-- 
1.9.0

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device Igor Mammedov
@ 2014-04-04 14:02   ` Paolo Bonzini
  2014-04-04 14:29     ` Igor Mammedov
  2014-04-07  3:07   ` Alexey Kardashevskiy
  2014-04-07 10:23   ` Michael S. Tsirkin
  2 siblings, 1 reply; 93+ messages in thread
From: Paolo Bonzini @ 2014-04-04 14:02 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, afaerber

Il 04/04/2014 15:36, Igor Mammedov ha scritto:
> +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> +    if (!acpi_dev) {
> +        error_setg(&local_err,
> +                   "memory hotplug is not enabled: missing acpi device");

errp, not &local_err.

Paolo

> +        return;
> +    }
> +

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

* Re: [Qemu-devel] [PATCH 27/35] pc: migrate piix4 & ich9 MemHotplugState
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 27/35] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
@ 2014-04-04 14:16   ` Paolo Bonzini
  2014-04-04 14:37     ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Paolo Bonzini @ 2014-04-04 14:16 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, afaerber

Il 04/04/2014 15:36, Igor Mammedov ha scritto:
> Adds an optional vmstate field that allows to migrate current
> state of acpi_memory_hotplug of ACPI PM device.
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/acpi/ich9.c                   |  8 ++++++++
>  hw/acpi/memory_hotplug.c         | 27 +++++++++++++++++++++++++++
>  hw/acpi/piix4.c                  |  8 ++++++++
>  include/hw/acpi/memory_hotplug.h |  7 +++++++
>  4 files changed, 50 insertions(+)
>
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index 86c45ba..e566f7e 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -140,6 +140,12 @@ 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, int version_id)
> +{
> +    ICH9LPCPMRegs *s = opaque;
> +    return s->acpi_memory_hotplug.is_enabled;
> +}
> +
>  const VMStateDescription vmstate_ich9_pm = {
>      .name = "ich9_pm",
>      .version_id = 1,
> @@ -156,6 +162,8 @@ const VMStateDescription vmstate_ich9_pm = {
>          VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs),
>          VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
>          VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
> +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug,
> +                               ICH9LPCPMRegs, vmstate_test_use_memhp),
>          VMSTATE_END_OF_LIST()
>      }
>  };
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index a5c3ef4..7d33cd7 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -155,3 +155,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..3028eb6 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -250,6 +250,12 @@ 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, int version_id)
> +{
> +    PIIX4PMState *s = opaque;
> +    return s->acpi_memory_hotplug.is_enabled;
> +}
> +
>  /* 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
> @@ -280,6 +286,8 @@ static const VMStateDescription vmstate_acpi = {
>              struct AcpiPciHpPciStatus),
>          VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
>                              vmstate_test_use_acpi_pci_hotplug),
> +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug,
> +                               PIIX4PMState, 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..7251dd0 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, test_memhp_fn) \
> +    VMSTATE_STRUCT_TEST(memhp, state, test_memhp_fn, 1, \
> +                        vmstate_memory_hotplug, MemHotplugState)
> +
>  #endif
>

It's better to use a subsection for this.  (In fact I think I had asked 
for the same for PCI hotplug as well, but my suggestion was ignored). :(

Paolo

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
       [not found] ` <533EBCB9.3040001@redhat.com>
@ 2014-04-04 14:24   ` Igor Mammedov
  2014-04-04 15:19     ` Paolo Bonzini
  0 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 14:24 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, vasilis.liaskovitis, afaerber

On Fri, 04 Apr 2014 16:07:53 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 04/04/2014 15:36, Igor Mammedov ha scritto:
> >
> > * dropped support for 32 bit guests
> 
> Can you explain this more?
v7 had ability to map hotplugged DIMMs below 4Gb, but Gerd suggested to drop
it since it consume precious lowmem for PCI devices. This version maps
DIMM devices beyond above4gb memory. So "dropped support for 32 bit guests"
here means that if it can't handle GPA above 4Gb and 64bit _CRS, it won't have
working memory cold/hot-plug DIMM devices.

> 
> > PS:
> >   Windows guest requires SRAT table for hotplug to work so add an extra option:
> >    -numa node
> >   to QEMU command line.
> 
> Should we consider always exposing a SRAT for 2.1+ machine types?
That certainly would help management not have to worry about it.

> 
> Paolo


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-04 14:02   ` Paolo Bonzini
@ 2014-04-04 14:29     ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 14:29 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, vasilis.liaskovitis, afaerber

On Fri, 04 Apr 2014 16:02:32 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 04/04/2014 15:36, Igor Mammedov ha scritto:
> > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> > +    if (!acpi_dev) {
> > +        error_setg(&local_err,
> > +                   "memory hotplug is not enabled: missing acpi device");
> 
> errp, not &local_err.
> 
> Paolo
>
or better for consistency with th rest of code:
+        goto out;
-        return;
> > +    }
> > +
> 
> 

-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 27/35] pc: migrate piix4 & ich9 MemHotplugState
  2014-04-04 14:16   ` Paolo Bonzini
@ 2014-04-04 14:37     ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 14:37 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, vasilis.liaskovitis, afaerber

On Fri, 04 Apr 2014 16:16:34 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 04/04/2014 15:36, Igor Mammedov ha scritto:
> > Adds an optional vmstate field that allows to migrate current
> > state of acpi_memory_hotplug of ACPI PM device.
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/acpi/ich9.c                   |  8 ++++++++
> >  hw/acpi/memory_hotplug.c         | 27 +++++++++++++++++++++++++++
> >  hw/acpi/piix4.c                  |  8 ++++++++
> >  include/hw/acpi/memory_hotplug.h |  7 +++++++
> >  4 files changed, 50 insertions(+)
> >
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index 86c45ba..e566f7e 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -140,6 +140,12 @@ 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, int version_id)
> > +{
> > +    ICH9LPCPMRegs *s = opaque;
> > +    return s->acpi_memory_hotplug.is_enabled;
> > +}
> > +
> >  const VMStateDescription vmstate_ich9_pm = {
> >      .name = "ich9_pm",
> >      .version_id = 1,
> > @@ -156,6 +162,8 @@ const VMStateDescription vmstate_ich9_pm = {
> >          VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs),
> >          VMSTATE_UINT32(smi_en, ICH9LPCPMRegs),
> >          VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs),
> > +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug,
> > +                               ICH9LPCPMRegs, vmstate_test_use_memhp),
> >          VMSTATE_END_OF_LIST()
> >      }
> >  };
> > diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> > index a5c3ef4..7d33cd7 100644
> > --- a/hw/acpi/memory_hotplug.c
> > +++ b/hw/acpi/memory_hotplug.c
> > @@ -155,3 +155,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..3028eb6 100644
> > --- a/hw/acpi/piix4.c
> > +++ b/hw/acpi/piix4.c
> > @@ -250,6 +250,12 @@ 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, int version_id)
> > +{
> > +    PIIX4PMState *s = opaque;
> > +    return s->acpi_memory_hotplug.is_enabled;
> > +}
> > +
> >  /* 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
> > @@ -280,6 +286,8 @@ static const VMStateDescription vmstate_acpi = {
> >              struct AcpiPciHpPciStatus),
> >          VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
> >                              vmstate_test_use_acpi_pci_hotplug),
> > +        VMSTATE_MEMORY_HOTPLUG(acpi_memory_hotplug,
> > +                               PIIX4PMState, 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..7251dd0 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, test_memhp_fn) \
> > +    VMSTATE_STRUCT_TEST(memhp, state, test_memhp_fn, 1, \
> > +                        vmstate_memory_hotplug, MemHotplugState)
> > +
> >  #endif
> >
> 
> It's better to use a subsection for this.  (In fact I think I had asked 
> for the same for PCI hotplug as well, but my suggestion was ignored). :(
I'm sorry about, I just followed recent code for PCI hotplug here thinking
it's a more preferred way. I'll switch it to subsection on the next respin.

> 
> Paolo
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
  2014-04-04 14:24   ` [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
@ 2014-04-04 15:19     ` Paolo Bonzini
  2014-04-04 15:37       ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Paolo Bonzini @ 2014-04-04 15:19 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, vasilis.liaskovitis, afaerber

Il 04/04/2014 16:24, Igor Mammedov ha scritto:
> > Can you explain this more?
>
> v7 had ability to map hotplugged DIMMs below 4Gb, but Gerd suggested to drop
> it since it consume precious lowmem for PCI devices. This version maps
> DIMM devices beyond above4gb memory. So "dropped support for 32 bit guests"
> here means that if it can't handle GPA above 4Gb and 64bit _CRS, it won't have
> working memory cold/hot-plug DIMM devices.

Ok, so PAE should work.  Just thinking ahead about release notes. :)

Paolo

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
  2014-04-04 15:19     ` Paolo Bonzini
@ 2014-04-04 15:37       ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-04 15:37 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, vasilis.liaskovitis, afaerber

On Fri, 04 Apr 2014 17:19:50 +0200
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 04/04/2014 16:24, Igor Mammedov ha scritto:
> > > Can you explain this more?
> >
> > v7 had ability to map hotplugged DIMMs below 4Gb, but Gerd suggested to drop
> > it since it consume precious lowmem for PCI devices. This version maps
> > DIMM devices beyond above4gb memory. So "dropped support for 32 bit guests"
> > here means that if it can't handle GPA above 4Gb and 64bit _CRS, it won't have
> > working memory cold/hot-plug DIMM devices.
> 
> Ok, so PAE should work.  Just thinking ahead about release notes. :)
it should, but to confirm I'm installing WS2003EE for the last hour to see if
it works with high mem.

> 
> Paolo


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (35 preceding siblings ...)
       [not found] ` <533EBCB9.3040001@redhat.com>
@ 2014-04-04 16:57 ` Dr. David Alan Gilbert
  2014-04-07  7:32   ` Igor Mammedov
  2014-05-07  9:15 ` Stefan Priebe - Profihost AG
  37 siblings, 1 reply; 93+ messages in thread
From: Dr. David Alan Gilbert @ 2014-04-04 16:57 UTC (permalink / raw)
  To: Igor Mammedov; +Cc: qemu-devel

* Igor Mammedov (imammedo@redhat.com) wrote:

<snip>

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

Some high level questions:
  1) Is the intention that all guest RAM would be hot pluggable like this
     (i.e. no memory would be allocated in the normal way)
  2) Does something stop it being invoked during a migration?

Dave
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [PATCH 14/35] pc: exit QEMU if slots > 256
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 14/35] pc: exit QEMU if slots > 256 Igor Mammedov
@ 2014-04-04 17:14   ` Eduardo Habkost
  2014-04-07  6:55     ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Eduardo Habkost @ 2014-04-04 17:14 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Fri, Apr 04, 2014 at 03:36:39PM +0200, Igor Mammedov wrote:
> ... which is current ACPI implementation limit.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

With this we will have yet another hardcoded limit/assumption scattererd
in different places around the code, which we won't know how/if it can
be changed in the future.

I would prefer to have a #define and an explanation on the code for the
specific limit, so people know if/when/how it is safe to change it a few
years from now.

Something like:

hw/acpi/acpi.h:
    /* current device naming scheme dosen't support
     * more that 256 memory devices
     */
    #define ACPI_MAX_RAM_SLOTS 256

hw/acpi/acpi-build.c:build_ssdt():
    assert(nr_mem <= ACPI_MAX_RAM_SLOTS)

hw/i386/pc.c:
    if (machine->init_args.ram_slots > ACPI_MAX_RAM_SLOTS) {
        error_report("unsupported amount of memory slots: %"PRIu64,
                     machine->init_args.ram_slots);
        exit(EXIT_FAILURE);
    }


> ---
>  hw/i386/pc.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 69e4225..6fe1803 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1204,6 +1204,12 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
>          ram_addr_t hotplug_mem_size =
>              machine->init_args.maxram_size - ram_size;
>  
> +        if (machine->init_args.ram_slots > 256) {
> +            error_report("unsupported amount of memory slots: %"PRIu64,
> +                         machine->init_args.ram_slots);
> +            exit(EXIT_FAILURE);
> +        }
> +
>          pcms->hotplug_memory_base =
>              ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
>  
> -- 
> 1.9.0
> 

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH 31/35] pc: ACPI BIOS: implement memory hotplug interface
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 31/35] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
@ 2014-04-06  9:13   ` Michael S. Tsirkin
  2014-04-07  7:23     ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-06  9:13 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Fri, Apr 04, 2014 at 03:36:56PM +0200, Igor Mammedov wrote:
> - provides static SSDT object for memory hotplug
> - 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>
> ---
>  hw/i386/Makefile.objs |   3 +-
>  hw/i386/acpi-build.c  |  37 ++++++++++++
>  hw/i386/ssdt-mem.dsl  |  75 +++++++++++++++++++++++
>  hw/i386/ssdt-misc.dsl | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 277 insertions(+), 1 deletion(-)
>  create mode 100644 hw/i386/ssdt-mem.dsl
> 
> diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
> index 3df1612..fd04fc2 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 a5d3fbf..6649480 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"
> @@ -664,6 +665,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
>  
> @@ -999,6 +1008,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->init_args.ram_slots;
>      unsigned acpi_cpus = guest_info->apic_id_limit;
>      int ssdt_start = table_data->len;
>      uint8_t *ssdt_ptr;
> @@ -1027,6 +1038,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 */
> @@ -1080,6 +1094,29 @@ build_ssdt(GArray *table_data, GArray *linker,
>              build_free_array(package);
>          }
>  
> +        if (nr_mem) {
> +            /*
> +             * current device naming scheme dosen't support

doesn't

> +             * more that 256 memory devices
> +             */
> +            assert(nr_mem <= 256);
> +            /* 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(MTFY, 2) {
> +             *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
> +             */
> +            build_append_notify_method(sb_scope, "MTFY", "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..7f68750
> --- /dev/null
> +++ b/hw/i386/ssdt-mem.dsl
> @@ -0,0 +1,75 @@
> +/*
> + * 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) }
> + *         ...
> + *     }
> + */
> +ACPI_EXTRACT_ALL_CODE ssdm_mem_aml
> +
> +DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
> +{
> +
> +    External(\_SB.MHPD.MCRS, MethodObj)
> +    External(\_SB.MHPD.MRST, MethodObj)
> +    External(\_SB.MHPD.MOST, MethodObj)
> +    External(\_SB.MHPD.MPXM, 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.MHPD.MCRS(_UID))
> +            }
> +
> +            Method(_STA, 0) {
> +                Return(\_SB.MHPD.MRST(_UID))
> +            }
> +
> +            Method(_PXM, 0) {
> +                Return(\_SB.MHPD.MPXM(_UID))
> +            }
> +
> +            Method(_OST, 3) {
> +                \_SB.MHPD.MOST(_UID, Arg0, Arg1, Arg2)
> +            }
> +        }
> +    }
> +}
> diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
> index a4484b8..d1caaed 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,166 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
>              }
>          }
>      }
> +
> +    External(MTFY, MethodObj)
> +    Scope(\_SB) {
> +        Device(MHPD) {
> +            Name(_HID, "ACPI0004")
> +            Name(_UID, "Memory hotplug resources")
> +
> +            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
> +            Name(MDNR, 0x12345678)

Let's define some macros and use descriptive names - is this one
MEMORY_DIMM_NUMBER?

Same for other ACPI names below.

> +
> +            /* Memory hotplug IO registers */
> +            OperationRegion(HPMR, 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(MDNR, Zero)) {
> +                    Return(0x0)
> +                }
> +                /* present, functioning, decoding, not shown in UI */
> +                Return(0xB)
> +            }
> +
> +            Field(HPMR, DWordAcc, NoLock, Preserve) {
> +                MRBL, 32, // DIMM start addr Low word, read only
> +                MRBH, 32, // DIMM start addr Hi word, read only
> +                MRLL, 32, // DIMM size Low word, read only
> +                MRLH, 32, // DIMM size Hi word, read only
> +                MPX, 32,  // DIMM node proximity, read only
> +            }
> +            Field(HPMR, ByteAcc, NoLock, Preserve) {
> +                Offset(20),
> +                MES,  1, // 1 if DIMM enabled used by _STA, read only
> +                MINS, 1, // (read) 1 if DIMM has a insert event. (write) 1 after MTFY() to clear event
> +            }
> +
> +            Mutex (MLCK, 0)
> +            Field (HPMR, DWordAcc, NoLock, Preserve) {
> +                MSEL, 32,  // DIMM selector, write only
> +                MOEV, 32,  // _OST event code, write only
> +                MOSC, 32,  // _OST status code, write only
> +            }
> +
> +            Method(MESC, 0, Serialized) {

Why is this one serialized? Shouldn't be necessary since
you use explicit locking, right?

> +                If (LEqual(MDNR, Zero)) {
> +                     Return(Zero)
> +                }
> +
> +                Store(Zero, Local0) // Mem devs iterrator
> +                Acquire(MLCK, 0xFFFF)
> +                while (LLess(Local0, MDNR)) {
> +                    Store(Local0, MSEL) // select Local0 DIMM
> +                    If (LEqual(MINS, One)) { // Memory device needs check

This works because MINS is a 1 bit fields.
OK but please use a name that reflects this fact.

> +                        MTFY(Local0, 1)
> +                        Store(1, MINS)
> +                    }
> +                    // TODO: handle memory eject request
> +                    Add(Local0, One, Local0) // goto next DIMM
> +                }
> +                Release(MLCK)
> +                Return(One)
> +            }
> +
> +            Method(MRST, 1) {
> +                Store(Zero, Local0)
> +
> +                Acquire(MLCK, 0xFFFF)
> +                Store(ToInteger(Arg0), MSEL) // select DIMM
> +
> +                If (LEqual(MES, One)) {
> +                    Store(0xF, Local0)
> +                }
> +
> +                Release(MLCK)
> +                Return(Local0)
> +            }
> +
> +            Method(MCRS, 1, Serialized) {
> +                Acquire(MLCK, 0xFFFF)
> +                Store(ToInteger(Arg0), MSEL) // 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(MRBH, MINH)
> +                Store(MRBL, MINL)
> +                Store(MRLH, LENH)
> +                Store(MRLL, 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(MLCK)
> +                    Return(MR32)
> +                }
> +
> +                Release(MLCK)
> +                Return(MR64)
> +            }
> +
> +            Method(MPXM, 1) {
> +                Acquire(MLCK, 0xFFFF)
> +                Store(ToInteger(Arg0), MSEL) // select DIMM
> +                Store(MPX, Local0)
> +                Release(MLCK)
> +                Return(Local0)
> +            }
> +
> +            Method(MOST, 4) {
> +                Acquire(MLCK, 0xFFFF)
> +                Store(ToInteger(Arg0), MSEL) // select DIMM
> +                Store(Arg1, MOEV)
> +                Store(Arg2, MOSC)
> +                Release(MLCK)
> +            }
> +        } // Device()
> +    } // Scope()
>  }
> -- 
> 1.9.0

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

* Re: [Qemu-devel] [PATCH 30/35] pc: ACPI BIOS: name CPU hotplug ACPI0004 device
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 30/35] pc: ACPI BIOS: name CPU hotplug ACPI0004 device Igor Mammedov
@ 2014-04-06  9:18   ` Michael S. Tsirkin
  2014-04-07  7:13     ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-06  9:18 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Fri, Apr 04, 2014 at 03:36:55PM +0200, Igor Mammedov wrote:
> Following patches will add another ACPI0004 device
> to the same scope, and that will make Windows BSOD
> because it thinks that the second ACPI0004 device
> is duplicate.
> Adding to device unique _UID, fixes issue and allows
> Windows to distinguish devices with the same _HID
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

Weren't we going to rename ACPI0004 to PNP0C02 or something?
I remember it creates problems for older guests.

> ---
>  hw/i386/acpi-dsdt-cpu-hotplug.dsl | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> index dee4843..81fb876 100644
> --- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> +++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> @@ -94,6 +94,7 @@ Scope(\_SB) {
>  
>      Device(CPU_HOTPLUG_RESOURCE_DEVICE) {
>          Name(_HID, "ACPI0004")
> +        Name(_UID, "CPU hotplug resources")
>  
>          Name(_CRS, ResourceTemplate() {
>              IO(Decode16, CPU_STATUS_BASE, CPU_STATUS_BASE, 0, CPU_STATUS_LEN)
> -- 
> 1.9.0

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

* Re: [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices Igor Mammedov
@ 2014-04-07  2:26   ` Alexey Kardashevskiy
  2014-04-07  6:51     ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Alexey Kardashevskiy @ 2014-04-07  2:26 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On 04/05/2014 12:36 AM, Igor Mammedov wrote:
> 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.


"returned controller" is a machine here?

Why not to make a memory controller + bus instead? I thought this is the
preferred approach in qom'ed QEMU :)



> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/core/qdev.c      | 13 +++++++++++++
>  include/hw/boards.h |  8 ++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> index 60f9df1..50bb8f5 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 **err)
>              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 3567190..67750b5 100644
> --- a/include/hw/boards.h
> +++ b/include/hw/boards.h
> @@ -73,6 +73,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 >*/
> @@ -80,6 +85,9 @@ struct MachineClass {
>      /*< public >*/
>  
>      QEMUMachine *qemu_machine;
> +
> +    HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
> +                                           DeviceState *dev);
>  };
>  
>  /**
> 


-- 
Alexey

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device Igor Mammedov
  2014-04-04 14:02   ` Paolo Bonzini
@ 2014-04-07  3:07   ` Alexey Kardashevskiy
  2014-04-07 14:13     ` Eduardo Habkost
  2014-04-07 10:23   ` Michael S. Tsirkin
  2 siblings, 1 reply; 93+ messages in thread
From: Alexey Kardashevskiy @ 2014-04-07  3:07 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On 04/05/2014 12:36 AM, Igor Mammedov wrote:
> 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>
> ---
>  hw/i386/pc.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 734c6ee..ee5cf88 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -60,6 +60,8 @@
>  #include "acpi-build.h"
>  #include "hw/mem/dimm.h"
>  #include "trace.h"
> +#include "hw/acpi/piix4.h"
> +#include "hw/i386/ich9.h"
>  
>  /* debug PC/ISA interrupts */
>  //#define DEBUG_IRQ
> @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
>  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
>                           DeviceState *dev, Error **errp)
>  {
> +    Object *acpi_dev;
> +    HotplugHandlerClass *hhc;
>      Error *local_err = NULL;
>      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
>      DimmDevice *dimm = DIMM(dev);
> @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
>      }
>      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
>  
> +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();


wow. just wow.


-- 
Alexey

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

* Re: [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
  2014-04-07  2:26   ` Alexey Kardashevskiy
@ 2014-04-07  6:51     ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07  6:51 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: peter.maydell, mst, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, 07 Apr 2014 12:26:23 +1000
Alexey Kardashevskiy <aik@ozlabs.ru> wrote:

> On 04/05/2014 12:36 AM, Igor Mammedov wrote:
> > 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.
> 
> 
> "returned controller" is a machine here?
not necessary, it could be any device that implements
HotplugHandler interface. Machine only provides simple means to get it
is a simplified version of
https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg04356.html
as suggested by Paolo.

> 
> Why not to make a memory controller + bus instead? I thought this is the
> preferred approach in qom'ed QEMU :)
It's generic mechanism that could be used for hotplugging
any bus-less device.
As regarding bus approach that was used for memory hotplug
in V7, Andreas've made suggestion to get rid of it as it doesn't
map well for generic DIMM device and might be problematic to reuse
on other targets.
In V7 bus was used only as a means to discover a hotplug handler,
with this path bus is not needed anymore.


> 
> 
> 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/core/qdev.c      | 13 +++++++++++++
> >  include/hw/boards.h |  8 ++++++++
> >  2 files changed, 21 insertions(+)
> > 
> > diff --git a/hw/core/qdev.c b/hw/core/qdev.c
> > index 60f9df1..50bb8f5 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 **err)
> >              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 3567190..67750b5 100644
> > --- a/include/hw/boards.h
> > +++ b/include/hw/boards.h
> > @@ -73,6 +73,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 >*/
> > @@ -80,6 +85,9 @@ struct MachineClass {
> >      /*< public >*/
> >  
> >      QEMUMachine *qemu_machine;
> > +
> > +    HotplugHandler *(*get_hotplug_handler)(MachineState *machine,
> > +                                           DeviceState *dev);
> >  };
> >  
> >  /**
> > 
> 
> 

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

* Re: [Qemu-devel] [PATCH 14/35] pc: exit QEMU if slots > 256
  2014-04-04 17:14   ` Eduardo Habkost
@ 2014-04-07  6:55     ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07  6:55 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Fri, 4 Apr 2014 14:14:04 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Fri, Apr 04, 2014 at 03:36:39PM +0200, Igor Mammedov wrote:
> > ... which is current ACPI implementation limit.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> With this we will have yet another hardcoded limit/assumption scattererd
> in different places around the code, which we won't know how/if it can
> be changed in the future.
> 
> I would prefer to have a #define and an explanation on the code for the
> specific limit, so people know if/when/how it is safe to change it a few
> years from now.
> 
> Something like:
> 
> hw/acpi/acpi.h:
>     /* current device naming scheme dosen't support
>      * more that 256 memory devices
>      */
>     #define ACPI_MAX_RAM_SLOTS 256
> 
> hw/acpi/acpi-build.c:build_ssdt():
>     assert(nr_mem <= ACPI_MAX_RAM_SLOTS)
> 
> hw/i386/pc.c:
>     if (machine->init_args.ram_slots > ACPI_MAX_RAM_SLOTS) {
>         error_report("unsupported amount of memory slots: %"PRIu64,
>                      machine->init_args.ram_slots);
>         exit(EXIT_FAILURE);
>     }
sure, I'll fix it for the next series respin.

> 
> > ---
> >  hw/i386/pc.c | 6 ++++++
> >  1 file changed, 6 insertions(+)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 69e4225..6fe1803 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1204,6 +1204,12 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
> >          ram_addr_t hotplug_mem_size =
> >              machine->init_args.maxram_size - ram_size;
> >  
> > +        if (machine->init_args.ram_slots > 256) {
> > +            error_report("unsupported amount of memory slots: %"PRIu64,
> > +                         machine->init_args.ram_slots);
> > +            exit(EXIT_FAILURE);
> > +        }
> > +
> >          pcms->hotplug_memory_base =
> >              ROUND_UP(0x100000000ULL + above_4g_mem_size, 1ULL << 30);
> >  
> > -- 
> > 1.9.0
> > 
> 

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

* Re: [Qemu-devel] [PATCH 30/35] pc: ACPI BIOS: name CPU hotplug ACPI0004 device
  2014-04-06  9:18   ` Michael S. Tsirkin
@ 2014-04-07  7:13     ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07  7:13 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Sun, 6 Apr 2014 12:18:50 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Apr 04, 2014 at 03:36:55PM +0200, Igor Mammedov wrote:
> > Following patches will add another ACPI0004 device
> > to the same scope, and that will make Windows BSOD
> > because it thinks that the second ACPI0004 device
> > is duplicate.
> > Adding to device unique _UID, fixes issue and allows
> > Windows to distinguish devices with the same _HID
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> Weren't we going to rename ACPI0004 to PNP0C02 or something?
> I remember it creates problems for older guests.
I've tested it wit XPsp3 and WS2003, and they are fine with it.

The reason why ACPI0004 didn't worked nice at the beginning
was that IO ranges that were exposed as _CRS in it were
conflicting with PCI0._CRS. With Q35 CPU hotplug patches
that was fixed and ACPI0004 works just fine.

PNP0C02 has a small drawback, which is that OSPM (Windows)
doesn't do _CRS verification (i.e. ignores it), so lets
keep it as the last resort/workaround to use if nothing else works.

> 
> > ---
> >  hw/i386/acpi-dsdt-cpu-hotplug.dsl | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/hw/i386/acpi-dsdt-cpu-hotplug.dsl b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> > index dee4843..81fb876 100644
> > --- a/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> > +++ b/hw/i386/acpi-dsdt-cpu-hotplug.dsl
> > @@ -94,6 +94,7 @@ Scope(\_SB) {
> >  
> >      Device(CPU_HOTPLUG_RESOURCE_DEVICE) {
> >          Name(_HID, "ACPI0004")
> > +        Name(_UID, "CPU hotplug resources")
> >  
> >          Name(_CRS, ResourceTemplate() {
> >              IO(Decode16, CPU_STATUS_BASE, CPU_STATUS_BASE, 0, CPU_STATUS_LEN)
> > -- 
> > 1.9.0

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

* Re: [Qemu-devel] [PATCH 31/35] pc: ACPI BIOS: implement memory hotplug interface
  2014-04-06  9:13   ` Michael S. Tsirkin
@ 2014-04-07  7:23     ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07  7:23 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Sun, 6 Apr 2014 12:13:36 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Apr 04, 2014 at 03:36:56PM +0200, Igor Mammedov wrote:
> > - provides static SSDT object for memory hotplug
> > - 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>
> > ---
> >  hw/i386/Makefile.objs |   3 +-
> >  hw/i386/acpi-build.c  |  37 ++++++++++++
> >  hw/i386/ssdt-mem.dsl  |  75 +++++++++++++++++++++++
> >  hw/i386/ssdt-misc.dsl | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++
> >  4 files changed, 277 insertions(+), 1 deletion(-)
> >  create mode 100644 hw/i386/ssdt-mem.dsl
> > 
> > diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
> > index 3df1612..fd04fc2 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 a5d3fbf..6649480 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"
> > @@ -664,6 +665,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
> >  
> > @@ -999,6 +1008,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->init_args.ram_slots;
> >      unsigned acpi_cpus = guest_info->apic_id_limit;
> >      int ssdt_start = table_data->len;
> >      uint8_t *ssdt_ptr;
> > @@ -1027,6 +1038,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 */
> > @@ -1080,6 +1094,29 @@ build_ssdt(GArray *table_data, GArray *linker,
> >              build_free_array(package);
> >          }
> >  
> > +        if (nr_mem) {
> > +            /*
> > +             * current device naming scheme dosen't support
> 
> doesn't
> 
> > +             * more that 256 memory devices
> > +             */
> > +            assert(nr_mem <= 256);
> > +            /* 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(MTFY, 2) {
> > +             *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ...
> > +             */
> > +            build_append_notify_method(sb_scope, "MTFY", "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..7f68750
> > --- /dev/null
> > +++ b/hw/i386/ssdt-mem.dsl
> > @@ -0,0 +1,75 @@
> > +/*
> > + * 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) }
> > + *         ...
> > + *     }
> > + */
> > +ACPI_EXTRACT_ALL_CODE ssdm_mem_aml
> > +
> > +DefinitionBlock ("ssdt-mem.aml", "SSDT", 0x02, "BXPC", "CSSDT", 0x1)
> > +{
> > +
> > +    External(\_SB.MHPD.MCRS, MethodObj)
> > +    External(\_SB.MHPD.MRST, MethodObj)
> > +    External(\_SB.MHPD.MOST, MethodObj)
> > +    External(\_SB.MHPD.MPXM, 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.MHPD.MCRS(_UID))
> > +            }
> > +
> > +            Method(_STA, 0) {
> > +                Return(\_SB.MHPD.MRST(_UID))
> > +            }
> > +
> > +            Method(_PXM, 0) {
> > +                Return(\_SB.MHPD.MPXM(_UID))
> > +            }
> > +
> > +            Method(_OST, 3) {
> > +                \_SB.MHPD.MOST(_UID, Arg0, Arg1, Arg2)
> > +            }
> > +        }
> > +    }
> > +}
> > diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
> > index a4484b8..d1caaed 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,166 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
> >              }
> >          }
> >      }
> > +
> > +    External(MTFY, MethodObj)
> > +    Scope(\_SB) {
> > +        Device(MHPD) {
> > +            Name(_HID, "ACPI0004")
> > +            Name(_UID, "Memory hotplug resources")
> > +
> > +            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
> > +            Name(MDNR, 0x12345678)
> 
> Let's define some macros and use descriptive names - is this one
> MEMORY_DIMM_NUMBER?
sure

> 
> Same for other ACPI names below.
> 
> > +
> > +            /* Memory hotplug IO registers */
> > +            OperationRegion(HPMR, 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(MDNR, Zero)) {
> > +                    Return(0x0)
> > +                }
> > +                /* present, functioning, decoding, not shown in UI */
> > +                Return(0xB)
> > +            }
> > +
> > +            Field(HPMR, DWordAcc, NoLock, Preserve) {
> > +                MRBL, 32, // DIMM start addr Low word, read only
> > +                MRBH, 32, // DIMM start addr Hi word, read only
> > +                MRLL, 32, // DIMM size Low word, read only
> > +                MRLH, 32, // DIMM size Hi word, read only
> > +                MPX, 32,  // DIMM node proximity, read only
> > +            }
> > +            Field(HPMR, ByteAcc, NoLock, Preserve) {
> > +                Offset(20),
> > +                MES,  1, // 1 if DIMM enabled used by _STA, read only
> > +                MINS, 1, // (read) 1 if DIMM has a insert event. (write) 1 after MTFY() to clear event
> > +            }
> > +
> > +            Mutex (MLCK, 0)
> > +            Field (HPMR, DWordAcc, NoLock, Preserve) {
> > +                MSEL, 32,  // DIMM selector, write only
> > +                MOEV, 32,  // _OST event code, write only
> > +                MOSC, 32,  // _OST status code, write only
> > +            }
> > +
> > +            Method(MESC, 0, Serialized) {
> 
> Why is this one serialized? Shouldn't be necessary since
> you use explicit locking, right?
Yep, it's not necessary, I'll drop it.

> 
> > +                If (LEqual(MDNR, Zero)) {
> > +                     Return(Zero)
> > +                }
> > +
> > +                Store(Zero, Local0) // Mem devs iterrator
> > +                Acquire(MLCK, 0xFFFF)
> > +                while (LLess(Local0, MDNR)) {
> > +                    Store(Local0, MSEL) // select Local0 DIMM
> > +                    If (LEqual(MINS, One)) { // Memory device needs check
> 
> This works because MINS is a 1 bit fields.
> OK but please use a name that reflects this fact.
Do you mean to replace it with macro name like this:
#define MEMORY_DIMM_HAS_INSERT_EVENT MINS
and use it throughout code?

> 
> > +                        MTFY(Local0, 1)
> > +                        Store(1, MINS)
> > +                    }
> > +                    // TODO: handle memory eject request
> > +                    Add(Local0, One, Local0) // goto next DIMM
> > +                }
> > +                Release(MLCK)
> > +                Return(One)
> > +            }
> > +
> > +            Method(MRST, 1) {
> > +                Store(Zero, Local0)
> > +
> > +                Acquire(MLCK, 0xFFFF)
> > +                Store(ToInteger(Arg0), MSEL) // select DIMM
> > +
> > +                If (LEqual(MES, One)) {
> > +                    Store(0xF, Local0)
> > +                }
> > +
> > +                Release(MLCK)
> > +                Return(Local0)
> > +            }
> > +
> > +            Method(MCRS, 1, Serialized) {
> > +                Acquire(MLCK, 0xFFFF)
> > +                Store(ToInteger(Arg0), MSEL) // 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(MRBH, MINH)
> > +                Store(MRBL, MINL)
> > +                Store(MRLH, LENH)
> > +                Store(MRLL, 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(MLCK)
> > +                    Return(MR32)
> > +                }
> > +
> > +                Release(MLCK)
> > +                Return(MR64)
> > +            }
> > +
> > +            Method(MPXM, 1) {
> > +                Acquire(MLCK, 0xFFFF)
> > +                Store(ToInteger(Arg0), MSEL) // select DIMM
> > +                Store(MPX, Local0)
> > +                Release(MLCK)
> > +                Return(Local0)
> > +            }
> > +
> > +            Method(MOST, 4) {
> > +                Acquire(MLCK, 0xFFFF)
> > +                Store(ToInteger(Arg0), MSEL) // select DIMM
> > +                Store(Arg1, MOEV)
> > +                Store(Arg2, MOSC)
> > +                Release(MLCK)
> > +            }
> > +        } // Device()
> > +    } // Scope()
> >  }
> > -- 
> > 1.9.0

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
  2014-04-04 16:57 ` Dr. David Alan Gilbert
@ 2014-04-07  7:32   ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07  7:32 UTC (permalink / raw)
  To: Dr. David Alan Gilbert; +Cc: qemu-devel

On Fri, 4 Apr 2014 17:57:28 +0100
"Dr. David Alan Gilbert" <dgilbert@redhat.com> wrote:

> * Igor Mammedov (imammedo@redhat.com) wrote:
> 
> <snip>
> 
> > This series allows to hotplug 'arbitrary' DIMM devices specifying size,
> > NUMA node mapping (guest side), slot and address where to map it, at runtime.
> 
> Some high level questions:
>   1) Is the intention that all guest RAM would be hot pluggable like this
>      (i.e. no memory would be allocated in the normal way)
Later, I plan to convert initial memory to DIMM devices as well, but only to not
hotpluggable ones so far for simplicity sake.

>   2) Does something stop it being invoked during a migration?
As far as I know, there is no checks to prevent any hotplug op during
migration. Considering how migration currently works, hotplug should be
disabled at migration time.

> 
> Dave
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device Igor Mammedov
  2014-04-04 14:02   ` Paolo Bonzini
  2014-04-07  3:07   ` Alexey Kardashevskiy
@ 2014-04-07 10:23   ` Michael S. Tsirkin
  2014-04-07 13:21     ` Igor Mammedov
  2014-04-07 14:32     ` Igor Mammedov
  2 siblings, 2 replies; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 10:23 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Fri, Apr 04, 2014 at 03:36:53PM +0200, Igor Mammedov wrote:
> 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>
> ---
>  hw/i386/pc.c | 13 +++++++++++++
>  1 file changed, 13 insertions(+)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 734c6ee..ee5cf88 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -60,6 +60,8 @@
>  #include "acpi-build.h"
>  #include "hw/mem/dimm.h"
>  #include "trace.h"
> +#include "hw/acpi/piix4.h"
> +#include "hw/i386/ich9.h"
>  
>  /* debug PC/ISA interrupts */
>  //#define DEBUG_IRQ
> @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
>  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
>                           DeviceState *dev, Error **errp)
>  {
> +    Object *acpi_dev;
> +    HotplugHandlerClass *hhc;
>      Error *local_err = NULL;
>      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
>      DimmDevice *dimm = DIMM(dev);
> @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
>      }
>      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
>  
> +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> +    if (!acpi_dev) {
> +        error_setg(&local_err,
> +                   "memory hotplug is not enabled: missing acpi device");
> +        return;
> +    }
> +
> +    hhc = HOTPLUG_HANDLER_GET_CLASS(acpi_dev);

How about simply looking for a hotplug handler type device instead?
We aren't likely to have many of these, are we?

>      memory_region_add_subregion(&pcms->hotplug_memory,
>                                  addr - pcms->hotplug_memory_base,
>                                  mr);
>      vmstate_register_ram(mr, dev);
> +    hhc->plug(HOTPLUG_HANDLER(acpi_dev), dev, &local_err);
>  
>  out:
>      error_propagate(errp, local_err);
> -- 
> 1.9.0

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic Igor Mammedov
@ 2014-04-07 11:32   ` Michael S. Tsirkin
  2014-04-07 12:00     ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 11:32 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> ... and report error if plugged in device is not supported.
> Later generic callbacks will be used by memory hotplug.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>


OK in that case, how about teaching all hotplug callbacks about this?

There are two ATM:
shpc_device_hotplug_cb
pcie_cap_slot_hotplug_cb

Teach them both to fail gracefully if they get
an object that is not a pci device.

Afterwards, simply iterate over all objects of type
TYPE_HOTPLUG_HANDLER
and look for one that will accept your object.


> ---
>  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
>  1 file 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.9.0

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 11:32   ` Michael S. Tsirkin
@ 2014-04-07 12:00     ` Igor Mammedov
  2014-04-07 12:07       ` Michael S. Tsirkin
  0 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07 12:00 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, 7 Apr 2014 14:32:41 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > ... and report error if plugged in device is not supported.
> > Later generic callbacks will be used by memory hotplug.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> 
> OK in that case, how about teaching all hotplug callbacks about this?
> 
> There are two ATM:
> shpc_device_hotplug_cb
> pcie_cap_slot_hotplug_cb
> 
> Teach them both to fail gracefully if they get
> an object that is not a pci device.
> 
> Afterwards, simply iterate over all objects of type
> TYPE_HOTPLUG_HANDLER
> and look for one that will accept your object.
Then you would never know if any hotplug handler has actually
handled event.

I think hotplug handler should return error if unsupported
device passed in rather than ignore it. It makes catching
wiring errors easier.
Dropping error so that we could not care which hotplug handler
should be notified, looks like a wrong direction and makes
system more fragile.

It shouldn't be up to consumer to determine that event should
be routed to it, but rather by external routing that knows
what and when should be notified.

> 
> 
> > ---
> >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> >  1 file 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.9.0

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 12:00     ` Igor Mammedov
@ 2014-04-07 12:07       ` Michael S. Tsirkin
  2014-04-07 13:12         ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 12:07 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, Apr 07, 2014 at 02:00:37PM +0200, Igor Mammedov wrote:
> On Mon, 7 Apr 2014 14:32:41 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > > ... and report error if plugged in device is not supported.
> > > Later generic callbacks will be used by memory hotplug.
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > 
> > 
> > OK in that case, how about teaching all hotplug callbacks about this?
> > 
> > There are two ATM:
> > shpc_device_hotplug_cb
> > pcie_cap_slot_hotplug_cb
> > 
> > Teach them both to fail gracefully if they get
> > an object that is not a pci device.
> > 
> > Afterwards, simply iterate over all objects of type
> > TYPE_HOTPLUG_HANDLER
> > and look for one that will accept your object.
> Then you would never know if any hotplug handler has actually
> handled event.

Why not? Check the error.
If no one accepts your object, return error to user.

> I think hotplug handler should return error if unsupported
> device passed in rather than ignore it. It makes catching
> wiring errors easier.

Absolutely.

> Dropping error so that we could not care which hotplug handler
> should be notified, looks like a wrong direction and makes
> system more fragile.

That's not what I was suggesting.

> It shouldn't be up to consumer to determine that event should
> be routed to it, but rather by external routing that knows
> what and when should be notified.

Yes. So

	for each hotplug handler (&err)
		handler->plug(device, &err)
		if (!err)
			break;


	if (err)
		hotplug failed - destroy device


> > 
> > 
> > > ---
> > >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> > >  1 file 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.9.0

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 12:07       ` Michael S. Tsirkin
@ 2014-04-07 13:12         ` Igor Mammedov
  2014-04-07 13:25           ` Michael S. Tsirkin
  0 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07 13:12 UTC (permalink / raw)
  To: Michael S. Tsirkin, afaerber
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini

On Mon, 7 Apr 2014 15:07:15 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Mon, Apr 07, 2014 at 02:00:37PM +0200, Igor Mammedov wrote:
> > On Mon, 7 Apr 2014 14:32:41 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > > > ... and report error if plugged in device is not supported.
> > > > Later generic callbacks will be used by memory hotplug.
> > > > 
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > 
> > > 
> > > OK in that case, how about teaching all hotplug callbacks about this?
> > > 
> > > There are two ATM:
> > > shpc_device_hotplug_cb
> > > pcie_cap_slot_hotplug_cb
> > > 
> > > Teach them both to fail gracefully if they get
> > > an object that is not a pci device.
> > > 
> > > Afterwards, simply iterate over all objects of type
> > > TYPE_HOTPLUG_HANDLER
> > > and look for one that will accept your object.
> > Then you would never know if any hotplug handler has actually
> > handled event.
> 
> Why not? Check the error.
> If no one accepts your object, return error to user.
> 
> > I think hotplug handler should return error if unsupported
> > device passed in rather than ignore it. It makes catching
> > wiring errors easier.
> 
> Absolutely.
> 
> > Dropping error so that we could not care which hotplug handler
> > should be notified, looks like a wrong direction and makes
> > system more fragile.
> 
> That's not what I was suggesting.
> 
> > It shouldn't be up to consumer to determine that event should
> > be routed to it, but rather by external routing that knows
> > what and when should be notified.
> 
> Yes. So
> 
> 	for each hotplug handler (&err)
> 		handler->plug(device, &err)
> 		if (!err)
> 			break;
here it would break on the first handler that doesn't support device
and tells so to caller.
And there isn't any routing here, it just blindly broadcast to every
handler, regardless whether it's right or not.

If broadcast should be ever done than it probably should be a part of
DEVICE class and part of
  [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
patch and be generic to all devices.

Andreas,
  since you care about QDEV
  do you have an opinion on ^^^ discussion?

> 
> 
> 	if (err)
> 		hotplug failed - destroy device
> 
> 
> > > 
> > > 
> > > > ---
> > > >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> > > >  1 file 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.9.0

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07 10:23   ` Michael S. Tsirkin
@ 2014-04-07 13:21     ` Igor Mammedov
  2014-04-07 14:32     ` Igor Mammedov
  1 sibling, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07 13:21 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, 7 Apr 2014 13:23:54 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Apr 04, 2014 at 03:36:53PM +0200, Igor Mammedov wrote:
> > 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>
> > ---
> >  hw/i386/pc.c | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 734c6ee..ee5cf88 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -60,6 +60,8 @@
> >  #include "acpi-build.h"
> >  #include "hw/mem/dimm.h"
> >  #include "trace.h"
> > +#include "hw/acpi/piix4.h"
> > +#include "hw/i386/ich9.h"
> >  
> >  /* debug PC/ISA interrupts */
> >  //#define DEBUG_IRQ
> > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> >                           DeviceState *dev, Error **errp)
> >  {
> > +    Object *acpi_dev;
> > +    HotplugHandlerClass *hhc;
> >      Error *local_err = NULL;
> >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> >      DimmDevice *dimm = DIMM(dev);
> > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> >      }
> >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> >  
> > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> > +    if (!acpi_dev) {
> > +        error_setg(&local_err,
> > +                   "memory hotplug is not enabled: missing acpi device");
> > +        return;
> > +    }
> > +
> > +    hhc = HOTPLUG_HANDLER_GET_CLASS(acpi_dev);
> 
> How about simply looking for a hotplug handler type device instead?
> We aren't likely to have many of these, are we?
There is at least 2 hotplug handlers that handle event for DIMM device,
this one in PCMachine and in acpi device.

Having explicit wiring where main handler forwards partially handled event
to another known in advance handler would be more simple and robust approach.
I think that's how real hardware works, i.e. when memory is hotplugged
it doesn't triggers signals to CPU or SHCP hotplug circuits.

Doing broadcast here would be overkill.

> 
> >      memory_region_add_subregion(&pcms->hotplug_memory,
> >                                  addr - pcms->hotplug_memory_base,
> >                                  mr);
> >      vmstate_register_ram(mr, dev);
> > +    hhc->plug(HOTPLUG_HANDLER(acpi_dev), dev, &local_err);
> >  
> >  out:
> >      error_propagate(errp, local_err);
> > -- 
> > 1.9.0

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 13:12         ` Igor Mammedov
@ 2014-04-07 13:25           ` Michael S. Tsirkin
  2014-04-07 14:22             ` Igor Mammedov
  2014-04-07 15:19             ` Michael S. Tsirkin
  0 siblings, 2 replies; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 13:25 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, Apr 07, 2014 at 03:12:11PM +0200, Igor Mammedov wrote:
> On Mon, 7 Apr 2014 15:07:15 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Mon, Apr 07, 2014 at 02:00:37PM +0200, Igor Mammedov wrote:
> > > On Mon, 7 Apr 2014 14:32:41 +0300
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > > > > ... and report error if plugged in device is not supported.
> > > > > Later generic callbacks will be used by memory hotplug.
> > > > > 
> > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > 
> > > > 
> > > > OK in that case, how about teaching all hotplug callbacks about this?
> > > > 
> > > > There are two ATM:
> > > > shpc_device_hotplug_cb
> > > > pcie_cap_slot_hotplug_cb
> > > > 
> > > > Teach them both to fail gracefully if they get
> > > > an object that is not a pci device.
> > > > 
> > > > Afterwards, simply iterate over all objects of type
> > > > TYPE_HOTPLUG_HANDLER
> > > > and look for one that will accept your object.
> > > Then you would never know if any hotplug handler has actually
> > > handled event.
> > 
> > Why not? Check the error.
> > If no one accepts your object, return error to user.
> > 
> > > I think hotplug handler should return error if unsupported
> > > device passed in rather than ignore it. It makes catching
> > > wiring errors easier.
> > 
> > Absolutely.
> > 
> > > Dropping error so that we could not care which hotplug handler
> > > should be notified, looks like a wrong direction and makes
> > > system more fragile.
> > 
> > That's not what I was suggesting.
> > 
> > > It shouldn't be up to consumer to determine that event should
> > > be routed to it, but rather by external routing that knows
> > > what and when should be notified.
> > 
> > Yes. So
> > 
> > 	for each hotplug handler (&err)
> > 		handler->plug(device, &err)
> > 		if (!err)
> > 			break;
> here it would break on the first handler that doesn't support device
> and tells so to caller.

This is pseudo-code, I really mean !err == no error reported.

> And there isn't any routing here, it just blindly broadcast to every
> handler, regardless whether it's right or not.

Yes - handlers verify what they can support.

> If broadcast should be ever done than it probably should be a part of
> DEVICE class and part of
>   [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
> patch and be generic to all devices.

Not sure what's suggested here.

> 
> Andreas,
>   since you care about QDEV
>   do you have an opinion on ^^^ discussion?
> 
> > 
> > 
> > 	if (err)
> > 		hotplug failed - destroy device
> > 
> > 
> > > > 
> > > > 
> > > > > ---
> > > > >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> > > > >  1 file 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.9.0

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07  3:07   ` Alexey Kardashevskiy
@ 2014-04-07 14:13     ` Eduardo Habkost
  2014-04-07 14:26       ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Eduardo Habkost @ 2014-04-07 14:13 UTC (permalink / raw)
  To: Alexey Kardashevskiy
  Cc: peter.maydell, mst, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, marcel.a,
	stefanha, pbonzini, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, Igor Mammedov, afaerber

On Mon, Apr 07, 2014 at 01:07:53PM +1000, Alexey Kardashevskiy wrote:
> On 04/05/2014 12:36 AM, Igor Mammedov wrote:
> > 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>
> > ---
> >  hw/i386/pc.c | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 734c6ee..ee5cf88 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -60,6 +60,8 @@
> >  #include "acpi-build.h"
> >  #include "hw/mem/dimm.h"
> >  #include "trace.h"
> > +#include "hw/acpi/piix4.h"
> > +#include "hw/i386/ich9.h"
> >  
> >  /* debug PC/ISA interrupts */
> >  //#define DEBUG_IRQ
> > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> >                           DeviceState *dev, Error **errp)
> >  {
> > +    Object *acpi_dev;
> > +    HotplugHandlerClass *hhc;
> >      Error *local_err = NULL;
> >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> >      DimmDevice *dimm = DIMM(dev);
> > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> >      }
> >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> >  
> > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> 
> 
> wow. just wow.

I had to read the C99 spec to find out if this was safe.  :-)

But I believe it is readable, I wouldn't mind keeping it that way.

-- 
Eduardo

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 13:25           ` Michael S. Tsirkin
@ 2014-04-07 14:22             ` Igor Mammedov
  2014-04-07 15:36               ` Michael S. Tsirkin
  2014-04-07 15:19             ` Michael S. Tsirkin
  1 sibling, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07 14:22 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, 7 Apr 2014 16:25:30 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Mon, Apr 07, 2014 at 03:12:11PM +0200, Igor Mammedov wrote:
> > On Mon, 7 Apr 2014 15:07:15 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Mon, Apr 07, 2014 at 02:00:37PM +0200, Igor Mammedov wrote:
> > > > On Mon, 7 Apr 2014 14:32:41 +0300
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > > > > > ... and report error if plugged in device is not supported.
> > > > > > Later generic callbacks will be used by memory hotplug.
> > > > > > 
> > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > 
> > > > > 
> > > > > OK in that case, how about teaching all hotplug callbacks about this?
> > > > > 
> > > > > There are two ATM:
> > > > > shpc_device_hotplug_cb
> > > > > pcie_cap_slot_hotplug_cb
> > > > > 
> > > > > Teach them both to fail gracefully if they get
> > > > > an object that is not a pci device.
> > > > > 
> > > > > Afterwards, simply iterate over all objects of type
> > > > > TYPE_HOTPLUG_HANDLER
> > > > > and look for one that will accept your object.
> > > > Then you would never know if any hotplug handler has actually
> > > > handled event.
> > > 
> > > Why not? Check the error.
> > > If no one accepts your object, return error to user.
> > > 
> > > > I think hotplug handler should return error if unsupported
> > > > device passed in rather than ignore it. It makes catching
> > > > wiring errors easier.
> > > 
> > > Absolutely.
> > > 
> > > > Dropping error so that we could not care which hotplug handler
> > > > should be notified, looks like a wrong direction and makes
> > > > system more fragile.
> > > 
> > > That's not what I was suggesting.
> > > 
> > > > It shouldn't be up to consumer to determine that event should
> > > > be routed to it, but rather by external routing that knows
> > > > what and when should be notified.
> > > 
> > > Yes. So
> > > 
> > > 	for each hotplug handler (&err)
> > > 		handler->plug(device, &err)
> > > 		if (!err)
> > > 			break;
> > here it would break on the first handler that doesn't support device
> > and tells so to caller.
> 
> This is pseudo-code, I really mean !err == no error reported.
 * what if all handlers returned error, err might not reflect the actual
   error returned from handler that cares about device?

 * What if there would be more handlers that could or should handle event
   for device?

 * What if only some of compatible handler should handle event

 * What if handler should conditionally handle event and only 
   caller knows about condition and have access to them?

 * What about ordering in which handlers should be called?

Broadcast would be useful if it were impossible to know in advance
which hotplug handler to use. Is there use case for this?

> 
> > And there isn't any routing here, it just blindly broadcast to every
> > handler, regardless whether it's right or not.
> 
> Yes - handlers verify what they can support.
Sure handlers could verify, there is no harm in extra checking, but
handlers should not decide what to handle. That's what I'm against from.
It should be upto caller to decide if handler is the right one and call it.
There shouldn't be a chance for random/wrong handler to be called.

> 
> > If broadcast should be ever done than it probably should be a part of
> > DEVICE class and part of
> >   [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
> > patch and be generic to all devices.
> 
> Not sure what's suggested here.
above looks like generic code that should be part of Device.realize()
and should replace 08/35 patch if it's deemed as acceptable.
I think implementing design like that requires much more though
if viable and out of scope of this series.

> 
> > 
> > Andreas,
> >   since you care about QDEV
> >   do you have an opinion on ^^^ discussion?
> > 
> > > 
> > > 
> > > 	if (err)
> > > 		hotplug failed - destroy device
> > > 
> > > 
> > > > > 
> > > > > 
> > > > > > ---
> > > > > >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> > > > > >  1 file 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.9.0
> 

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07 14:13     ` Eduardo Habkost
@ 2014-04-07 14:26       ` Igor Mammedov
  2014-04-07 15:21         ` Michael S. Tsirkin
  0 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07 14:26 UTC (permalink / raw)
  To: Eduardo Habkost
  Cc: peter.maydell, mst, Alexey Kardashevskiy, hutao, mjt, qemu-devel,
	lcapitulino, kraxel, akong, quintela, armbru, aliguori,
	jan.kiszka, lersek, marcel.a, stefanha, chegu_vinod, rth, kwolf,
	s.priebe, mreitz, vasilis.liaskovitis, pbonzini, afaerber

On Mon, 7 Apr 2014 11:13:01 -0300
Eduardo Habkost <ehabkost@redhat.com> wrote:

> On Mon, Apr 07, 2014 at 01:07:53PM +1000, Alexey Kardashevskiy wrote:
> > On 04/05/2014 12:36 AM, Igor Mammedov wrote:
> > > 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>
> > > ---
> > >  hw/i386/pc.c | 13 +++++++++++++
> > >  1 file changed, 13 insertions(+)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 734c6ee..ee5cf88 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -60,6 +60,8 @@
> > >  #include "acpi-build.h"
> > >  #include "hw/mem/dimm.h"
> > >  #include "trace.h"
> > > +#include "hw/acpi/piix4.h"
> > > +#include "hw/i386/ich9.h"
> > >  
> > >  /* debug PC/ISA interrupts */
> > >  //#define DEBUG_IRQ
> > > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> > >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > >                           DeviceState *dev, Error **errp)
> > >  {
> > > +    Object *acpi_dev;
> > > +    HotplugHandlerClass *hhc;
> > >      Error *local_err = NULL;
> > >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > >      DimmDevice *dimm = DIMM(dev);
> > > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > >      }
> > >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> > >  
> > > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ;
;
> > 
> > 
> > wow. just wow.
> 
> I had to read the C99 spec to find out if this was safe.  :-)
> 
> But I believe it is readable, I wouldn't mind keeping it that way.
> 
I'll change it to a less obscure form:

acpi_dev = piix4_pm_find();
if (!acpi_dev) {
    acpi_dev = ich9_lpc_find();
}

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07 10:23   ` Michael S. Tsirkin
  2014-04-07 13:21     ` Igor Mammedov
@ 2014-04-07 14:32     ` Igor Mammedov
  2014-04-07 15:14       ` Michael S. Tsirkin
  1 sibling, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-04-07 14:32 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, 7 Apr 2014 13:23:54 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Apr 04, 2014 at 03:36:53PM +0200, Igor Mammedov wrote:
> > 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>
> > ---
> >  hw/i386/pc.c | 13 +++++++++++++
> >  1 file changed, 13 insertions(+)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 734c6ee..ee5cf88 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -60,6 +60,8 @@
> >  #include "acpi-build.h"
> >  #include "hw/mem/dimm.h"
> >  #include "trace.h"
> > +#include "hw/acpi/piix4.h"
> > +#include "hw/i386/ich9.h"
> >  
> >  /* debug PC/ISA interrupts */
> >  //#define DEBUG_IRQ
> > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> >                           DeviceState *dev, Error **errp)
> >  {
> > +    Object *acpi_dev;
> > +    HotplugHandlerClass *hhc;
> >      Error *local_err = NULL;
> >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> >      DimmDevice *dimm = DIMM(dev);
> > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> >      }
> >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> >  
> > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> > +    if (!acpi_dev) {
> > +        error_setg(&local_err,
> > +                   "memory hotplug is not enabled: missing acpi device");
> > +        return;
> > +    }
> > +
> > +    hhc = HOTPLUG_HANDLER_GET_CLASS(acpi_dev);
> 
> How about simply looking for a hotplug handler type device instead?
> We aren't likely to have many of these, are we?

How about adding link<acpi_device>  to PCMachine when it's created
and use it instead of piix4_pm_find()/ich9_lpc_find() everywhere?
that would allow to remove above searches in QOM tree and simplify
code including acpi-build.c

> >      memory_region_add_subregion(&pcms->hotplug_memory,
> >                                  addr - pcms->hotplug_memory_base,
> >                                  mr);
> >      vmstate_register_ram(mr, dev);
> > +    hhc->plug(HOTPLUG_HANDLER(acpi_dev), dev, &local_err);
> >  
> >  out:
> >      error_propagate(errp, local_err);
> > -- 
> > 1.9.0

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07 14:32     ` Igor Mammedov
@ 2014-04-07 15:14       ` Michael S. Tsirkin
  2014-04-11  9:14         ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 15:14 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, Apr 07, 2014 at 04:32:16PM +0200, Igor Mammedov wrote:
> On Mon, 7 Apr 2014 13:23:54 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Fri, Apr 04, 2014 at 03:36:53PM +0200, Igor Mammedov wrote:
> > > 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>
> > > ---
> > >  hw/i386/pc.c | 13 +++++++++++++
> > >  1 file changed, 13 insertions(+)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 734c6ee..ee5cf88 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -60,6 +60,8 @@
> > >  #include "acpi-build.h"
> > >  #include "hw/mem/dimm.h"
> > >  #include "trace.h"
> > > +#include "hw/acpi/piix4.h"
> > > +#include "hw/i386/ich9.h"
> > >  
> > >  /* debug PC/ISA interrupts */
> > >  //#define DEBUG_IRQ
> > > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> > >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > >                           DeviceState *dev, Error **errp)
> > >  {
> > > +    Object *acpi_dev;
> > > +    HotplugHandlerClass *hhc;
> > >      Error *local_err = NULL;
> > >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > >      DimmDevice *dimm = DIMM(dev);
> > > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > >      }
> > >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> > >  
> > > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> > > +    if (!acpi_dev) {
> > > +        error_setg(&local_err,
> > > +                   "memory hotplug is not enabled: missing acpi device");
> > > +        return;
> > > +    }
> > > +
> > > +    hhc = HOTPLUG_HANDLER_GET_CLASS(acpi_dev);
> > 
> > How about simply looking for a hotplug handler type device instead?
> > We aren't likely to have many of these, are we?
> 
> How about adding link<acpi_device>  to PCMachine when it's created
> and use it instead of piix4_pm_find()/ich9_lpc_find() everywhere?
> that would allow to remove above searches in QOM tree and simplify
> code including acpi-build.c

So each acpi implementation registers a link at a pre-defined path?
I'm fine with this, need an ack from afaerber though.

> > >      memory_region_add_subregion(&pcms->hotplug_memory,
> > >                                  addr - pcms->hotplug_memory_base,
> > >                                  mr);
> > >      vmstate_register_ram(mr, dev);
> > > +    hhc->plug(HOTPLUG_HANDLER(acpi_dev), dev, &local_err);
> > >  
> > >  out:
> > >      error_propagate(errp, local_err);
> > > -- 
> > > 1.9.0

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 13:25           ` Michael S. Tsirkin
  2014-04-07 14:22             ` Igor Mammedov
@ 2014-04-07 15:19             ` Michael S. Tsirkin
  2014-04-12  1:40               ` Paolo Bonzini
  1 sibling, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 15:19 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, Apr 07, 2014 at 04:25:30PM +0300, Michael S. Tsirkin wrote:
> On Mon, Apr 07, 2014 at 03:12:11PM +0200, Igor Mammedov wrote:
> > On Mon, 7 Apr 2014 15:07:15 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Mon, Apr 07, 2014 at 02:00:37PM +0200, Igor Mammedov wrote:
> > > > On Mon, 7 Apr 2014 14:32:41 +0300
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > > > > > ... and report error if plugged in device is not supported.
> > > > > > Later generic callbacks will be used by memory hotplug.
> > > > > > 
> > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > 
> > > > > 
> > > > > OK in that case, how about teaching all hotplug callbacks about this?
> > > > > 
> > > > > There are two ATM:
> > > > > shpc_device_hotplug_cb
> > > > > pcie_cap_slot_hotplug_cb
> > > > > 
> > > > > Teach them both to fail gracefully if they get
> > > > > an object that is not a pci device.
> > > > > 
> > > > > Afterwards, simply iterate over all objects of type
> > > > > TYPE_HOTPLUG_HANDLER
> > > > > and look for one that will accept your object.
> > > > Then you would never know if any hotplug handler has actually
> > > > handled event.
> > > 
> > > Why not? Check the error.
> > > If no one accepts your object, return error to user.
> > > 
> > > > I think hotplug handler should return error if unsupported
> > > > device passed in rather than ignore it. It makes catching
> > > > wiring errors easier.
> > > 
> > > Absolutely.
> > > 
> > > > Dropping error so that we could not care which hotplug handler
> > > > should be notified, looks like a wrong direction and makes
> > > > system more fragile.
> > > 
> > > That's not what I was suggesting.
> > > 
> > > > It shouldn't be up to consumer to determine that event should
> > > > be routed to it, but rather by external routing that knows
> > > > what and when should be notified.
> > > 
> > > Yes. So
> > > 
> > > 	for each hotplug handler (&err)
> > > 		handler->plug(device, &err)
> > > 		if (!err)
> > > 			break;
> > here it would break on the first handler that doesn't support device
> > and tells so to caller.
> 
> This is pseudo-code, I really mean !err == no error reported.
> 
> > And there isn't any routing here, it just blindly broadcast to every
> > handler, regardless whether it's right or not.
> 
> Yes - handlers verify what they can support.
> 
> > If broadcast should be ever done than it probably should be a part of
> > DEVICE class and part of
> >   [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
> > patch and be generic to all devices.
> 
> Not sure what's suggested here.
> 
> > 
> > Andreas,
> >   since you care about QDEV
> >   do you have an opinion on ^^^ discussion?


Actually, there's one useful case that this would help address.
At the moment ACPI code has to poke at SHPC bridges and
modify their hotplug callbacks in order to get notified
of hotplug events.

This means we can't cleanly implement an option for guest to
disable ACPI and switch to native if supported,
like the ACPI spec allows.

If we change hotplug code to walk the tree top down
and invoke all callbacks, then it will be fixed
in a cleaner way: bridges would just do:

	if (dev->bus != self) {
		set_error
		return;
	}

and suddently pci host can trap callbacks and redirect
to acpi if it wants to.


> > > 
> > > 
> > > 	if (err)
> > > 		hotplug failed - destroy device
> > > 
> > > 
> > > > > 
> > > > > 
> > > > > > ---
> > > > > >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> > > > > >  1 file 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.9.0

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07 14:26       ` Igor Mammedov
@ 2014-04-07 15:21         ` Michael S. Tsirkin
  2014-04-11  9:13           ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 15:21 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, Alexey Kardashevskiy, hutao, mjt, qemu-devel,
	lcapitulino, kraxel, akong, quintela, armbru, aliguori,
	jan.kiszka, lersek, Eduardo Habkost, marcel.a, stefanha,
	chegu_vinod, rth, kwolf, s.priebe, mreitz, vasilis.liaskovitis,
	pbonzini, afaerber

On Mon, Apr 07, 2014 at 04:26:02PM +0200, Igor Mammedov wrote:
> On Mon, 7 Apr 2014 11:13:01 -0300
> Eduardo Habkost <ehabkost@redhat.com> wrote:
> 
> > On Mon, Apr 07, 2014 at 01:07:53PM +1000, Alexey Kardashevskiy wrote:
> > > On 04/05/2014 12:36 AM, Igor Mammedov wrote:
> > > > 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>
> > > > ---
> > > >  hw/i386/pc.c | 13 +++++++++++++
> > > >  1 file changed, 13 insertions(+)
> > > > 
> > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > > index 734c6ee..ee5cf88 100644
> > > > --- a/hw/i386/pc.c
> > > > +++ b/hw/i386/pc.c
> > > > @@ -60,6 +60,8 @@
> > > >  #include "acpi-build.h"
> > > >  #include "hw/mem/dimm.h"
> > > >  #include "trace.h"
> > > > +#include "hw/acpi/piix4.h"
> > > > +#include "hw/i386/ich9.h"
> > > >  
> > > >  /* debug PC/ISA interrupts */
> > > >  //#define DEBUG_IRQ
> > > > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> > > >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > > >                           DeviceState *dev, Error **errp)
> > > >  {
> > > > +    Object *acpi_dev;
> > > > +    HotplugHandlerClass *hhc;
> > > >      Error *local_err = NULL;
> > > >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > > >      DimmDevice *dimm = DIMM(dev);
> > > > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > > >      }
> > > >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> > > >  
> > > > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ;
> ;
> > > 
> > > 
> > > wow. just wow.
> > 
> > I had to read the C99 spec to find out if this was safe.  :-)
> > 
> > But I believe it is readable, I wouldn't mind keeping it that way.
> > 
> I'll change it to a less obscure form:
> 
> acpi_dev = piix4_pm_find();
> if (!acpi_dev) {
>     acpi_dev = ich9_lpc_find();
> }


or

    Object *piix = piix4_pm_find();
    Object *lpc = ich9_lpc_find();
    assert(!!piix != !!lpc);


so we verify it's one of the other.

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 14:22             ` Igor Mammedov
@ 2014-04-07 15:36               ` Michael S. Tsirkin
  2014-04-11  9:41                 ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Michael S. Tsirkin @ 2014-04-07 15:36 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, Apr 07, 2014 at 04:22:06PM +0200, Igor Mammedov wrote:
> On Mon, 7 Apr 2014 16:25:30 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Mon, Apr 07, 2014 at 03:12:11PM +0200, Igor Mammedov wrote:
> > > On Mon, 7 Apr 2014 15:07:15 +0300
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Mon, Apr 07, 2014 at 02:00:37PM +0200, Igor Mammedov wrote:
> > > > > On Mon, 7 Apr 2014 14:32:41 +0300
> > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > 
> > > > > > On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > > > > > > ... and report error if plugged in device is not supported.
> > > > > > > Later generic callbacks will be used by memory hotplug.
> > > > > > > 
> > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > > 
> > > > > > 
> > > > > > OK in that case, how about teaching all hotplug callbacks about this?
> > > > > > 
> > > > > > There are two ATM:
> > > > > > shpc_device_hotplug_cb
> > > > > > pcie_cap_slot_hotplug_cb
> > > > > > 
> > > > > > Teach them both to fail gracefully if they get
> > > > > > an object that is not a pci device.
> > > > > > 
> > > > > > Afterwards, simply iterate over all objects of type
> > > > > > TYPE_HOTPLUG_HANDLER
> > > > > > and look for one that will accept your object.
> > > > > Then you would never know if any hotplug handler has actually
> > > > > handled event.
> > > > 
> > > > Why not? Check the error.
> > > > If no one accepts your object, return error to user.
> > > > 
> > > > > I think hotplug handler should return error if unsupported
> > > > > device passed in rather than ignore it. It makes catching
> > > > > wiring errors easier.
> > > > 
> > > > Absolutely.
> > > > 
> > > > > Dropping error so that we could not care which hotplug handler
> > > > > should be notified, looks like a wrong direction and makes
> > > > > system more fragile.
> > > > 
> > > > That's not what I was suggesting.
> > > > 
> > > > > It shouldn't be up to consumer to determine that event should
> > > > > be routed to it, but rather by external routing that knows
> > > > > what and when should be notified.
> > > > 
> > > > Yes. So
> > > > 
> > > > 	for each hotplug handler (&err)
> > > > 		handler->plug(device, &err)
> > > > 		if (!err)
> > > > 			break;
> > > here it would break on the first handler that doesn't support device
> > > and tells so to caller.
> > 
> > This is pseudo-code, I really mean !err == no error reported.
>  * what if all handlers returned error, err might not reflect the actual
>    error returned from handler that cares about device?

We can use a special error code to mean "hotplug not supported".

>  * What if there would be more handlers that could or should handle event
>    for device?

That's actually very useful. We could scan top to bottom
so e.g. acpi can intercept bridges.

>  * What if only some of compatible handler should handle event

Each one can check whether it's applicable.

>  * What if handler should conditionally handle event and only 
>    caller knows about condition and have access to them?

Doesn't sound possible.

>  * What about ordering in which handlers should be called?
> 
> Broadcast would be useful if it were impossible to know in advance
> which hotplug handler to use. Is there use case for this?

ACPI vs SHPC would be an example. For that one, we need to order
them top to bottom.

> > 
> > > And there isn't any routing here, it just blindly broadcast to every
> > > handler, regardless whether it's right or not.
> > 
> > Yes - handlers verify what they can support.
> Sure handlers could verify, there is no harm in extra checking, but
> handlers should not decide what to handle. That's what I'm against from.
> It should be upto caller to decide if handler is the right one and call it.
> There shouldn't be a chance for random/wrong handler to be called.
> 
> > 
> > > If broadcast should be ever done than it probably should be a part of
> > > DEVICE class and part of
> > >   [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
> > > patch and be generic to all devices.
> > 
> > Not sure what's suggested here.
> above looks like generic code that should be part of Device.realize()
> and should replace 08/35 patch if it's deemed as acceptable.
> I think implementing design like that requires much more though
> if viable and out of scope of this series.
> 
> > 
> > > 
> > > Andreas,
> > >   since you care about QDEV
> > >   do you have an opinion on ^^^ discussion?
> > > 
> > > > 
> > > > 
> > > > 	if (err)
> > > > 		hotplug failed - destroy device
> > > > 
> > > > 
> > > > > > 
> > > > > > 
> > > > > > > ---
> > > > > > >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> > > > > > >  1 file 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.9.0
> > 

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07 15:21         ` Michael S. Tsirkin
@ 2014-04-11  9:13           ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-11  9:13 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, Alexey Kardashevskiy, hutao, mjt, qemu-devel,
	lcapitulino, kraxel, akong, quintela, armbru, aliguori,
	jan.kiszka, lersek, Eduardo Habkost, marcel.a, stefanha,
	chegu_vinod, rth, kwolf, s.priebe, mreitz, vasilis.liaskovitis,
	pbonzini, afaerber

On Mon, 7 Apr 2014 18:21:14 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Mon, Apr 07, 2014 at 04:26:02PM +0200, Igor Mammedov wrote:
> > On Mon, 7 Apr 2014 11:13:01 -0300
> > Eduardo Habkost <ehabkost@redhat.com> wrote:
> > 
> > > On Mon, Apr 07, 2014 at 01:07:53PM +1000, Alexey Kardashevskiy wrote:
> > > > On 04/05/2014 12:36 AM, Igor Mammedov wrote:
> > > > > 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>
> > > > > ---
> > > > >  hw/i386/pc.c | 13 +++++++++++++
> > > > >  1 file changed, 13 insertions(+)
> > > > > 
> > > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > > > index 734c6ee..ee5cf88 100644
> > > > > --- a/hw/i386/pc.c
> > > > > +++ b/hw/i386/pc.c
> > > > > @@ -60,6 +60,8 @@
> > > > >  #include "acpi-build.h"
> > > > >  #include "hw/mem/dimm.h"
> > > > >  #include "trace.h"
> > > > > +#include "hw/acpi/piix4.h"
> > > > > +#include "hw/i386/ich9.h"
> > > > >  
> > > > >  /* debug PC/ISA interrupts */
> > > > >  //#define DEBUG_IRQ
> > > > > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> > > > >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > > > >                           DeviceState *dev, Error **errp)
> > > > >  {
> > > > > +    Object *acpi_dev;
> > > > > +    HotplugHandlerClass *hhc;
> > > > >      Error *local_err = NULL;
> > > > >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > > > >      DimmDevice *dimm = DIMM(dev);
> > > > > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > > > >      }
> > > > >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> > > > >  
> > > > > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ;
> > ;
> > > > 
> > > > 
> > > > wow. just wow.
> > > 
> > > I had to read the C99 spec to find out if this was safe.  :-)
> > > 
> > > But I believe it is readable, I wouldn't mind keeping it that way.
> > > 
> > I'll change it to a less obscure form:
> > 
> > acpi_dev = piix4_pm_find();
> > if (!acpi_dev) {
> >     acpi_dev = ich9_lpc_find();
> > }
> 
> 
> or
> 
>     Object *piix = piix4_pm_find();
>     Object *lpc = ich9_lpc_find();
>     assert(!!piix != !!lpc);
wouldn't that assert on device_add if qemu was started without ACPI?
Exiting with error if acpi_dev == NULL seems safer here.

> 
> 
> so we verify it's one of the other.
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device
  2014-04-07 15:14       ` Michael S. Tsirkin
@ 2014-04-11  9:14         ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-11  9:14 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, 7 Apr 2014 18:14:51 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Mon, Apr 07, 2014 at 04:32:16PM +0200, Igor Mammedov wrote:
> > On Mon, 7 Apr 2014 13:23:54 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Fri, Apr 04, 2014 at 03:36:53PM +0200, Igor Mammedov wrote:
> > > > 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>
> > > > ---
> > > >  hw/i386/pc.c | 13 +++++++++++++
> > > >  1 file changed, 13 insertions(+)
> > > > 
> > > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > > index 734c6ee..ee5cf88 100644
> > > > --- a/hw/i386/pc.c
> > > > +++ b/hw/i386/pc.c
> > > > @@ -60,6 +60,8 @@
> > > >  #include "acpi-build.h"
> > > >  #include "hw/mem/dimm.h"
> > > >  #include "trace.h"
> > > > +#include "hw/acpi/piix4.h"
> > > > +#include "hw/i386/ich9.h"
> > > >  
> > > >  /* debug PC/ISA interrupts */
> > > >  //#define DEBUG_IRQ
> > > > @@ -1484,6 +1486,8 @@ void qemu_register_pc_machine(QEMUMachine *m)
> > > >  static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > > >                           DeviceState *dev, Error **errp)
> > > >  {
> > > > +    Object *acpi_dev;
> > > > +    HotplugHandlerClass *hhc;
> > > >      Error *local_err = NULL;
> > > >      PCMachineState *pcms = PC_MACHINE(hotplug_dev);
> > > >      DimmDevice *dimm = DIMM(dev);
> > > > @@ -1517,10 +1521,19 @@ static void pc_dimm_plug(HotplugHandler *hotplug_dev,
> > > >      }
> > > >      trace_mhp_pc_dimm_assigned_slot(dimm->slot);
> > > >  
> > > > +    acpi_dev = (acpi_dev = piix4_pm_find()) ? acpi_dev : ich9_lpc_find();
> > > > +    if (!acpi_dev) {
> > > > +        error_setg(&local_err,
> > > > +                   "memory hotplug is not enabled: missing acpi device");
> > > > +        return;
> > > > +    }
> > > > +
> > > > +    hhc = HOTPLUG_HANDLER_GET_CLASS(acpi_dev);
> > > 
> > > How about simply looking for a hotplug handler type device instead?
> > > We aren't likely to have many of these, are we?
> > 
> > How about adding link<acpi_device>  to PCMachine when it's created
> > and use it instead of piix4_pm_find()/ich9_lpc_find() everywhere?
> > that would allow to remove above searches in QOM tree and simplify
> > code including acpi-build.c
> 
> So each acpi implementation registers a link at a pre-defined path?
> I'm fine with this, need an ack from afaerber though.
It could be a just plain pointer since it points to system device which
won't disappear suddenly (i.e. it's not hot-unplugable).

> 
> > > >      memory_region_add_subregion(&pcms->hotplug_memory,
> > > >                                  addr - pcms->hotplug_memory_base,
> > > >                                  mr);
> > > >      vmstate_register_ram(mr, dev);
> > > > +    hhc->plug(HOTPLUG_HANDLER(acpi_dev), dev, &local_err);
> > > >  
> > > >  out:
> > > >      error_propagate(errp, local_err);
> > > > -- 
> > > > 1.9.0
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 15:36               ` Michael S. Tsirkin
@ 2014-04-11  9:41                 ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-04-11  9:41 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

On Mon, 7 Apr 2014 18:36:34 +0300
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Mon, Apr 07, 2014 at 04:22:06PM +0200, Igor Mammedov wrote:
> > On Mon, 7 Apr 2014 16:25:30 +0300
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Mon, Apr 07, 2014 at 03:12:11PM +0200, Igor Mammedov wrote:
> > > > On Mon, 7 Apr 2014 15:07:15 +0300
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Mon, Apr 07, 2014 at 02:00:37PM +0200, Igor Mammedov wrote:
> > > > > > On Mon, 7 Apr 2014 14:32:41 +0300
> > > > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > > > 
> > > > > > > On Fri, Apr 04, 2014 at 03:36:48PM +0200, Igor Mammedov wrote:
> > > > > > > > ... and report error if plugged in device is not supported.
> > > > > > > > Later generic callbacks will be used by memory hotplug.
> > > > > > > > 
> > > > > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > > > > 
> > > > > > > 
> > > > > > > OK in that case, how about teaching all hotplug callbacks about this?
> > > > > > > 
> > > > > > > There are two ATM:
> > > > > > > shpc_device_hotplug_cb
> > > > > > > pcie_cap_slot_hotplug_cb
> > > > > > > 
> > > > > > > Teach them both to fail gracefully if they get
> > > > > > > an object that is not a pci device.
> > > > > > > 
> > > > > > > Afterwards, simply iterate over all objects of type
> > > > > > > TYPE_HOTPLUG_HANDLER
> > > > > > > and look for one that will accept your object.
> > > > > > Then you would never know if any hotplug handler has actually
> > > > > > handled event.
> > > > > 
> > > > > Why not? Check the error.
> > > > > If no one accepts your object, return error to user.
> > > > > 
> > > > > > I think hotplug handler should return error if unsupported
> > > > > > device passed in rather than ignore it. It makes catching
> > > > > > wiring errors easier.
> > > > > 
> > > > > Absolutely.
> > > > > 
> > > > > > Dropping error so that we could not care which hotplug handler
> > > > > > should be notified, looks like a wrong direction and makes
> > > > > > system more fragile.
> > > > > 
> > > > > That's not what I was suggesting.
> > > > > 
> > > > > > It shouldn't be up to consumer to determine that event should
> > > > > > be routed to it, but rather by external routing that knows
> > > > > > what and when should be notified.
> > > > > 
> > > > > Yes. So
> > > > > 
> > > > > 	for each hotplug handler (&err)
> > > > > 		handler->plug(device, &err)
> > > > > 		if (!err)
> > > > > 			break;
> > > > here it would break on the first handler that doesn't support device
> > > > and tells so to caller.
> > > 
> > > This is pseudo-code, I really mean !err == no error reported.
> >  * what if all handlers returned error, err might not reflect the actual
> >    error returned from handler that cares about device?
> 
> We can use a special error code to mean "hotplug not supported".
That would start special casing some error codes.
With explicit "routing table" it won't be necessary.

> 
> >  * What if there would be more handlers that could or should handle event
> >    for device?
> 
> That's actually very useful. We could scan top to bottom
> so e.g. acpi can intercept bridges.
That would imply specific ordering in event propagation, which in case of
broadcast is not guarantied. And without explicit "routing table" it
could easily break if propagation order changes.
 
> 
> >  * What if only some of compatible handler should handle event
> 
> Each one can check whether it's applicable.
handler might need to access some device internals to do so, it means
that it might to pull in target dependent headers in its implementation.

> 
> >  * What if handler should conditionally handle event and only 
> >    caller knows about condition and have access to them?
> 
> Doesn't sound possible.
If it's not handler who decides whether to handle/receive event or not, it's
quite possible.

> 
> >  * What about ordering in which handlers should be called?
> > 
> > Broadcast would be useful if it were impossible to know in advance
> > which hotplug handler to use. Is there use case for this?
> 
> ACPI vs SHPC would be an example. For that one, we need to order
> them top to bottom.

To sum-up above said, I'm not convinced that implementing generic hotplug
event broadcast is what is needed. You are trying to fix with it a very
specific use-case, which might not need it at all.

Instead of broadcast, if there is a need the hardcoded event routing should
be replaced with data driven approach (like VMSD) with explicit routing
tables which describes where and when to forward hotplug event. That would
make sure that event won't be mis-routed accidentally and no need to
special case routing decisions on error code.

> 
> > > 
> > > > And there isn't any routing here, it just blindly broadcast to every
> > > > handler, regardless whether it's right or not.
> > > 
> > > Yes - handlers verify what they can support.
> > Sure handlers could verify, there is no harm in extra checking, but
> > handlers should not decide what to handle. That's what I'm against from.
> > It should be upto caller to decide if handler is the right one and call it.
> > There shouldn't be a chance for random/wrong handler to be called.
> > 
> > > 
> > > > If broadcast should be ever done than it probably should be a part of
> > > > DEVICE class and part of
> > > >   [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices
> > > > patch and be generic to all devices.
> > > 
> > > Not sure what's suggested here.
> > above looks like generic code that should be part of Device.realize()
> > and should replace 08/35 patch if it's deemed as acceptable.
> > I think implementing design like that requires much more though
> > if viable and out of scope of this series.
> > 
> > > 
> > > > 
> > > > Andreas,
> > > >   since you care about QDEV
> > > >   do you have an opinion on ^^^ discussion?
> > > > 
> > > > > 
> > > > > 
> > > > > 	if (err)
> > > > > 		hotplug failed - destroy device
> > > > > 
> > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > > ---
> > > > > > > >  hw/acpi/piix4.c | 31 ++++++++++++++++++++++---------
> > > > > > > >  1 file 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.9.0
> > > 
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic
  2014-04-07 15:19             ` Michael S. Tsirkin
@ 2014-04-12  1:40               ` Paolo Bonzini
  0 siblings, 0 replies; 93+ messages in thread
From: Paolo Bonzini @ 2014-04-12  1:40 UTC (permalink / raw)
  To: Michael S. Tsirkin, Igor Mammedov
  Cc: peter.maydell, aik, hutao, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, afaerber

Il 07/04/2014 11:19, Michael S. Tsirkin ha scritto:
> This means we can't cleanly implement an option for guest to
> disable ACPI and switch to native if supported,
> like the ACPI spec allows.
>
> If we change hotplug code to walk the tree top down
> and invoke all callbacks, then it will be fixed
> in a cleaner way: bridges would just do:
>
> 	if (dev->bus != self) {
> 		set_error
> 		return;
> 	}
>
> and suddently pci host can trap callbacks and redirect
> to acpi if it wants to.

I think this should be handled by making the q35 PCI host bridge 
implement HotplugHandler itself, possibly overriding the parent's 
implementation.

Paolo

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

* Re: [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
@ 2014-05-05 12:20   ` Vasilis Liaskovitis
  2014-05-06  7:13     ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Vasilis Liaskovitis @ 2014-05-05 12:20 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, pbonzini, afaerber

Hi,

On Fri, Apr 04, 2014 at 03:36:45PM +0200, Igor Mammedov wrote:
> - implements QEMU hardware part of memory hotplug protocol
>   described at "docs/specs/acpi_mem_hotplug.txt"
> - handles only memory add notification event for now
>
[...]
> +      [0x4-0x7] OST event code reported by OSPM
> +      [0x8-0xb] OST status code reported by OSPM
> +    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 */
> +        }

Are there any patches planned to report _OST notifications to upper management
layers? E.g. some older patchseries implemented a queue for these notifications
that could be queried with an "info memhp" command.

As a more general question for the patchseries: How do we query status/presence
of dimms present? Some posssible options could be:

- info qtree: If links<> are implemented between dimms and an acpi machine
adapter, would the dimms show up in the general device tree? Currently I believe
they don't.

- info dimm: We could have a new "info dimm" command that shows information for
present DIMMs: start-end guest physical address, last _OST notification received
for this DIMM, as well as backing memdev object for this dimm.

(qemu) info dimm
dimm0: range="start_address - end_address" memdev="obj0" _OST="last_OST message"
dimm1: range="start_address - end_address" memdev="obj1" _OST="last_OST message"

where last_OST message could be "hot-add succesfull", "hot-add failed",
"hot-remove failed". Not sure how "hot-remove successful" would be reported
though, as the dimm device would be removed (or soon to be removed) from the
machine. Unless we have a separate command for OST messages received/queued, as
mentioned above.

If the guest does not support _OST, the OST entries would remain empty,
at least giving management layer a hint that the guest may not have succesfully
completed the requested hot-operation.

The examples are all in hmp, but there should obviously be qmp support.
Thoughts?

thanks,

- Vasilis

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

* Re: [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
       [not found]     ` <20140414184442.6ff3e626@nial.usersys.redhat.com>
@ 2014-05-05 15:59       ` Vasilis Liaskovitis
  2014-05-06  1:52         ` Hu Tao
  0 siblings, 1 reply; 93+ messages in thread
From: Vasilis Liaskovitis @ 2014-05-05 15:59 UTC (permalink / raw)
  To: Igor Mammedov, Hu Tao
  Cc: peter.maydell, mst, aik, mjt, qemu-devel, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	pbonzini, afaerber

Hi,

On Mon, Apr 14, 2014 at 06:44:42PM +0200, Igor Mammedov wrote:
> On Mon, 14 Apr 2014 15:25:01 +0800
> Hu Tao <hutao@cn.fujitsu.com> wrote:
> 
> > On Fri, Apr 04, 2014 at 03:36:58PM +0200, Igor Mammedov wrote:
> Could you be more specific, what and how doesn't work and why there is
> need for SRAT entries per DIMM?
> I've briefly tested with your unplug patches and linux seemed be ok with unplug,
> i.e. device node was removed from /sys after receiving remove notification.

Just a heads-up, is this the unplug patch that you are using for testing:
https://github.com/taohu/qemu/commit/55c9540919e189b0ad2e6a759af742080f8f5dc4

or is there a newer version based on Igor's patchseries?

thanks,

- Vasilis

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

* Re: [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
@ 2014-05-05 16:25   ` Eric Blake
  2014-05-05 16:28     ` Paolo Bonzini
  2014-05-06  7:16     ` Igor Mammedov
  0 siblings, 2 replies; 93+ messages in thread
From: Eric Blake @ 2014-05-05 16:25 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, aik, jan.kiszka, mjt, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, hutao, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

[-- Attachment #1: Type: text/plain, Size: 722 bytes --]

On 04/04/2014 07:36 AM, Igor Mammedov wrote:
> also make handler edge based to avoid loosing events, the same as

s/loosing/losing/

(loose rhymes with goose and means the opposite of "tight"; lose rhymes
with use and means the opposite of "gain" - it is a very frequent typo
to see people put too many 'o's when they meant a variant of "lose")

> it has been done for PCI and CPU hotplug handlers.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  hw/i386/acpi-dsdt.dsl     | 5 ++++-
>  hw/i386/q35-acpi-dsdt.dsl | 5 ++++-
>  2 files changed, 8 insertions(+), 2 deletions(-)
> 

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

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

* Re: [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines
  2014-05-05 16:25   ` Eric Blake
@ 2014-05-05 16:28     ` Paolo Bonzini
  2014-05-06 10:05       ` Laszlo Ersek
  2014-05-06  7:16     ` Igor Mammedov
  1 sibling, 1 reply; 93+ messages in thread
From: Paolo Bonzini @ 2014-05-05 16:28 UTC (permalink / raw)
  To: Eric Blake, Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, aik, jan.kiszka, mjt, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, hutao, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, afaerber

Il 05/05/2014 18:25, Eric Blake ha scritto:
>> > also make handler edge based to avoid loosing events, the same as
> s/loosing/losing/
>
> (loose rhymes with goose and means the opposite of "tight"; lose rhymes
> with use and means the opposite of "gain" - it is a very frequent typo
> to see people put too many 'o's when they meant a variant of "lose")

Unfortunately rhymes are useless to non-native speakers. :)  A good way 
to remember it is to think of 'loosen' and 'lost' rather than 'loose' 
and 'lose', which are pronounced differently and hence easier to 
associate with the right number of 'o's.

Paolo

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

* Re: [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-05 15:59       ` Vasilis Liaskovitis
@ 2014-05-06  1:52         ` Hu Tao
  2014-05-06 13:00           ` Vasilis Liaskovitis
  0 siblings, 1 reply; 93+ messages in thread
From: Hu Tao @ 2014-05-06  1:52 UTC (permalink / raw)
  To: Vasilis Liaskovitis
  Cc: peter.maydell, mst, aik, jan.kiszka, mjt, qemu-devel,
	lcapitulino, kraxel, akong, quintela, armbru, aliguori, lersek,
	ehabkost, marcel.a, stefanha, pbonzini, chegu_vinod, rth, kwolf,
	s.priebe, mreitz, Igor Mammedov, afaerber

On Mon, May 05, 2014 at 05:59:15PM +0200, Vasilis Liaskovitis wrote:
> Hi,
> 
> On Mon, Apr 14, 2014 at 06:44:42PM +0200, Igor Mammedov wrote:
> > On Mon, 14 Apr 2014 15:25:01 +0800
> > Hu Tao <hutao@cn.fujitsu.com> wrote:
> > 
> > > On Fri, Apr 04, 2014 at 03:36:58PM +0200, Igor Mammedov wrote:
> > Could you be more specific, what and how doesn't work and why there is
> > need for SRAT entries per DIMM?
> > I've briefly tested with your unplug patches and linux seemed be ok with unplug,
> > i.e. device node was removed from /sys after receiving remove notification.
> 
> Just a heads-up, is this the unplug patch that you are using for testing:
> https://github.com/taohu/qemu/commit/55c9540919e189b0ad2e6a759af742080f8f5dc4
> 
> or is there a newer version based on Igor's patchseries?

Yeah. There is a new version. I pushed it up to
https://github.com/taohu/qemu/commits/memhp for you to check out.

Regards,
Hu Tao

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

* Re: [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation
  2014-05-05 12:20   ` Vasilis Liaskovitis
@ 2014-05-06  7:13     ` Igor Mammedov
  2014-05-06 12:58       ` Vasilis Liaskovitis
  0 siblings, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-05-06  7:13 UTC (permalink / raw)
  To: Vasilis Liaskovitis
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, pbonzini, afaerber

On Mon, 5 May 2014 14:20:25 +0200
Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:

> Hi,
> 
> On Fri, Apr 04, 2014 at 03:36:45PM +0200, Igor Mammedov wrote:
> > - implements QEMU hardware part of memory hotplug protocol
> >   described at "docs/specs/acpi_mem_hotplug.txt"
> > - handles only memory add notification event for now
> >
> [...]
> > +      [0x4-0x7] OST event code reported by OSPM
> > +      [0x8-0xb] OST status code reported by OSPM
> > +    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 */
> > +        }
> 
> Are there any patches planned to report _OST notifications to upper management
> layers? E.g. some older patchseries implemented a queue for these notifications
> that could be queried with an "info memhp" command.
I don't recall seeing patches "info memhp", could you point them to me, please?
But I have in mind to add corresponding commands for get OST and sending
corresponding QMP events.

> 
> As a more general question for the patchseries: How do we query status/presence
> of dimms present? Some posssible options could be:
> 
> - info qtree: If links<> are implemented between dimms and an acpi machine
> adapter, would the dimms show up in the general device tree? Currently I believe
> they don't.
> 
> - info dimm: We could have a new "info dimm" command that shows information for
> present DIMMs: start-end guest physical address, last _OST notification received
> for this DIMM, as well as backing memdev object for this dimm.
I'd prefer this one for hmp and from QMP side qom-get could be used to enumerate/get
properties.

> 
> (qemu) info dimm
> dimm0: range="start_address - end_address" memdev="obj0" _OST="last_OST message"
> dimm1: range="start_address - end_address" memdev="obj1" _OST="last_OST message"
> 
> where last_OST message could be "hot-add succesfull", "hot-add failed",
> "hot-remove failed". Not sure how "hot-remove successful" would be reported
> though, as the dimm device would be removed (or soon to be removed) from the
> machine. Unless we have a separate command for OST messages received/queued, as
> mentioned above.
Not much could be done here except of sending QMP event. It's generic hot-unplug
issue.

> 
> If the guest does not support _OST, the OST entries would remain empty,
> at least giving management layer a hint that the guest may not have succesfully
> completed the requested hot-operation.
> 
> The examples are all in hmp, but there should obviously be qmp support.
> Thoughts?
> 
> thanks,
> 
> - Vasilis
> 
> 

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

* Re: [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines
  2014-05-05 16:25   ` Eric Blake
  2014-05-05 16:28     ` Paolo Bonzini
@ 2014-05-06  7:16     ` Igor Mammedov
  1 sibling, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-05-06  7:16 UTC (permalink / raw)
  To: Eric Blake
  Cc: peter.maydell, mst, aik, jan.kiszka, mjt, qemu-devel,
	lcapitulino, kraxel, akong, quintela, armbru, aliguori, hutao,
	lersek, ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf,
	s.priebe, mreitz, vasilis.liaskovitis, pbonzini, afaerber

On Mon, 05 May 2014 10:25:09 -0600
Eric Blake <eblake@redhat.com> wrote:

> On 04/04/2014 07:36 AM, Igor Mammedov wrote:
> > also make handler edge based to avoid loosing events, the same as
> 
> s/loosing/losing/
Thanks, I'll fix it.

> 
> (loose rhymes with goose and means the opposite of "tight"; lose rhymes
> with use and means the opposite of "gain" - it is a very frequent typo
> to see people put too many 'o's when they meant a variant of "lose")
> 
> > it has been done for PCI and CPU hotplug handlers.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  hw/i386/acpi-dsdt.dsl     | 5 ++++-
> >  hw/i386/q35-acpi-dsdt.dsl | 5 ++++-
> >  2 files changed, 8 insertions(+), 2 deletions(-)
> > 
> 

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

* Re: [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines
  2014-05-05 16:28     ` Paolo Bonzini
@ 2014-05-06 10:05       ` Laszlo Ersek
  0 siblings, 0 replies; 93+ messages in thread
From: Laszlo Ersek @ 2014-05-06 10:05 UTC (permalink / raw)
  To: Paolo Bonzini, Eric Blake, Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, aik, jan.kiszka, mjt, lcapitulino, kraxel,
	akong, quintela, armbru, aliguori, hutao, ehabkost, marcel.a,
	stefanha, chegu_vinod, rth, kwolf, s.priebe, mreitz,
	vasilis.liaskovitis, afaerber

On 05/05/14 18:28, Paolo Bonzini wrote:
> Il 05/05/2014 18:25, Eric Blake ha scritto:
>>> > also make handler edge based to avoid loosing events, the same as
>> s/loosing/losing/
>>
>> (loose rhymes with goose and means the opposite of "tight"; lose rhymes
>> with use and means the opposite of "gain" - it is a very frequent typo
>> to see people put too many 'o's when they meant a variant of "lose")
> 
> Unfortunately rhymes are useless to non-native speakers. :)  A good way
> to remember it is to think of 'loosen' and 'lost' rather than 'loose'
> and 'lose', which are pronounced differently and hence easier to
> associate with the right number of 'o's.

Wiktionary is also helpful. The articles frequently come with phonetic
notation(s) and an audio sample. For example:

http://en.wiktionary.org/wiki/loose   enPR: loo͞s, IPA: /luːs/
http://en.wiktionary.org/wiki/lose    enPR: lo͞oz, IPA: /luːz/
                                               ^           ^
                                               |           |

I'd say these are helpful; in this case even without audio samples
(although the articles in question have them too).

Other favorites of mine are "close" (as in, shut the door) vs. "close"
(as in, is your house near) -- the two etimologies incur different
pronounciations:

http://en.wiktionary.org/wiki/close#Pronunciation     kloʊz
http://en.wiktionary.org/wiki/close#Pronunciation_2   kləʊs
                                                          ^
                                                          |
               (minimally these consonants are accessible to foreigners)

Laszlo

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

* Re: [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation
  2014-05-06  7:13     ` Igor Mammedov
@ 2014-05-06 12:58       ` Vasilis Liaskovitis
  0 siblings, 0 replies; 93+ messages in thread
From: Vasilis Liaskovitis @ 2014-05-06 12:58 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mst, aik, hutao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf, s.priebe,
	mreitz, pbonzini, afaerber

On Tue, May 06, 2014 at 09:13:13AM +0200, Igor Mammedov wrote:
> On Mon, 5 May 2014 14:20:25 +0200
> Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:
> > On Fri, Apr 04, 2014 at 03:36:45PM +0200, Igor Mammedov wrote:
> > > +        if (data == 1) {
> > > +            /* TODO: handle device insert OST event */
> > > +        } else if (data == 3) {
> > > +            /* TODO: handle device remove OST event */
> > > +        }
> > 
> > Are there any patches planned to report _OST notifications to upper management
> > layers? E.g. some older patchseries implemented a queue for these notifications
> > that could be queried with an "info memhp" command.
> I don't recall seeing patches "info memhp", could you point them to me, please?
> But I have in mind to add corresponding commands for get OST and sending
> corresponding QMP events.

Old patch for "info memhp" (or "info memory-hotplug") are here:
http://lists.gnu.org/archive/html/qemu-devel/2012-09/msg03539.html

not sure if we want a separate command though, or have eveyrhting in "info dimm"

> 
> > 
> > As a more general question for the patchseries: How do we query status/presence
> > of dimms present? Some posssible options could be:
> > 
> > - info qtree: If links<> are implemented between dimms and an acpi machine
> > adapter, would the dimms show up in the general device tree? Currently I believe
> > they don't.
> > 
> > - info dimm: We could have a new "info dimm" command that shows information for
> > present DIMMs: start-end guest physical address, last _OST notification received
> > for this DIMM, as well as backing memdev object for this dimm.
> I'd prefer this one for hmp and from QMP side qom-get could be used to enumerate/get
> properties.

I also prefer "info dimm" for hmp. For qmp, how flexible is qom-get? Can we use
a single qom-get command to e.g. receive properties of all dimm devices? I
think a command that lists all dimm devices and properties could be useful.

thanks,

- Vasilis

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

* Re: [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-05-06  1:52         ` Hu Tao
@ 2014-05-06 13:00           ` Vasilis Liaskovitis
       [not found]             ` <CAM4NYE8WjH-AhEAv9h8Z14+g3XutfEDM8UYFHtDUF7iR4jAOUg@mail.gmail.com>
  0 siblings, 1 reply; 93+ messages in thread
From: Vasilis Liaskovitis @ 2014-05-06 13:00 UTC (permalink / raw)
  To: Hu Tao
  Cc: peter.maydell, mst, aik, jan.kiszka, mjt, qemu-devel,
	lcapitulino, kraxel, akong, quintela, armbru, aliguori, lersek,
	ehabkost, marcel.a, stefanha, pbonzini, chegu_vinod, rth, kwolf,
	s.priebe, mreitz, Igor Mammedov, afaerber

On Tue, May 06, 2014 at 09:52:39AM +0800, Hu Tao wrote:
> On Mon, May 05, 2014 at 05:59:15PM +0200, Vasilis Liaskovitis wrote:
> > Hi,
> > 
> > On Mon, Apr 14, 2014 at 06:44:42PM +0200, Igor Mammedov wrote:
> > > On Mon, 14 Apr 2014 15:25:01 +0800
> > > Hu Tao <hutao@cn.fujitsu.com> wrote:
> > > 
> > > > On Fri, Apr 04, 2014 at 03:36:58PM +0200, Igor Mammedov wrote:
> > > Could you be more specific, what and how doesn't work and why there is
> > > need for SRAT entries per DIMM?
> > > I've briefly tested with your unplug patches and linux seemed be ok with unplug,
> > > i.e. device node was removed from /sys after receiving remove notification.
> > 
> > Just a heads-up, is this the unplug patch that you are using for testing:
> > https://github.com/taohu/qemu/commit/55c9540919e189b0ad2e6a759af742080f8f5dc4
> > 
> > or is there a newer version based on Igor's patchseries?
> 
> Yeah. There is a new version. I pushed it up to
> https://github.com/taohu/qemu/commits/memhp for you to check out.

cool, thanks.

- Vasilis

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
  2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
                   ` (36 preceding siblings ...)
  2014-04-04 16:57 ` Dr. David Alan Gilbert
@ 2014-05-07  9:15 ` Stefan Priebe - Profihost AG
  2014-05-19 21:24   ` [Qemu-devel] [PATCH] vl.c: daemonize before guest memory allocation Igor Mammedov
  2014-08-25 13:28   ` [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Anshul Makkar
  37 siblings, 2 replies; 93+ messages in thread
From: Stefan Priebe - Profihost AG @ 2014-05-07  9:15 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, mst, aik, hutao, mjt, lcapitulino, kraxel, akong,
	quintela, armbru, aliguori, jan.kiszka, lersek, ehabkost,
	marcel.a, stefanha, chegu_vinod, rth, kwolf, mreitz,
	vasilis.liaskovitis, pbonzini, afaerber

Hello Igor,

while testing your patchset i came to a very stupid problem.

I wanted to test migration and it cames out that the migration works
fine after plugging in memory only if i run the target VM without the
-daemonize option.

If i enable the -daemonize option the target vm tries to read from non
readable memory.

proc maps shows:
7f9334021000-7f9338000000 ---p 00000000 00:00 0

where it tries to read from.

Also the memory layout is different in daemonize mode than in non
daemonize mode.

Stefan

Am 04.04.2014 15:36, schrieb Igor Mammedov:
> 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
>   start - 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 255 (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
>    start/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-v8
> 
> 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 (34):
>   vl: convert -m to QemuOpts
>   object_add: allow completion handler to get canonical path
>   add memdev backend infrastructure
>   vl.c: extend -m option to support options for memory hotplug
>   add pc-{i440fx,q35}-2.1 machine types
>   pc: create custom generic PC machine type
>   qdev: hotplug for buss-less devices
>   qdev: expose DeviceState.hotplugged field as a property
>   dimm: implement dimm device abstraction
>   memory: add memory_region_is_mapped() API
>   dimm: do not allow to set already busy memdev
>   pc: initialize memory hotplug address space
>   pc: exit QEMU if slots > 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: add DIMM slot & address allocation for target-i386
>   acpi:piix4: make plug/unlug callbacks generic
>   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: propagate memory hotplug event to ACPI device
>   pc: ACPI BIOS: punch holes in PCI0._CRS for memory hotplug IO region
>   pc: ACPI BIOS: name CPU hotplug ACPI0004 device
>   pc: ACPI BIOS: implement memory hotplug interface
>   pc: ACPI BIOS: use enum for defining memory affinity flags
>   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
>   pc: ACPI BIOS: update pregenerated ACPI table blobs
> 
> Paolo Bonzini (1):
>   qemu-option: introduce qemu_find_opts_singleton
> 
>  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                      |  46 ++
>  hw/acpi/memory_hotplug.c            | 184 ++++++++
>  hw/acpi/piix4.c                     |  52 ++-
>  hw/core/qdev.c                      |  30 ++
>  hw/i386/Makefile.objs               |   3 +-
>  hw/i386/acpi-build.c                |  74 +++-
>  hw/i386/acpi-dsdt-cpu-hotplug.dsl   |   1 +
>  hw/i386/acpi-dsdt.dsl               |  17 +-
>  hw/i386/acpi-dsdt.hex.generated     | 102 ++++-
>  hw/i386/pc.c                        | 165 +++++++-
>  hw/i386/pc_piix.c                   |  64 ++-
>  hw/i386/pc_q35.c                    |  38 +-
>  hw/i386/q35-acpi-dsdt.dsl           |  17 +-
>  hw/i386/q35-acpi-dsdt.hex.generated | 104 ++++-
>  hw/i386/ssdt-mem.dsl                |  75 ++++
>  hw/i386/ssdt-mem.hex.generated      | 197 +++++++++
>  hw/i386/ssdt-misc.dsl               | 163 ++++++++
>  hw/i386/ssdt-misc.hex.generated     | 809 +++++++++++++++++++++++++++++++++++-
>  hw/isa/lpc_ich9.c                   |  33 +-
>  hw/mem/Makefile.objs                |   1 +
>  hw/mem/dimm.c                       | 234 +++++++++++
>  include/exec/memory.h               |   8 +
>  include/hw/acpi/acpi_defs.h         |  35 ++
>  include/hw/acpi/cpu_hotplug.h       |   2 +-
>  include/hw/acpi/cpu_hotplug_defs.h  |  32 --
>  include/hw/acpi/ich9.h              |   4 +
>  include/hw/acpi/memory_hotplug.h    |  37 ++
>  include/hw/boards.h                 |  10 +
>  include/hw/i386/pc.h                |  59 +++
>  include/hw/mem/dimm.h               |  72 ++++
>  include/qemu/config-file.h          |   2 +
>  include/sysemu/hostmem.h            |  60 +++
>  memory.c                            |  15 +-
>  qemu-options.hx                     |  14 +-
>  qmp.c                               |  11 +-
>  trace-events                        |  17 +
>  util/qemu-config.c                  |  14 +
>  vl.c                                | 145 +++++--
>  46 files changed, 2987 insertions(+), 173 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/i386/ssdt-mem.hex.generated
>  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] 93+ messages in thread

* Re: [Qemu-devel] [PATCH 17/35] dimm: add busy address check and address auto-allocation
  2014-04-04 13:36 ` [Qemu-devel] [PATCH 17/35] dimm: add busy address check and address auto-allocation Igor Mammedov
@ 2014-05-07  9:58   ` Tang Chen
  0 siblings, 0 replies; 93+ messages in thread
From: Tang Chen @ 2014-05-07  9:58 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mst, aik, Hu Tao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, Yasuaki Ishimatsu, aliguori,
	jan.kiszka, lersek, ehabkost, marcel.a, stefanha, chegu_vinod,
	rth, kwolf, s.priebe, mreitz, vasilis.liaskovitis, guz.fnst,
	pbonzini, afaerber

[-- Attachment #1: Type: text/plain, Size: 2245 bytes --]

Hi Igor,

On 04/04/2014 09:36 PM, Igor Mammedov wrote:
......
> +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_start, ret;
> +    uint64_t address_space_end = address_space_start + address_space_size;
> +
> +    object_child_foreach(qdev_get_machine(), dimm_built_list,&list);
> +
> +    if (hint) {
> +        new_start = *hint;
> +    } else {
> +        new_start = 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),
> +                             "size",&error_abort);
> +        if (ranges_overlap(dimm->start, dimm_size, new_start, size)) {
> +            if (hint) {
> +                DeviceState *d = DEVICE(dimm);
> +                error_setg(errp, "address range conflicts with '%s'", d->id);
> +                break;

Actually we got an error here.

If we break from here, new_start is set to *hint, and ret will also be 
set to *hint.
So the return value is a little ambiguous.

I can understand that caller will check errp to find out if there is an 
error. And I
also understand we need to free list. But please also see below.

> +            }
> +            new_start = dimm->start + dimm_size;
> +        }
> +    }
> +    ret = new_start;
> +
> +    g_slist_free(list);
> +
> +    if (new_start<  address_space_start) {
> +        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
> +                   "] at 0x%" PRIx64, new_start, size, address_space_start);
> +    } else if ((new_start + size)>  address_space_end) {
> +        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
> +                   "] beyond 0x%" PRIx64, new_start, size, address_space_end);
> +    }

The error here could also be triggered. If so, errp will be reset, not 
the error
status set above.

> +    return ret;
> +}
>

So, how about the attached patch ?

Thanks. :)

[-- Attachment #2: 0001-dimm-add-busy-address-check-and-address-auto-allocat.patch --]
[-- Type: text/x-patch, Size: 5268 bytes --]

>From 2af81231d7a5479f70b1444589b01a47d37145c2 Mon Sep 17 00:00:00 2001
From: Igor Mammedov <imammedo@redhat.com>
Date: Fri, 4 Apr 2014 15:36:42 +0200
Subject: [PATCH] dimm: add busy address check and address auto-allocation

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

- if 'start' 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>
---
 hw/i386/pc.c          | 16 +++++++++++-
 hw/mem/dimm.c         | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h |  5 ++++
 3 files changed, 90 insertions(+), 1 deletion(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 4038e2c..29382ec 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1483,15 +1483,29 @@ void qemu_register_pc_machine(QEMUMachine *m)
 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 = dimm->start;
+
+    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, "start", &local_err);
 
     memory_region_add_subregion(&pcms->hotplug_memory,
-                                dimm->start - pcms->hotplug_memory_base,
+                                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,
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 65d4cd0..d8a3c5e 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -21,6 +21,76 @@
 #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->start - y->start;
+}
+
+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_start, ret = 0;
+    uint64_t address_space_end = address_space_start + address_space_size;
+
+    object_child_foreach(qdev_get_machine(), dimm_built_list, &list);
+
+    if (hint) {
+        new_start = *hint;
+    } else {
+        new_start = 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),
+                             "size", &error_abort);
+        if (ranges_overlap(dimm->start, dimm_size, new_start, size)) {
+            if (hint) {
+                DeviceState *d = DEVICE(dimm);
+                error_setg(errp, "address range conflicts with '%s'", d->id);
+                goto out;
+            }
+            new_start = dimm->start + dimm_size;
+        }
+    }
+    ret = new_start;
+
+    if (new_start < address_space_start) {
+        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
+                   "] at 0x%" PRIx64, new_start, size, address_space_start);
+    } else if ((new_start + size) > address_space_end) {
+        error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
+                   "] beyond 0x%" PRIx64, new_start, size, address_space_end);
+    }
+
+out:
+    g_slist_free(list);
+    return ret;
+}
 
 static Property dimm_properties[] = {
     DEFINE_PROP_UINT64("start", DimmDevice, start, 0),
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 4bbf0ed..d6e4d65 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -62,4 +62,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.8.0


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

* [Qemu-devel] [PATCH] vl.c: daemonize before guest memory allocation
  2014-05-07  9:15 ` Stefan Priebe - Profihost AG
@ 2014-05-19 21:24   ` Igor Mammedov
  2014-05-19 21:28     ` Eric Blake
  2014-08-25 13:28   ` [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Anshul Makkar
  1 sibling, 1 reply; 93+ messages in thread
From: Igor Mammedov @ 2014-05-19 21:24 UTC (permalink / raw)
  To: qemu-devel; +Cc: peter.maydell, mst, jan.kiszka, s.priebe, aliguori, pbonzini

memory allocated for guest before QEMU is demonized and then mapped
later in guest's addess space after it is demonized, leads to EPT
violation and QEMU abort.

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

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
I haven't digged in kvm itsefl 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 | 15 ++++++++-------
 1 file changed, 8 insertions(+), 7 deletions(-)

diff --git a/vl.c b/vl.c
index ca9db1c..19f731d 100644
--- a/vl.c
+++ b/vl.c
@@ -4012,6 +4012,14 @@ int main(int argc, char **argv, char **envp)
     }
     loc_set_none();
 
+    os_daemonize();
+
+    if (pid_file && qemu_create_pidfile(pid_file) != 0) {
+        os_pidfile_error();
+        exit(1);
+    }
+
+
     if (qemu_init_main_loop()) {
         fprintf(stderr, "qemu_init_main_loop failed\n");
         exit(1);
@@ -4249,13 +4257,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);
-    }
-
     /* store value for the future use */
     qemu_opt_set_number(qemu_find_opts_singleton("memory"), "size", ram_size);
 
-- 
1.9.0

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

* Re: [Qemu-devel] [PATCH] vl.c: daemonize before guest memory allocation
  2014-05-19 21:24   ` [Qemu-devel] [PATCH] vl.c: daemonize before guest memory allocation Igor Mammedov
@ 2014-05-19 21:28     ` Eric Blake
  2014-05-19 21:35       ` Igor Mammedov
  0 siblings, 1 reply; 93+ messages in thread
From: Eric Blake @ 2014-05-19 21:28 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, s.priebe, jan.kiszka, mst, aliguori, pbonzini

[-- Attachment #1: Type: text/plain, Size: 619 bytes --]

On 05/19/2014 03:24 PM, Igor Mammedov wrote:
> memory allocated for guest before QEMU is demonized and then mapped

s/demonized/daemonized/

> later in guest's addess space after it is demonized, leads to EPT

s/addess/address/, daemonized again

> violation and QEMU abort.
> 
> To avoid this and similar issues switch to deamonized mode early

s/deamonized/daemonized/

> before processing applying/processing other options.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 604 bytes --]

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

* Re: [Qemu-devel] [PATCH] vl.c: daemonize before guest memory allocation
  2014-05-19 21:28     ` Eric Blake
@ 2014-05-19 21:35       ` Igor Mammedov
  0 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-05-19 21:35 UTC (permalink / raw)
  To: Eric Blake
  Cc: peter.maydell, s.priebe, jan.kiszka, mst, qemu-devel, aliguori, pbonzini

On Mon, 19 May 2014 15:28:55 -0600
Eric Blake <eblake@redhat.com> wrote:

> On 05/19/2014 03:24 PM, Igor Mammedov wrote:
> > memory allocated for guest before QEMU is demonized and then mapped
> 
> s/demonized/daemonized/
> 
> > later in guest's addess space after it is demonized, leads to EPT
> 
> s/addess/address/, daemonized again
> 
> > violation and QEMU abort.
> > 
> > To avoid this and similar issues switch to deamonized mode early
> 
> s/deamonized/daemonized/
> 
> > before processing applying/processing other options.
Thanks Eric a lot for pointing out to my silly typos/mistakes,
I'll include fixed patch on next respin of this series.

> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> 
> -- 
> Eric Blake   eblake redhat com    +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
       [not found]                       ` <20140529111237.7d775371@nial.usersys.redhat.com>
@ 2014-06-02 14:29                           ` Vasilis Liaskovitis
  0 siblings, 0 replies; 93+ messages in thread
From: Vasilis Liaskovitis @ 2014-06-02 14:29 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Maydell, mst, aik, Hu Tao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, aliguori, jan.kiszka, lersek,
	ehabkost, marcel.a, stefanha, Anshul Makkar, chegu_vinod, rth,
	kwolf, s.priebe, mreitz, pbonzini, afaerber, linux-acpi

On Thu, May 29, 2014 at 11:12:37AM +0200, Igor Mammedov wrote:
> On Wed, 28 May 2014 18:38:13 +0200
> Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:
> 
> > On Wed, May 28, 2014 at 03:26:42PM +0200, Igor Mammedov wrote:
> > > On Wed, 28 May 2014 14:23:13 +0200
> > > Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:
> > > 
> > > > On Wed, May 28, 2014 at 10:07:22AM +0200, Igor Mammedov wrote:
> > > > > On Tue, 27 May 2014 17:57:31 +0200
> > > > > Anshul Makkar <anshul.makkar@profitbricks.com> wrote:
> > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > I tested the hot unplug patch and doesn't seem to work properly with Debian
> > > > > > 6 and Ubuntu host.
> > > > > > 
> > > > > > Scenario:
> > > > > > I added 3 dimm devices of 1G each:
> > > > > > 
> > > > > > object_add memory-ram,id=ram0,size=1G, device_add dimm,id=dimm1,memdev=ram0
> > > > > > 
> > > > > > object_add memory-ram,id=ram1,size=1G, device_add dimm,id=dimm2,memdev=ram1
> > > > > > 
> > > > > > object_add memory-ram,id=ram2,size=1G, device_add dimm,id=dimm3,memdev=ram2
> > > > > > 
> > > > > > device_del dimm3: I get the OST EVENT EJECT 0x3 and OST STATUS as 0x84(IN
> > > > > > PROGRESS) If I check on the guest, the device has been successfully
> > > > > > removed. But no OST EJECT SUCCESS event was received.
> > > > > I think there should be a SUCCESS event,
> > > > > it should be investigated from the guest side first, OST support in kernel
> > > > > is relatively new.
> > > > 
> > > > When testing older guest kernel (3.11), _OST success events are not sent
> > > > from the guest. I haven't tried newer versions yet.
> > > > 
> > > > In terms of OSPM _OST behaviour, I am not sure if returning OST success status
> > > > on succcesful removal is *required*. Figure 6-37, page 306 of ACPI spec5.0
> > > > shows that on succcesfull OS ejection ejection, _EJ0 is evaluated. Evaluating
> > > > _OST does not seem to be a requirement, is it? (cc'ing linux-acpi for input)
> > > > 
> > > > In linux guests, on successful removal, _EJ0 is always evaluated. I believe we
> > > > should be handling _EJ0 and doing the dimm removal (object_unparent) there.
> > > > Currently OST successes are never received and dimm devices remain in QEMU even
> > > > when successfully ejected from guest.
> > > > E.g. a quick patch for _EJ0 handling, on top of Hu Tao's series:
> > > > 
> The same register [0x14] is control register when writing there, so we can use-reuse
> the same bit position as MRMV for signaling QEMU to perform eject on writing 1 there,
> similarly like it's done for insert event.

thanks, on a closer look that makes sense. MRMV is sufficient, example patch
below.

With the new "query-acpi-ospm-status" we can read OST status from QMP. However
as I mentioned, on succesful removal, the guest kernel does not send the OST success
status (0x0).

This leads to the scenario where memory device is succesfully ejected, _EJ0 is
evaluated in guest and device is deleted in qemu (with the patch below). The
dimm will no longer show up in "query-memory-devices", however the ospm status
of the dimm slot will still remain  at 0x84 (ejection in progress).  This can
be confusing to management layers. Do you have any suggestion for how to
report the succesful _EJ0? We could simply write a succesful status:

  mdev->ost_status = 0x0 

when MRMV is written to, but it is a bit hacky. On the other hand, having another
command only for _EJ0 notification sounds like overkill.

In terms of linux kernel ACPI conformity, Figure 6-37 in the spec implies that
_OST evaluation is not required after succesfull _EJ0 evaluation. Also see
relevant comment in drivers/acpi/scan.c: acpi_scan_hot_remove() line 378
(3.15-rc8):
    /*
    * Verify if eject was indeed successful.  If not, log an error
    * message.  No need to call _OST since _EJ0 call was made
    * OK.
    */



acpi, memory-hotplug: Add _EJ0 handling

---
 docs/specs/acpi_mem_hotplug.txt |    3 ++-
 hw/acpi/memory_hotplug.c        |    9 +++------
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
index 1290994..4501774 100644
--- a/docs/specs/acpi_mem_hotplug.txt
+++ b/docs/specs/acpi_mem_hotplug.txt
@@ -35,7 +35,8 @@ Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
               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
+              2: Device no longer used by guest, can be safely removed	 
+              3-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
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 8aa829d..24989d3 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -93,9 +93,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
         case 0x03: /* EJECT */
             switch (mdev->ost_status) {
             case 0x0: /* SUCCESS */
-                object_unparent(OBJECT(mdev->dimm));
-                mdev->is_removing = false;
-                mdev->dimm = NULL;
                 break;
             case 0x1: /* FAILURE */
             case 0x2: /* UNRECOGNIZED NOTIFY */
@@ -115,9 +112,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
         case 0x103: /* OSPM EJECT */
             switch (mdev->ost_status) {
             case 0x0: /* SUCCESS */
-                object_unparent(OBJECT(mdev->dimm));
-                mdev->is_removing = false;
-                mdev->dimm = NULL;
                 break;
             case 0x84: /* EJECTION IN PROGRESS */
                 mdev->is_enabled = false;
@@ -135,6 +129,9 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
             trace_mhp_acpi_clear_insert_evt(mem_st->selector);
         } else if (data & 4) { /* MRMV */
             mdev->is_enabled = false;
+            object_unparent(OBJECT(mdev->dimm));
+            mdev->is_removing = false;
+            mdev->dimm = NULL;
         }
         break;
     }


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

* Re: [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
@ 2014-06-02 14:29                           ` Vasilis Liaskovitis
  0 siblings, 0 replies; 93+ messages in thread
From: Vasilis Liaskovitis @ 2014-06-02 14:29 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: Peter Maydell, mst, aik, Hu Tao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, linux-acpi, aliguori,
	jan.kiszka, lersek, ehabkost, marcel.a, stefanha, Anshul Makkar,
	chegu_vinod, rth, kwolf, s.priebe, mreitz, pbonzini, afaerber

On Thu, May 29, 2014 at 11:12:37AM +0200, Igor Mammedov wrote:
> On Wed, 28 May 2014 18:38:13 +0200
> Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:
> 
> > On Wed, May 28, 2014 at 03:26:42PM +0200, Igor Mammedov wrote:
> > > On Wed, 28 May 2014 14:23:13 +0200
> > > Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:
> > > 
> > > > On Wed, May 28, 2014 at 10:07:22AM +0200, Igor Mammedov wrote:
> > > > > On Tue, 27 May 2014 17:57:31 +0200
> > > > > Anshul Makkar <anshul.makkar@profitbricks.com> wrote:
> > > > > 
> > > > > > Hi,
> > > > > > 
> > > > > > I tested the hot unplug patch and doesn't seem to work properly with Debian
> > > > > > 6 and Ubuntu host.
> > > > > > 
> > > > > > Scenario:
> > > > > > I added 3 dimm devices of 1G each:
> > > > > > 
> > > > > > object_add memory-ram,id=ram0,size=1G, device_add dimm,id=dimm1,memdev=ram0
> > > > > > 
> > > > > > object_add memory-ram,id=ram1,size=1G, device_add dimm,id=dimm2,memdev=ram1
> > > > > > 
> > > > > > object_add memory-ram,id=ram2,size=1G, device_add dimm,id=dimm3,memdev=ram2
> > > > > > 
> > > > > > device_del dimm3: I get the OST EVENT EJECT 0x3 and OST STATUS as 0x84(IN
> > > > > > PROGRESS) If I check on the guest, the device has been successfully
> > > > > > removed. But no OST EJECT SUCCESS event was received.
> > > > > I think there should be a SUCCESS event,
> > > > > it should be investigated from the guest side first, OST support in kernel
> > > > > is relatively new.
> > > > 
> > > > When testing older guest kernel (3.11), _OST success events are not sent
> > > > from the guest. I haven't tried newer versions yet.
> > > > 
> > > > In terms of OSPM _OST behaviour, I am not sure if returning OST success status
> > > > on succcesful removal is *required*. Figure 6-37, page 306 of ACPI spec5.0
> > > > shows that on succcesfull OS ejection ejection, _EJ0 is evaluated. Evaluating
> > > > _OST does not seem to be a requirement, is it? (cc'ing linux-acpi for input)
> > > > 
> > > > In linux guests, on successful removal, _EJ0 is always evaluated. I believe we
> > > > should be handling _EJ0 and doing the dimm removal (object_unparent) there.
> > > > Currently OST successes are never received and dimm devices remain in QEMU even
> > > > when successfully ejected from guest.
> > > > E.g. a quick patch for _EJ0 handling, on top of Hu Tao's series:
> > > > 
> The same register [0x14] is control register when writing there, so we can use-reuse
> the same bit position as MRMV for signaling QEMU to perform eject on writing 1 there,
> similarly like it's done for insert event.

thanks, on a closer look that makes sense. MRMV is sufficient, example patch
below.

With the new "query-acpi-ospm-status" we can read OST status from QMP. However
as I mentioned, on succesful removal, the guest kernel does not send the OST success
status (0x0).

This leads to the scenario where memory device is succesfully ejected, _EJ0 is
evaluated in guest and device is deleted in qemu (with the patch below). The
dimm will no longer show up in "query-memory-devices", however the ospm status
of the dimm slot will still remain  at 0x84 (ejection in progress).  This can
be confusing to management layers. Do you have any suggestion for how to
report the succesful _EJ0? We could simply write a succesful status:

  mdev->ost_status = 0x0 

when MRMV is written to, but it is a bit hacky. On the other hand, having another
command only for _EJ0 notification sounds like overkill.

In terms of linux kernel ACPI conformity, Figure 6-37 in the spec implies that
_OST evaluation is not required after succesfull _EJ0 evaluation. Also see
relevant comment in drivers/acpi/scan.c: acpi_scan_hot_remove() line 378
(3.15-rc8):
    /*
    * Verify if eject was indeed successful.  If not, log an error
    * message.  No need to call _OST since _EJ0 call was made
    * OK.
    */



acpi, memory-hotplug: Add _EJ0 handling

---
 docs/specs/acpi_mem_hotplug.txt |    3 ++-
 hw/acpi/memory_hotplug.c        |    9 +++------
 2 files changed, 5 insertions(+), 7 deletions(-)

diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
index 1290994..4501774 100644
--- a/docs/specs/acpi_mem_hotplug.txt
+++ b/docs/specs/acpi_mem_hotplug.txt
@@ -35,7 +35,8 @@ Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
               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
+              2: Device no longer used by guest, can be safely removed	 
+              3-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
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index 8aa829d..24989d3 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -93,9 +93,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
         case 0x03: /* EJECT */
             switch (mdev->ost_status) {
             case 0x0: /* SUCCESS */
-                object_unparent(OBJECT(mdev->dimm));
-                mdev->is_removing = false;
-                mdev->dimm = NULL;
                 break;
             case 0x1: /* FAILURE */
             case 0x2: /* UNRECOGNIZED NOTIFY */
@@ -115,9 +112,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
         case 0x103: /* OSPM EJECT */
             switch (mdev->ost_status) {
             case 0x0: /* SUCCESS */
-                object_unparent(OBJECT(mdev->dimm));
-                mdev->is_removing = false;
-                mdev->dimm = NULL;
                 break;
             case 0x84: /* EJECTION IN PROGRESS */
                 mdev->is_enabled = false;
@@ -135,6 +129,9 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
             trace_mhp_acpi_clear_insert_evt(mem_st->selector);
         } else if (data & 4) { /* MRMV */
             mdev->is_enabled = false;
+            object_unparent(OBJECT(mdev->dimm));
+            mdev->is_removing = false;
+            mdev->dimm = NULL;
         }
         break;
     }

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

* Re: [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2014-06-02 14:29                           ` Vasilis Liaskovitis
  (?)
@ 2014-06-02 14:54                           ` Igor Mammedov
  -1 siblings, 0 replies; 93+ messages in thread
From: Igor Mammedov @ 2014-06-02 14:54 UTC (permalink / raw)
  To: Vasilis Liaskovitis
  Cc: Peter Maydell, mst, aik, Hu Tao, mjt, qemu-devel, lcapitulino,
	kraxel, akong, quintela, armbru, linux-acpi, aliguori,
	jan.kiszka, lersek, ehabkost, marcel.a, stefanha, Anshul Makkar,
	chegu_vinod, rth, kwolf, s.priebe, mreitz, pbonzini, afaerber

On Mon, 2 Jun 2014 16:29:32 +0200
Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:

> On Thu, May 29, 2014 at 11:12:37AM +0200, Igor Mammedov wrote:
> > On Wed, 28 May 2014 18:38:13 +0200
> > Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:
> > 
> > > On Wed, May 28, 2014 at 03:26:42PM +0200, Igor Mammedov wrote:
> > > > On Wed, 28 May 2014 14:23:13 +0200
> > > > Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com> wrote:
> > > > 
> > > > > On Wed, May 28, 2014 at 10:07:22AM +0200, Igor Mammedov wrote:
> > > > > > On Tue, 27 May 2014 17:57:31 +0200
> > > > > > Anshul Makkar <anshul.makkar@profitbricks.com> wrote:
> > > > > > 
> > > > > > > Hi,
> > > > > > > 
> > > > > > > I tested the hot unplug patch and doesn't seem to work properly with Debian
> > > > > > > 6 and Ubuntu host.
> > > > > > > 
> > > > > > > Scenario:
> > > > > > > I added 3 dimm devices of 1G each:
> > > > > > > 
> > > > > > > object_add memory-ram,id=ram0,size=1G, device_add dimm,id=dimm1,memdev=ram0
> > > > > > > 
> > > > > > > object_add memory-ram,id=ram1,size=1G, device_add dimm,id=dimm2,memdev=ram1
> > > > > > > 
> > > > > > > object_add memory-ram,id=ram2,size=1G, device_add dimm,id=dimm3,memdev=ram2
> > > > > > > 
> > > > > > > device_del dimm3: I get the OST EVENT EJECT 0x3 and OST STATUS as 0x84(IN
> > > > > > > PROGRESS) If I check on the guest, the device has been successfully
> > > > > > > removed. But no OST EJECT SUCCESS event was received.
> > > > > > I think there should be a SUCCESS event,
> > > > > > it should be investigated from the guest side first, OST support in kernel
> > > > > > is relatively new.
> > > > > 
> > > > > When testing older guest kernel (3.11), _OST success events are not sent
> > > > > from the guest. I haven't tried newer versions yet.
> > > > > 
> > > > > In terms of OSPM _OST behaviour, I am not sure if returning OST success status
> > > > > on succcesful removal is *required*. Figure 6-37, page 306 of ACPI spec5.0
> > > > > shows that on succcesfull OS ejection ejection, _EJ0 is evaluated. Evaluating
> > > > > _OST does not seem to be a requirement, is it? (cc'ing linux-acpi for input)
> > > > > 
> > > > > In linux guests, on successful removal, _EJ0 is always evaluated. I believe we
> > > > > should be handling _EJ0 and doing the dimm removal (object_unparent) there.
> > > > > Currently OST successes are never received and dimm devices remain in QEMU even
> > > > > when successfully ejected from guest.
> > > > > E.g. a quick patch for _EJ0 handling, on top of Hu Tao's series:
> > > > > 
> > The same register [0x14] is control register when writing there, so we can use-reuse
> > the same bit position as MRMV for signaling QEMU to perform eject on writing 1 there,
> > similarly like it's done for insert event.
> 
> thanks, on a closer look that makes sense. MRMV is sufficient, example patch
> below.
> 
> With the new "query-acpi-ospm-status" we can read OST status from QMP. However
> as I mentioned, on succesful removal, the guest kernel does not send the OST success
> status (0x0).
> 
> This leads to the scenario where memory device is succesfully ejected, _EJ0 is
> evaluated in guest and device is deleted in qemu (with the patch below). The
> dimm will no longer show up in "query-memory-devices", however the ospm status
> of the dimm slot will still remain  at 0x84 (ejection in progress).  This can
> be confusing to management layers. Do you have any suggestion for how to
> report the succesful _EJ0? We could simply write a succesful status:
> 
>   mdev->ost_status = 0x0 
> 
> when MRMV is written to, but it is a bit hacky. On the other hand, having another
> command only for _EJ0 notification sounds like overkill.
I'd go with your suggestion, it provides management with necessary information
without complicating interface further needlessly.

> 
> In terms of linux kernel ACPI conformity, Figure 6-37 in the spec implies that
> _OST evaluation is not required after succesfull _EJ0 evaluation. Also see
> relevant comment in drivers/acpi/scan.c: acpi_scan_hot_remove() line 378
> (3.15-rc8):
>     /*
>     * Verify if eject was indeed successful.  If not, log an error
>     * message.  No need to call _OST since _EJ0 call was made
>     * OK.
>     */
> 
> 
> 
> acpi, memory-hotplug: Add _EJ0 handling
> 
> ---
>  docs/specs/acpi_mem_hotplug.txt |    3 ++-
>  hw/acpi/memory_hotplug.c        |    9 +++------
>  2 files changed, 5 insertions(+), 7 deletions(-)
> 
> diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
> index 1290994..4501774 100644
> --- a/docs/specs/acpi_mem_hotplug.txt
> +++ b/docs/specs/acpi_mem_hotplug.txt
> @@ -35,7 +35,8 @@ Memory hot-plug interface (IO port 0xa00-0xa17, 1-4 byte access):
>                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
> +              2: Device no longer used by guest, can be safely removed	 
> +              3-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
> diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
> index 8aa829d..24989d3 100644
> --- a/hw/acpi/memory_hotplug.c
> +++ b/hw/acpi/memory_hotplug.c
> @@ -93,9 +93,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
>          case 0x03: /* EJECT */
>              switch (mdev->ost_status) {
>              case 0x0: /* SUCCESS */
> -                object_unparent(OBJECT(mdev->dimm));
> -                mdev->is_removing = false;
> -                mdev->dimm = NULL;
>                  break;
>              case 0x1: /* FAILURE */
>              case 0x2: /* UNRECOGNIZED NOTIFY */
> @@ -115,9 +112,6 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
>          case 0x103: /* OSPM EJECT */
>              switch (mdev->ost_status) {
>              case 0x0: /* SUCCESS */
> -                object_unparent(OBJECT(mdev->dimm));
> -                mdev->is_removing = false;
> -                mdev->dimm = NULL;
>                  break;
>              case 0x84: /* EJECTION IN PROGRESS */
>                  mdev->is_enabled = false;
> @@ -135,6 +129,9 @@ static void acpi_memory_hotplug_write(void *opaque, hwaddr addr, uint64_t data,
>              trace_mhp_acpi_clear_insert_evt(mem_st->selector);
>          } else if (data & 4) { /* MRMV */
>              mdev->is_enabled = false;
> +            object_unparent(OBJECT(mdev->dimm));
> +            mdev->is_removing = false;
> +            mdev->dimm = NULL;
>          }
>          break;
>      }
> 
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
  2014-05-07  9:15 ` Stefan Priebe - Profihost AG
  2014-05-19 21:24   ` [Qemu-devel] [PATCH] vl.c: daemonize before guest memory allocation Igor Mammedov
@ 2014-08-25 13:28   ` Anshul Makkar
  2014-08-25 13:35     ` Paolo Bonzini
  1 sibling, 1 reply; 93+ messages in thread
From: Anshul Makkar @ 2014-08-25 13:28 UTC (permalink / raw)
  To: Stefan Priebe - Profihost AG
  Cc: Peter Maydell, mst, aik, Hu Tao, mjt, qemu-devel, lcapitulino,
	Gerd Hoffmann, akong, quintela, armbru, aliguori, J. Kiszka,
	lersek, ehabkost, marcel.a, stefanha, pbonzini, chegu_vinod, rth,
	kwolf, mreitz, Vasilis Liaskovitis, Igor Mammedov, afaerber

[-- Attachment #1: Type: text/plain, Size: 797 bytes --]

Hi,

I am testing memory hotadd/remove functionality for Windows guest
(currently 2012 server). Memory hot remove is not working.

As mentioned in the mail chain, hot remove on Windows is not supported.So
just wanted to check if its still not supported or has been supported or
its a work in progress. If its already been supported or still a work in
progress, please can you share the relevant links/patches.

Sorry, if I have missed any latest patches that support Windows memory hot
remove.

Thanks
Anshul Makkar

On Wed, May 7, 2014 at 11:15 AM, Stefan Priebe - Profihost AG <
s.priebe@profihost.ag> wrote:

> ax number of supported DIMM devices 255 (due to ACPI object name
> >    limit), could be increased creating several containers and putting
> >    DIMMs there. (exercise for future)
>

[-- Attachment #2: Type: text/html, Size: 1305 bytes --]

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

* Re: [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug
  2014-08-25 13:28   ` [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Anshul Makkar
@ 2014-08-25 13:35     ` Paolo Bonzini
  0 siblings, 0 replies; 93+ messages in thread
From: Paolo Bonzini @ 2014-08-25 13:35 UTC (permalink / raw)
  To: Anshul Makkar, Stefan Priebe - Profihost AG
  Cc: Peter Maydell, mst, aik, Hu Tao, mjt, qemu-devel, lcapitulino,
	Gerd Hoffmann, akong, quintela, armbru, aliguori, J. Kiszka,
	lersek, ehabkost, marcel.a, stefanha, chegu_vinod, rth, kwolf,
	mreitz, Vasilis Liaskovitis, Igor Mammedov, afaerber

Il 25/08/2014 15:28, Anshul Makkar ha scritto:
> 
> I am testing memory hotadd/remove functionality for Windows guest
> (currently 2012 server). Memory hot remove is not working.
> 
> As mentioned in the mail chain, hot remove on Windows is not
> supported.So just wanted to check if its still not supported or has been
> supported or its a work in progress. If its already been supported or
> still a work in progress, please can you share the relevant links/patches.
> 
> Sorry, if I have missed any latest patches that support Windows memory
> hot remove.

Hot remove is not implemented yet.

Paolo

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

end of thread, other threads:[~2014-08-25 13:37 UTC | newest]

Thread overview: 93+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-04 13:36 [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 01/35] qemu-option: introduce qemu_find_opts_singleton Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 02/35] vl: convert -m to QemuOpts Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 03/35] object_add: allow completion handler to get canonical path Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 04/35] add memdev backend infrastructure Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 05/35] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 06/35] add pc-{i440fx,q35}-2.1 machine types Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 07/35] pc: create custom generic PC machine type Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 08/35] qdev: hotplug for buss-less devices Igor Mammedov
2014-04-07  2:26   ` Alexey Kardashevskiy
2014-04-07  6:51     ` Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 09/35] qdev: expose DeviceState.hotplugged field as a property Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 10/35] dimm: implement dimm device abstraction Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 11/35] memory: add memory_region_is_mapped() API Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 12/35] dimm: do not allow to set already busy memdev Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 14/35] pc: exit QEMU if slots > 256 Igor Mammedov
2014-04-04 17:14   ` Eduardo Habkost
2014-04-07  6:55     ` Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 15/35] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 16/35] pc: add memory hotplug handler to PC_MACHINE Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 17/35] dimm: add busy address check and address auto-allocation Igor Mammedov
2014-05-07  9:58   ` Tang Chen
2014-04-04 13:36 ` [Qemu-devel] [PATCH 18/35] dimm: add busy slot check and slot auto-allocation Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 19/35] acpi: rename cpu_hotplug_defs.h to acpi_defs.h Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 20/35] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
2014-05-05 12:20   ` Vasilis Liaskovitis
2014-05-06  7:13     ` Igor Mammedov
2014-05-06 12:58       ` Vasilis Liaskovitis
2014-04-04 13:36 ` [Qemu-devel] [PATCH 21/35] trace: add acpi memory hotplug IO region events Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 22/35] trace: add DIMM slot & address allocation for target-i386 Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 23/35] acpi:piix4: make plug/unlug callbacks generic Igor Mammedov
2014-04-07 11:32   ` Michael S. Tsirkin
2014-04-07 12:00     ` Igor Mammedov
2014-04-07 12:07       ` Michael S. Tsirkin
2014-04-07 13:12         ` Igor Mammedov
2014-04-07 13:25           ` Michael S. Tsirkin
2014-04-07 14:22             ` Igor Mammedov
2014-04-07 15:36               ` Michael S. Tsirkin
2014-04-11  9:41                 ` Igor Mammedov
2014-04-07 15:19             ` Michael S. Tsirkin
2014-04-12  1:40               ` Paolo Bonzini
2014-04-04 13:36 ` [Qemu-devel] [PATCH 24/35] acpi:piix4: add memory hotplug handling Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 25/35] pc: ich9 lpc: make it work with global/compat properties Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 26/35] acpi:ich9: add memory hotplug handling Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 27/35] pc: migrate piix4 & ich9 MemHotplugState Igor Mammedov
2014-04-04 14:16   ` Paolo Bonzini
2014-04-04 14:37     ` Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 28/35] pc: propagate memory hotplug event to ACPI device Igor Mammedov
2014-04-04 14:02   ` Paolo Bonzini
2014-04-04 14:29     ` Igor Mammedov
2014-04-07  3:07   ` Alexey Kardashevskiy
2014-04-07 14:13     ` Eduardo Habkost
2014-04-07 14:26       ` Igor Mammedov
2014-04-07 15:21         ` Michael S. Tsirkin
2014-04-11  9:13           ` Igor Mammedov
2014-04-07 10:23   ` Michael S. Tsirkin
2014-04-07 13:21     ` Igor Mammedov
2014-04-07 14:32     ` Igor Mammedov
2014-04-07 15:14       ` Michael S. Tsirkin
2014-04-11  9:14         ` Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 29/35] pc: ACPI BIOS: punch holes in PCI0._CRS for memory hotplug IO region Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 30/35] pc: ACPI BIOS: name CPU hotplug ACPI0004 device Igor Mammedov
2014-04-06  9:18   ` Michael S. Tsirkin
2014-04-07  7:13     ` Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 31/35] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
2014-04-06  9:13   ` Michael S. Tsirkin
2014-04-07  7:23     ` Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 32/35] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 33/35] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
     [not found]   ` <20140414072501.GC10931@G08FNSTD100614.fnst.cn.fujitsu.com>
     [not found]     ` <20140414184442.6ff3e626@nial.usersys.redhat.com>
2014-05-05 15:59       ` Vasilis Liaskovitis
2014-05-06  1:52         ` Hu Tao
2014-05-06 13:00           ` Vasilis Liaskovitis
     [not found]             ` <CAM4NYE8WjH-AhEAv9h8Z14+g3XutfEDM8UYFHtDUF7iR4jAOUg@mail.gmail.com>
     [not found]               ` <20140528100722.01b59a48@nial.usersys.redhat.com>
     [not found]                 ` <20140528122312.GA4730@dhcp-192-168-178-175.profitbricks.localdomain>
     [not found]                   ` <20140528152642.108cb193@nial.usersys.redhat.com>
     [not found]                     ` <20140528163813.GB28017@dhcp-192-168-178-175.profitbricks.localdomain>
     [not found]                       ` <20140529111237.7d775371@nial.usersys.redhat.com>
2014-06-02 14:29                         ` Vasilis Liaskovitis
2014-06-02 14:29                           ` Vasilis Liaskovitis
2014-06-02 14:54                           ` Igor Mammedov
2014-04-04 13:36 ` [Qemu-devel] [PATCH 34/35] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
2014-05-05 16:25   ` Eric Blake
2014-05-05 16:28     ` Paolo Bonzini
2014-05-06 10:05       ` Laszlo Ersek
2014-05-06  7:16     ` Igor Mammedov
2014-04-04 13:37 ` [Qemu-devel] [PATCH 35/35] pc: ACPI BIOS: update pregenerated ACPI table blobs Igor Mammedov
     [not found] ` <533EBCB9.3040001@redhat.com>
2014-04-04 14:24   ` [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Igor Mammedov
2014-04-04 15:19     ` Paolo Bonzini
2014-04-04 15:37       ` Igor Mammedov
2014-04-04 16:57 ` Dr. David Alan Gilbert
2014-04-07  7:32   ` Igor Mammedov
2014-05-07  9:15 ` Stefan Priebe - Profihost AG
2014-05-19 21:24   ` [Qemu-devel] [PATCH] vl.c: daemonize before guest memory allocation Igor Mammedov
2014-05-19 21:28     ` Eric Blake
2014-05-19 21:35       ` Igor Mammedov
2014-08-25 13:28   ` [Qemu-devel] [PATCH 00/35] pc: ACPI memory hotplug Anshul Makkar
2014-08-25 13:35     ` Paolo Bonzini

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.