All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug
@ 2013-11-21  2:38 Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core Igor Mammedov
                   ` (27 more replies)
  0 siblings, 28 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

---
What's new since v6:

* DIMM device is split to backend and frontend. Therefore following
  command/options were added for supporting it:

  For memdev backend:
      CLI: -memdev-add
      Monitor/QMP: memdev-add
          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'

* Added Q35 support
* Added support for 32 bit guests
* build for i386 emulator (not tested)
---

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:

  memdev-add 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
 - Windows 2008DCx32

Known limitations/bugs/TODOs:
 - only hot-add supported
 - 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) 
 - failed hotplug action consumes 1 slot (device_add doesn't delete
   device properly if realize failed)
 - 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.

Series is based on mst's PCI tree and requires following SeaBIOS patch:
  http://patchwork.ozlabs.org/patch/292614/
  on top of patches to load ACPI tables from QEMU
  working SeaBIOS tree for testing is available at:
    https://github.com/imammedo/seabios/commits/memhp-wip

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

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

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


Igor Mammedov (26):
  acpi: factor out common pm_update_sci() into acpi core
  rename pci_hotplug_fn to hotplug_fn and make it available for other
    devices
  pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  vl: convert -m to qemu_opts_parse()
  qapi: add SIZE type parser to string_input_visitor
  get reference to /backend container via qemu_get_backend()
  add memdev backend infrastructure
  dimm: map DimmDevice into DimBus provided address space
  dimm: add busy slot check and slot auto-allocation
  dimm: add busy address check and address auto-allocation
  dimm: add hotplug callback to DimmBus
  acpi: memory hotplug ACPI hardware implementation
  acpi: initialize memory hotplug ACPI PIIX4 hardware
  acpi: piix4: add memory-hotplug-io-base property to piix4_pm
  acpi: ich9: allow guest to clear SCI rised by GPE
  acpi: initialize memory hotplug ACPI ICH9 hardware
  acpi: ich9: add memory-hotplug-io-base property to ich9_pm
  acpi: piix4/ich9: add optional vmstate field for MemHotplugState
    migration
  pc: piix: make PCII440FXState type public
  pc: add memory hotplug 440fx machine
  pc: add memory hotplug Q35 machine
  pc: ACPI BIOS: implement memory hotplug interface
  pc: ACPI BIOS: add ssdt-mem.hex.generated and update
    ssdt-misc.hex.generated
  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

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

 backends/Makefile.objs             |    2 +
 backends/hostmem.c                 |  275 +++++++++++
 backends/hostmem_compat_ram.c      |   42 ++
 default-configs/i386-softmmu.mak   |    1 +
 default-configs/x86_64-softmmu.mak |    1 +
 docs/specs/acpi_mem_hotplug.txt    |   38 ++
 hmp-commands.hx                    |   13 +
 hw/Makefile.objs                   |    1 +
 hw/acpi/core.c                     |  189 ++++++++
 hw/acpi/ich9.c                     |   57 ++-
 hw/acpi/pcihp.c                    |    6 +-
 hw/acpi/piix4.c                    |   91 +++--
 hw/i386/Makefile.objs              |    3 +-
 hw/i386/acpi-build.c               |   91 ++++-
 hw/i386/acpi-dsdt.dsl              |    5 +-
 hw/i386/pc.c                       |   90 ++++-
 hw/i386/pc_piix.c                  |    7 +-
 hw/i386/pc_q35.c                   |    4 +
 hw/i386/q35-acpi-dsdt.dsl          |    5 +-
 hw/i386/ssdt-mem.dsl               |   75 +++
 hw/i386/ssdt-mem.hex.generated     |  197 ++++++++
 hw/i386/ssdt-misc.dsl              |  179 ++++++++
 hw/i386/ssdt-misc.hex.generated    |  881 +++++++++++++++++++++++++++++++++++-
 hw/mem/Makefile.objs               |    1 +
 hw/mem/dimm.c                      |  321 +++++++++++++
 hw/pci-host/piix.c                 |   36 +-
 hw/pci-host/q35.c                  |   19 +-
 hw/pci/pci.c                       |   12 +-
 hw/pci/pcie.c                      |    7 +-
 hw/pci/shpc.c                      |    9 +-
 include/hw/acpi/acpi.h             |   42 ++
 include/hw/acpi/ich9.h             |    6 +
 include/hw/acpi/pcihp.h            |    2 +-
 include/hw/acpi/piix4.h            |    2 +
 include/hw/i386/pc.h               |   33 ++-
 include/hw/mem/dimm.h              |   99 ++++
 include/hw/pci-host/piix.h         |   29 ++
 include/hw/pci-host/q35.h          |    1 +
 include/hw/pci/pci.h               |   11 +-
 include/hw/pci/pci_bus.h           |    2 +-
 include/hw/qdev-core.h             |    9 +
 include/sysemu/hostmem.h           |  102 +++++
 include/sysemu/sysemu.h            |    3 +
 monitor.c                          |    1 +
 qapi-schema.json                   |   18 +
 qapi/string-input-visitor.c        |   18 +
 qemu-options.hx                    |   16 +-
 qmp-commands.hx                    |   27 ++
 ui/console.c                       |    3 +-
 vl.c                               |   98 ++++-
 50 files changed, 3040 insertions(+), 140 deletions(-)
 create mode 100644 backends/hostmem.c
 create mode 100644 backends/hostmem_compat_ram.c
 create mode 100644 docs/specs/acpi_mem_hotplug.txt
 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/mem/dimm.h
 create mode 100644 include/hw/pci-host/piix.h
 create mode 100644 include/sysemu/hostmem.h

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

* [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-12-05 12:37   ` Michael S. Tsirkin
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices Igor Mammedov
                   ` (26 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
perhaps this patch sholud go before "piix4: add acpi pci hotplug support"
so that there were no need in this rename in piix4_acpi_pci_hotplug()
here.

s/pm_update_sci/acpi_update_sci/
---
 hw/acpi/core.c         |   18 ++++++++++++++++++
 hw/acpi/ich9.c         |   23 ++---------------------
 hw/acpi/piix4.c        |   34 ++++++++++------------------------
 include/hw/acpi/acpi.h |    8 ++++++++
 4 files changed, 38 insertions(+), 45 deletions(-)

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 58308a3..8c0d48c 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -662,3 +662,21 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
 
     return val;
 }
+
+void acpi_update_sci(ACPIREGS *regs, qemu_irq irq, uint32_t gpe0_sts_mask)
+{
+    int sci_level, pm1a_sts;
+
+    pm1a_sts = acpi_pm1_evt_get_sts(regs);
+
+    sci_level = ((pm1a_sts &
+                  regs->pm1.evt.en & ACPI_BITMASK_PM1_COMMON_ENABLED) != 0) ||
+                ((regs->gpe.sts[0] & regs->gpe.en[0] & gpe0_sts_mask) != 0);
+
+    qemu_set_irq(irq, sci_level);
+
+    /* schedule a timer interruption if needed */
+    acpi_pm_tmr_update(regs,
+                       (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
+                       !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
+}
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 7e0429e..e59688b 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -44,29 +44,10 @@ do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0)
 #define ICH9_DEBUG(fmt, ...)    do { } while (0)
 #endif
 
-static void pm_update_sci(ICH9LPCPMRegs *pm)
-{
-    int sci_level, pm1a_sts;
-
-    pm1a_sts = acpi_pm1_evt_get_sts(&pm->acpi_regs);
-
-    sci_level = (((pm1a_sts & pm->acpi_regs.pm1.evt.en) &
-                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
-                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
-                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
-                   ACPI_BITMASK_TIMER_ENABLE)) != 0);
-    qemu_set_irq(pm->irq, sci_level);
-
-    /* schedule a timer interruption if needed */
-    acpi_pm_tmr_update(&pm->acpi_regs,
-                       (pm->acpi_regs.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
-                       !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
-}
-
 static void ich9_pm_update_sci_fn(ACPIREGS *regs)
 {
     ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs);
-    pm_update_sci(pm);
+    acpi_update_sci(&pm->acpi_regs, pm->irq, 0);
 }
 
 static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width)
@@ -193,7 +174,7 @@ static void pm_reset(void *opaque)
         pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
     }
 
-    pm_update_sci(pm);
+    acpi_update_sci(&pm->acpi_regs, pm->irq, 0);
 }
 
 static void pm_powerdown_req(Notifier *n, void *opaque)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 0be385e..b6dfa71 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -117,29 +117,11 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
 #define ACPI_ENABLE 0xf1
 #define ACPI_DISABLE 0xf0
 
-static void pm_update_sci(PIIX4PMState *s)
-{
-    int sci_level, pmsts;
-
-    pmsts = acpi_pm1_evt_get_sts(&s->ar);
-    sci_level = (((pmsts & s->ar.pm1.evt.en) &
-                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
-                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
-                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
-                   ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
-        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) &
-          (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS)) != 0);
-
-    qemu_set_irq(s->irq, sci_level);
-    /* schedule a timer interruption if needed */
-    acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
-                       !(pmsts & ACPI_BITMASK_TIMER_STATUS));
-}
-
 static void pm_tmr_timer(ACPIREGS *ar)
 {
     PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
-    pm_update_sci(s);
+    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
+                    PIIX4_CPU_HOTPLUG_STATUS);
 }
 
 static void apm_ctrl_changed(uint32_t val, void *arg)
@@ -429,7 +411,8 @@ static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev,
     }
     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
 
-    pm_update_sci(s);
+    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
+                    PIIX4_CPU_HOTPLUG_STATUS);
     return 0;
 }
 
@@ -629,7 +612,8 @@ static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
     PIIX4PMState *s = opaque;
 
     acpi_gpe_ioport_writeb(&s->ar, addr, val);
-    pm_update_sci(s);
+    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
+                    PIIX4_CPU_HOTPLUG_STATUS);
 
     PIIX4_DPRINTF("gpe write %" HWADDR_PRIx " <== %" PRIu64 "\n", addr, val);
 }
@@ -745,7 +729,8 @@ static void piix4_cpu_hotplug_req(PIIX4PMState *s, CPUState *cpu,
     } else {
         g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
     }
-    pm_update_sci(s);
+    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
+                    PIIX4_CPU_HOTPLUG_STATUS);
 }
 
 static void piix4_cpu_added_req(Notifier *n, void *opaque)
@@ -823,7 +808,8 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
         disable_device(s, slot);
     }
 
-    pm_update_sci(s);
+    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
+                    PIIX4_CPU_HOTPLUG_STATUS);
 
     return 0;
 }
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 6bbcb17..c4ae7d7 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -69,6 +69,12 @@
 #define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
 #define ACPI_BITMASK_PCIEXP_WAKE_DISABLE        0x4000	/* ACPI 3.0 */
 
+#define ACPI_BITMASK_PM1_COMMON_ENABLED         ( \
+        ACPI_BITMASK_RT_CLOCK_ENABLE        | \
+        ACPI_BITMASK_POWER_BUTTON_ENABLE    | \
+        ACPI_BITMASK_GLOBAL_LOCK_ENABLE     | \
+        ACPI_BITMASK_TIMER_ENABLE)
+
 /* PM1x_CNT */
 #define ACPI_BITMASK_SCI_ENABLE                 0x0001
 #define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
@@ -160,6 +166,8 @@ void acpi_gpe_reset(ACPIREGS *ar);
 void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
 uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
 
+void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
+
 /* acpi.c */
 extern int acpi_enabled;
 extern char unsigned *acpi_tables;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-25 12:49   ` Paolo Bonzini
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
                   ` (25 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
resolving conflict with pcihp: s/PCIHotplugState/HotplugState/
perhaps this patch should go before  pcihp patches to avoid
unnecessary code churn??
---
 hw/acpi/pcihp.c          |    6 +++---
 hw/acpi/piix4.c          |   22 ++++++++++++----------
 hw/pci/pci.c             |   12 ++++++------
 hw/pci/pcie.c            |    7 ++++---
 hw/pci/shpc.c            |    9 +++++----
 include/hw/acpi/pcihp.h  |    2 +-
 include/hw/pci/pci.h     |   11 +----------
 include/hw/pci/pci_bus.h |    2 +-
 include/hw/qdev-core.h   |    9 +++++++++
 9 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 8a0822e..04d39e9 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -195,7 +195,7 @@ static void disable_device(AcpiPciHpState *s, unsigned bsel, int slot)
 }
 
 int acpi_pcihp_device_hotplug(AcpiPciHpState *s, PCIDevice *dev,
-                              PCIHotplugState state)
+                              HotplugState state)
 {
     int slot = PCI_SLOT(dev->devfn);
     int bsel = acpi_pcihp_get_bsel(dev->bus);
@@ -206,12 +206,12 @@ int acpi_pcihp_device_hotplug(AcpiPciHpState *s, PCIDevice *dev,
     /* Don't send event when device is enabled during qemu machine creation:
      * it is present on boot, no hotplug event is necessary. We do send an
      * event when the device is disabled later. */
-    if (state == PCI_COLDPLUG_ENABLED) {
+    if (state == COLDPLUG_ENABLED) {
         s->acpi_pcihp_pci_status[bsel].device_present |= (1U << slot);
         return 0;
     }
 
-    if (state == PCI_HOTPLUG_ENABLED) {
+    if (state == HOTPLUG_ENABLED) {
         enable_device(s, bsel, slot);
     } else {
         disable_device(s, bsel, slot);
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index b6dfa71..cf42f13 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -401,11 +401,12 @@ static void piix4_pm_powerdown_req(Notifier *n, void *opaque)
     acpi_pm1_evt_power_down(&s->ar);
 }
 
-static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev,
-                                  PCIHotplugState state)
+static int piix4_acpi_pci_hotplug(DeviceState *qdev, DeviceState *dev,
+                                  HotplugState state)
 {
     PIIX4PMState *s = PIIX4_PM(qdev);
-    int ret = acpi_pcihp_device_hotplug(&s->acpi_pci_hotplug, dev, state);
+    int ret = acpi_pcihp_device_hotplug(&s->acpi_pci_hotplug, PCI_DEVICE(dev),
+                                        state);
     if (ret < 0) {
         return ret;
     }
@@ -740,8 +741,8 @@ static void piix4_cpu_added_req(Notifier *n, void *opaque)
     piix4_cpu_hotplug_req(s, CPU(opaque), PLUG);
 }
 
-static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
-                                PCIHotplugState state);
+static int piix4_device_hotplug(DeviceState *qdev, DeviceState *dev,
+                                HotplugState state);
 
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                            PCIBus *bus, PIIX4PMState *s)
@@ -788,21 +789,22 @@ static void disable_device(PIIX4PMState *s, int slot)
     s->pci0_status.down |= (1U << slot);
 }
 
-static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
-				PCIHotplugState state)
+static int piix4_device_hotplug(DeviceState *qdev, DeviceState *dev,
+                                HotplugState state)
 {
-    int slot = PCI_SLOT(dev->devfn);
+    PCIDevice *d = PCI_DEVICE(dev);
+    int slot = PCI_SLOT(d->devfn);
     PIIX4PMState *s = PIIX4_PM(qdev);
 
     /* Don't send event when device is enabled during qemu machine creation:
      * it is present on boot, no hotplug event is necessary. We do send an
      * event when the device is disabled later. */
-    if (state == PCI_COLDPLUG_ENABLED) {
+    if (state == COLDPLUG_ENABLED) {
         s->pci0_slot_device_present |= (1U << slot);
         return 0;
     }
 
-    if (state == PCI_HOTPLUG_ENABLED) {
+    if (state == HOTPLUG_ENABLED) {
         enable_device(s, slot);
     } else {
         disable_device(s, slot);
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 31165cf..0713a1b 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -346,7 +346,7 @@ void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
     bus->irq_count = g_malloc0(nirq * sizeof(bus->irq_count[0]));
 }
 
-void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *qdev)
+void pci_bus_hotplug(PCIBus *bus, hotplug_fn hotplug, DeviceState *qdev)
 {
     bus->qbus.allow_hotplug = 1;
     bus->hotplug = hotplug;
@@ -1779,9 +1779,9 @@ static int pci_qdev_init(DeviceState *qdev)
     if (bus->hotplug) {
         /* Let buses differentiate between hotplug and when device is
          * enabled during qemu machine creation. */
-        rc = bus->hotplug(bus->hotplug_qdev, pci_dev,
-                          qdev->hotplugged ? PCI_HOTPLUG_ENABLED:
-                          PCI_COLDPLUG_ENABLED);
+        rc = bus->hotplug(bus->hotplug_qdev, DEVICE(pci_dev),
+                          qdev->hotplugged ? HOTPLUG_ENABLED :
+                          COLDPLUG_ENABLED);
         if (rc != 0) {
             int r = pci_unregister_device(&pci_dev->qdev);
             assert(!r);
@@ -1800,8 +1800,8 @@ static int pci_unplug_device(DeviceState *qdev)
         qerror_report(QERR_DEVICE_NO_HOTPLUG, object_get_typename(OBJECT(dev)));
         return -1;
     }
-    return dev->bus->hotplug(dev->bus->hotplug_qdev, dev,
-                             PCI_HOTPLUG_DISABLED);
+    return dev->bus->hotplug(dev->bus->hotplug_qdev, qdev,
+                             HOTPLUG_DISABLED);
 }
 
 PCIDevice *pci_create_multifunction(PCIBus *bus, int devfn, bool multifunction,
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index ca60cf2..64500c1 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -217,16 +217,17 @@ static void pcie_cap_slot_event(PCIDevice *dev, PCIExpressHotPlugEvent event)
 }
 
 static int pcie_cap_slot_hotplug(DeviceState *qdev,
-                                 PCIDevice *pci_dev, PCIHotplugState state)
+                                 DeviceState *dev, HotplugState state)
 {
     PCIDevice *d = PCI_DEVICE(qdev);
+    PCIDevice *pci_dev = PCI_DEVICE(dev);
     uint8_t *exp_cap = d->config + d->exp.exp_cap;
     uint16_t sltsta = pci_get_word(exp_cap + PCI_EXP_SLTSTA);
 
     /* Don't send event when device is enabled during qemu machine creation:
      * it is present on boot, no hotplug event is necessary. We do send an
      * event when the device is disabled later. */
-    if (state == PCI_COLDPLUG_ENABLED) {
+    if (state == COLDPLUG_ENABLED) {
         pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
                                    PCI_EXP_SLTSTA_PDS);
         return 0;
@@ -246,7 +247,7 @@ static int pcie_cap_slot_hotplug(DeviceState *qdev,
      */
     assert(PCI_FUNC(pci_dev->devfn) == 0);
 
-    if (state == PCI_HOTPLUG_ENABLED) {
+    if (state == HOTPLUG_ENABLED) {
         pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,
                                    PCI_EXP_SLTSTA_PDS);
         pcie_cap_slot_event(d, PCI_EXP_HP_EV_PDC);
diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
index 576244b..e7efe63 100644
--- a/hw/pci/shpc.c
+++ b/hw/pci/shpc.c
@@ -491,9 +491,10 @@ static const MemoryRegionOps shpc_mmio_ops = {
     },
 };
 
-static int shpc_device_hotplug(DeviceState *qdev, PCIDevice *affected_dev,
-                               PCIHotplugState hotplug_state)
+static int shpc_device_hotplug(DeviceState *qdev, DeviceState *dev,
+                               HotplugState hotplug_state)
 {
+    PCIDevice *affected_dev = PCI_DEVICE(dev);
     int pci_slot = PCI_SLOT(affected_dev->devfn);
     uint8_t state;
     uint8_t led;
@@ -510,13 +511,13 @@ static int shpc_device_hotplug(DeviceState *qdev, PCIDevice *affected_dev,
     /* Don't send event when device is enabled during qemu machine creation:
      * it is present on boot, no hotplug event is necessary. We do send an
      * event when the device is disabled later. */
-    if (hotplug_state == PCI_COLDPLUG_ENABLED) {
+    if (hotplug_state == COLDPLUG_ENABLED) {
         shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_MRL_OPEN);
         shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_7_5W,
                         SHPC_SLOT_STATUS_PRSNT_MASK);
         return 0;
     }
-    if (hotplug_state == PCI_HOTPLUG_DISABLED) {
+    if (hotplug_state == HOTPLUG_DISABLED) {
         shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |= SHPC_SLOT_EVENT_BUTTON;
         state = shpc_get_status(shpc, slot, SHPC_SLOT_STATE_MASK);
         led = shpc_get_status(shpc, slot, SHPC_SLOT_PWR_LED_MASK);
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 6230e60..aa16bff 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -53,7 +53,7 @@ void acpi_pcihp_init(AcpiPciHpState *, PCIBus *root,
 
 /* Invoke on device hotplug */
 int acpi_pcihp_device_hotplug(AcpiPciHpState *, PCIDevice *,
-                              PCIHotplugState state);
+                              HotplugState state);
 
 /* Called on reset */
 void acpi_pcihp_reset(AcpiPciHpState *s);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 81fdddc..0eb89be 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -330,15 +330,6 @@ typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
 typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
 
-typedef enum {
-    PCI_HOTPLUG_DISABLED,
-    PCI_HOTPLUG_ENABLED,
-    PCI_COLDPLUG_ENABLED,
-} PCIHotplugState;
-
-typedef int (*pci_hotplug_fn)(DeviceState *qdev, PCIDevice *pci_dev,
-                              PCIHotplugState state);
-
 #define TYPE_PCI_BUS "PCI"
 #define PCI_BUS(obj) OBJECT_CHECK(PCIBus, (obj), TYPE_PCI_BUS)
 #define TYPE_PCIE_BUS "PCIE"
@@ -357,7 +348,7 @@ PCIBus *pci_bus_new(DeviceState *parent, const char *name,
 void pci_bus_irqs(PCIBus *bus, pci_set_irq_fn set_irq, pci_map_irq_fn map_irq,
                   void *irq_opaque, int nirq);
 int pci_bus_get_irq_level(PCIBus *bus, int irq_num);
-void pci_bus_hotplug(PCIBus *bus, pci_hotplug_fn hotplug, DeviceState *dev);
+void pci_bus_hotplug(PCIBus *bus, hotplug_fn hotplug, DeviceState *dev);
 /* 0 <= pin <= 3 0 = INTA, 1 = INTB, 2 = INTC, 3 = INTD */
 int pci_swizzle_map_irq_fn(PCIDevice *pci_dev, int pin);
 PCIBus *pci_register_bus(DeviceState *parent, const char *name,
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 9df1788..ac5eb6a 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -16,7 +16,7 @@ struct PCIBus {
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
     pci_route_irq_fn route_intx_to_irq;
-    pci_hotplug_fn hotplug;
+    hotplug_fn hotplug;
     DeviceState *hotplug_qdev;
     void *irq_opaque;
     PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX];
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index f2043a6..1eb2028 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -307,4 +307,13 @@ extern int qdev_hotplug;
 
 char *qdev_get_dev_path(DeviceState *dev);
 
+typedef enum {
+    HOTPLUG_DISABLED,
+    HOTPLUG_ENABLED,
+    COLDPLUG_ENABLED,
+} HotplugState;
+
+typedef int (*hotplug_fn)(DeviceState *hotplug_dev, DeviceState *dev,
+                          HotplugState state);
+
 #endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-12-19 14:35   ` Michael S. Tsirkin
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Igor Mammedov
                   ` (24 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, 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>
---
v2:
   * disable 'etc/reserved-memory-end' for 1.7 and older machine types
---
 hw/i386/pc.c         |   27 +++++++++++++++++++++++++--
 hw/i386/pc_piix.c    |    1 +
 hw/i386/pc_q35.c     |    1 +
 hw/pci-host/piix.c   |    3 ++-
 hw/pci-host/q35.c    |    3 ++-
 include/hw/i386/pc.h |   11 +++++++++--
 6 files changed, 40 insertions(+), 6 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 6c82ada..ba82c67 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1094,14 +1094,37 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
 }
 
 /* setup pci memory address space mapping into system address space */
-void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
-                            MemoryRegion *pci_address_space)
+void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
+                                MemoryRegion *pci_address_space,
+                                uint64_t reserved_memory_end)
 {
     /* Set to lower priority than RAM */
     memory_region_add_subregion_overlap(system_memory, 0x0,
                                         pci_address_space, -1);
 }
 
+static
+void pc_pci_as_mapping_init_1_8(Object *owner, MemoryRegion *system_memory,
+                                MemoryRegion *pci_address_space,
+                                uint64_t reserved_memory_end)
+{
+    uint64_t *val;
+    FWCfgState *fw_cfg = fw_cfg_find();
+    g_assert(fw_cfg);
+    /*
+     *  Align address at 1G, this makes sure it can be exactly covered
+     *  with a PAT entry even when using huge pages.
+     */
+    val = g_malloc(sizeof(*val));
+    *val = cpu_to_le64(ROUND_UP(reserved_memory_end, 0x1ULL << 30));
+    fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
+
+    pc_pci_as_mapping_init_1_7(owner, system_memory, pci_address_space,
+                               reserved_memory_end);
+}
+
+pc_pci_as_mapping_init_fn pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_8;
+
 void pc_acpi_init(const char *default_dsdt)
 {
     char *filename;
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 36f2495..e1fe85a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -249,6 +249,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
 static void pc_compat_1_7(QEMUMachineInitArgs *args)
 {
     smbios_type1_defaults = false;
+    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
 }
 
 static void pc_compat_1_6(QEMUMachineInitArgs *args)
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 50ca458..5525465 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -233,6 +233,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 static void pc_compat_1_7(QEMUMachineInitArgs *args)
 {
     smbios_type1_defaults = false;
+    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
 }
 
 static void pc_compat_1_6(QEMUMachineInitArgs *args)
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 63be7f6..615ab0d 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -352,7 +352,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
 
     /* setup pci memory mapping */
     pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
-                           f->pci_address_space);
+                           f->pci_address_space,
+                           0x100000000ULL + above_4g_mem_size);
 
     memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
                              f->pci_address_space, 0xa0000, 0x20000);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 81c8240..6e28418 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -359,7 +359,8 @@ static int mch_init(PCIDevice *d)
 
     /* setup pci memory mapping */
     pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
-                           mch->pci_address_space);
+                           mch->pci_address_space,
+                           0x100000000ULL + mch->above_4g_mem_size);
 
     /* smram */
     cpu_smm_register(&mch_set_smm, mch);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 9af09d3..c4e8048 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -129,8 +129,15 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
 #define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
 
 
-void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
-                            MemoryRegion *pci_address_space);
+typedef
+void (*pc_pci_as_mapping_init_fn)(Object *owner, MemoryRegion *system_memory,
+                                  MemoryRegion *pci_address_space,
+                                  uint64_t reserved_memory_end);
+extern pc_pci_as_mapping_init_fn pc_pci_as_mapping_init;
+
+void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
+                                MemoryRegion *pci_address_space,
+                                uint64_t reserved_memory_end);
 
 FWCfgState *pc_memory_init(MemoryRegion *system_memory,
                            const char *kernel_filename,
-- 
1.7.1

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

* [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (2 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  6:01   ` Li Guang
                     ` (2 more replies)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor Igor Mammedov
                   ` (23 subsequent siblings)
  27 siblings, 3 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Along with conversion extend -m option to support following parameters:
  "mem" - startup memory amount
  "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 usable.

v2:
  make sure maxmem is not less than ram size

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 qemu-options.hx |    9 +++++-
 vl.c            |   73 ++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 68 insertions(+), 14 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 8b94264..fe4559b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -210,8 +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 [mem=]megs[,slots=n,maxmem=size]\n"
+    "                set virtual RAM size to megs MB [default="
+    stringify(DEFAULT_RAM_SIZE) "]\n"
+    "                mem=start-up memory amount\n"
+    "                slots=maximum number of hotplug slots\n"
+    "                maxmem=maximum total amount of memory\n",
+    QEMU_ARCH_ALL)
 STEXI
 @item -m @var{megs}
 @findex -m
diff --git a/vl.c b/vl.c
index f28674f..5974f0f 100644
--- a/vl.c
+++ b/vl.c
@@ -529,6 +529,28 @@ static QemuOptsList qemu_msg_opts = {
     },
 };
 
+static QemuOptsList qemu_mem_opts = {
+    .name = "memory-opts",
+    .implied_opt_name = "mem",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
+    .merge_lists = true,
+    .desc = {
+        {
+            .name = "mem",
+            .type = QEMU_OPT_SIZE,
+        },
+        {
+            .name = "slots",
+            .type = QEMU_OPT_NUMBER,
+        },
+        {
+            .name = "maxmem",
+            .type = QEMU_OPT_SIZE,
+        },
+        { /* end of list */ }
+    },
+};
+
 /**
  * Get machine options
  *
@@ -2816,6 +2838,14 @@ static int object_create(QemuOpts *opts, void *opaque)
     return 0;
 }
 
+static void qemu_init_default_mem_opts(uint64_t size)
+{
+    QemuOpts *opts = qemu_opts_create_nofail(&qemu_mem_opts);
+    qemu_opt_set_number(opts, "mem", size);
+    qemu_opt_set_number(opts, "maxmem", size);
+    qemu_opt_set_number(opts, "slots", 0);
+}
+
 int main(int argc, char **argv, char **envp)
 {
     int i;
@@ -2887,6 +2917,7 @@ int main(int argc, char **argv, char **envp)
     qemu_add_opts(&qemu_tpmdev_opts);
     qemu_add_opts(&qemu_realtime_opts);
     qemu_add_opts(&qemu_msg_opts);
+    qemu_add_opts(&qemu_mem_opts);
 
     runstate_init();
 
@@ -2901,7 +2932,8 @@ int main(int argc, char **argv, char **envp)
     module_call_init(MODULE_INIT_MACHINE);
     machine = find_default_machine();
     cpu_model = NULL;
-    ram_size = 0;
+    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
+    qemu_init_default_mem_opts(ram_size);
     snapshot = 0;
     cyls = heads = secs = 0;
     translation = BIOS_ATA_TRANSLATION_AUTO;
@@ -3178,21 +3210,43 @@ 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 *end;
+                char *s;
 
-                value = strtosz(optarg, &end);
-                if (value < 0 || *end) {
-                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
+                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
+                                       optarg, 1);
+                if (!opts) {
                     exit(1);
                 }
-                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+
+                /* fixup legacy sugffix-less format */
+                end = qemu_opt_get(opts, "mem");
+                if (g_ascii_isdigit(end[strlen(end) - 1])) {
+                    s = g_strconcat(end, "M", NULL);
+                    qemu_opt_set(opts, "mem", s);
+                    g_free(s);
+                }
+
+                sz = QEMU_ALIGN_UP(qemu_opt_get_size(opts, "mem", ram_size),
+                                   8192);
+                /* compatibility behaviour for case "-m 0" */
+                if (sz == 0) {
+                    sz = DEFAULT_RAM_SIZE * 1024 * 1024;
+                }
+
                 ram_size = sz;
                 if (ram_size != sz) {
                     fprintf(stderr, "qemu: ram size too large\n");
                     exit(1);
                 }
+                /* store aligned value for future use */
+                qemu_opt_set_number(opts, "mem", ram_size);
+
+                sz = qemu_opt_get_size(opts, "maxmem", ram_size);
+                if (sz < ram_size) {
+                    qemu_opt_set_number(opts, "maxmem", ram_size);
+                }
                 break;
             }
 #ifdef CONFIG_TPM
@@ -4029,11 +4083,6 @@ int main(int argc, char **argv, char **envp)
         exit(1);
     }
 
-    /* init the memory */
-    if (ram_size == 0) {
-        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
-    }
-
     if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
         != 0) {
         exit(0);
-- 
1.7.1

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

* [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (3 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21 10:15   ` Markus Armbruster
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 06/27] get reference to /backend container via qemu_get_backend() Igor Mammedov
                   ` (22 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 qapi/string-input-visitor.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 8f1bc41..a152f5d 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -97,6 +97,23 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
     *obj = val;
 }
 
+static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
+                            Error **errp)
+{
+    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
+    int64_t val;
+    char *endp;
+
+    val = strtosz_suffix(siv->string ? siv->string : "", &endp,
+                         STRTOSZ_DEFSUFFIX_B);
+    if (val < 0 || *endp != '\0') {
+        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name,
+                  "a size value representible as a non-negative int64");
+        return;
+    }
+    *obj = val;
+}
+
 static void parse_start_optional(Visitor *v, bool *present,
                                  const char *name, Error **errp)
 {
@@ -131,6 +148,7 @@ StringInputVisitor *string_input_visitor_new(const char *str)
     v->visitor.type_bool = parse_type_bool;
     v->visitor.type_str = parse_type_str;
     v->visitor.type_number = parse_type_number;
+    v->visitor.type_size = parse_type_size;
     v->visitor.start_optional = parse_start_optional;
 
     v->string = str;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 06/27] get reference to /backend container via qemu_get_backend()
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (4 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure Igor Mammedov
                   ` (21 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

... API, so it could be reused later using qemu_get_backend()
without duplicating "/backend" everywhere.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 include/sysemu/sysemu.h |    3 +++
 ui/console.c            |    3 ++-
 vl.c                    |   11 +++++++++++
 3 files changed, 16 insertions(+), 1 deletions(-)

diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index cd5791e..2a71293 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -9,6 +9,7 @@
 #include "qapi-types.h"
 #include "qemu/notify.h"
 #include "qemu/main-loop.h"
+#include "qom/object.h"
 
 /* vl.c */
 
@@ -87,6 +88,8 @@ void qemu_savevm_state_cancel(void);
 uint64_t qemu_savevm_state_pending(QEMUFile *f, uint64_t max_size);
 int qemu_loadvm_state(QEMUFile *f);
 
+Object *qemu_get_backend(void);
+
 /* SLIRP */
 void do_info_slirp(Monitor *mon);
 
diff --git a/ui/console.c b/ui/console.c
index aad4fc9..868d5a1 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -27,6 +27,7 @@
 #include "qemu/timer.h"
 #include "qmp-commands.h"
 #include "sysemu/char.h"
+#include "sysemu/sysemu.h"
 
 //#define DEBUG_CONSOLE
 #define DEFAULT_BACKSCROLL 512
@@ -1598,7 +1599,7 @@ DisplayState *init_displaystate(void)
          * all QemuConsoles are created and the order / numbering
          * doesn't change any more */
         name = g_strdup_printf("console[%d]", i);
-        object_property_add_child(container_get(object_get_root(), "/backend"),
+        object_property_add_child(qemu_get_backend(),
                                   name, OBJECT(consoles[i]), &local_err);
         g_free(name);
     }
diff --git a/vl.c b/vl.c
index 5974f0f..1de3d57 100644
--- a/vl.c
+++ b/vl.c
@@ -2846,6 +2846,17 @@ static void qemu_init_default_mem_opts(uint64_t size)
     qemu_opt_set_number(opts, "slots", 0);
 }
 
+Object *qemu_get_backend(void)
+{
+    static Object *obj;
+
+    if (obj == NULL) {
+        obj = container_get(object_get_root(), "/backend");
+    }
+
+    return obj;
+}
+
 int main(int argc, char **argv, char **envp)
 {
     int i;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (5 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 06/27] get reference to /backend container via qemu_get_backend() Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-25 12:54   ` Paolo Bonzini
  2013-11-27 15:25   ` Eric Blake
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction Igor Mammedov
                   ` (20 subsequent siblings)
  27 siblings, 2 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Provides framework for splitting host RAM allocation/
policies into a separate backend that could be used
by devices. It would allow to separate host specific
options from device model like it's done for netdev & co.

It adds new:
   -memdev CLI option and corresponding memdev-add
    QMP/HMP commands.

Upon successful command execution an new memdev object
is added to QOM tree into "/backend/memdev" container.

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

memdev object is intendend for usage with Dimm device,
example:
 -memdev id=m1,size=1G -device dimm,id=dimm1,memdev=m1

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 backends/Makefile.objs        |    2 +
 backends/hostmem.c            |  275 +++++++++++++++++++++++++++++++++++++++++
 backends/hostmem_compat_ram.c |   42 ++++++
 hmp-commands.hx               |   13 ++
 include/sysemu/hostmem.h      |  102 +++++++++++++++
 monitor.c                     |    1 +
 qapi-schema.json              |   18 +++
 qemu-options.hx               |    7 +
 qmp-commands.hx               |   27 ++++
 vl.c                          |   14 ++
 10 files changed, 501 insertions(+), 0 deletions(-)
 create mode 100644 backends/hostmem.c
 create mode 100644 backends/hostmem_compat_ram.c
 create mode 100644 include/sysemu/hostmem.h

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 42557d5..01c4476 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_compat_ram.o
diff --git a/backends/hostmem.c b/backends/hostmem.c
new file mode 100644
index 0000000..9948b63
--- /dev/null
+++ b/backends/hostmem.c
@@ -0,0 +1,275 @@
+/*
+ * 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"
+
+QemuOptsList qemu_memdev_opts = {
+    .name = "memdev",
+    .implied_opt_name = "type",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_memdev_opts.head),
+    .desc = {
+        { /* end of list */ }
+    },
+};
+
+static int set_object_prop(const char *name, const char *value, void *opaque)
+{
+    Error *local_err = NULL;
+    Object *obj = OBJECT(opaque);
+
+    object_property_parse(obj, value, name, &local_err);
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+void memdev_add(QemuOpts *opts, Error **errp)
+{
+    Error *local_err = NULL;
+    HostMemoryBackendClass *bc;
+    Object *obj = NULL;
+    ObjectClass *oc;
+    const char *type;
+
+    type = qemu_opt_get(opts, "type");
+    if (!type) {
+        type = TYPE_COMPAT_RAM_MEMORY_BACKEND;
+    }
+
+    oc = object_class_by_name(type);
+    if (!oc) {
+        error_setg(&local_err, "Unknown memdev type: %s", type);
+        goto out;
+    }
+    if (object_class_is_abstract(oc)) {
+        error_setg(&local_err, "Can't create abstract memdev type: %s", type);
+        goto out;
+    }
+
+    obj = object_new(type);
+    if (!object_dynamic_cast(obj, TYPE_MEMORY_BACKEND)) {
+        error_setg(&local_err, "Invalid memdev type: %s", type);
+        goto out;
+    }
+
+    if (qemu_opt_foreach(opts, set_object_prop, obj, true)) {
+        error_setg(&local_err, "failed to create memdev");
+        goto out;
+    }
+    object_property_parse(obj, qemu_opts_id(opts), "id", &local_err);
+    if (error_is_set(&local_err)) {
+        goto out;
+    }
+
+    /* verify properties correctnes and initialize backend */
+    bc = MEMORY_BACKEND_GET_CLASS(obj);
+    if (bc->get_memory) {
+        HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+        if (!bc->get_memory(backend, &local_err)) {
+            goto out;
+        }
+    }
+
+    /* make backend available to the world via QOM tree */
+    object_property_add_child(container_get(qemu_get_backend(), "/memdev"),
+                              qemu_opts_id(opts), obj, &local_err);
+
+out:
+    if (error_is_set(&local_err)) {
+        error_propagate(errp, local_err);
+        if (obj) {
+            object_unref(obj);
+        }
+    }
+}
+
+int qmp_memdev_add(Monitor *mon, const QDict *qdict, QObject **ret)
+{
+    Error *local_err = NULL;
+    QemuOptsList *opts_list;
+    QemuOpts *opts = NULL;
+
+    opts_list = qemu_find_opts_err("memdev", &local_err);
+    if (error_is_set(&local_err)) {
+        goto out;
+    }
+
+    opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
+    if (error_is_set(&local_err)) {
+        goto out;
+    }
+
+    memdev_add(opts, &local_err);
+
+out:
+    if (opts) {
+        qemu_opts_del(opts);
+    }
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+    return 0;
+}
+
+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;
+
+    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_get_id(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+
+    visit_type_str(v, &backend->id, name, errp);
+}
+
+static void
+hostmemory_backend_set_id(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    HostMemoryBackend *backend = MEMORY_BACKEND(obj);
+    Error *local_err = NULL;
+    Object *dup_obj;
+    char *str;
+
+    visit_type_str(v, &str, name, &local_err);
+    if (local_err) {
+        error_propagate(errp, local_err);
+        return;
+    }
+
+    dup_obj = object_resolve_path(str, NULL);
+    if (dup_obj) {
+        error_setg(errp, "Duplicate property [%s.%s] value: '%s'",
+                   object_get_typename(obj), name, str);
+        error_propagate(errp, local_err);
+        g_free(str);
+        return;
+    }
+
+    if (backend->id) {
+        g_free(backend->id);
+    }
+    backend->id = str;
+}
+
+static void hostmemory_backend_initfn(Object *obj)
+{
+    object_property_add(obj, "id", "string",
+                        hostmemory_backend_get_id,
+                        hostmemory_backend_set_id, NULL, NULL, NULL);
+    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);
+
+    g_free(backend->id);
+    if (memory_region_size(&backend->mr)) {
+        memory_region_destroy(&backend->mr);
+    }
+}
+
+static void
+hostmemory_backend_memory_init(HostMemoryBackend *backend, Error **errp)
+{
+    error_setg(errp, "memory_init is not implemented for type [%s]",
+               object_get_typename(OBJECT(backend)));
+}
+
+static MemoryRegion *
+hostmemory_backend_get_memory(HostMemoryBackend *backend, Error **errp)
+{
+    HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(backend);
+    Object *obj = OBJECT(backend);
+    char *id = backend->id;
+
+    if (!id || (*id == '\0')) {
+        error_setg(errp, "Invalid property [%s.id] value: '%s'",
+                   object_get_typename(obj), id ? id : "");
+        return NULL;
+    }
+
+    if (!backend->size) {
+        error_setg(errp, "Invalid property [%s.size] value: %" PRIu64,
+                   object_get_typename(obj), backend->size);
+        return NULL;
+    }
+
+    bc->memory_init(backend, errp);
+
+    return memory_region_size(&backend->mr) ? &backend->mr : NULL;
+}
+
+static void
+hostmemory_backend_class_init(ObjectClass *oc, void *data)
+{
+    HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
+
+    bc->memory_init = hostmemory_backend_memory_init;
+    bc->get_memory = hostmemory_backend_get_memory;
+}
+
+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,
+};
+
+static void register_types(void)
+{
+    type_register_static(&hostmemory_backend_info);
+}
+
+type_init(register_types);
diff --git a/backends/hostmem_compat_ram.c b/backends/hostmem_compat_ram.c
new file mode 100644
index 0000000..af1bbe0
--- /dev/null
+++ b/backends/hostmem_compat_ram.c
@@ -0,0 +1,42 @@
+/*
+ * 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"
+
+static void
+compat_ram_backend_memory_init(HostMemoryBackend *backend, Error **errp)
+{
+    if (!memory_region_size(&backend->mr)) {
+        memory_region_init_ram(&backend->mr, OBJECT(backend),
+                               backend->id, backend->size);
+    }
+}
+
+static void
+compat_ram_backend_class_init(ObjectClass *oc, void *data)
+{
+    HostMemoryBackendClass *bc = MEMORY_BACKEND_CLASS(oc);
+
+    bc->memory_init = compat_ram_backend_memory_init;
+}
+
+static const TypeInfo compat_ram_backend_info = {
+    .name = TYPE_COMPAT_RAM_MEMORY_BACKEND,
+    .parent = TYPE_MEMORY_BACKEND,
+    .class_init = compat_ram_backend_class_init,
+};
+
+static void register_types(void)
+{
+    type_register_static(&compat_ram_backend_info);
+}
+
+type_init(register_types);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index caae5ad..4f35ffa 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1719,3 +1719,16 @@ ETEXI
 STEXI
 @end table
 ETEXI
+
+    {
+        .name       = "memdev-add",
+        .args_type  = "memdev:O",
+        .params     = "id size",
+        .help       = "add host memory",
+        .mhandler.cmd_new = qmp_memdev_add,
+    },
+
+STEXI
+@item memdev-add
+@findex memdev-add
+Add host memory.
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
new file mode 100644
index 0000000..7437712
--- /dev/null
+++ b/include/sysemu/hostmem.h
@@ -0,0 +1,102 @@
+/*
+ * 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 "host-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
+ * @memory_init: hook for derived classes to perform memory allocation
+ * @get_memory: get #MemoryRegion backed by @backend and link @backend
+ *   with user @uobj to prevent backend disapearing while @uobj exists.
+ *   @uobj must have "backend" link property or @get_memory will fail.
+ *   retuns: pointer to intialized #MemoryRegion on success or
+ *           NULL on failure with error set in errp
+ *
+ */
+struct HostMemoryBackendClass {
+    ObjectClass parent_class;
+
+    void (*memory_init)(HostMemoryBackend *backend, Error **errp);
+    MemoryRegion* (*get_memory)(HostMemoryBackend *backend, Error **errp);
+};
+
+/**
+ * @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 */
+    char *id;
+    uint64_t size;
+
+    MemoryRegion mr;
+};
+
+extern QemuOptsList qemu_memdev_opts;
+
+/**
+ * @qmp_memdev_add:
+ *   QMP/HMP memdev-add command handler
+ * returns 0 on success or -1 on failure
+ */
+int qmp_memdev_add(Monitor *mon, const QDict *qdict, QObject **ret);
+
+/**
+ * @memdev_add:
+ *   CLI "-memdev" option parser
+ * @opts: options for accossiated with -memdev
+ * @errp: returns an error if this function fails
+ */
+void memdev_add(QemuOpts *opts, Error **errp);
+
+/**
+ * @memdev_name:
+ * @id: backend identification string
+ *
+ * returns backend name in format "memdev[id]",
+ * caller is responsible for freeing returned value.
+ */
+char *memdev_name(const char *id);
+
+/* hostmem_compat_ram.c */
+/**
+ * @TYPE_COMPAT_RAM_MEMORY_BACKEND:
+ * name of backend that uses legacy RAM allocation methods
+ * implemented by #memory_region_init_ram
+ */
+#define TYPE_COMPAT_RAM_MEMORY_BACKEND "compat-ram-host-memory"
+
+#endif
diff --git a/monitor.c b/monitor.c
index 845f608..39b4d8b 100644
--- a/monitor.c
+++ b/monitor.c
@@ -67,6 +67,7 @@
 #include "qmp-commands.h"
 #include "hmp.h"
 #include "qemu/thread.h"
+#include "sysemu/hostmem.h"
 
 /* for pic/irq_info */
 #if defined(TARGET_SPARC)
diff --git a/qapi-schema.json b/qapi-schema.json
index 76c98a7..c1a20d2 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -4212,3 +4212,21 @@
 # Since: 1.7
 ##
 { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
+
+##
+# @memdev_add:
+#
+# Add a host memory backend.
+#
+# @id: the name of the new memory backend
+# @size: amount of memory backend should allocate
+# @type: backend type. [default: compat-ram-host-memory]
+#
+# Since: 1.8
+#
+# Returns: Nothing on success
+##
+{ 'command': 'memdev-add',
+  'data': {'id': 'str', 'size': 'size', '*type': 'str'},
+  'gen': 'no'
+}
diff --git a/qemu-options.hx b/qemu-options.hx
index fe4559b..314b731 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3125,3 +3125,10 @@ HXCOMM This is the last statement. Insert new options before this line!
 STEXI
 @end table
 ETEXI
+
+DEF("memdev", HAS_ARG, QEMU_OPTION_memdev,
+    "-memdev [backend-type,]id=str,size=value\n"
+    "                add host memory\n"
+    "                default backend-type: compat-ram-host-memory\n",
+    QEMU_ARCH_ALL)
+STEXI
diff --git a/qmp-commands.hx b/qmp-commands.hx
index fba15cd..f2a8998 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3291,7 +3291,34 @@ Example (2):
          }
        }
      }
+<- { "return": {} }
+
+EQMP
+
+    {
+        .name       = "memdev-add",
+        .args_type  = "memdev:O",
+        .mhandler.cmd_new = qmp_memdev_add,
+    },
+
+SQMP
+memdev-add
+----------
+
+Add host memory.
+
+Arguments:
+
+- "id": the device's ID, must be unique (json-string)
+- "size": amount of memory backend should allocate (json-int)
+- "type": backend type (json-string, optional), default: compat-ram-host-memory
+
+Example:
 
+-> { "execute": "memdev-add",
+     "arguments": { "id": "memdev1",
+                    "size": "1G",
+                    "type": "compat-ram-host-memory" } }
 <- { "return": {} }
 
 EQMP
diff --git a/vl.c b/vl.c
index 1de3d57..2e3a5a5 100644
--- a/vl.c
+++ b/vl.c
@@ -170,6 +170,7 @@ int main(int argc, char **argv)
 
 #include "ui/qemu-spice.h"
 #include "qapi/string-input-visitor.h"
+#include "sysemu/hostmem.h"
 
 //#define DEBUG_NET
 //#define DEBUG_SLIRP
@@ -2929,6 +2930,7 @@ int main(int argc, char **argv, char **envp)
     qemu_add_opts(&qemu_realtime_opts);
     qemu_add_opts(&qemu_msg_opts);
     qemu_add_opts(&qemu_mem_opts);
+    qemu_add_opts(&qemu_memdev_opts);
 
     runstate_init();
 
@@ -3859,6 +3861,18 @@ int main(int argc, char **argv, char **envp)
                 }
                 configure_msg(opts);
                 break;
+            case QEMU_OPTION_memdev:
+                {
+                    Error *local_err = NULL;
+                    opts = qemu_opts_parse(qemu_find_opts("memdev"), optarg, 1);
+                    memdev_add(opts, &local_err);
+                    if (error_is_set(&local_err)) {
+                        qerror_report_err(local_err);
+                        error_free(local_err);
+                        exit(1);
+                    }
+                    break;
+                }
             default:
                 os_parse_cmd_args(popt->index, optarg);
             }
-- 
1.7.1

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

* [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (6 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-25 12:57   ` Paolo Bonzini
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 09/27] dimm: map DimmDevice into DimBus provided address space Igor Mammedov
                   ` (19 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

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

Each hotplug-able memory slot is a DimmDevice. All DimmDevices are
attached to a new bus called DimmBus.

A hot-add operation for a DIMM:
- creates a new DimmDevice and attaches it to the DimmBus

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 target.

To simplify review, patch introduces only DimmDevice and DimmBus basic
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>
---
v3:
  pc: compile memhotplug on i386 target too
v2:
  fix typo s/DimmBus/DimmDevice/ in doc comment
  s/klass/oc/;s/*/parent_obj/;a/gtk-doc markup/

dimm impl
---
 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                      |  176 ++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h              |   71 +++++++++++++++
 6 files changed, 251 insertions(+), 0 deletions(-)
 create mode 100644 hw/mem/Makefile.objs
 create mode 100644 hw/mem/dimm.c
 create mode 100644 include/hw/mem/dimm.h

diff --git a/default-configs/i386-softmmu.mak b/default-configs/i386-softmmu.mak
index 37ef90f..8e08841 100644
--- a/default-configs/i386-softmmu.mak
+++ b/default-configs/i386-softmmu.mak
@@ -44,3 +44,4 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_ICC_BUS=y
 CONFIG_PVPANIC=y
+CONFIG_MEM_HOTPLUG=y
diff --git a/default-configs/x86_64-softmmu.mak b/default-configs/x86_64-softmmu.mak
index 31bddce..66557ac 100644
--- a/default-configs/x86_64-softmmu.mak
+++ b/default-configs/x86_64-softmmu.mak
@@ -44,3 +44,4 @@ CONFIG_APIC=y
 CONFIG_IOAPIC=y
 CONFIG_ICC_BUS=y
 CONFIG_PVPANIC=y
+CONFIG_MEM_HOTPLUG=y
diff --git a/hw/Makefile.objs b/hw/Makefile.objs
index d91b9cc..0c23b57 100644
--- a/hw/Makefile.objs
+++ b/hw/Makefile.objs
@@ -28,6 +28,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..fe81226
--- /dev/null
+++ b/hw/mem/dimm.c
@@ -0,0 +1,176 @@
+/*
+ * Dimm device for Memory Hotplug
+ *
+ * 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/>
+ */
+
+#include "hw/mem/dimm.h"
+#include "qemu/config-file.h"
+#include "qapi/visitor.h"
+
+static void dimm_bus_initfn(Object *obj)
+{
+    BusState *b = BUS(obj);
+
+    b->allow_hotplug = true;
+}
+static void dimm_bus_class_init(ObjectClass *oc, void *data)
+{
+    BusClass *bc = BUS_CLASS(oc);
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
+
+    bc->max_dev = qemu_opt_get_number(opts, "slots", 0);
+}
+
+static const TypeInfo dimm_bus_info = {
+    .name = TYPE_DIMM_BUS,
+    .parent = TYPE_BUS,
+    .instance_init = dimm_bus_initfn,
+    .instance_size = sizeof(DimmBus),
+    .class_init = dimm_bus_class_init,
+};
+
+static Property dimm_properties[] = {
+    DEFINE_PROP_UINT64("start", DimmDevice, start, 0),
+    DEFINE_PROP_UINT32("node", DimmDevice, node, 0),
+    DEFINE_PROP_INT32("slot", DimmDevice, slot, 0),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void dimm_set_memdev(Object *obj, Visitor *v, void *opaque,
+                            const char *name, Error **errp)
+{
+    HostMemoryBackendClass *backend_cls;
+    DimmDevice *dimm = DIMM(obj);
+    MemoryRegion *mr;
+    Object *memdev;
+    char *str;
+
+    visit_type_str(v, &str, name, errp);
+    if (error_is_set(errp)) {
+        return;
+    }
+
+    memdev = object_resolve_path_type(str, TYPE_MEMORY_BACKEND, NULL);
+    if (!memdev) {
+        error_setg(errp, "couldn't find memdev object with ID='%s'", str);
+        return;
+    }
+
+    backend_cls = MEMORY_BACKEND_GET_CLASS(memdev);
+    mr = backend_cls->get_memory(MEMORY_BACKEND(memdev), errp);
+    if (error_is_set(errp)) {
+        return;
+    }
+    memory_region_unref(dimm->mr);
+    memory_region_ref(mr);
+    dimm->mr = mr;
+}
+
+static void dimm_get_memdev(Object *obj, Visitor *v, void *opaque,
+                            const char *name, Error **errp)
+{
+    DimmDevice *dimm = DIMM(obj);
+    Object *memdev;
+    char *str;
+
+    if (!dimm->mr) {
+        error_setg(errp, "property %s hasn't been set", name);
+        return;
+    }
+
+    memdev = memory_region_owner(dimm->mr);
+    str = object_property_get_str(memdev, "id", errp);
+    visit_type_str(v, &str, name, errp);
+    g_free(str);
+}
+
+static void dimm_get_size(Object *obj, Visitor *v, void *opaque,
+                          const char *name, Error **errp)
+{
+    DimmDevice *dimm = DIMM(obj);
+    int64_t value = memory_region_size(dimm->mr);
+
+    visit_type_int(v, &value, name, errp);
+}
+
+static void dimm_initfn(Object *obj)
+{
+    object_property_add(obj, "memdev", "string", dimm_get_memdev,
+                        dimm_set_memdev, NULL, NULL, NULL);
+    object_property_add(obj, "size", "int", dimm_get_size,
+                        NULL, NULL, NULL, NULL);
+}
+
+static void dimm_realize(DeviceState *dev, Error **errp)
+{
+    DimmDevice *dimm = DIMM(dev);
+    DimmBus *bus = DIMM_BUS(qdev_get_parent_bus(dev));
+    BusClass *bc = BUS_GET_CLASS(bus);
+
+    if (!dimm->mr) {
+        error_setg(errp, "'memdev' property is not set");
+        return;
+    }
+
+    if (!dev->id) {
+        error_setg(errp, "'id' property is not set");
+        return;
+    }
+
+    if (dimm->slot >= bc->max_dev) {
+        error_setg(errp, "maximum allowed slot is: %d", bc->max_dev - 1);
+        return;
+    }
+
+}
+
+static void dimm_finalize(Object *obj)
+{
+    DimmDevice *dimm = DIMM(obj);
+
+    if (dimm->mr) {
+        memory_region_unref(dimm->mr);
+        dimm->mr = NULL;
+    }
+}
+
+static void dimm_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = dimm_realize;
+    dc->props = dimm_properties;
+    dc->bus_type = TYPE_DIMM_BUS;
+}
+
+static TypeInfo dimm_info = {
+    .name          = TYPE_DIMM,
+    .parent        = TYPE_DEVICE,
+    .instance_size = sizeof(DimmDevice),
+    .instance_init = dimm_initfn,
+    .instance_finalize = dimm_finalize,
+    .class_init    = dimm_class_init,
+};
+
+static void dimm_register_types(void)
+{
+    type_register_static(&dimm_bus_info);
+    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..0d9c28e
--- /dev/null
+++ b/include/hw/mem/dimm.h
@@ -0,0 +1,71 @@
+/*
+ * 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:
+ * @parent_obj: opaque parent object container
+ * @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.
+ * @mr: memory region provided by host memory backend
+ */
+typedef struct DimmDevice {
+    /* private */
+    DeviceState parent_obj;
+    ram_addr_t start;
+    uint32_t node;
+    int32_t slot;
+    MemoryRegion *mr;
+} DimmDevice;
+
+typedef struct DimmDeviceClass {
+    DeviceClass parent_class;
+} DimmDeviceClass;
+
+#define TYPE_DIMM_BUS "dimm-bus"
+#define DIMM_BUS(obj) OBJECT_CHECK(DimmBus, (obj), TYPE_DIMM_BUS)
+#define DIMM_BUS_CLASS(oc) \
+    OBJECT_CLASS_CHECK(DimmBusClass, (oc), TYPE_DIMM_BUS)
+#define DIMM_BUS_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(DimmBusClass, (obj), TYPE_DIMM_BUS)
+
+/**
+ * DimmBus:
+ * @parent_obj: opaque parent object container
+ */
+typedef struct DimmBus {
+    BusState parent_obj;
+} DimmBus;
+
+#endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 09/27] dimm: map DimmDevice into DimBus provided address space
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (7 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 10/27] dimm: add busy slot check and slot auto-allocation Igor Mammedov
                   ` (18 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/mem/dimm.c         |   13 +++++++++++++
 include/hw/mem/dimm.h |   15 +++++++++++++++
 2 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index fe81226..b3d6fda 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -28,12 +28,21 @@ static void dimm_bus_initfn(Object *obj)
 
     b->allow_hotplug = true;
 }
+static void dimm_bus_register_memory(DimmBus *bus, DimmDevice *dimm,
+                                     Error **errp)
+{
+    memory_region_add_subregion(&bus->as, dimm->start - bus->base, dimm->mr);
+    vmstate_register_ram(dimm->mr, DEVICE(dimm));
+}
+
 static void dimm_bus_class_init(ObjectClass *oc, void *data)
 {
     BusClass *bc = BUS_CLASS(oc);
+    DimmBusClass *dbc = DIMM_BUS_CLASS(oc);
     QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
 
     bc->max_dev = qemu_opt_get_number(opts, "slots", 0);
+    dbc->register_memory = dimm_bus_register_memory;
 }
 
 static const TypeInfo dimm_bus_info = {
@@ -42,6 +51,7 @@ static const TypeInfo dimm_bus_info = {
     .instance_init = dimm_bus_initfn,
     .instance_size = sizeof(DimmBus),
     .class_init = dimm_bus_class_init,
+    .class_size = sizeof(DimmBusClass),
 };
 
 static Property dimm_properties[] = {
@@ -121,6 +131,7 @@ static void dimm_realize(DeviceState *dev, Error **errp)
     DimmDevice *dimm = DIMM(dev);
     DimmBus *bus = DIMM_BUS(qdev_get_parent_bus(dev));
     BusClass *bc = BUS_GET_CLASS(bus);
+    DimmBusClass *dbc = DIMM_BUS_GET_CLASS(bus);
 
     if (!dimm->mr) {
         error_setg(errp, "'memdev' property is not set");
@@ -137,6 +148,8 @@ static void dimm_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    g_assert(dbc->register_memory);
+    dbc->register_memory(bus, dimm, errp);
 }
 
 static void dimm_finalize(Object *obj)
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 0d9c28e..ae9ad2e 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -63,9 +63,24 @@ typedef struct DimmDeviceClass {
 /**
  * DimmBus:
  * @parent_obj: opaque parent object container
+ * @base: address from which to start mapping @DimmDevice
+ * @as: hot-plugabble memory area where @DimmDevice-s are attached
  */
 typedef struct DimmBus {
     BusState parent_obj;
+    hwaddr base;
+    MemoryRegion as;
 } DimmBus;
 
+/**
+ * DimmBusClass:
+ * @parent_class: opaque parent class container
+ * @register_memory: map @DimmDevice into hot-plugable address space
+ */
+typedef struct DimmBusClass {
+    BusClass parent_class;
+
+    void (*register_memory)(DimmBus *bus, DimmDevice *dimm, Error **errp);
+} DimmBusClass;
+
 #endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 10/27] dimm: add busy slot check and slot auto-allocation
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (8 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 09/27] dimm: map DimmDevice into DimBus provided address space Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 11/27] dimm: add busy address check and address auto-allocation Igor Mammedov
                   ` (17 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, 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>
---
v2:
  s/dc/dbc/
---
 hw/mem/dimm.c         |   51 ++++++++++++++++++++++++++++++++++++++++++++++++-
 include/hw/mem/dimm.h |    4 +++
 2 files changed, 54 insertions(+), 1 deletions(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index b3d6fda..8837ffe 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -21,6 +21,7 @@
 #include "hw/mem/dimm.h"
 #include "qemu/config-file.h"
 #include "qapi/visitor.h"
+#include "qemu/bitmap.h"
 
 static void dimm_bus_initfn(Object *obj)
 {
@@ -28,6 +29,45 @@ static void dimm_bus_initfn(Object *obj)
 
     b->allow_hotplug = true;
 }
+
+static int dimm_bus_slot2bitmap(DeviceState *dev, void *opaque)
+{
+    unsigned long *bitmap = opaque;
+    BusClass *bc = BUS_GET_CLASS(qdev_get_parent_bus(dev));
+    DimmDevice *d = DIMM(dev);
+
+    if (dev->realized) { /* count only realized DIMMs */
+        g_assert(d->slot < bc->max_dev);
+        set_bit(d->slot, bitmap);
+    }
+    return 0;
+}
+
+static int dimm_bus_get_free_slot(DimmBus *bus, const int *hint, Error **errp)
+{
+    BusClass *bc = BUS_GET_CLASS(bus);
+    unsigned long *bitmap = bitmap_new(bc->max_dev);
+    int slot = 0;
+
+    qbus_walk_children(BUS(bus), dimm_bus_slot2bitmap, NULL, bitmap);
+
+    /* check if requested slot is not occupied */
+    if (hint) {
+        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, bc->max_dev);
+out:
+    g_free(bitmap);
+    return slot;
+}
+
 static void dimm_bus_register_memory(DimmBus *bus, DimmDevice *dimm,
                                      Error **errp)
 {
@@ -43,6 +83,7 @@ static void dimm_bus_class_init(ObjectClass *oc, void *data)
 
     bc->max_dev = qemu_opt_get_number(opts, "slots", 0);
     dbc->register_memory = dimm_bus_register_memory;
+    dbc->get_free_slot = dimm_bus_get_free_slot;
 }
 
 static const TypeInfo dimm_bus_info = {
@@ -57,7 +98,7 @@ static const TypeInfo dimm_bus_info = {
 static Property dimm_properties[] = {
     DEFINE_PROP_UINT64("start", DimmDevice, start, 0),
     DEFINE_PROP_UINT32("node", DimmDevice, node, 0),
-    DEFINE_PROP_INT32("slot", DimmDevice, slot, 0),
+    DEFINE_PROP_INT32("slot", DimmDevice, slot, -1),
     DEFINE_PROP_END_OF_LIST(),
 };
 
@@ -132,6 +173,7 @@ static void dimm_realize(DeviceState *dev, Error **errp)
     DimmBus *bus = DIMM_BUS(qdev_get_parent_bus(dev));
     BusClass *bc = BUS_GET_CLASS(bus);
     DimmBusClass *dbc = DIMM_BUS_GET_CLASS(bus);
+    int *slot_hint;
 
     if (!dimm->mr) {
         error_setg(errp, "'memdev' property is not set");
@@ -147,6 +189,13 @@ static void dimm_realize(DeviceState *dev, Error **errp)
         error_setg(errp, "maximum allowed slot is: %d", bc->max_dev - 1);
         return;
     }
+    g_assert(dbc->get_free_slot);
+    slot_hint = dimm->slot < 0 ? NULL : &dimm->slot;
+    dimm->slot = dbc->get_free_slot(bus, slot_hint, errp);
+    if (error_is_set(errp)) {
+        return;
+    }
+
 
     g_assert(dbc->register_memory);
     dbc->register_memory(bus, dimm, errp);
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index ae9ad2e..963b26d 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -75,11 +75,15 @@ typedef struct DimmBus {
 /**
  * DimmBusClass:
  * @parent_class: opaque parent class container
+ * @get_free_slot: returns a not occupied slot number. If @hint is provided,
+ * it tries to return slot specified by @hint if it's not busy or returns
+ * error in @errp.
  * @register_memory: map @DimmDevice into hot-plugable address space
  */
 typedef struct DimmBusClass {
     BusClass parent_class;
 
+    int (*get_free_slot)(DimmBus *bus, const int *hint, Error **errp);
     void (*register_memory)(DimmBus *bus, DimmDevice *dimm, Error **errp);
 } DimmBusClass;
 
-- 
1.7.1

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

* [Qemu-devel] [PATCH 11/27] dimm: add busy address check and address auto-allocation
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (9 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 10/27] dimm: add busy slot check and slot auto-allocation Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 12/27] dimm: add hotplug callback to DimmBus Igor Mammedov
                   ` (16 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, 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>
---
v2:
  * s/dc/dbc/
  * if DimmBus is not initialized, report error "memory add is disabled"
---
 hw/mem/dimm.c         |   79 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/mem/dimm.h |    5 +++
 2 files changed, 84 insertions(+), 0 deletions(-)

diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index 8837ffe..b3c27cc 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -22,6 +22,7 @@
 #include "qemu/config-file.h"
 #include "qapi/visitor.h"
 #include "qemu/bitmap.h"
+#include "qemu/range.h"
 
 static void dimm_bus_initfn(Object *obj)
 {
@@ -68,6 +69,70 @@ out:
     return slot;
 }
 
+static gint dimm_bus_addr_sort(gconstpointer a, gconstpointer b)
+{
+    DimmDevice *x = DIMM(a);
+    DimmDevice *y = DIMM(b);
+
+    return x->start - y->start;
+}
+
+static int dimm_bus_built_dimm_list(DeviceState *dev, void *opaque)
+{
+    GSList **list = opaque;
+
+    if (dev->realized) { /* only realized DIMMs matter */
+        *list = g_slist_insert_sorted(*list, dev, dimm_bus_addr_sort);
+    }
+    return 0;
+}
+
+static hwaddr dimm_bus_get_free_addr(DimmBus *bus, const hwaddr *hint,
+                                     uint64_t size, Error **errp)
+{
+    GSList *list = NULL, *item;
+    hwaddr new_start, ret;
+    uint64_t as_size;
+
+    if (!bus->base) {
+        error_setg(errp, "adding memory to '%s' is disabled", BUS(bus)->name);
+        return 0;
+    }
+
+    qbus_walk_children(BUS(bus), dimm_bus_built_dimm_list, NULL, &list);
+
+    if (hint) {
+        new_start = *hint;
+    } else {
+        new_start = bus->base;
+    }
+
+    /* find address range that will fit new DIMM */
+    for (item = list; item; item = g_slist_next(item)) {
+        DimmDevice *dimm = item->data;
+        if (ranges_overlap(dimm->start, memory_region_size(dimm->mr),
+                           new_start, size)) {
+            if (hint) {
+                DeviceState *d = DEVICE(dimm);
+                error_setg(errp, "address range conflicts with '%s'", d->id);
+                break;
+            }
+            new_start = dimm->start + memory_region_size(dimm->mr);
+        }
+    }
+    ret = new_start;
+
+    g_slist_free(list);
+
+    as_size = memory_region_size(&bus->as);
+    if ((new_start + size) > (bus->base + as_size)) {
+        error_setg(errp, "can't add memory beyond 0x%" PRIx64,
+                   bus->base + as_size);
+    }
+
+    return ret;
+}
+
 static void dimm_bus_register_memory(DimmBus *bus, DimmDevice *dimm,
                                      Error **errp)
 {
@@ -84,6 +149,7 @@ static void dimm_bus_class_init(ObjectClass *oc, void *data)
     bc->max_dev = qemu_opt_get_number(opts, "slots", 0);
     dbc->register_memory = dimm_bus_register_memory;
     dbc->get_free_slot = dimm_bus_get_free_slot;
+    dbc->get_free_addr = dimm_bus_get_free_addr;
 }
 
 static const TypeInfo dimm_bus_info = {
@@ -174,6 +240,7 @@ static void dimm_realize(DeviceState *dev, Error **errp)
     BusClass *bc = BUS_GET_CLASS(bus);
     DimmBusClass *dbc = DIMM_BUS_GET_CLASS(bus);
     int *slot_hint;
+    hwaddr *start_hint;
 
     if (!dimm->mr) {
         error_setg(errp, "'memdev' property is not set");
@@ -196,6 +263,18 @@ static void dimm_realize(DeviceState *dev, Error **errp)
         return;
     }
 
+    start_hint = !dimm->start ? NULL : &dimm->start;
+    if (start_hint && (dimm->start < bus->base)) {
+        error_setg(errp, "can't map DIMM below: 0x%" PRIx64, bus->base);
+        return;
+    }
+
+    g_assert(dbc->get_free_addr);
+    dimm->start = dbc->get_free_addr(bus, start_hint,
+                                     memory_region_size(dimm->mr), errp);
+    if (error_is_set(errp)) {
+        return;
+    }
 
     g_assert(dbc->register_memory);
     dbc->register_memory(bus, dimm, errp);
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index 963b26d..abedae2 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -78,6 +78,9 @@ typedef struct DimmBus {
  * @get_free_slot: returns a not occupied slot number. If @hint is provided,
  * it tries to return slot specified by @hint if it's not busy or returns
  * error in @errp.
+ * @get_free_addr: returns address where @DimmDevice of specified size
+ * might be mapped. If @hint is specified it returns hinted address if
+ * region is available or error in @errp.
  * @register_memory: map @DimmDevice into hot-plugable address space
  */
 typedef struct DimmBusClass {
@@ -85,6 +88,8 @@ typedef struct DimmBusClass {
 
     int (*get_free_slot)(DimmBus *bus, const int *hint, Error **errp);
     void (*register_memory)(DimmBus *bus, DimmDevice *dimm, Error **errp);
+    hwaddr (*get_free_addr)(DimmBus *bus, const hwaddr *hint,
+                            uint64_t size, Error **errp);
 } DimmBusClass;
 
 #endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 12/27] dimm: add hotplug callback to DimmBus
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (10 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 11/27] dimm: add busy address check and address auto-allocation Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-25 13:01   ` Paolo Bonzini
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
                   ` (15 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c          |   11 +++++++++++
 hw/mem/dimm.c         |    4 ++++
 include/hw/i386/pc.h  |    6 ++++++
 include/hw/mem/dimm.h |    4 ++++
 4 files changed, 25 insertions(+), 0 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index ba82c67..85d0862 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1225,6 +1225,17 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
     return fw_cfg;
 }
 
+void pc_acpi_dev_memory_hotplug_init(DimmBus *hotplug_mem_bus,
+                                     hotplug_fn hotplug,
+                                     Object *acpi_dev)
+{
+    g_assert(acpi_dev);
+    if (memory_region_size(&hotplug_mem_bus->as)) {
+        hotplug_mem_bus->hotplug_dev = DEVICE(acpi_dev);
+        hotplug_mem_bus->hotplug = hotplug;
+    }
+}
+
 qemu_irq *pc_allocate_cpu_irq(void)
 {
     return qemu_allocate_irqs(pic_irq_request, NULL, 1);
diff --git a/hw/mem/dimm.c b/hw/mem/dimm.c
index b3c27cc..7029675 100644
--- a/hw/mem/dimm.c
+++ b/hw/mem/dimm.c
@@ -278,6 +278,10 @@ static void dimm_realize(DeviceState *dev, Error **errp)
 
     g_assert(dbc->register_memory);
     dbc->register_memory(bus, dimm, errp);
+
+    if (bus->hotplug) {
+        bus->hotplug(bus->hotplug_dev, dev, HOTPLUG_ENABLED);
+    }
 }
 
 static void dimm_finalize(Object *obj)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index c4e8048..0c86ee5 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -12,6 +12,7 @@
 #include "qemu/bitmap.h"
 #include "sysemu/sysemu.h"
 #include "hw/pci/pci.h"
+#include "hw/mem/dimm.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
@@ -148,6 +149,11 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
                            MemoryRegion *rom_memory,
                            MemoryRegion **ram_memory,
                            PcGuestInfo *guest_info);
+
+void pc_acpi_dev_memory_hotplug_init(DimmBus *hotplug_mem_bus,
+                                     hotplug_fn hotplug,
+                                     Object *acpi_dev);
+
 qemu_irq *pc_allocate_cpu_irq(void);
 DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
index abedae2..b655006 100644
--- a/include/hw/mem/dimm.h
+++ b/include/hw/mem/dimm.h
@@ -65,11 +65,15 @@ typedef struct DimmDeviceClass {
  * @parent_obj: opaque parent object container
  * @base: address from which to start mapping @DimmDevice
  * @as: hot-plugabble memory area where @DimmDevice-s are attached
+ * @hotplug_dev: device that hotplugs realized DimmDevice
+ * @hotplug: hotplug callback set by the board
  */
 typedef struct DimmBus {
     BusState parent_obj;
     hwaddr base;
     MemoryRegion as;
+    DeviceState *hotplug_dev;
+    hotplug_fn hotplug;
 } DimmBus;
 
 /**
-- 
1.7.1

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

* [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (11 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 12/27] dimm: add hotplug callback to DimmBus Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  9:42   ` Michael S. Tsirkin
  2013-11-27 17:59   ` Eric Blake
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 14/27] acpi: initialize memory hotplug ACPI PIIX4 hardware Igor Mammedov
                   ` (14 subsequent siblings)
  27 siblings, 2 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, 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 |   38 ++++++++++
 hw/acpi/core.c                  |  144 +++++++++++++++++++++++++++++++++++++++
 include/hw/acpi/acpi.h          |   24 +++++++
 3 files changed, 206 insertions(+), 0 deletions(-)
 create mode 100644 docs/specs/acpi_mem_hotplug.txt

diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
new file mode 100644
index 0000000..fc34142
--- /dev/null
+++ b/docs/specs/acpi_mem_hotplug.txt
@@ -0,0 +1,38 @@
+QEMU<->ACPI BIOS memory hotplug interface
+--------------------------------------
+
+ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
+or hot-remove 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
+      [0x14] highest memory hot-plug interface version supported by QEMU
+      [0x15] Memory device status fields
+          bits:
+              1: device is enabled and may be used by guest
+              2: device insert event, used by ACPI BIOS to distinguish
+                 device for which no device check event to OSPM was issued
+      [0x16-0x17] reserved
+
+  write access:
+      [0x0-0x3] Memory device slot selector, selects active memory device.
+                All following accesses to other registers in 0xaf80-0xaf97
+                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
+      [0x15] Memory device status fields
+          bits:
+              2: if set to 1 clears device insert event, set by ACPI BIOS
+                 after it has sent device check event to OSPM for
+                 seleted memory device
+
+Selecting memory device slot beyond present range has no effect on platform:
+   - not documented above write accesses to memory hot-plug registers
+     are ignored;
+   - not documented above read accesses to memory hot-plug registers return 0xFF
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 8c0d48c..18e169c 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -680,3 +680,147 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq, uint32_t gpe0_sts_mask)
                        (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
                        !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
 }
+
+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: /* intf version */
+        val = 1;
+        break;
+    case 0x15: /* pack and return is_* fields */
+        val |= mdev->is_enabled   ? 1 : 0;
+        val |= mdev->is_inserting ? 2 : 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 0x15:
+        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(Object *owner, MemoryRegion *io,
+                              MemHotplugState *state)
+{
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
+    g_assert(opts);
+
+    state->dev_count = qemu_opt_get_number(opts, "slots", 0);
+
+    if (!state->dev_count) {
+        return;
+    }
+
+    state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
+    memory_region_init_io(io, owner, &acpi_memory_hotplug_ops, state,
+                          "apci-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
+}
+
+int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
+                           DeviceState *dev, HotplugState state)
+{
+    MemStatus *mdev;
+    Error *local_err = NULL;
+    int slot = object_property_get_int(OBJECT(dev), "slot", &local_err);
+
+    if (error_is_set(&local_err)) {
+        qerror_report_err(local_err);
+        error_free(local_err);
+        return -1;
+    }
+
+    if (slot >= mem_st->dev_count) {
+        char *dev_path = object_get_canonical_path(OBJECT(dev));
+        qerror_report(ERROR_CLASS_GENERIC_ERROR, "acpi_memory_hotplug_cb: "
+                      "device [%s] returned invalid memory slot[%d]",
+                      dev_path, slot);
+        g_free(dev_path);
+        return -1;
+    }
+
+    mdev = &mem_st->devs[slot];
+    if (state == HOTPLUG_ENABLED) {
+        mdev->dimm = dev;
+        mdev->is_enabled = true;
+        mdev->is_inserting = true;
+    }
+
+    /* do ACPI magic */
+    regs->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
+    return 0;
+}
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index c4ae7d7..e5717df 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -168,6 +168,30 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
 
 void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
 
+#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
+#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
+
+#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 {
+    uint32_t selector;
+    uint32_t dev_count;
+    MemStatus *devs;
+} MemHotplugState;
+
+void acpi_memory_hotplug_init(Object *owner, MemoryRegion *io,
+                              MemHotplugState *state);
+
+int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
+                           DeviceState *dev, HotplugState state);
 /* acpi.c */
 extern int acpi_enabled;
 extern char unsigned *acpi_tables;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 14/27] acpi: initialize memory hotplug ACPI PIIX4 hardware
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (12 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 15/27] acpi: piix4: add memory-hotplug-io-base property to piix4_pm Igor Mammedov
                   ` (13 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

to be used by i440fx machine for handling hardware ACPI part of
memory hotplug interface with guest.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/piix4.c         |   16 ++++++++++++++++
 include/hw/acpi/piix4.h |    2 ++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index cf42f13..e0d9270 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -75,6 +75,7 @@ typedef struct PIIX4PMState {
 
     MemoryRegion io_gpe;
     MemoryRegion io_cpu;
+    MemoryRegion io_mem;
     ACPIREGS ar;
 
     APMState apm;
@@ -104,6 +105,8 @@ typedef struct PIIX4PMState {
 
     CPUStatus gpe_cpu;
     Notifier cpu_added_notifier;
+
+    MemHotplugState  gpe_mem;
 } PIIX4PMState;
 
 #define TYPE_PIIX4_PM "PIIX4_PM"
@@ -741,6 +744,16 @@ static void piix4_cpu_added_req(Notifier *n, void *opaque)
     piix4_cpu_hotplug_req(s, CPU(opaque), PLUG);
 }
 
+int piix4_mem_hotplug(DeviceState *hotplug_dev, DeviceState *dev,
+                      HotplugState state)
+{
+    PIIX4PMState *s = PIIX4_PM(hotplug_dev);
+
+    acpi_memory_hotplug_cb(&s->ar, &s->gpe_mem, dev, state);
+    acpi_update_sci(&s->ar, s->irq, ACPI_MEMORY_HOTPLUG_STATUS);
+    return 0;
+}
+
 static int piix4_device_hotplug(DeviceState *qdev, DeviceState *dev,
                                 HotplugState state);
 
@@ -775,6 +788,9 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
     memory_region_add_subregion(parent, PIIX4_PROC_BASE, &s->io_cpu);
     s->cpu_added_notifier.notify = piix4_cpu_added_req;
     qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
+
+    acpi_memory_hotplug_init(OBJECT(s), &s->io_mem, &s->gpe_mem);
+    memory_region_add_subregion(parent, ACPI_MEMORY_HOTPLUG_BASE, &s->io_mem);
 }
 
 static void enable_device(PIIX4PMState *s, int slot)
diff --git a/include/hw/acpi/piix4.h b/include/hw/acpi/piix4.h
index 65e6fd7..c314ab5 100644
--- a/include/hw/acpi/piix4.h
+++ b/include/hw/acpi/piix4.h
@@ -4,5 +4,7 @@
 #include "qemu/typedefs.h"
 
 Object *piix4_pm_find(void);
+int piix4_mem_hotplug(DeviceState *hotplug_dev, DeviceState *dev,
+                      HotplugState state);
 
 #endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 15/27] acpi: piix4: add memory-hotplug-io-base property to piix4_pm
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (13 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 14/27] acpi: initialize memory hotplug ACPI PIIX4 hardware Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE Igor Mammedov
                   ` (12 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

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

diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index e0d9270..a835981 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -18,6 +18,7 @@
  * Contributions after 2012-01-13 are licensed under the terms of the
  * GNU GPL, version 2 or (at your option) any later version.
  */
+#include "qapi/visitor.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
 #include "hw/isa/apm.h"
@@ -757,6 +758,14 @@ int piix4_mem_hotplug(DeviceState *hotplug_dev, DeviceState *dev,
 static int piix4_device_hotplug(DeviceState *qdev, DeviceState *dev,
                                 HotplugState state);
 
+static void piix4_get_mem_io_base(Object *obj, Visitor *v, void *opaque,
+                                  const char *name, Error **errp)
+{
+    PIIX4PMState *s = PIIX4_PM(obj);
+
+    visit_type_uint16(v, &s->gpe_mem.port, name, errp);
+}
+
 static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
                                            PCIBus *bus, PIIX4PMState *s)
 {
@@ -789,8 +798,11 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
     s->cpu_added_notifier.notify = piix4_cpu_added_req;
     qemu_register_cpu_added_notifier(&s->cpu_added_notifier);
 
+    s->gpe_mem.port = ACPI_MEMORY_HOTPLUG_BASE;
+    object_property_add(OBJECT(s), ACPI_MEMORY_HOTPLUG_IO_BASE_PROP, "int",
+                        piix4_get_mem_io_base, NULL, NULL, NULL, NULL);
     acpi_memory_hotplug_init(OBJECT(s), &s->io_mem, &s->gpe_mem);
-    memory_region_add_subregion(parent, ACPI_MEMORY_HOTPLUG_BASE, &s->io_mem);
+    memory_region_add_subregion(parent, s->gpe_mem.port, &s->io_mem);
 }
 
 static void enable_device(PIIX4PMState *s, int slot)
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index e5717df..95c608f 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -170,6 +170,7 @@ void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
 
 #define ACPI_MEMORY_HOTPLUG_IO_LEN 24
 #define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
+#define ACPI_MEMORY_HOTPLUG_IO_BASE_PROP "memory-hotplug-io-base"
 
 #define ACPI_MEMORY_HOTPLUG_STATUS 8
 
@@ -182,6 +183,7 @@ typedef struct MemStatus {
 } MemStatus;
 
 typedef struct MemHotplugState {
+    uint16_t port;
     uint32_t selector;
     uint32_t dev_count;
     MemStatus *devs;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (14 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 15/27] acpi: piix4: add memory-hotplug-io-base property to piix4_pm Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  7:14   ` Michael S. Tsirkin
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 17/27] acpi: initialize memory hotplug ACPI ICH9 hardware Igor Mammedov
                   ` (11 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

it fixes IRQ storm since guest isn't able to lower SCI IRQ
after it has been handled when it clears GPE event.

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

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index e59688b..fb88162 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -61,6 +61,7 @@ static void ich9_gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
 {
     ICH9LPCPMRegs *pm = opaque;
     acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
+    acpi_update_sci(&pm->acpi_regs, pm->irq, ACPI_MEMORY_HOTPLUG_STATUS);
 }
 
 static const MemoryRegionOps ich9_gpe_ops = {
-- 
1.7.1

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

* [Qemu-devel] [PATCH 17/27] acpi: initialize memory hotplug ACPI ICH9 hardware
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (15 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 18/27] acpi: ich9: add memory-hotplug-io-base property to ich9_pm Igor Mammedov
                   ` (10 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

to be used by Q35 machine for handling hardware ACPI part of
memory hotplug interface with guest.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/acpi/ich9.c         |   15 +++++++++++++++
 include/hw/acpi/ich9.h |    6 ++++++
 2 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index fb88162..0efb875 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -210,6 +210,10 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
     qemu_register_reset(pm_reset, pm);
     pm->powerdown_notifier.notify = pm_powerdown_req;
     qemu_register_powerdown_notifier(&pm->powerdown_notifier);
+
+    acpi_memory_hotplug_init(OBJECT(lpc_pci), &pm->io_mem, &pm->gpe_mem);
+    memory_region_add_subregion(pci_address_space_io(lpc_pci),
+                                ACPI_MEMORY_HOTPLUG_BASE, &pm->io_mem);
 }
 
 static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v,
@@ -234,3 +238,14 @@ void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
     object_property_add_uint32_ptr(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
                                    &gpe0_len, errp);
 }
+
+int ich9_mem_hotplug(DeviceState *hotplug_dev, DeviceState *dev,
+                     HotplugState state)
+{
+    ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev);
+    ICH9LPCPMRegs *pm = &lpc->pm;
+
+    acpi_memory_hotplug_cb(&pm->acpi_regs, &pm->gpe_mem, dev, state);
+    acpi_update_sci(&pm->acpi_regs, pm->irq, ACPI_MEMORY_HOTPLUG_STATUS);
+    return 0;
+}
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index 82fcf9f..7e747be 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -34,6 +34,9 @@ typedef struct ICH9LPCPMRegs {
     MemoryRegion io;
     MemoryRegion io_gpe;
     MemoryRegion io_smi;
+    MemoryRegion io_mem;
+
+    MemHotplugState gpe_mem;
 
     uint32_t smi_en;
     uint32_t smi_sts;
@@ -51,4 +54,7 @@ extern const VMStateDescription vmstate_ich9_pm;
 
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp);
 
+int ich9_mem_hotplug(DeviceState *hotplug_dev, DeviceState *dev,
+                     HotplugState state);
+
 #endif /* HW_ACPI_ICH9_H */
-- 
1.7.1

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

* [Qemu-devel] [PATCH 18/27] acpi: ich9: add memory-hotplug-io-base property to ich9_pm
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (16 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 17/27] acpi: initialize memory hotplug ACPI ICH9 hardware Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 19/27] acpi: piix4/ich9: add optional vmstate field for MemHotplugState migration Igor Mammedov
                   ` (9 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

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

diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 0efb875..ab76cc6 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -226,6 +226,14 @@ static void ich9_pm_get_gpe0_blk(Object *obj, Visitor *v,
     visit_type_uint32(v, &value, name, errp);
 }
 
+static void ich9_pm_get_mem_io_base(Object *obj, Visitor *v, void *opaque,
+                                    const char *name, Error **errp)
+{
+    ICH9LPCState *s = ICH9_LPC_DEVICE(obj);
+
+    visit_type_uint16(v, &s->pm.gpe_mem.port, name, errp);
+}
+
 void ich9_pm_add_properties(Object *obj, ICH9LPCPMRegs *pm, Error **errp)
 {
     static const uint32_t gpe0_len = ICH9_PMIO_GPE0_LEN;
@@ -237,6 +245,9 @@ 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);
+    pm->gpe_mem.port = ACPI_MEMORY_HOTPLUG_BASE;
+    object_property_add(obj, ACPI_MEMORY_HOTPLUG_IO_BASE_PROP, "int",
+                        ich9_pm_get_mem_io_base, NULL, NULL, NULL, NULL);
 }
 
 int ich9_mem_hotplug(DeviceState *hotplug_dev, DeviceState *dev,
-- 
1.7.1

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

* [Qemu-devel] [PATCH 19/27] acpi: piix4/ich9: add optional vmstate field for MemHotplugState migration
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (17 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 18/27] acpi: ich9: add memory-hotplug-io-base property to ich9_pm Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 20/27] pc: piix: make PCII440FXState type public Igor Mammedov
                   ` (8 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

it should not be present for machine versions that do not support
memory hotplug.

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

diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index 18e169c..664aec0 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -824,3 +824,30 @@ int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
     regs->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
     return 0;
 }
+
+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/ich9.c b/hw/acpi/ich9.c
index ab76cc6..ae0c198 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -139,6 +139,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->gpe_mem.dev_count != 0;
+}
+
 const VMStateDescription vmstate_ich9_pm = {
     .name = "ich9_pm",
     .version_id = 1,
@@ -155,6 +161,7 @@ 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(gpe_mem, ICH9LPCPMRegs, vmstate_test_use_memhp),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index a835981..3121738 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -285,6 +285,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->gpe_mem.dev_count != 0;
+}
+
 /* 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
@@ -313,6 +319,7 @@ static const VMStateDescription vmstate_acpi = {
                             struct pci_status),
         VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState,
                             vmstate_test_use_acpi_pci_hotplug),
+        VMSTATE_MEMORY_HOTPLUG(gpe_mem, PIIX4PMState, vmstate_test_use_memhp),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 95c608f..93637a5 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -194,6 +194,14 @@ void acpi_memory_hotplug_init(Object *owner, MemoryRegion *io,
 
 int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
                            DeviceState *dev, HotplugState state);
+
+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)
+
+
 /* acpi.c */
 extern int acpi_enabled;
 extern char unsigned *acpi_tables;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 20/27] pc: piix: make PCII440FXState type public
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (18 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 19/27] acpi: piix4/ich9: add optional vmstate field for MemHotplugState migration Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine Igor Mammedov
                   ` (7 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/pci-host/piix.c         |   22 +---------------------
 include/hw/pci-host/piix.h |   27 +++++++++++++++++++++++++++
 2 files changed, 28 insertions(+), 21 deletions(-)
 create mode 100644 include/hw/pci-host/piix.h

diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 615ab0d..8351430 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -22,15 +22,13 @@
  * THE SOFTWARE.
  */
 
+#include "hw/pci-host/piix.h"
 #include "hw/hw.h"
 #include "hw/i386/pc.h"
-#include "hw/pci/pci.h"
-#include "hw/pci/pci_host.h"
 #include "hw/isa/isa.h"
 #include "hw/sysbus.h"
 #include "qemu/range.h"
 #include "hw/xen/xen.h"
-#include "hw/pci-host/pam.h"
 #include "sysemu/sysemu.h"
 #include "hw/i386/ioapic.h"
 #include "qapi/visitor.h"
@@ -91,24 +89,6 @@ typedef struct PIIX3State {
     MemoryRegion rcr_mem;
 } PIIX3State;
 
-#define TYPE_I440FX_PCI_DEVICE "i440FX"
-#define I440FX_PCI_DEVICE(obj) \
-    OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
-
-struct PCII440FXState {
-    /*< private >*/
-    PCIDevice parent_obj;
-    /*< public >*/
-
-    MemoryRegion *system_memory;
-    MemoryRegion *pci_address_space;
-    MemoryRegion *ram_memory;
-    PAMMemoryRegion pam_regions[13];
-    MemoryRegion smram_region;
-    uint8_t smm_enabled;
-};
-
-
 #define I440FX_PAM      0x59
 #define I440FX_PAM_SIZE 7
 #define I440FX_SMRAM    0x72
diff --git a/include/hw/pci-host/piix.h b/include/hw/pci-host/piix.h
new file mode 100644
index 0000000..1155996
--- /dev/null
+++ b/include/hw/pci-host/piix.h
@@ -0,0 +1,27 @@
+#ifndef HW_PCIHOST_PIIX_H
+#define HW_PCIHOST_PIIX_H
+
+#include "exec/memory.h"
+#include "hw/qdev.h"
+#include "hw/pci/pci.h"
+#include "hw/pci/pci_host.h"
+#include "hw/pci-host/pam.h"
+
+#define TYPE_I440FX_PCI_DEVICE "i440FX"
+#define I440FX_PCI_DEVICE(obj) \
+    OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE)
+
+struct PCII440FXState {
+    /*< private >*/
+    PCIDevice parent_obj;
+    /*< public >*/
+
+    MemoryRegion *system_memory;
+    MemoryRegion *pci_address_space;
+    MemoryRegion *ram_memory;
+    PAMMemoryRegion pam_regions[13];
+    MemoryRegion smram_region;
+    uint8_t smm_enabled;
+};
+
+#endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (19 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 20/27] pc: piix: make PCII440FXState type public Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  5:48   ` Li Guang
  2013-11-22 14:23   ` Gerd Hoffmann
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 22/27] pc: add memory hotplug Q35 machine Igor Mammedov
                   ` (6 subsequent siblings)
  27 siblings, 2 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Add DimmBus for memory hotplug below 4Gb or above 4Gb depending
on initial memory size and hotplug memory size.

* if ram_size is less than 32-bit PCI hole start, reserve
  hotplug memory region as [ram_size,32bit-PCIhole-start)
  if hotplug memory region fits there,
  otherwise reserve hotplug memory region after "0x100000000ULL
  + above_4g_mem_size"

* setup memory hotplug callback to pass event to ACPI hadware.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc.c               |   52 ++++++++++++++++++++++++++++++++++++++++++++
 hw/i386/pc_piix.c          |    6 ++++-
 hw/pci-host/piix.c         |   13 ++++++++++-
 include/hw/i386/pc.h       |   16 +++++++++++++
 include/hw/pci-host/piix.h |    2 +
 5 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 85d0862..306ed22 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1236,6 +1236,58 @@ void pc_acpi_dev_memory_hotplug_init(DimmBus *hotplug_mem_bus,
     }
 }
 
+static
+void pc_hotplug_memory_init_impl(Object *owner,
+                                 MemoryRegion *system_memory,
+                                 ram_addr_t low_hotplug_mem_start,
+                                 ram_addr_t low_hotplug_mem_end,
+                                 DimmBus *hotplug_mem_bus,
+                                 ram_addr_t *high_mem_end)
+{
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
+    ram_addr_t ram_size = qemu_opt_get_size(opts, "mem", 0);
+    ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", 0);
+    ram_addr_t hotplug_mem_size;
+
+    if (maxmem <= ram_size) {
+        /* Disable ACPI migration code and creation of memory devices in SSDT */
+        qemu_opt_set_number(opts, "slots", 0);
+        return;
+    }
+
+    hotplug_mem_size = maxmem - ram_size;
+    if (hotplug_mem_size <= (low_hotplug_mem_end - low_hotplug_mem_start)) {
+        hotplug_mem_bus->base = low_hotplug_mem_start;
+    } else {
+        hotplug_mem_bus->base = ROUND_UP(*high_mem_end, 1ULL << 30);
+        *high_mem_end = hotplug_mem_bus->base + hotplug_mem_size;
+    }
+
+    memory_region_init(&hotplug_mem_bus->as, owner, "hotplug-memory",
+                       hotplug_mem_size);
+    memory_region_add_subregion(system_memory, hotplug_mem_bus->base,
+                                &hotplug_mem_bus->as);
+}
+
+pc_hotplug_memory_init_fn pc_hotplug_memory_init = pc_hotplug_memory_init_impl;
+
+void pc_hotplug_memory_init_compat_1_7(Object *owner,
+                                       MemoryRegion *system_memory,
+                                       ram_addr_t low_hotplug_mem_start,
+                                       ram_addr_t low_hotplug_mem_end,
+                                       DimmBus *hotplug_mem_bus,
+                                       ram_addr_t *high_mem_end)
+{
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
+    /*
+     * clearing slots tells acpi code that memory hotplug is disabled,
+     * so there is not need to migrate its state and create related
+     * SSDT table objects
+     */
+    qemu_opt_set_number(opts, "slots", 0);
+}
+
+
 qemu_irq *pc_allocate_cpu_irq(void)
 {
     return qemu_allocate_irqs(pic_irq_request, NULL, 1);
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index e1fe85a..7d30c12 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -48,6 +48,8 @@
 #include "exec/address-spaces.h"
 #include "hw/acpi/acpi.h"
 #include "cpu.h"
+#include "hw/acpi/piix4.h"
+#include "hw/pci-host/piix.h"
 #ifdef CONFIG_XEN
 #  include <xen/hvm/hvm_info_table.h>
 #endif
@@ -230,6 +232,8 @@ static void pc_init1(QEMUMachineInitArgs *args,
                               gsi[9], *smi_irq,
                               kvm_enabled(), fw_cfg);
         smbus_eeprom_init(smbus, 8, NULL, 0);
+        pc_acpi_dev_memory_hotplug_init(&i440fx_state->hotplug_mem_bus,
+                                        piix4_mem_hotplug, piix4_pm_find());
     }
 
     if (pci_enabled) {
@@ -250,6 +254,7 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
 {
     smbios_type1_defaults = false;
     pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
+    pc_hotplug_memory_init = pc_hotplug_memory_init_compat_1_7;
 }
 
 static void pc_compat_1_6(QEMUMachineInitArgs *args)
@@ -367,7 +372,6 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
     .desc = "Standard PC (i440FX + PIIX, 1996)", \
     .hot_add_cpu = pc_hot_add_cpu
 
-
 #define PC_I440FX_1_8_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
 static QEMUMachine pc_i440fx_machine_v1_8 = {
     PC_I440FX_1_8_MACHINE_OPTIONS,
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index 8351430..2f2785b 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -282,6 +282,11 @@ static int i440fx_initfn(PCIDevice *dev)
     dev->config[I440FX_SMRAM] = 0x02;
 
     cpu_smm_register(&i440fx_set_smm, d);
+
+    qbus_create_inplace(&d->hotplug_mem_bus,
+                        sizeof(d->hotplug_mem_bus),
+                        TYPE_DIMM_BUS, DEVICE(d),
+                        "hotplug-membus");
     return 0;
 }
 
@@ -303,6 +308,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
     PCII440FXState *f;
     unsigned i;
     I440FXState *i440fx;
+    ram_addr_t below_4g_mem_size = ram_size - above_4g_mem_size;
+    ram_addr_t high_memory_end = 0x100000000ULL + above_4g_mem_size;
 
     dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
     s = PCI_HOST_BRIDGE(dev);
@@ -330,10 +337,14 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
         i440fx->pci_info.w32.begin = 0xe0000000;
     }
 
+    pc_hotplug_memory_init(OBJECT(f), f->system_memory,
+                           below_4g_mem_size, i440fx->pci_info.w32.begin,
+                           &f->hotplug_mem_bus, &high_memory_end);
+
     /* setup pci memory mapping */
     pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
                            f->pci_address_space,
-                           0x100000000ULL + above_4g_mem_size);
+                           high_memory_end);
 
     memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
                              f->pci_address_space, 0xa0000, 0x20000);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 0c86ee5..fea7d60 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -154,6 +154,22 @@ void pc_acpi_dev_memory_hotplug_init(DimmBus *hotplug_mem_bus,
                                      hotplug_fn hotplug,
                                      Object *acpi_dev);
 
+typedef
+void (*pc_hotplug_memory_init_fn)(Object *owner,
+                                  MemoryRegion *system_memory,
+                                  ram_addr_t low_hotplug_mem_start,
+                                  ram_addr_t low_hotplug_mem_end,
+                                  DimmBus *hotplug_mem_bus,
+                                  ram_addr_t *high_mem_end);
+extern pc_hotplug_memory_init_fn pc_hotplug_memory_init;
+
+void pc_hotplug_memory_init_compat_1_7(Object *owner,
+                                       MemoryRegion *system_memory,
+                                       ram_addr_t low_hotplug_mem_start,
+                                       ram_addr_t low_hotplug_mem_end,
+                                       DimmBus *hotplug_mem_bus,
+                                       ram_addr_t *high_mem_end);
+
 qemu_irq *pc_allocate_cpu_irq(void);
 DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
diff --git a/include/hw/pci-host/piix.h b/include/hw/pci-host/piix.h
index 1155996..a301c9d 100644
--- a/include/hw/pci-host/piix.h
+++ b/include/hw/pci-host/piix.h
@@ -6,6 +6,7 @@
 #include "hw/pci/pci.h"
 #include "hw/pci/pci_host.h"
 #include "hw/pci-host/pam.h"
+#include "hw/mem/dimm.h"
 
 #define TYPE_I440FX_PCI_DEVICE "i440FX"
 #define I440FX_PCI_DEVICE(obj) \
@@ -22,6 +23,7 @@ struct PCII440FXState {
     PAMMemoryRegion pam_regions[13];
     MemoryRegion smram_region;
     uint8_t smm_enabled;
+    DimmBus hotplug_mem_bus;
 };
 
 #endif
-- 
1.7.1

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

* [Qemu-devel] [PATCH 22/27] pc: add memory hotplug Q35 machine
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (20 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
                   ` (5 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Add DimmBus to q35 machine, initialize memory hotplug window and plumb
in ACPI callback (ich9_pm) for communicating hotplug event to guest.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/pc_q35.c          |    3 +++
 hw/pci-host/q35.c         |   18 +++++++++++++++++-
 include/hw/pci-host/q35.h |    1 +
 3 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 5525465..59887db 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -167,6 +167,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
                  ICH9_LPC_NB_PIRQS);
     pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq);
     isa_bus = ich9_lpc->isa_bus;
+    pc_acpi_dev_memory_hotplug_init(&q35_host->mch.hotplug_mem_bus,
+                                    ich9_mem_hotplug, OBJECT(ich9_lpc));
 
     /*end early*/
     isa_bus_irqs(isa_bus, gsi);
@@ -234,6 +236,7 @@ static void pc_compat_1_7(QEMUMachineInitArgs *args)
 {
     smbios_type1_defaults = false;
     pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
+    pc_hotplug_memory_init = pc_hotplug_memory_init_compat_1_7;
 }
 
 static void pc_compat_1_6(QEMUMachineInitArgs *args)
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 6e28418..ead982b 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -356,11 +356,16 @@ static int mch_init(PCIDevice *d)
 {
     int i;
     MCHPCIState *mch = MCH_PCI_DEVICE(d);
+    ram_addr_t high_memory_end = 0x100000000ULL + mch->above_4g_mem_size;
+
+    pc_hotplug_memory_init(OBJECT(mch), mch->system_memory,
+                           mch->below_4g_mem_size, mch->pci_info.w32.begin,
+                           &mch->hotplug_mem_bus, &high_memory_end);
 
     /* setup pci memory mapping */
     pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
                            mch->pci_address_space,
-                           0x100000000ULL + mch->above_4g_mem_size);
+                           high_memory_end);
 
     /* smram */
     cpu_smm_register(&mch_set_smm, mch);
@@ -389,6 +394,16 @@ uint64_t mch_mcfg_base(void)
     return MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT;
 }
 
+static void mch_initfn(Object *obj)
+{
+    MCHPCIState *mch = MCH_PCI_DEVICE(obj);
+
+    qbus_create_inplace(&mch->hotplug_mem_bus,
+                        sizeof(mch->hotplug_mem_bus),
+                        TYPE_DIMM_BUS, DEVICE(mch),
+                        "hotplug-membus");
+}
+
 static void mch_class_init(ObjectClass *klass, void *data)
 {
     PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
@@ -410,6 +425,7 @@ static const TypeInfo mch_info = {
     .name = TYPE_MCH_PCI_DEVICE,
     .parent = TYPE_PCI_DEVICE,
     .instance_size = sizeof(MCHPCIState),
+    .instance_init = mch_initfn,
     .class_init = mch_class_init,
 };
 
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index d0355b7..c9aa790 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -47,6 +47,7 @@ typedef struct MCHPCIState {
     PCIDevice parent_obj;
     /*< public >*/
 
+    DimmBus hotplug_mem_bus;
     MemoryRegion *ram_memory;
     MemoryRegion *pci_address_space;
     MemoryRegion *system_memory;
-- 
1.7.1

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

* [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (21 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 22/27] pc: add memory hotplug Q35 machine Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  9:37   ` Michael S. Tsirkin
  2013-11-25 13:42   ` Paolo Bonzini
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 24/27] pc: ACPI BIOS: add ssdt-mem.hex.generated and update ssdt-misc.hex.generated Igor Mammedov
                   ` (4 subsequent siblings)
  27 siblings, 2 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, 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>
---
mst/pci tree specific change:
   acpi-build: s/build_append_notify/build_append_notify_method/
introduced by "acpi-build: enable hotplug for PCI bridges"
should be moved to separate patch since it's generic internal API rename.
---
 hw/i386/Makefile.objs |    3 +-
 hw/i386/acpi-build.c  |   36 ++++++++++
 hw/i386/ssdt-mem.dsl  |   75 ++++++++++++++++++++
 hw/i386/ssdt-misc.dsl |  179 +++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 292 insertions(+), 1 deletions(-)
 create mode 100644 hw/i386/ssdt-mem.dsl

diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 185aacb..f9262a1 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 93ffb17..d41fd81 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -36,6 +36,7 @@
 #include "hw/nvram/fw_cfg.h"
 #include "bios-linker-loader.h"
 #include "hw/loader.h"
+#include "qemu/config-file.h"
 
 /* Supported chipsets: */
 #include "hw/acpi/piix4.h"
@@ -69,6 +70,7 @@ typedef struct AcpiPmInfo {
     uint32_t gpe0_blk;
     uint32_t gpe0_blk_len;
     uint32_t io_base;
+    uint16_t mem_hotplug_io_base;
 } AcpiPmInfo;
 
 typedef struct AcpiMiscInfo {
@@ -176,6 +178,8 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
                                            NULL);
     pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
                                                NULL);
+    pm->mem_hotplug_io_base =
+        object_property_get_int(obj, ACPI_MEMORY_HOTPLUG_IO_BASE_PROP, NULL);
 }
 
 static void acpi_get_misc_info(AcpiMiscInfo *info)
@@ -632,6 +636,14 @@ static inline char acpi_get_hex(uint32_t val)
 #define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start)
 #define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_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
 
@@ -897,6 +909,8 @@ build_ssdt(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
            PcPciInfo *pci, PcGuestInfo *guest_info)
 {
+    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
+    uint32_t nr_mem = qemu_opt_get_number(opts, "slots", 0);
     int acpi_cpus = MIN(0xff, guest_info->apic_id_limit);
     int ssdt_start = table_data->len;
     uint8_t *ssdt_ptr;
@@ -920,6 +934,10 @@ build_ssdt(GArray *table_data, GArray *linker,
     *(uint16_t *)(ssdt_ptr + *ssdt_isa_pest) =
         cpu_to_le16(misc->pvpanic_port);
 
+    *(uint16_t *)(ssdt_ptr + *ssdt_mctrl_port) =
+        cpu_to_le16(pm->mem_hotplug_io_base);
+    *(int32_t *)(ssdt_ptr + *ssdt_mctrl_nr_slots) = cpu_to_le32(nr_mem);
+
     {
         GArray *sb_scope = build_alloc_array();
         uint8_t op = 0x10; /* ScopeOp */
@@ -961,6 +979,24 @@ build_ssdt(GArray *table_data, GArray *linker,
             build_free_array(package);
         }
 
+        if (nr_mem) {
+            /* 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;
             PCIBus *bus = find_i440fx(); /* TODO: Q35 support */
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..b0c581e 100644
--- a/hw/i386/ssdt-misc.dsl
+++ b/hw/i386/ssdt-misc.dsl
@@ -116,4 +116,183 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
             }
         }
     }
+
+    External(MTFY, MethodObj)
+
+    Scope(\_SB) {
+        Device(MHPD) {
+            Name(_HID, EISAID("PNP0C08"))
+
+            ACPI_EXTRACT_NAME_WORD_CONST ssdt_mctrl_port
+            Name(MHPP, 0xFFFF)
+
+            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
+            Name(MDNR, 0x12345678)
+
+            /* Memory hotplug IO registers */
+            OperationRegion(HPMR, SystemIO, MHPP, 24)
+
+            Method(_CRS, 0, Serialized) {
+                Name(CRS, ResourceTemplate() {
+                    IO(Decode16, 0x00, 0x00, 0x01, 24, IO)
+                })
+
+                CreateWordField(CRS, IO._MIN, IOMN)
+                CreateWordField(CRS, IO._MAX, IOMX)
+
+                Store(MHPP, IOMN)
+                Subtract(Add(MHPP, 24), 1, IOMX)
+                Return(CRS)
+            }
+
+            Method(_STA, 0) {
+                If (LEqual(MDNR, Zero)) {
+                    Return(0x0)
+                }
+                /* Leave bit 0 cleared to avoid Windows BSOD */
+                Return(0xA)
+            }
+
+            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),
+                MVER, 8, // Interface version
+                MES,  1, // 1 if DIMM enabled for _STA, read only
+                MINS, 1, // (read) 1 if DIMM has a insert event. (write) 1 after MTFY()
+                MRMV, 1, // 1 if DIMM has a remove request, read only
+            }
+
+            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)
+                    }
+                    If (LEqual(MRMV, One)) { // Ejection request
+                        MTFY(Local0, 3)
+                    }
+                    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 (Or(LLess(MAXL, MINL), LLess(MAXL, LENL))) {
+                    Add(MAXH, 1, MAXH)
+                }
+                // Ignore (MAXL == 0 & MAXH == 0) case
+                If (LEqual(MAXL, Zero)) {
+                    Subtract(MAXH, One, MAXH)
+                    Store(0xFFFFFFFF, MAXL)
+                } Else {
+                    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.7.1

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

* [Qemu-devel] [PATCH 24/27] pc: ACPI BIOS: add ssdt-mem.hex.generated and update ssdt-misc.hex.generated
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (22 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 25/27] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
                   ` (3 subsequent siblings)
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
---
 hw/i386/ssdt-mem.hex.generated  |  197 +++++++++
 hw/i386/ssdt-misc.hex.generated |  881 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 1074 insertions(+), 4 deletions(-)
 create mode 100644 hw/i386/ssdt-mem.hex.generated

diff --git a/hw/i386/ssdt-mem.hex.generated b/hw/i386/ssdt-mem.hex.generated
new file mode 100644
index 0000000..6d53faa
--- /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,
+0xc2,
+0x42,
+0x58,
+0x50,
+0x43,
+0x0,
+0x0,
+0x43,
+0x53,
+0x53,
+0x44,
+0x54,
+0x0,
+0x0,
+0x0,
+0x1,
+0x0,
+0x0,
+0x0,
+0x49,
+0x4e,
+0x54,
+0x4c,
+0x23,
+0x8,
+0x13,
+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..8160ccf 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[] = {
+0x18a
+};
 static unsigned char acpi_s3_name[] = {
 0x7c
 };
@@ -18,12 +21,12 @@ static unsigned char ssdp_misc_aml[] = {
 0x53,
 0x44,
 0x54,
-0x62,
-0x1,
+0xc5,
+0x4,
 0x0,
 0x0,
 0x1,
-0x76,
+0xfd,
 0x42,
 0x58,
 0x50,
@@ -367,7 +370,874 @@ static unsigned char ssdp_misc_aml[] = {
 0x49,
 0x4f,
 0x4d,
-0x58
+0x58,
+0x10,
+0x42,
+0x36,
+0x5c,
+0x5f,
+0x53,
+0x42,
+0x5f,
+0x5b,
+0x82,
+0x49,
+0x35,
+0x4d,
+0x48,
+0x50,
+0x44,
+0x8,
+0x5f,
+0x48,
+0x49,
+0x44,
+0xc,
+0x41,
+0xd0,
+0xc,
+0x8,
+0x8,
+0x4d,
+0x48,
+0x50,
+0x50,
+0xb,
+0xff,
+0xff,
+0x8,
+0x4d,
+0x44,
+0x4e,
+0x52,
+0xc,
+0x78,
+0x56,
+0x34,
+0x12,
+0x5b,
+0x80,
+0x48,
+0x50,
+0x4d,
+0x52,
+0x1,
+0x4d,
+0x48,
+0x50,
+0x50,
+0xa,
+0x18,
+0x14,
+0x4c,
+0x4,
+0x5f,
+0x43,
+0x52,
+0x53,
+0x8,
+0x8,
+0x43,
+0x52,
+0x53,
+0x5f,
+0x11,
+0xd,
+0xa,
+0xa,
+0x47,
+0x1,
+0x0,
+0x0,
+0x0,
+0x0,
+0x1,
+0x18,
+0x79,
+0x0,
+0x8b,
+0x43,
+0x52,
+0x53,
+0x5f,
+0xa,
+0x2,
+0x49,
+0x4f,
+0x4d,
+0x4e,
+0x8b,
+0x43,
+0x52,
+0x53,
+0x5f,
+0xa,
+0x4,
+0x49,
+0x4f,
+0x4d,
+0x58,
+0x70,
+0x4d,
+0x48,
+0x50,
+0x50,
+0x49,
+0x4f,
+0x4d,
+0x4e,
+0x74,
+0x72,
+0x4d,
+0x48,
+0x50,
+0x50,
+0xa,
+0x18,
+0x0,
+0x1,
+0x49,
+0x4f,
+0x4d,
+0x58,
+0xa4,
+0x43,
+0x52,
+0x53,
+0x5f,
+0x14,
+0x13,
+0x5f,
+0x53,
+0x54,
+0x41,
+0x0,
+0xa0,
+0x9,
+0x93,
+0x4d,
+0x44,
+0x4e,
+0x52,
+0x0,
+0xa4,
+0x0,
+0xa4,
+0xa,
+0xa,
+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,
+0x1d,
+0x48,
+0x50,
+0x4d,
+0x52,
+0x1,
+0x0,
+0x40,
+0xa,
+0x4d,
+0x56,
+0x45,
+0x52,
+0x8,
+0x4d,
+0x45,
+0x53,
+0x5f,
+0x1,
+0x4d,
+0x49,
+0x4e,
+0x53,
+0x1,
+0x4d,
+0x52,
+0x4d,
+0x56,
+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,
+0x49,
+0x5,
+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,
+0x34,
+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,
+0xa0,
+0xe,
+0x93,
+0x4d,
+0x52,
+0x4d,
+0x56,
+0x1,
+0x4d,
+0x54,
+0x46,
+0x59,
+0x60,
+0xa,
+0x3,
+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,
+0x44,
+0x19,
+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,
+0x1f,
+0x7d,
+0x95,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x4d,
+0x49,
+0x4e,
+0x4c,
+0x95,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x4c,
+0x45,
+0x4e,
+0x4c,
+0x0,
+0x72,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x1,
+0x4d,
+0x41,
+0x58,
+0x48,
+0xa0,
+0x17,
+0x93,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0x0,
+0x74,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x1,
+0x4d,
+0x41,
+0x58,
+0x48,
+0x70,
+0xff,
+0x4d,
+0x41,
+0x58,
+0x4c,
+0xa1,
+0xb,
+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
@@ -384,3 +1254,6 @@ static unsigned char acpi_pci64_end[] = {
 static unsigned char acpi_pci32_end[] = {
 0x39
 };
+static unsigned short ssdt_mctrl_port[] = {
+0x182
+};
-- 
1.7.1

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

* [Qemu-devel] [PATCH 25/27] pc: ACPI BIOS: use enum for defining memory affinity flags
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (23 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 24/27] pc: ACPI BIOS: add ssdt-mem.hex.generated and update ssdt-misc.hex.generated Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  7:20   ` Michael S. Tsirkin
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 26/27] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
                   ` (2 subsequent siblings)
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, 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 |   22 +++++++++++++++-------
 1 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index d41fd81..86c1372 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -1038,15 +1038,22 @@ build_hpet(GArray *table_data, GArray *linker)
                  (void *)hpet, ACPI_HPET_SIGNATURE, sizeof(*hpet), 1);
 }
 
+typedef enum {
+    NOFLAGS_MEM       = 0,
+    ENABLED_MEM       = (1 << 0),
+    HOT_PLUGGABLE_MEM = (1 << 1),
+    NON_VOLATILE_MEM  = (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);
 }
@@ -1094,7 +1101,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, ENABLED_MEM);
     next_base = 1024 * 1024;
     for (i = 1; i < guest_info->numa_nodes + 1; ++i) {
         mem_base = next_base;
@@ -1110,19 +1117,20 @@ build_srat(GArray *table_data, GArray *linker,
             mem_len -= next_base - guest_info->ram_size;
             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,
+                                       ENABLED_MEM);
             }
             mem_base = 1ULL << 32;
             mem_len = next_base - guest_info->ram_size;
             next_base += (1ULL << 32) - guest_info->ram_size;
         }
         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, ENABLED_MEM);
     }
     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, NOFLAGS_MEM);
     }
 
     build_header(linker, table_data,
-- 
1.7.1

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

* [Qemu-devel] [PATCH 26/27] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (24 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 25/27] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  7:18   ` Michael S. Tsirkin
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 27/27] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
  2013-11-21  6:20 ` [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Michael S. Tsirkin
  27 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, 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 |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 86c1372..ab8e923 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -50,6 +50,7 @@
 
 #include "qapi/qmp/qint.h"
 #include "qom/qom-qobject.h"
+#include "hw/mem/dimm.h"
 
 typedef struct AcpiCpuInfo {
     DECLARE_BITMAP(found_cpus, MAX_CPUMASK_BITS + 1);
@@ -1058,6 +1059,31 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
     numamem->range_length = cpu_to_le64(len);
 }
 
+typedef struct {
+    AcpiSratMemoryAffinity **numamem;
+    GArray *table_data;
+} AcpiSratHotplugMemoryArg;
+
+static int acpi_add_hotplug_memory_region_entry(Object *obj, void *opaque)
+{
+    AcpiSratHotplugMemoryArg *arg = opaque;
+    DimmBus *bus = (DimmBus *)object_dynamic_cast(obj, TYPE_DIMM_BUS);
+
+    if (bus) {
+        uint64_t size = memory_region_size(&bus->as);
+        if (size) {
+            *arg->numamem = acpi_data_push(arg->table_data,
+                                           sizeof **arg->numamem);
+            acpi_build_srat_memory(*arg->numamem, bus->base, size, 0,
+                                   HOT_PLUGGABLE_MEM | ENABLED_MEM);
+        }
+    }
+
+    object_child_foreach(obj, acpi_add_hotplug_memory_region_entry,
+                         opaque);
+   return 0;
+}
+
 static void
 build_srat(GArray *table_data, GArray *linker,
            AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
@@ -1133,6 +1159,13 @@ build_srat(GArray *table_data, GArray *linker,
         acpi_build_srat_memory(numamem, 0, 0, 0, NOFLAGS_MEM);
     }
 
+    {
+        AcpiSratHotplugMemoryArg arg = { .numamem = &numamem,
+                                         .table_data = table_data };
+        object_child_foreach(qdev_get_machine(),
+                             acpi_add_hotplug_memory_region_entry, &arg);
+    }
+
     build_header(linker, table_data,
                  (void *)(table_data->data + srat_start),
                  ACPI_SRAT_SIGNATURE,
-- 
1.7.1

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

* [Qemu-devel] [PATCH 27/27] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (25 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 26/27] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
@ 2013-11-21  2:38 ` Igor Mammedov
  2013-11-21  6:20 ` [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Michael S. Tsirkin
  27 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21  2:38 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, chegu_vinod, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori, hutao,
	pbonzini, marcel.a, lcapitulino, afaerber

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 084a22e..2980deb 100644
--- a/hw/i386/acpi-dsdt.dsl
+++ b/hw/i386/acpi-dsdt.dsl
@@ -295,6 +295,7 @@ DefinitionBlock (
 /****************************************************************
  * General purpose events
  ****************************************************************/
+    External(\_SB.MHPD.MESC, MethodObj)
 
     Scope(\_GPE) {
         Name(_HID, "ACPI0006")
@@ -311,7 +312,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 575c5d7..d8a0a52 100644
--- a/hw/i386/q35-acpi-dsdt.dsl
+++ b/hw/i386/q35-acpi-dsdt.dsl
@@ -410,6 +410,7 @@ DefinitionBlock (
 /****************************************************************
  * General purpose events
  ****************************************************************/
+    External(\_SB.MHPD.MESC, MethodObj)
 
     Scope(\_GPE) {
         Name(_HID, "ACPI0006")
@@ -422,7 +423,9 @@ DefinitionBlock (
         }
         Method(_L02) {
         }
-        Method(_L03) {
+        Method(_E03) {
+            // Memory hotplug event
+            \_SB.MHPD.MESC()
         }
         Method(_L04) {
         }
-- 
1.7.1

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine Igor Mammedov
@ 2013-11-21  5:48   ` Li Guang
  2013-11-21 14:13     ` Andreas Färber
  2013-11-22 14:23   ` Gerd Hoffmann
  1 sibling, 1 reply; 143+ messages in thread
From: Li Guang @ 2013-11-21  5:48 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, armbru, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha, hutao,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

Hi, Igor

Igor Mammedov wrote:
> Add DimmBus for memory hotplug below 4Gb or above 4Gb depending
> on initial memory size and hotplug memory size.
>    
...
> +static
> +void pc_hotplug_memory_init_impl(Object *owner,
> +                                 MemoryRegion *system_memory,
> +                                 ram_addr_t low_hotplug_mem_start,
> +                                 ram_addr_t low_hotplug_mem_end,
> +                                 DimmBus *hotplug_mem_bus,
> +                                 ram_addr_t *high_mem_end)
> +{
> +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
> +    ram_addr_t ram_size = qemu_opt_get_size(opts, "mem", 0);
> +    ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", 0);
> +    ram_addr_t hotplug_mem_size;
> +
> +    if (maxmem<= ram_size) {
> +        /* Disable ACPI migration code and creation of memory devices in SSDT */
>    

Why not give the memory that not be hot-added a chance to be placed on 
one memory slot?
if all memory can be hot-added and hot-removed, then we can bring in 
more flexibility for
memory hotplug feature.

Thanks!

> +        qemu_opt_set_number(opts, "slots", 0);
> +        return;
> +    }
> +
> +    hotplug_mem_size = maxmem - ram_size;
> +    if (hotplug_mem_size<= (low_hotplug_mem_end - low_hotplug_mem_start)) {
> +        hotplug_mem_bus->base = low_hotplug_mem_start;
> +    } else {
> +        hotplug_mem_bus->base = ROUND_UP(*high_mem_end, 1ULL<<  30);
> +        *high_mem_end = hotplug_mem_bus->base + hotplug_mem_size;
> +    }
> +
>    
...

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Igor Mammedov
@ 2013-11-21  6:01   ` Li Guang
  2013-11-21 13:45     ` Igor Mammedov
  2013-11-21 10:12   ` Markus Armbruster
  2013-11-25 12:51   ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Paolo Bonzini
  2 siblings, 1 reply; 143+ messages in thread
From: Li Guang @ 2013-11-21  6:01 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, armbru, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha, hutao,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

Igor Mammedov wrote:
> Along with conversion extend -m option to support following parameters
>    
...
> +                if (!opts) {
>                       exit(1);
>                   }
> -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
> +
> +                /* fixup legacy sugffix-less format */
>    
s/sugffix/suffix

> +                end = qemu_opt_get(opts, "mem");
> +                if (g_ascii_isdigit(end[strlen(end) - 1])) {
> +                    s = g_strconcat(end, "M", NULL);
> +                    qemu_opt_set(opts, "mem", s);
> +                    g_free(s);
> +                }
> +
> +                sz = QEMU_ALIGN_UP(qemu_opt_get_size(opts, "mem", ram_size),
> +                                   8192);
> +                /* compatibility behaviour for case "-m 0" */
> +                if (sz == 0) {
> +                    sz = DEFAULT_RAM_SIZE * 1024 * 1024;
> +                }
> +
>                   ram_size = sz;
>                   if (ram_size != sz) {
>                       fprintf(stderr, "qemu: ram size too large\n");
>                       exit(1);
>                   }
> +                /* store aligned value for future use */
> +                qemu_opt_set_number(opts, "mem", ram_size);
> +
> +                sz = qemu_opt_get_size(opts, "maxmem", ram_size);
> +                if (sz<  ram_size) {
> +                    qemu_opt_set_number(opts, "maxmem", ram_size);
> +                }
>                   break;
>               }
>   #ifdef CONFIG_TPM
> @@ -4029,11 +4083,6 @@ int main(int argc, char **argv, char **envp)
>           exit(1);
>       }
>
> -    /* init the memory */
> -    if (ram_size == 0) {
> -        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
> -    }
> -
>       if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
>           != 0) {
>           exit(0);
>    

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

* Re: [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug
  2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
                   ` (26 preceding siblings ...)
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 27/27] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
@ 2013-11-21  6:20 ` Michael S. Tsirkin
  2013-11-21 13:39   ` Igor Mammedov
  27 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  6:20 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:21AM +0100, Igor Mammedov wrote:
> ---
> What's new since v6:
> 
> * DIMM device is split to backend and frontend. Therefore following
>   command/options were added for supporting it:
> 
>   For memdev backend:
>       CLI: -memdev-add
>       Monitor/QMP: memdev-add
>           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'
> 
> * Added Q35 support
> * Added support for 32 bit guests
> * build for i386 emulator (not tested)

OK so a large patchset so did not review yet.  One question
due to the dependency on bios honouring etc/reserved-memory-end: is
there some way to detect old BIOS and fail memory hotplug?

> ---
> 
> 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:
> 
>   memdev-add 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
>  - Windows 2008DCx32
> 
> Known limitations/bugs/TODOs:
>  - only hot-add supported
>  - 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) 
>  - failed hotplug action consumes 1 slot (device_add doesn't delete
>    device properly if realize failed)
>  - 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.
> 
> Series is based on mst's PCI tree and requires following SeaBIOS patch:
>   http://patchwork.ozlabs.org/patch/292614/
>   on top of patches to load ACPI tables from QEMU
>   working SeaBIOS tree for testing is available at:
>     https://github.com/imammedo/seabios/commits/memhp-wip
> 
> QEMU git tree for testing is available at:
>   https://github.com/imammedo/qemu/commits/memory-hotplug-v7
> 
> Example QEMU cmd line:
>   qemu-system-x86_64 -enable-kvm -monitor unix:/tmp/mon,server,nowait \ 
>      -m 4096,slots=4,maxmem=8G -L /custome_seabios guest.img
> 
> PS:
>   Windows guest requires SRAT table for hotplug to work so add extra option:
>    -numa node
>   to QEMU command line.
> 
> 
> Igor Mammedov (26):
>   acpi: factor out common pm_update_sci() into acpi core
>   rename pci_hotplug_fn to hotplug_fn and make it available for other
>     devices
>   pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
>   vl: convert -m to qemu_opts_parse()
>   qapi: add SIZE type parser to string_input_visitor
>   get reference to /backend container via qemu_get_backend()
>   add memdev backend infrastructure
>   dimm: map DimmDevice into DimBus provided address space
>   dimm: add busy slot check and slot auto-allocation
>   dimm: add busy address check and address auto-allocation
>   dimm: add hotplug callback to DimmBus
>   acpi: memory hotplug ACPI hardware implementation
>   acpi: initialize memory hotplug ACPI PIIX4 hardware
>   acpi: piix4: add memory-hotplug-io-base property to piix4_pm
>   acpi: ich9: allow guest to clear SCI rised by GPE
>   acpi: initialize memory hotplug ACPI ICH9 hardware
>   acpi: ich9: add memory-hotplug-io-base property to ich9_pm
>   acpi: piix4/ich9: add optional vmstate field for MemHotplugState
>     migration
>   pc: piix: make PCII440FXState type public
>   pc: add memory hotplug 440fx machine
>   pc: add memory hotplug Q35 machine
>   pc: ACPI BIOS: implement memory hotplug interface
>   pc: ACPI BIOS: add ssdt-mem.hex.generated and update
>     ssdt-misc.hex.generated
>   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
> 
> Vasilis Liaskovitis (1):
>   dimm: implement dimm device abstraction
> 
>  backends/Makefile.objs             |    2 +
>  backends/hostmem.c                 |  275 +++++++++++
>  backends/hostmem_compat_ram.c      |   42 ++
>  default-configs/i386-softmmu.mak   |    1 +
>  default-configs/x86_64-softmmu.mak |    1 +
>  docs/specs/acpi_mem_hotplug.txt    |   38 ++
>  hmp-commands.hx                    |   13 +
>  hw/Makefile.objs                   |    1 +
>  hw/acpi/core.c                     |  189 ++++++++
>  hw/acpi/ich9.c                     |   57 ++-
>  hw/acpi/pcihp.c                    |    6 +-
>  hw/acpi/piix4.c                    |   91 +++--
>  hw/i386/Makefile.objs              |    3 +-
>  hw/i386/acpi-build.c               |   91 ++++-
>  hw/i386/acpi-dsdt.dsl              |    5 +-
>  hw/i386/pc.c                       |   90 ++++-
>  hw/i386/pc_piix.c                  |    7 +-
>  hw/i386/pc_q35.c                   |    4 +
>  hw/i386/q35-acpi-dsdt.dsl          |    5 +-
>  hw/i386/ssdt-mem.dsl               |   75 +++
>  hw/i386/ssdt-mem.hex.generated     |  197 ++++++++
>  hw/i386/ssdt-misc.dsl              |  179 ++++++++
>  hw/i386/ssdt-misc.hex.generated    |  881 +++++++++++++++++++++++++++++++++++-
>  hw/mem/Makefile.objs               |    1 +
>  hw/mem/dimm.c                      |  321 +++++++++++++
>  hw/pci-host/piix.c                 |   36 +-
>  hw/pci-host/q35.c                  |   19 +-
>  hw/pci/pci.c                       |   12 +-
>  hw/pci/pcie.c                      |    7 +-
>  hw/pci/shpc.c                      |    9 +-
>  include/hw/acpi/acpi.h             |   42 ++
>  include/hw/acpi/ich9.h             |    6 +
>  include/hw/acpi/pcihp.h            |    2 +-
>  include/hw/acpi/piix4.h            |    2 +
>  include/hw/i386/pc.h               |   33 ++-
>  include/hw/mem/dimm.h              |   99 ++++
>  include/hw/pci-host/piix.h         |   29 ++
>  include/hw/pci-host/q35.h          |    1 +
>  include/hw/pci/pci.h               |   11 +-
>  include/hw/pci/pci_bus.h           |    2 +-
>  include/hw/qdev-core.h             |    9 +
>  include/sysemu/hostmem.h           |  102 +++++
>  include/sysemu/sysemu.h            |    3 +
>  monitor.c                          |    1 +
>  qapi-schema.json                   |   18 +
>  qapi/string-input-visitor.c        |   18 +
>  qemu-options.hx                    |   16 +-
>  qmp-commands.hx                    |   27 ++
>  ui/console.c                       |    3 +-
>  vl.c                               |   98 ++++-
>  50 files changed, 3040 insertions(+), 140 deletions(-)
>  create mode 100644 backends/hostmem.c
>  create mode 100644 backends/hostmem_compat_ram.c
>  create mode 100644 docs/specs/acpi_mem_hotplug.txt
>  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/mem/dimm.h
>  create mode 100644 include/hw/pci-host/piix.h
>  create mode 100644 include/sysemu/hostmem.h

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE Igor Mammedov
@ 2013-11-21  7:14   ` Michael S. Tsirkin
  2013-11-21  8:12     ` Hu Tao
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  7:14 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> it fixes IRQ storm since guest isn't able to lower SCI IRQ
> after it has been handled when it clears GPE event.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

The storm is only on memory hotplug right?
But memory hotplug support is only added by next
patch.
Maybe just smash with that one?

> ---
>  hw/acpi/ich9.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index e59688b..fb88162 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -61,6 +61,7 @@ static void ich9_gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
>  {
>      ICH9LPCPMRegs *pm = opaque;
>      acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val);
> +    acpi_update_sci(&pm->acpi_regs, pm->irq, ACPI_MEMORY_HOTPLUG_STATUS);
>  }
>  
>  static const MemoryRegionOps ich9_gpe_ops = {
> -- 
> 1.7.1

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

* Re: [Qemu-devel] [PATCH 26/27] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 26/27] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
@ 2013-11-21  7:18   ` Michael S. Tsirkin
  2013-11-25 10:11     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  7:18 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:47AM +0100, Igor Mammedov wrote:
> Needed for Windows to use hotplugged memory device, otherwise
> it complains that server is not configured for memory hotplug.
> Tests shows that aftewards it uses dynamically provided
> proximity value from _PXM() method if available.
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

Maybe add comment in code?
Someone reading the spec might well wonder.

> ---
>  hw/i386/acpi-build.c |   33 +++++++++++++++++++++++++++++++++
>  1 files changed, 33 insertions(+), 0 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 86c1372..ab8e923 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -50,6 +50,7 @@
>  
>  #include "qapi/qmp/qint.h"
>  #include "qom/qom-qobject.h"
> +#include "hw/mem/dimm.h"
>  
>  typedef struct AcpiCpuInfo {
>      DECLARE_BITMAP(found_cpus, MAX_CPUMASK_BITS + 1);
> @@ -1058,6 +1059,31 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
>      numamem->range_length = cpu_to_le64(len);
>  }
>  
> +typedef struct {
> +    AcpiSratMemoryAffinity **numamem;
> +    GArray *table_data;
> +} AcpiSratHotplugMemoryArg;
> +
> +static int acpi_add_hotplug_memory_region_entry(Object *obj, void *opaque)
> +{
> +    AcpiSratHotplugMemoryArg *arg = opaque;
> +    DimmBus *bus = (DimmBus *)object_dynamic_cast(obj, TYPE_DIMM_BUS);
> +
> +    if (bus) {
> +        uint64_t size = memory_region_size(&bus->as);
> +        if (size) {
> +            *arg->numamem = acpi_data_push(arg->table_data,
> +                                           sizeof **arg->numamem);
> +            acpi_build_srat_memory(*arg->numamem, bus->base, size, 0,
> +                                   HOT_PLUGGABLE_MEM | ENABLED_MEM);
> +        }
> +    }
> +
> +    object_child_foreach(obj, acpi_add_hotplug_memory_region_entry,
> +                         opaque);
> +   return 0;
> +}
> +
>  static void
>  build_srat(GArray *table_data, GArray *linker,
>             AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
> @@ -1133,6 +1159,13 @@ build_srat(GArray *table_data, GArray *linker,
>          acpi_build_srat_memory(numamem, 0, 0, 0, NOFLAGS_MEM);
>      }
>  
> +    {
> +        AcpiSratHotplugMemoryArg arg = { .numamem = &numamem,
> +                                         .table_data = table_data };
> +        object_child_foreach(qdev_get_machine(),
> +                             acpi_add_hotplug_memory_region_entry, &arg);
> +    }
> +
>      build_header(linker, table_data,
>                   (void *)(table_data->data + srat_start),
>                   ACPI_SRAT_SIGNATURE,
> -- 
> 1.7.1

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

* Re: [Qemu-devel] [PATCH 25/27] pc: ACPI BIOS: use enum for defining memory affinity flags
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 25/27] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
@ 2013-11-21  7:20   ` Michael S. Tsirkin
  2013-11-25 10:11     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  7:20 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:46AM +0100, Igor Mammedov wrote:
> 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 |   22 +++++++++++++++-------
>  1 files changed, 15 insertions(+), 7 deletions(-)
> 
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index d41fd81..86c1372 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -1038,15 +1038,22 @@ build_hpet(GArray *table_data, GArray *linker)
>                   (void *)hpet, ACPI_HPET_SIGNATURE, sizeof(*hpet), 1);
>  }
>  
> +typedef enum {
> +    NOFLAGS_MEM       = 0,
> +    ENABLED_MEM       = (1 << 0),
> +    HOT_PLUGGABLE_MEM = (1 << 1),
> +    NON_VOLATILE_MEM  = (1 << 2),
> +} MemoryAffinityFlags;

Absolutely but please use prefixes not suffixes, and make them
a bit more specific.
E.g.  MEM_AFFINITY_NOFLAGS

> +
>  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);
>  }
> @@ -1094,7 +1101,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, ENABLED_MEM);
>      next_base = 1024 * 1024;
>      for (i = 1; i < guest_info->numa_nodes + 1; ++i) {
>          mem_base = next_base;
> @@ -1110,19 +1117,20 @@ build_srat(GArray *table_data, GArray *linker,
>              mem_len -= next_base - guest_info->ram_size;
>              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,
> +                                       ENABLED_MEM);
>              }
>              mem_base = 1ULL << 32;
>              mem_len = next_base - guest_info->ram_size;
>              next_base += (1ULL << 32) - guest_info->ram_size;
>          }
>          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, ENABLED_MEM);
>      }
>      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, NOFLAGS_MEM);
>      }
>  
>      build_header(linker, table_data,
> -- 
> 1.7.1

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  7:14   ` Michael S. Tsirkin
@ 2013-11-21  8:12     ` Hu Tao
  2013-11-21  8:18       ` Li Guang
  2013-11-21  8:26       ` Michael S. Tsirkin
  0 siblings, 2 replies; 143+ messages in thread
From: Hu Tao @ 2013-11-21  8:12 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, mdroth, stefanb, mjt, marcel.a, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, Igor Mammedov, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> > it fixes IRQ storm since guest isn't able to lower SCI IRQ
> > after it has been handled when it clears GPE event.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> The storm is only on memory hotplug right?

IIRC, it happens on cpu hotplug, too.

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:12     ` Hu Tao
@ 2013-11-21  8:18       ` Li Guang
  2013-11-21  8:29         ` Michael S. Tsirkin
  2013-11-21  8:26       ` Michael S. Tsirkin
  1 sibling, 1 reply; 143+ messages in thread
From: Li Guang @ 2013-11-21  8:18 UTC (permalink / raw)
  To: Hu Tao
  Cc: peter.maydell, aliguori, marcel.a, qemu-devel, stefanb, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela,
	Michael S. Tsirkin, kraxel, stefanha, Igor Mammedov, pbonzini,
	lcapitulino, chegu_vinod, afaerber

Hu Tao wrote:
> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
>    
>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
>>      
>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
>>> after it has been handled when it clears GPE event.
>>>
>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
>>>        
>> The storm is only on memory hotplug right?
>>      
> IIRC, it happens on cpu hotplug, too.
>
>
>
>    
:-), that made remember EC implementation,
with EC, SCI will be safer, I think.

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:12     ` Hu Tao
  2013-11-21  8:18       ` Li Guang
@ 2013-11-21  8:26       ` Michael S. Tsirkin
  2013-11-21  8:28         ` Hu Tao
  2013-11-21 13:21         ` Igor Mammedov
  1 sibling, 2 replies; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  8:26 UTC (permalink / raw)
  To: Hu Tao
  Cc: peter.maydell, mdroth, stefanb, mjt, marcel.a, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, Igor Mammedov, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 04:12:22PM +0800, Hu Tao wrote:
> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> > On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> > > it fixes IRQ storm since guest isn't able to lower SCI IRQ
> > > after it has been handled when it clears GPE event.
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > 
> > The storm is only on memory hotplug right?
> 
> IIRC, it happens on cpu hotplug, too.

So this is a bugfix then? We should include this in 1.7?

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:26       ` Michael S. Tsirkin
@ 2013-11-21  8:28         ` Hu Tao
  2013-11-21 13:31           ` Igor Mammedov
  2013-11-21 13:21         ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Hu Tao @ 2013-11-21  8:28 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, mdroth, stefanb, mjt, marcel.a, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, Igor Mammedov, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 10:26:36AM +0200, Michael S. Tsirkin wrote:
> On Thu, Nov 21, 2013 at 04:12:22PM +0800, Hu Tao wrote:
> > On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> > > On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> > > > it fixes IRQ storm since guest isn't able to lower SCI IRQ
> > > > after it has been handled when it clears GPE event.
> > > > 
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > 
> > > The storm is only on memory hotplug right?
> > 
> > IIRC, it happens on cpu hotplug, too.
> 
> So this is a bugfix then? We should include this in 1.7?

Yes. but cpu hotplug support is not added for q35, so the bug doesn't
affect anyone, yet.

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:18       ` Li Guang
@ 2013-11-21  8:29         ` Michael S. Tsirkin
  2013-11-21  8:32           ` Li Guang
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  8:29 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, aliguori, marcel.a, qemu-devel, Hu Tao, stefanb,
	mjt, mdroth, armbru, vasilis.liaskovitis, quintela, kraxel,
	stefanha, Igor Mammedov, pbonzini, lcapitulino, chegu_vinod,
	afaerber

On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
> Hu Tao wrote:
> >On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> >>On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> >>>it fixes IRQ storm since guest isn't able to lower SCI IRQ
> >>>after it has been handled when it clears GPE event.
> >>>
> >>>Signed-off-by: Igor Mammedov<imammedo@redhat.com>
> >>The storm is only on memory hotplug right?
> >IIRC, it happens on cpu hotplug, too.
> >
> >
> >
> :-), that made remember EC implementation,
> with EC, SCI will be safer, I think.

Hmm you are saying let's use EC for memory hotplug?

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:29         ` Michael S. Tsirkin
@ 2013-11-21  8:32           ` Li Guang
  2013-11-21  9:43             ` Michael S. Tsirkin
  2013-11-21 13:19             ` Igor Mammedov
  0 siblings, 2 replies; 143+ messages in thread
From: Li Guang @ 2013-11-21  8:32 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, marcel.a, qemu-devel, Hu Tao, stefanb,
	mjt, mdroth, armbru, vasilis.liaskovitis, quintela, kraxel,
	stefanha, Igor Mammedov, pbonzini, lcapitulino, chegu_vinod,
	afaerber

Michael S. Tsirkin wrote:
> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
>    
>> Hu Tao wrote:
>>      
>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
>>>        
>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
>>>>          
>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
>>>>> after it has been handled when it clears GPE event.
>>>>>
>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
>>>>>            
>>>> The storm is only on memory hotplug right?
>>>>          
>>> IIRC, it happens on cpu hotplug, too.
>>>
>>>
>>>
>>>        
>> :-), that made remember EC implementation,
>> with EC, SCI will be safer, I think.
>>      
> Hmm you are saying let's use EC for memory hotplug?
>
>
>    
It can be a bridge between guest and QEMU,
with it, we may don't have to bother ASL writing
and south-bridge hardware related work(or very
little) if we implement EC correctly.

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

* Re: [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
@ 2013-11-21  9:37   ` Michael S. Tsirkin
  2013-11-25 14:39     ` Igor Mammedov
  2013-11-25 13:42   ` Paolo Bonzini
  1 sibling, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  9:37 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:44AM +0100, 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>
> ---
> mst/pci tree specific change:
>    acpi-build: s/build_append_notify/build_append_notify_method/
> introduced by "acpi-build: enable hotplug for PCI bridges"
> should be moved to separate patch since it's generic internal API rename.
> ---
>  hw/i386/Makefile.objs |    3 +-
>  hw/i386/acpi-build.c  |   36 ++++++++++
>  hw/i386/ssdt-mem.dsl  |   75 ++++++++++++++++++++
>  hw/i386/ssdt-misc.dsl |  179 +++++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 292 insertions(+), 1 deletions(-)
>  create mode 100644 hw/i386/ssdt-mem.dsl
> 
> diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
> index 185aacb..f9262a1 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 93ffb17..d41fd81 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -36,6 +36,7 @@
>  #include "hw/nvram/fw_cfg.h"
>  #include "bios-linker-loader.h"
>  #include "hw/loader.h"
> +#include "qemu/config-file.h"
>  
>  /* Supported chipsets: */
>  #include "hw/acpi/piix4.h"
> @@ -69,6 +70,7 @@ typedef struct AcpiPmInfo {
>      uint32_t gpe0_blk;
>      uint32_t gpe0_blk_len;
>      uint32_t io_base;
> +    uint16_t mem_hotplug_io_base;
>  } AcpiPmInfo;
>  
>  typedef struct AcpiMiscInfo {
> @@ -176,6 +178,8 @@ static void acpi_get_pm_info(AcpiPmInfo *pm)
>                                             NULL);
>      pm->gpe0_blk_len = object_property_get_int(obj, ACPI_PM_PROP_GPE0_BLK_LEN,
>                                                 NULL);
> +    pm->mem_hotplug_io_base =
> +        object_property_get_int(obj, ACPI_MEMORY_HOTPLUG_IO_BASE_PROP, NULL);
>  }
>  
>  static void acpi_get_misc_info(AcpiMiscInfo *info)
> @@ -632,6 +636,14 @@ static inline char acpi_get_hex(uint32_t val)
>  #define ACPI_PCIHP_SIZEOF (*ssdt_pcihp_end - *ssdt_pcihp_start)
>  #define ACPI_PCIHP_AML (ssdp_pcihp_aml + *ssdt_pcihp_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
>  
> @@ -897,6 +909,8 @@ build_ssdt(GArray *table_data, GArray *linker,
>             AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,
>             PcPciInfo *pci, PcGuestInfo *guest_info)
>  {
> +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
> +    uint32_t nr_mem = qemu_opt_get_number(opts, "slots", 0);
>      int acpi_cpus = MIN(0xff, guest_info->apic_id_limit);
>      int ssdt_start = table_data->len;
>      uint8_t *ssdt_ptr;
> @@ -920,6 +934,10 @@ build_ssdt(GArray *table_data, GArray *linker,
>      *(uint16_t *)(ssdt_ptr + *ssdt_isa_pest) =
>          cpu_to_le16(misc->pvpanic_port);
>  
> +    *(uint16_t *)(ssdt_ptr + *ssdt_mctrl_port) =
> +        cpu_to_le16(pm->mem_hotplug_io_base);
> +    *(int32_t *)(ssdt_ptr + *ssdt_mctrl_nr_slots) = cpu_to_le32(nr_mem);
> +
>      {
>          GArray *sb_scope = build_alloc_array();
>          uint8_t op = 0x10; /* ScopeOp */
> @@ -961,6 +979,24 @@ build_ssdt(GArray *table_data, GArray *linker,
>              build_free_array(package);
>          }
>  
> +        if (nr_mem) {
> +            /* 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;
>              PCIBus *bus = find_i440fx(); /* TODO: Q35 support */
> 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..b0c581e 100644
> --- a/hw/i386/ssdt-misc.dsl
> +++ b/hw/i386/ssdt-misc.dsl
> @@ -116,4 +116,183 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
>              }
>          }
>      }
> +
> +    External(MTFY, MethodObj)
> +
> +    Scope(\_SB) {
> +        Device(MHPD) {
> +            Name(_HID, EISAID("PNP0C08"))
> +
> +            ACPI_EXTRACT_NAME_WORD_CONST ssdt_mctrl_port
> +            Name(MHPP, 0xFFFF)
> +
> +            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
> +            Name(MDNR, 0x12345678)
> +
> +            /* Memory hotplug IO registers */
> +            OperationRegion(HPMR, SystemIO, MHPP, 24)
> +
> +            Method(_CRS, 0, Serialized) {
> +                Name(CRS, ResourceTemplate() {
> +                    IO(Decode16, 0x00, 0x00, 0x01, 24, IO)
> +                })


Declaring name makes us serialize it.
Can't we use a local variable?

> +
> +                CreateWordField(CRS, IO._MIN, IOMN)
> +                CreateWordField(CRS, IO._MAX, IOMX)
> +
> +                Store(MHPP, IOMN)
> +                Subtract(Add(MHPP, 24), 1, IOMX)
> +                Return(CRS)
> +            }
> +
> +            Method(_STA, 0) {
> +                If (LEqual(MDNR, Zero)) {
> +                    Return(0x0)
> +                }
> +                /* Leave bit 0 cleared to avoid Windows BSOD */
> +                Return(0xA)
> +            }
> +
> +            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),
> +                MVER, 8, // Interface version
> +                MES,  1, // 1 if DIMM enabled for _STA, read only
> +                MINS, 1, // (read) 1 if DIMM has a insert event. (write) 1 after MTFY()
> +                MRMV, 1, // 1 if DIMM has a remove request, read only
> +            }
> +
> +            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)
> +                    }
> +                    If (LEqual(MRMV, One)) { // Ejection request
> +                        MTFY(Local0, 3)
> +                    }
> +                    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 (Or(LLess(MAXL, MINL), LLess(MAXL, LENL))) {
> +                    Add(MAXH, 1, MAXH)
> +                }
> +                // Ignore (MAXL == 0 & MAXH == 0) case
> +                If (LEqual(MAXL, Zero)) {
> +                    Subtract(MAXH, One, MAXH)
> +                    Store(0xFFFFFFFF, MAXL)
> +                } Else {
> +                    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.7.1

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
@ 2013-11-21  9:42   ` Michael S. Tsirkin
  2013-11-21 14:21     ` Igor Mammedov
  2013-11-27 17:59   ` Eric Blake
  1 sibling, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  9:42 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:34AM +0100, 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
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  docs/specs/acpi_mem_hotplug.txt |   38 ++++++++++
>  hw/acpi/core.c                  |  144 +++++++++++++++++++++++++++++++++++++++
>  include/hw/acpi/acpi.h          |   24 +++++++
>  3 files changed, 206 insertions(+), 0 deletions(-)
>  create mode 100644 docs/specs/acpi_mem_hotplug.txt
> 
> diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
> new file mode 100644
> index 0000000..fc34142
> --- /dev/null
> +++ b/docs/specs/acpi_mem_hotplug.txt
> @@ -0,0 +1,38 @@
> +QEMU<->ACPI BIOS memory hotplug interface
> +--------------------------------------
> +
> +ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
> +or hot-remove 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
> +      [0x14] highest memory hot-plug interface version supported by QEMU

So this can make guest fail gracefully but it appears that
detecting guest version would be nicer?
It would let us actually support old guests ...

> +      [0x15] Memory device status fields
> +          bits:
> +              1: device is enabled and may be used by guest
> +              2: device insert event, used by ACPI BIOS to distinguish
> +                 device for which no device check event to OSPM was issued

what does the above mean?
what if device is not present?

> +      [0x16-0x17] reserved
> +
> +  write access:
> +      [0x0-0x3] Memory device slot selector, selects active memory device.
> +                All following accesses to other registers in 0xaf80-0xaf97
> +                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
> +      [0x15] Memory device status fields

this is control, not status?

> +          bits:
> +              2: if set to 1 clears device insert event, set by ACPI BIOS
> +                 after it has sent device check event to OSPM for
> +                 seleted memory device

selected?

How about we actually require guest to enable memory?

This way if we hotplug, but old guest does not enable
and puts a PCI device there, it just works.


> +
> +Selecting memory device slot beyond present range has no effect on platform:
> +   - not documented above write accesses to memory hot-plug registers
> +     are ignored;
> +   - not documented above read accesses to memory hot-plug registers return 0xFF

00 would be cleaner (matches not enabled - no event)?

> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index 8c0d48c..18e169c 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -680,3 +680,147 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq, uint32_t gpe0_sts_mask)
>                         (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
>                         !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
>  }
> +
> +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: /* intf version */
> +        val = 1;
> +        break;
> +    case 0x15: /* pack and return is_* fields */
> +        val |= mdev->is_enabled   ? 1 : 0;
> +        val |= mdev->is_inserting ? 2 : 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 0x15:
> +        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(Object *owner, MemoryRegion *io,
> +                              MemHotplugState *state)
> +{
> +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
> +    g_assert(opts);
> +
> +    state->dev_count = qemu_opt_get_number(opts, "slots", 0);
> +
> +    if (!state->dev_count) {
> +        return;
> +    }
> +
> +    state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
> +    memory_region_init_io(io, owner, &acpi_memory_hotplug_ops, state,
> +                          "apci-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
> +}
> +
> +int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
> +                           DeviceState *dev, HotplugState state)
> +{
> +    MemStatus *mdev;
> +    Error *local_err = NULL;
> +    int slot = object_property_get_int(OBJECT(dev), "slot", &local_err);
> +
> +    if (error_is_set(&local_err)) {
> +        qerror_report_err(local_err);
> +        error_free(local_err);
> +        return -1;
> +    }
> +
> +    if (slot >= mem_st->dev_count) {
> +        char *dev_path = object_get_canonical_path(OBJECT(dev));
> +        qerror_report(ERROR_CLASS_GENERIC_ERROR, "acpi_memory_hotplug_cb: "
> +                      "device [%s] returned invalid memory slot[%d]",
> +                      dev_path, slot);
> +        g_free(dev_path);
> +        return -1;
> +    }
> +
> +    mdev = &mem_st->devs[slot];
> +    if (state == HOTPLUG_ENABLED) {
> +        mdev->dimm = dev;
> +        mdev->is_enabled = true;
> +        mdev->is_inserting = true;
> +    }
> +
> +    /* do ACPI magic */
> +    regs->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
> +    return 0;
> +}
> diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> index c4ae7d7..e5717df 100644
> --- a/include/hw/acpi/acpi.h
> +++ b/include/hw/acpi/acpi.h
> @@ -168,6 +168,30 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
>  
>  void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
>  
> +#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
> +#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
> +
> +#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 {
> +    uint32_t selector;
> +    uint32_t dev_count;
> +    MemStatus *devs;
> +} MemHotplugState;
> +
> +void acpi_memory_hotplug_init(Object *owner, MemoryRegion *io,
> +                              MemHotplugState *state);
> +
> +int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
> +                           DeviceState *dev, HotplugState state);
>  /* acpi.c */
>  extern int acpi_enabled;
>  extern char unsigned *acpi_tables;
> -- 
> 1.7.1

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:32           ` Li Guang
@ 2013-11-21  9:43             ` Michael S. Tsirkin
  2013-11-22  0:57               ` Li Guang
  2013-11-21 13:19             ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21  9:43 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, aliguori, marcel.a, qemu-devel, Hu Tao, stefanb,
	mjt, mdroth, armbru, vasilis.liaskovitis, quintela, kraxel,
	stefanha, Igor Mammedov, pbonzini, lcapitulino, chegu_vinod,
	afaerber

On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
> Michael S. Tsirkin wrote:
> >On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
> >>Hu Tao wrote:
> >>>On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> >>>>On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> >>>>>it fixes IRQ storm since guest isn't able to lower SCI IRQ
> >>>>>after it has been handled when it clears GPE event.
> >>>>>
> >>>>>Signed-off-by: Igor Mammedov<imammedo@redhat.com>
> >>>>The storm is only on memory hotplug right?
> >>>IIRC, it happens on cpu hotplug, too.
> >>>
> >>>
> >>>
> >>:-), that made remember EC implementation,
> >>with EC, SCI will be safer, I think.
> >Hmm you are saying let's use EC for memory hotplug?
> >
> >
> It can be a bridge between guest and QEMU,
> with it, we may don't have to bother ASL writing
> and south-bridge hardware related work(or very
> little) if we implement EC correctly.
> 
> 


I'd like to see that. Can you write a document (just text)
for an imaginary EC support for memory hotplug?

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Igor Mammedov
  2013-11-21  6:01   ` Li Guang
@ 2013-11-21 10:12   ` Markus Armbruster
  2013-11-26 13:17     ` Igor Mammedov
  2013-11-25 12:51   ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Paolo Bonzini
  2 siblings, 1 reply; 143+ messages in thread
From: Markus Armbruster @ 2013-11-21 10:12 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, hutao, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

Igor Mammedov <imammedo@redhat.com> writes:

> Along with conversion extend -m option to support following parameters:

Please split this into two patches: first conversion to QemuOpts, then
extension.

>   "mem" - startup memory amount
>   "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 usable.
>
> v2:
>   make sure maxmem is not less than ram size
>
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  qemu-options.hx |    9 +++++-
>  vl.c            |   73 ++++++++++++++++++++++++++++++++++++++++++++++---------
>  2 files changed, 68 insertions(+), 14 deletions(-)
>
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 8b94264..fe4559b 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -210,8 +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 [mem=]megs[,slots=n,maxmem=size]\n"
> +    "                set virtual RAM size to megs MB [default="
> +    stringify(DEFAULT_RAM_SIZE) "]\n"
> +    "                mem=start-up memory amount\n"
> +    "                slots=maximum number of hotplug slots\n"
> +    "                maxmem=maximum total amount of memory\n",
> +    QEMU_ARCH_ALL)

Help text is confusing, because it discusses megs twice.  Fits right in,
as output of -help is generally confusing (to put it politely).

What about something like this:

-m [mem=]megs[,slots=n,maxmem=size]
                configure guest RAM
                mem: initial amount of guest memory (default: XXX)
                slots: number of hotplug slots (default: none)
                maxmem: maximum amount of guest memory (default: mem)

>  STEXI
>  @item -m @var{megs}
>  @findex -m
> diff --git a/vl.c b/vl.c
> index f28674f..5974f0f 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -529,6 +529,28 @@ static QemuOptsList qemu_msg_opts = {
>      },
>  };
>  
> +static QemuOptsList qemu_mem_opts = {
> +    .name = "memory-opts",
> +    .implied_opt_name = "mem",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
> +    .merge_lists = true,

Yes, because multiple -m need to accumulate.

> +    .desc = {
> +        {
> +            .name = "mem",
> +            .type = QEMU_OPT_SIZE,
> +        },
> +        {
> +            .name = "slots",
> +            .type = QEMU_OPT_NUMBER,
> +        },
> +        {
> +            .name = "maxmem",
> +            .type = QEMU_OPT_SIZE,
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
>  /**
>   * Get machine options
>   *
> @@ -2816,6 +2838,14 @@ static int object_create(QemuOpts *opts, void *opaque)
>      return 0;
>  }
>  
> +static void qemu_init_default_mem_opts(uint64_t size)
> +{
> +    QemuOpts *opts = qemu_opts_create_nofail(&qemu_mem_opts);
> +    qemu_opt_set_number(opts, "mem", size);
> +    qemu_opt_set_number(opts, "maxmem", size);
> +    qemu_opt_set_number(opts, "slots", 0);
> +}
> +

We usually don't put defaults in QemuOpts.  Instead, the code querying
QemuOpts detects and handles absence of the parameter.  Can be as simple
as qemu_opt_get_size(opts, "mem", DEFAULT_RAM_SIZE * 1024 * 1024).

See also below.

>  int main(int argc, char **argv, char **envp)
>  {
>      int i;
> @@ -2887,6 +2917,7 @@ int main(int argc, char **argv, char **envp)
>      qemu_add_opts(&qemu_tpmdev_opts);
>      qemu_add_opts(&qemu_realtime_opts);
>      qemu_add_opts(&qemu_msg_opts);
> +    qemu_add_opts(&qemu_mem_opts);
>  
>      runstate_init();
>  
> @@ -2901,7 +2932,8 @@ int main(int argc, char **argv, char **envp)
>      module_call_init(MODULE_INIT_MACHINE);
>      machine = find_default_machine();
>      cpu_model = NULL;
> -    ram_size = 0;
> +    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
> +    qemu_init_default_mem_opts(ram_size);
>      snapshot = 0;
>      cyls = heads = secs = 0;
>      translation = BIOS_ATA_TRANSLATION_AUTO;
> @@ -3178,21 +3210,43 @@ 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 *end;
> +                char *s;
>  
> -                value = strtosz(optarg, &end);
> -                if (value < 0 || *end) {
> -                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
> +                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
> +                                       optarg, 1);
> +                if (!opts) {
>                      exit(1);
>                  }
> -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
> +
> +                /* fixup legacy sugffix-less format */

/* fix up legacy suffix-less format */

The problem here is that OPT_SIZE treats values without a size suffix as
bytes, but we need to default to MiB for backward compatibility.

> +                end = qemu_opt_get(opts, "mem");
> +                if (g_ascii_isdigit(end[strlen(end) - 1])) {
> +                    s = g_strconcat(end, "M", NULL);
> +                    qemu_opt_set(opts, "mem", s);
> +                    g_free(s);
> +                }

Ugly.

Why is the variable called 'end'?

qemu_opt_set() appends to the list of options.  The un-fixed-up option
remains in the list.  qemu_opt_unset() could fix that, but it asserts
opts_accepts_any() for unclear reasons.  git-blame points to Kevin.

Have you considered qemu_opt_set_number()?

If this "need a default suffix" pattern exists elsewhere, we should
consider extending QemuOptDesc to cover it.

> +
> +                sz = QEMU_ALIGN_UP(qemu_opt_get_size(opts, "mem", ram_size),
> +                                   8192);
> +                /* compatibility behaviour for case "-m 0" */
> +                if (sz == 0) {
> +                    sz = DEFAULT_RAM_SIZE * 1024 * 1024;
> +                }
> +

Yes, this is needed.  Our command line is bonkers.

>                  ram_size = sz;
>                  if (ram_size != sz) {
>                      fprintf(stderr, "qemu: ram size too large\n");
>                      exit(1);
>                  }
> +                /* store aligned value for future use */
> +                qemu_opt_set_number(opts, "mem", ram_size);

Here, you use qemu_opt_set_number().

Again, this appends to the list, and leaves the non-aligned value in.

> +
> +                sz = qemu_opt_get_size(opts, "maxmem", ram_size);
> +                if (sz < ram_size) {
> +                    qemu_opt_set_number(opts, "maxmem", ram_size);
> +                }
>                  break;
>              }

Looks like you want to fix up something like "-m 1024", so that maxmem
stays equal to mem.  I'm afraid you also "fix" user errors like "-m
mem=1024M,maxmem=512M".

If you refrain from putting defaults into opts, you can distinguish the
cases "user didn't specify maxmem, so assume mem", and "user specified
maxmem, so check it's >= mem".

>  #ifdef CONFIG_TPM
> @@ -4029,11 +4083,6 @@ int main(int argc, char **argv, char **envp)
>          exit(1);
>      }
>  
> -    /* init the memory */
> -    if (ram_size == 0) {
> -        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
> -    }
> -
>      if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
>          != 0) {
>          exit(0);

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor Igor Mammedov
@ 2013-11-21 10:15   ` Markus Armbruster
  2013-11-25 15:36     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Markus Armbruster @ 2013-11-21 10:15 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, hutao, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

Igor Mammedov <imammedo@redhat.com> writes:

> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  qapi/string-input-visitor.c |   18 ++++++++++++++++++
>  1 files changed, 18 insertions(+), 0 deletions(-)
>
> diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
> index 8f1bc41..a152f5d 100644
> --- a/qapi/string-input-visitor.c
> +++ b/qapi/string-input-visitor.c
> @@ -97,6 +97,23 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
>      *obj = val;
>  }
>  
> +static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
> +                            Error **errp)
> +{
> +    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
> +    int64_t val;
> +    char *endp;
> +
> +    val = strtosz_suffix(siv->string ? siv->string : "", &endp,
> +                         STRTOSZ_DEFSUFFIX_B);
> +    if (val < 0 || *endp != '\0') {
> +        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name,
> +                  "a size value representible as a non-negative int64");
> +        return;
> +    }
> +    *obj = val;
> +}
> +
>  static void parse_start_optional(Visitor *v, bool *present,
>                                   const char *name, Error **errp)
>  {
> @@ -131,6 +148,7 @@ StringInputVisitor *string_input_visitor_new(const char *str)
>      v->visitor.type_bool = parse_type_bool;
>      v->visitor.type_str = parse_type_str;
>      v->visitor.type_number = parse_type_number;
> +    v->visitor.type_size = parse_type_size;
>      v->visitor.start_optional = parse_start_optional;
>  
>      v->string = str;

Does this put syntax like "value": "128M" in QMP?  If yes, NAK.  QMP
does not want fancy syntax for numbers, only plain numbers.

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:32           ` Li Guang
  2013-11-21  9:43             ` Michael S. Tsirkin
@ 2013-11-21 13:19             ` Igor Mammedov
  2013-11-22  1:03               ` Li Guang
  1 sibling, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 13:19 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, aliguori, stefanb, qemu-devel, Hu Tao,
	Michael S. Tsirkin, mjt, mdroth, armbru, vasilis.liaskovitis,
	quintela, kraxel, stefanha, pbonzini, marcel.a, lcapitulino,
	chegu_vinod, afaerber

On Thu, 21 Nov 2013 16:32:27 +0800
Li Guang <lig.fnst@cn.fujitsu.com> wrote:

> Michael S. Tsirkin wrote:
> > On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
> >    
> >> Hu Tao wrote:
> >>      
> >>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> >>>        
> >>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> >>>>          
> >>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
> >>>>> after it has been handled when it clears GPE event.
> >>>>>
> >>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
> >>>>>            
> >>>> The storm is only on memory hotplug right?
> >>>>          
> >>> IIRC, it happens on cpu hotplug, too.
> >>>
> >>>
> >>>
> >>>        
> >> :-), that made remember EC implementation,
> >> with EC, SCI will be safer, I think.
> >>      
> > Hmm you are saying let's use EC for memory hotplug?
> >
> >
> >    
> It can be a bridge between guest and QEMU,
> with it, we may don't have to bother ASL writing
> and south-bridge hardware related work(or very
> little) if we implement EC correctly.
> 
Wouldn't it require guest driver though?
Beauty of ASL/GPE it's that it supported by Windows and Linux
out of box.

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:26       ` Michael S. Tsirkin
  2013-11-21  8:28         ` Hu Tao
@ 2013-11-21 13:21         ` Igor Mammedov
  1 sibling, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 13:21 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, mdroth, stefanb, Hu Tao, marcel.a, stefanha,
	armbru, qemu-devel, vasilis.liaskovitis, quintela, mjt,
	chegu_vinod, kraxel, aliguori, pbonzini, lcapitulino, afaerber

On Thu, 21 Nov 2013 10:26:36 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 04:12:22PM +0800, Hu Tao wrote:
> > On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> > > On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> > > > it fixes IRQ storm since guest isn't able to lower SCI IRQ
> > > > after it has been handled when it clears GPE event.
> > > > 
> > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > 
> > > The storm is only on memory hotplug right?
> > 
> > IIRC, it happens on cpu hotplug, too.
> 
> So this is a bugfix then? We should include this in 1.7?

It's bug fix but, since GPE event's werent' used by by Q35 before
it doesn't affect 1.7.

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  8:28         ` Hu Tao
@ 2013-11-21 13:31           ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 13:31 UTC (permalink / raw)
  To: Hu Tao
  Cc: peter.maydell, mdroth, Michael S. Tsirkin, qemu-devel, mjt,
	stefanb, stefanha, armbru, lcapitulino, vasilis.liaskovitis,
	quintela, chegu_vinod, kraxel, aliguori, pbonzini, marcel.a,
	afaerber

On Thu, 21 Nov 2013 16:28:40 +0800
Hu Tao <hutao@cn.fujitsu.com> wrote:

> On Thu, Nov 21, 2013 at 10:26:36AM +0200, Michael S. Tsirkin wrote:
> > On Thu, Nov 21, 2013 at 04:12:22PM +0800, Hu Tao wrote:
> > > On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> > > > On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> > > > > it fixes IRQ storm since guest isn't able to lower SCI IRQ
> > > > > after it has been handled when it clears GPE event.
> > > > > 
> > > > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > > 
> > > > The storm is only on memory hotplug right?
> > > 
> > > IIRC, it happens on cpu hotplug, too.
> > 
> > So this is a bugfix then? We should include this in 1.7?
> 
> Yes. but cpu hotplug support is not added for q35, so the bug doesn't
> affect anyone, yet.
> 

I was thinking about CPU hotplug for q35 as well, thus patch

1/27 "acpi: factor out common pm_update_sci() into acpi core"

moves common for CPU/Memory hotplug ACPI bits into generic code,
so making CPU hotplug for q35 would require only unifying CPU
hotplug bits and plumbing it in q35 its done for mem hotplug in:

 [PATCH 17/27] acpi: initialize memory hotplug ACPI ICH9 hardware

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

* Re: [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug
  2013-11-21  6:20 ` [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Michael S. Tsirkin
@ 2013-11-21 13:39   ` Igor Mammedov
  2013-11-21 13:43     ` Michael S. Tsirkin
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 13:39 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, 21 Nov 2013 08:20:56 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:38:21AM +0100, Igor Mammedov wrote:
> > ---
> > What's new since v6:
> > 
> > * DIMM device is split to backend and frontend. Therefore following
> >   command/options were added for supporting it:
> > 
> >   For memdev backend:
> >       CLI: -memdev-add
> >       Monitor/QMP: memdev-add
> >           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'
> > 
> > * Added Q35 support
> > * Added support for 32 bit guests
> > * build for i386 emulator (not tested)
> 
> OK so a large patchset so did not review yet.  One question
> due to the dependency on bios honouring etc/reserved-memory-end: is
> there some way to detect old BIOS and fail memory hotplug?
version negotiation between ASL and hardware could be used to that effect.

QEMU could start with present but disabled memory hotplug and if
QEMU and BIOS ASL could come in agreement that both support it in
compatible way, it could be enabled.

> 
> > ---
> > 
> > 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:
> > 
> >   memdev-add 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
> >  - Windows 2008DCx32
> > 
> > Known limitations/bugs/TODOs:
> >  - only hot-add supported
> >  - 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) 
> >  - failed hotplug action consumes 1 slot (device_add doesn't delete
> >    device properly if realize failed)
> >  - 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.
> > 
> > Series is based on mst's PCI tree and requires following SeaBIOS patch:
> >   http://patchwork.ozlabs.org/patch/292614/
> >   on top of patches to load ACPI tables from QEMU
> >   working SeaBIOS tree for testing is available at:
> >     https://github.com/imammedo/seabios/commits/memhp-wip
> > 
> > QEMU git tree for testing is available at:
> >   https://github.com/imammedo/qemu/commits/memory-hotplug-v7
> > 
> > Example QEMU cmd line:
> >   qemu-system-x86_64 -enable-kvm -monitor unix:/tmp/mon,server,nowait \ 
> >      -m 4096,slots=4,maxmem=8G -L /custome_seabios guest.img
> > 
> > PS:
> >   Windows guest requires SRAT table for hotplug to work so add extra option:
> >    -numa node
> >   to QEMU command line.
> > 
> > 
> > Igor Mammedov (26):
> >   acpi: factor out common pm_update_sci() into acpi core
> >   rename pci_hotplug_fn to hotplug_fn and make it available for other
> >     devices
> >   pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
> >   vl: convert -m to qemu_opts_parse()
> >   qapi: add SIZE type parser to string_input_visitor
> >   get reference to /backend container via qemu_get_backend()
> >   add memdev backend infrastructure
> >   dimm: map DimmDevice into DimBus provided address space
> >   dimm: add busy slot check and slot auto-allocation
> >   dimm: add busy address check and address auto-allocation
> >   dimm: add hotplug callback to DimmBus
> >   acpi: memory hotplug ACPI hardware implementation
> >   acpi: initialize memory hotplug ACPI PIIX4 hardware
> >   acpi: piix4: add memory-hotplug-io-base property to piix4_pm
> >   acpi: ich9: allow guest to clear SCI rised by GPE
> >   acpi: initialize memory hotplug ACPI ICH9 hardware
> >   acpi: ich9: add memory-hotplug-io-base property to ich9_pm
> >   acpi: piix4/ich9: add optional vmstate field for MemHotplugState
> >     migration
> >   pc: piix: make PCII440FXState type public
> >   pc: add memory hotplug 440fx machine
> >   pc: add memory hotplug Q35 machine
> >   pc: ACPI BIOS: implement memory hotplug interface
> >   pc: ACPI BIOS: add ssdt-mem.hex.generated and update
> >     ssdt-misc.hex.generated
> >   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
> > 
> > Vasilis Liaskovitis (1):
> >   dimm: implement dimm device abstraction
> > 
> >  backends/Makefile.objs             |    2 +
> >  backends/hostmem.c                 |  275 +++++++++++
> >  backends/hostmem_compat_ram.c      |   42 ++
> >  default-configs/i386-softmmu.mak   |    1 +
> >  default-configs/x86_64-softmmu.mak |    1 +
> >  docs/specs/acpi_mem_hotplug.txt    |   38 ++
> >  hmp-commands.hx                    |   13 +
> >  hw/Makefile.objs                   |    1 +
> >  hw/acpi/core.c                     |  189 ++++++++
> >  hw/acpi/ich9.c                     |   57 ++-
> >  hw/acpi/pcihp.c                    |    6 +-
> >  hw/acpi/piix4.c                    |   91 +++--
> >  hw/i386/Makefile.objs              |    3 +-
> >  hw/i386/acpi-build.c               |   91 ++++-
> >  hw/i386/acpi-dsdt.dsl              |    5 +-
> >  hw/i386/pc.c                       |   90 ++++-
> >  hw/i386/pc_piix.c                  |    7 +-
> >  hw/i386/pc_q35.c                   |    4 +
> >  hw/i386/q35-acpi-dsdt.dsl          |    5 +-
> >  hw/i386/ssdt-mem.dsl               |   75 +++
> >  hw/i386/ssdt-mem.hex.generated     |  197 ++++++++
> >  hw/i386/ssdt-misc.dsl              |  179 ++++++++
> >  hw/i386/ssdt-misc.hex.generated    |  881 +++++++++++++++++++++++++++++++++++-
> >  hw/mem/Makefile.objs               |    1 +
> >  hw/mem/dimm.c                      |  321 +++++++++++++
> >  hw/pci-host/piix.c                 |   36 +-
> >  hw/pci-host/q35.c                  |   19 +-
> >  hw/pci/pci.c                       |   12 +-
> >  hw/pci/pcie.c                      |    7 +-
> >  hw/pci/shpc.c                      |    9 +-
> >  include/hw/acpi/acpi.h             |   42 ++
> >  include/hw/acpi/ich9.h             |    6 +
> >  include/hw/acpi/pcihp.h            |    2 +-
> >  include/hw/acpi/piix4.h            |    2 +
> >  include/hw/i386/pc.h               |   33 ++-
> >  include/hw/mem/dimm.h              |   99 ++++
> >  include/hw/pci-host/piix.h         |   29 ++
> >  include/hw/pci-host/q35.h          |    1 +
> >  include/hw/pci/pci.h               |   11 +-
> >  include/hw/pci/pci_bus.h           |    2 +-
> >  include/hw/qdev-core.h             |    9 +
> >  include/sysemu/hostmem.h           |  102 +++++
> >  include/sysemu/sysemu.h            |    3 +
> >  monitor.c                          |    1 +
> >  qapi-schema.json                   |   18 +
> >  qapi/string-input-visitor.c        |   18 +
> >  qemu-options.hx                    |   16 +-
> >  qmp-commands.hx                    |   27 ++
> >  ui/console.c                       |    3 +-
> >  vl.c                               |   98 ++++-
> >  50 files changed, 3040 insertions(+), 140 deletions(-)
> >  create mode 100644 backends/hostmem.c
> >  create mode 100644 backends/hostmem_compat_ram.c
> >  create mode 100644 docs/specs/acpi_mem_hotplug.txt
> >  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/mem/dimm.h
> >  create mode 100644 include/hw/pci-host/piix.h
> >  create mode 100644 include/sysemu/hostmem.h

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

* Re: [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug
  2013-11-21 13:39   ` Igor Mammedov
@ 2013-11-21 13:43     ` Michael S. Tsirkin
  2013-11-21 14:37       ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21 13:43 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 02:39:10PM +0100, Igor Mammedov wrote:
> On Thu, 21 Nov 2013 08:20:56 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Nov 21, 2013 at 03:38:21AM +0100, Igor Mammedov wrote:
> > > ---
> > > What's new since v6:
> > > 
> > > * DIMM device is split to backend and frontend. Therefore following
> > >   command/options were added for supporting it:
> > > 
> > >   For memdev backend:
> > >       CLI: -memdev-add
> > >       Monitor/QMP: memdev-add
> > >           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'
> > > 
> > > * Added Q35 support
> > > * Added support for 32 bit guests
> > > * build for i386 emulator (not tested)
> > 
> > OK so a large patchset so did not review yet.  One question
> > due to the dependency on bios honouring etc/reserved-memory-end: is
> > there some way to detect old BIOS and fail memory hotplug?
> version negotiation between ASL and hardware could be used to that effect.
> 
> QEMU could start with present but disabled memory hotplug and if
> QEMU and BIOS ASL could come in agreement that both support it in
> compatible way, it could be enabled.

So at the moment there's no negotiation, is there?


> > 
> > > ---
> > > 
> > > 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:
> > > 
> > >   memdev-add 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
> > >  - Windows 2008DCx32
> > > 
> > > Known limitations/bugs/TODOs:
> > >  - only hot-add supported
> > >  - 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) 
> > >  - failed hotplug action consumes 1 slot (device_add doesn't delete
> > >    device properly if realize failed)
> > >  - 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.
> > > 
> > > Series is based on mst's PCI tree and requires following SeaBIOS patch:
> > >   http://patchwork.ozlabs.org/patch/292614/
> > >   on top of patches to load ACPI tables from QEMU
> > >   working SeaBIOS tree for testing is available at:
> > >     https://github.com/imammedo/seabios/commits/memhp-wip
> > > 
> > > QEMU git tree for testing is available at:
> > >   https://github.com/imammedo/qemu/commits/memory-hotplug-v7
> > > 
> > > Example QEMU cmd line:
> > >   qemu-system-x86_64 -enable-kvm -monitor unix:/tmp/mon,server,nowait \ 
> > >      -m 4096,slots=4,maxmem=8G -L /custome_seabios guest.img
> > > 
> > > PS:
> > >   Windows guest requires SRAT table for hotplug to work so add extra option:
> > >    -numa node
> > >   to QEMU command line.
> > > 
> > > 
> > > Igor Mammedov (26):
> > >   acpi: factor out common pm_update_sci() into acpi core
> > >   rename pci_hotplug_fn to hotplug_fn and make it available for other
> > >     devices
> > >   pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
> > >   vl: convert -m to qemu_opts_parse()
> > >   qapi: add SIZE type parser to string_input_visitor
> > >   get reference to /backend container via qemu_get_backend()
> > >   add memdev backend infrastructure
> > >   dimm: map DimmDevice into DimBus provided address space
> > >   dimm: add busy slot check and slot auto-allocation
> > >   dimm: add busy address check and address auto-allocation
> > >   dimm: add hotplug callback to DimmBus
> > >   acpi: memory hotplug ACPI hardware implementation
> > >   acpi: initialize memory hotplug ACPI PIIX4 hardware
> > >   acpi: piix4: add memory-hotplug-io-base property to piix4_pm
> > >   acpi: ich9: allow guest to clear SCI rised by GPE
> > >   acpi: initialize memory hotplug ACPI ICH9 hardware
> > >   acpi: ich9: add memory-hotplug-io-base property to ich9_pm
> > >   acpi: piix4/ich9: add optional vmstate field for MemHotplugState
> > >     migration
> > >   pc: piix: make PCII440FXState type public
> > >   pc: add memory hotplug 440fx machine
> > >   pc: add memory hotplug Q35 machine
> > >   pc: ACPI BIOS: implement memory hotplug interface
> > >   pc: ACPI BIOS: add ssdt-mem.hex.generated and update
> > >     ssdt-misc.hex.generated
> > >   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
> > > 
> > > Vasilis Liaskovitis (1):
> > >   dimm: implement dimm device abstraction
> > > 
> > >  backends/Makefile.objs             |    2 +
> > >  backends/hostmem.c                 |  275 +++++++++++
> > >  backends/hostmem_compat_ram.c      |   42 ++
> > >  default-configs/i386-softmmu.mak   |    1 +
> > >  default-configs/x86_64-softmmu.mak |    1 +
> > >  docs/specs/acpi_mem_hotplug.txt    |   38 ++
> > >  hmp-commands.hx                    |   13 +
> > >  hw/Makefile.objs                   |    1 +
> > >  hw/acpi/core.c                     |  189 ++++++++
> > >  hw/acpi/ich9.c                     |   57 ++-
> > >  hw/acpi/pcihp.c                    |    6 +-
> > >  hw/acpi/piix4.c                    |   91 +++--
> > >  hw/i386/Makefile.objs              |    3 +-
> > >  hw/i386/acpi-build.c               |   91 ++++-
> > >  hw/i386/acpi-dsdt.dsl              |    5 +-
> > >  hw/i386/pc.c                       |   90 ++++-
> > >  hw/i386/pc_piix.c                  |    7 +-
> > >  hw/i386/pc_q35.c                   |    4 +
> > >  hw/i386/q35-acpi-dsdt.dsl          |    5 +-
> > >  hw/i386/ssdt-mem.dsl               |   75 +++
> > >  hw/i386/ssdt-mem.hex.generated     |  197 ++++++++
> > >  hw/i386/ssdt-misc.dsl              |  179 ++++++++
> > >  hw/i386/ssdt-misc.hex.generated    |  881 +++++++++++++++++++++++++++++++++++-
> > >  hw/mem/Makefile.objs               |    1 +
> > >  hw/mem/dimm.c                      |  321 +++++++++++++
> > >  hw/pci-host/piix.c                 |   36 +-
> > >  hw/pci-host/q35.c                  |   19 +-
> > >  hw/pci/pci.c                       |   12 +-
> > >  hw/pci/pcie.c                      |    7 +-
> > >  hw/pci/shpc.c                      |    9 +-
> > >  include/hw/acpi/acpi.h             |   42 ++
> > >  include/hw/acpi/ich9.h             |    6 +
> > >  include/hw/acpi/pcihp.h            |    2 +-
> > >  include/hw/acpi/piix4.h            |    2 +
> > >  include/hw/i386/pc.h               |   33 ++-
> > >  include/hw/mem/dimm.h              |   99 ++++
> > >  include/hw/pci-host/piix.h         |   29 ++
> > >  include/hw/pci-host/q35.h          |    1 +
> > >  include/hw/pci/pci.h               |   11 +-
> > >  include/hw/pci/pci_bus.h           |    2 +-
> > >  include/hw/qdev-core.h             |    9 +
> > >  include/sysemu/hostmem.h           |  102 +++++
> > >  include/sysemu/sysemu.h            |    3 +
> > >  monitor.c                          |    1 +
> > >  qapi-schema.json                   |   18 +
> > >  qapi/string-input-visitor.c        |   18 +
> > >  qemu-options.hx                    |   16 +-
> > >  qmp-commands.hx                    |   27 ++
> > >  ui/console.c                       |    3 +-
> > >  vl.c                               |   98 ++++-
> > >  50 files changed, 3040 insertions(+), 140 deletions(-)
> > >  create mode 100644 backends/hostmem.c
> > >  create mode 100644 backends/hostmem_compat_ram.c
> > >  create mode 100644 docs/specs/acpi_mem_hotplug.txt
> > >  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/mem/dimm.h
> > >  create mode 100644 include/hw/pci-host/piix.h
> > >  create mode 100644 include/sysemu/hostmem.h

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-21  6:01   ` Li Guang
@ 2013-11-21 13:45     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 13:45 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, aliguori, stefanb, armbru, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha, hutao,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Thu, 21 Nov 2013 14:01:43 +0800
Li Guang <lig.fnst@cn.fujitsu.com> wrote:

> Igor Mammedov wrote:
> > Along with conversion extend -m option to support following parameters
> >    
> ...
> > +                if (!opts) {
> >                       exit(1);
> >                   }
> > -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
> > +
> > +                /* fixup legacy sugffix-less format */
> >    
> s/sugffix/suffix
> 
Thaks, fixed in memhpv2-wip-on-pci tree

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21  5:48   ` Li Guang
@ 2013-11-21 14:13     ` Andreas Färber
  2013-11-21 14:34       ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Andreas Färber @ 2013-11-21 14:13 UTC (permalink / raw)
  To: Li Guang, Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, armbru, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha, hutao,
	pbonzini, marcel.a, lcapitulino, chegu_vinod

Am 21.11.2013 06:48, schrieb Li Guang:
> Hi, Igor
> 
> Igor Mammedov wrote:
>> Add DimmBus for memory hotplug below 4Gb or above 4Gb depending
>> on initial memory size and hotplug memory size.
>>    
> ...
>> +static
>> +void pc_hotplug_memory_init_impl(Object *owner,
>> +                                 MemoryRegion *system_memory,
>> +                                 ram_addr_t low_hotplug_mem_start,
>> +                                 ram_addr_t low_hotplug_mem_end,
>> +                                 DimmBus *hotplug_mem_bus,
>> +                                 ram_addr_t *high_mem_end)
>> +{
>> +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"),
>> NULL);
>> +    ram_addr_t ram_size = qemu_opt_get_size(opts, "mem", 0);
>> +    ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", 0);
>> +    ram_addr_t hotplug_mem_size;
>> +
>> +    if (maxmem<= ram_size) {
>> +        /* Disable ACPI migration code and creation of memory devices
>> in SSDT */
>>    
> 
> Why not give the memory that not be hot-added a chance to be placed on
> one memory slot?

Seconded, I believe I requested that on the previous version already.

Andreas

> if all memory can be hot-added and hot-removed, then we can bring in
> more flexibility for
> memory hotplug feature.

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-21  9:42   ` Michael S. Tsirkin
@ 2013-11-21 14:21     ` Igor Mammedov
  2013-11-21 14:38       ` Michael S. Tsirkin
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 14:21 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, 21 Nov 2013 11:42:02 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:38:34AM +0100, 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
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  docs/specs/acpi_mem_hotplug.txt |   38 ++++++++++
> >  hw/acpi/core.c                  |  144 +++++++++++++++++++++++++++++++++++++++
> >  include/hw/acpi/acpi.h          |   24 +++++++
> >  3 files changed, 206 insertions(+), 0 deletions(-)
> >  create mode 100644 docs/specs/acpi_mem_hotplug.txt
> > 
> > diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
> > new file mode 100644
> > index 0000000..fc34142
> > --- /dev/null
> > +++ b/docs/specs/acpi_mem_hotplug.txt
> > @@ -0,0 +1,38 @@
> > +QEMU<->ACPI BIOS memory hotplug interface
> > +--------------------------------------
> > +
> > +ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
> > +or hot-remove 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
> > +      [0x14] highest memory hot-plug interface version supported by QEMU
> 
> So this can make guest fail gracefully but it appears that
> detecting guest version would be nicer?
> It would let us actually support old guests ...

my idea of how to it was,
guest writes its version into [0x14] register and reads QEMU version
from it back, if they do not match then than BIOS ignores GPE.3 event
effectively disabling hotplug on guest side.
I haven't thought about supporting multiple implementations in QEMU though.
Do we really want it?

> 
> > +      [0x15] Memory device status fields
> > +          bits:
> > +              1: device is enabled and may be used by guest
> > +              2: device insert event, used by ACPI BIOS to distinguish
> > +                 device for which no device check event to OSPM was issued
> 
> what does the above mean?
After OSPM issued device check on selected device it clears this bit to mark event
as handled.
It allows to avoid keeping this state in ASL (as it's done for CPU hotplug, see CPON)

> what if device is not present?
ASL will issue device check and clear bit, it might be a bug since _STA would report
not present but no eject event was issued.

Papering over it ASL could check present bit first and issue device check only if
it's present.

> 
> > +      [0x16-0x17] reserved
> > +
> > +  write access:
> > +      [0x0-0x3] Memory device slot selector, selects active memory device.
> > +                All following accesses to other registers in 0xaf80-0xaf97
> > +                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
> > +      [0x15] Memory device status fields
> 
> this is control, not status?
Thanks, I'll fix it.

> 
> > +          bits:
> > +              2: if set to 1 clears device insert event, set by ACPI BIOS
> > +                 after it has sent device check event to OSPM for
> > +                 seleted memory device
> 
> selected?
see "write access: [0x0-0x3]"

> 
> How about we actually require guest to enable memory?
> 
> This way if we hotplug, but old guest does not enable
> and puts a PCI device there, it just works.
I've lost you here, could you elaborate pls?

> 
> > +
> > +Selecting memory device slot beyond present range has no effect on platform:
> > +   - not documented above write accesses to memory hot-plug registers
> > +     are ignored;
> > +   - not documented above read accesses to memory hot-plug registers return 0xFF
> 
> 00 would be cleaner (matches not enabled - no event)?
I'm following pattern, where reading from not present IO port returns 0xFF on hardware.
Fact that ASL reads 0xFF could be used as not supported indication.

> 
> > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > index 8c0d48c..18e169c 100644
> > --- a/hw/acpi/core.c
> > +++ b/hw/acpi/core.c
> > @@ -680,3 +680,147 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq, uint32_t gpe0_sts_mask)
> >                         (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> >                         !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
> >  }
> > +
> > +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: /* intf version */
> > +        val = 1;
> > +        break;
> > +    case 0x15: /* pack and return is_* fields */
> > +        val |= mdev->is_enabled   ? 1 : 0;
> > +        val |= mdev->is_inserting ? 2 : 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 0x15:
> > +        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(Object *owner, MemoryRegion *io,
> > +                              MemHotplugState *state)
> > +{
> > +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
> > +    g_assert(opts);
> > +
> > +    state->dev_count = qemu_opt_get_number(opts, "slots", 0);
> > +
> > +    if (!state->dev_count) {
> > +        return;
> > +    }
> > +
> > +    state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
> > +    memory_region_init_io(io, owner, &acpi_memory_hotplug_ops, state,
> > +                          "apci-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
> > +}
> > +
> > +int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
> > +                           DeviceState *dev, HotplugState state)
> > +{
> > +    MemStatus *mdev;
> > +    Error *local_err = NULL;
> > +    int slot = object_property_get_int(OBJECT(dev), "slot", &local_err);
> > +
> > +    if (error_is_set(&local_err)) {
> > +        qerror_report_err(local_err);
> > +        error_free(local_err);
> > +        return -1;
> > +    }
> > +
> > +    if (slot >= mem_st->dev_count) {
> > +        char *dev_path = object_get_canonical_path(OBJECT(dev));
> > +        qerror_report(ERROR_CLASS_GENERIC_ERROR, "acpi_memory_hotplug_cb: "
> > +                      "device [%s] returned invalid memory slot[%d]",
> > +                      dev_path, slot);
> > +        g_free(dev_path);
> > +        return -1;
> > +    }
> > +
> > +    mdev = &mem_st->devs[slot];
> > +    if (state == HOTPLUG_ENABLED) {
> > +        mdev->dimm = dev;
> > +        mdev->is_enabled = true;
> > +        mdev->is_inserting = true;
> > +    }
> > +
> > +    /* do ACPI magic */
> > +    regs->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
> > +    return 0;
> > +}
> > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > index c4ae7d7..e5717df 100644
> > --- a/include/hw/acpi/acpi.h
> > +++ b/include/hw/acpi/acpi.h
> > @@ -168,6 +168,30 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
> >  
> >  void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
> >  
> > +#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
> > +#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
> > +
> > +#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 {
> > +    uint32_t selector;
> > +    uint32_t dev_count;
> > +    MemStatus *devs;
> > +} MemHotplugState;
> > +
> > +void acpi_memory_hotplug_init(Object *owner, MemoryRegion *io,
> > +                              MemHotplugState *state);
> > +
> > +int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
> > +                           DeviceState *dev, HotplugState state);
> >  /* acpi.c */
> >  extern int acpi_enabled;
> >  extern char unsigned *acpi_tables;
> > -- 
> > 1.7.1

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21 14:13     ` Andreas Färber
@ 2013-11-21 14:34       ` Igor Mammedov
  2013-11-21 14:39         ` Michael S. Tsirkin
  2013-11-21 16:09         ` Andreas Färber
  0 siblings, 2 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 14:34 UTC (permalink / raw)
  To: Andreas Färber
  Cc: peter.maydell, mdroth, mst, hutao, stefanb, mjt, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, stefanha, Li Guang

On Thu, 21 Nov 2013 15:13:12 +0100
Andreas Färber <afaerber@suse.de> wrote:

> Am 21.11.2013 06:48, schrieb Li Guang:
> > Hi, Igor
> > 
> > Igor Mammedov wrote:
> >> Add DimmBus for memory hotplug below 4Gb or above 4Gb depending
> >> on initial memory size and hotplug memory size.
> >>    
> > ...
> >> +static
> >> +void pc_hotplug_memory_init_impl(Object *owner,
> >> +                                 MemoryRegion *system_memory,
> >> +                                 ram_addr_t low_hotplug_mem_start,
> >> +                                 ram_addr_t low_hotplug_mem_end,
> >> +                                 DimmBus *hotplug_mem_bus,
> >> +                                 ram_addr_t *high_mem_end)
> >> +{
> >> +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"),
> >> NULL);
> >> +    ram_addr_t ram_size = qemu_opt_get_size(opts, "mem", 0);
> >> +    ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", 0);
> >> +    ram_addr_t hotplug_mem_size;
> >> +
> >> +    if (maxmem<= ram_size) {
> >> +        /* Disable ACPI migration code and creation of memory devices
> >> in SSDT */
> >>    
> > 
> > Why not give the memory that not be hot-added a chance to be placed on
> > one memory slot?
> 
> Seconded, I believe I requested that on the previous version already.
Because current initial memory allocation is a mess and this already
large series would become even more large and intrusive, so far series
it relatively not intrusive and self contained.

I believe re-factoring of initial memory to use Dimm devices should be
done later on top of infrastructure this series provides.

> Andreas
> 
> > if all memory can be hot-added and hot-removed, then we can bring in
> > more flexibility for
> > memory hotplug feature.
> 

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

* Re: [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug
  2013-11-21 13:43     ` Michael S. Tsirkin
@ 2013-11-21 14:37       ` Igor Mammedov
  2013-11-21 14:45         ` Michael S. Tsirkin
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-21 14:37 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, marcel.a, armbru, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, hutao, pbonzini, lcapitulino, chegu_vinod, afaerber

On Thu, 21 Nov 2013 15:43:27 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 02:39:10PM +0100, Igor Mammedov wrote:
> > On Thu, 21 Nov 2013 08:20:56 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Nov 21, 2013 at 03:38:21AM +0100, Igor Mammedov wrote:
> > > > ---
> > > > What's new since v6:
> > > > 
> > > > * DIMM device is split to backend and frontend. Therefore following
> > > >   command/options were added for supporting it:
> > > > 
> > > >   For memdev backend:
> > > >       CLI: -memdev-add
> > > >       Monitor/QMP: memdev-add
> > > >           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'
> > > > 
> > > > * Added Q35 support
> > > > * Added support for 32 bit guests
> > > > * build for i386 emulator (not tested)
> > > 
> > > OK so a large patchset so did not review yet.  One question
> > > due to the dependency on bios honouring etc/reserved-memory-end: is
> > > there some way to detect old BIOS and fail memory hotplug?
> > version negotiation between ASL and hardware could be used to that effect.
> > 
> > QEMU could start with present but disabled memory hotplug and if
> > QEMU and BIOS ASL could come in agreement that both support it in
> > compatible way, it could be enabled.
> 
> So at the moment there's no negotiation, is there?
Nope, I surely can add it in next iteration.

> 
> > > 
> > > > ---
> > > > 
> > > > 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:
> > > > 
> > > >   memdev-add 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
> > > >  - Windows 2008DCx32
> > > > 
> > > > Known limitations/bugs/TODOs:
> > > >  - only hot-add supported
> > > >  - 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) 
> > > >  - failed hotplug action consumes 1 slot (device_add doesn't delete
> > > >    device properly if realize failed)
> > > >  - 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.
> > > > 
> > > > Series is based on mst's PCI tree and requires following SeaBIOS patch:
> > > >   http://patchwork.ozlabs.org/patch/292614/
> > > >   on top of patches to load ACPI tables from QEMU
> > > >   working SeaBIOS tree for testing is available at:
> > > >     https://github.com/imammedo/seabios/commits/memhp-wip
> > > > 
> > > > QEMU git tree for testing is available at:
> > > >   https://github.com/imammedo/qemu/commits/memory-hotplug-v7
> > > > 
> > > > Example QEMU cmd line:
> > > >   qemu-system-x86_64 -enable-kvm -monitor unix:/tmp/mon,server,nowait \ 
> > > >      -m 4096,slots=4,maxmem=8G -L /custome_seabios guest.img
> > > > 
> > > > PS:
> > > >   Windows guest requires SRAT table for hotplug to work so add extra option:
> > > >    -numa node
> > > >   to QEMU command line.
> > > > 
> > > > 
> > > > Igor Mammedov (26):
> > > >   acpi: factor out common pm_update_sci() into acpi core
> > > >   rename pci_hotplug_fn to hotplug_fn and make it available for other
> > > >     devices
> > > >   pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
> > > >   vl: convert -m to qemu_opts_parse()
> > > >   qapi: add SIZE type parser to string_input_visitor
> > > >   get reference to /backend container via qemu_get_backend()
> > > >   add memdev backend infrastructure
> > > >   dimm: map DimmDevice into DimBus provided address space
> > > >   dimm: add busy slot check and slot auto-allocation
> > > >   dimm: add busy address check and address auto-allocation
> > > >   dimm: add hotplug callback to DimmBus
> > > >   acpi: memory hotplug ACPI hardware implementation
> > > >   acpi: initialize memory hotplug ACPI PIIX4 hardware
> > > >   acpi: piix4: add memory-hotplug-io-base property to piix4_pm
> > > >   acpi: ich9: allow guest to clear SCI rised by GPE
> > > >   acpi: initialize memory hotplug ACPI ICH9 hardware
> > > >   acpi: ich9: add memory-hotplug-io-base property to ich9_pm
> > > >   acpi: piix4/ich9: add optional vmstate field for MemHotplugState
> > > >     migration
> > > >   pc: piix: make PCII440FXState type public
> > > >   pc: add memory hotplug 440fx machine
> > > >   pc: add memory hotplug Q35 machine
> > > >   pc: ACPI BIOS: implement memory hotplug interface
> > > >   pc: ACPI BIOS: add ssdt-mem.hex.generated and update
> > > >     ssdt-misc.hex.generated
> > > >   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
> > > > 
> > > > Vasilis Liaskovitis (1):
> > > >   dimm: implement dimm device abstraction
> > > > 
> > > >  backends/Makefile.objs             |    2 +
> > > >  backends/hostmem.c                 |  275 +++++++++++
> > > >  backends/hostmem_compat_ram.c      |   42 ++
> > > >  default-configs/i386-softmmu.mak   |    1 +
> > > >  default-configs/x86_64-softmmu.mak |    1 +
> > > >  docs/specs/acpi_mem_hotplug.txt    |   38 ++
> > > >  hmp-commands.hx                    |   13 +
> > > >  hw/Makefile.objs                   |    1 +
> > > >  hw/acpi/core.c                     |  189 ++++++++
> > > >  hw/acpi/ich9.c                     |   57 ++-
> > > >  hw/acpi/pcihp.c                    |    6 +-
> > > >  hw/acpi/piix4.c                    |   91 +++--
> > > >  hw/i386/Makefile.objs              |    3 +-
> > > >  hw/i386/acpi-build.c               |   91 ++++-
> > > >  hw/i386/acpi-dsdt.dsl              |    5 +-
> > > >  hw/i386/pc.c                       |   90 ++++-
> > > >  hw/i386/pc_piix.c                  |    7 +-
> > > >  hw/i386/pc_q35.c                   |    4 +
> > > >  hw/i386/q35-acpi-dsdt.dsl          |    5 +-
> > > >  hw/i386/ssdt-mem.dsl               |   75 +++
> > > >  hw/i386/ssdt-mem.hex.generated     |  197 ++++++++
> > > >  hw/i386/ssdt-misc.dsl              |  179 ++++++++
> > > >  hw/i386/ssdt-misc.hex.generated    |  881 +++++++++++++++++++++++++++++++++++-
> > > >  hw/mem/Makefile.objs               |    1 +
> > > >  hw/mem/dimm.c                      |  321 +++++++++++++
> > > >  hw/pci-host/piix.c                 |   36 +-
> > > >  hw/pci-host/q35.c                  |   19 +-
> > > >  hw/pci/pci.c                       |   12 +-
> > > >  hw/pci/pcie.c                      |    7 +-
> > > >  hw/pci/shpc.c                      |    9 +-
> > > >  include/hw/acpi/acpi.h             |   42 ++
> > > >  include/hw/acpi/ich9.h             |    6 +
> > > >  include/hw/acpi/pcihp.h            |    2 +-
> > > >  include/hw/acpi/piix4.h            |    2 +
> > > >  include/hw/i386/pc.h               |   33 ++-
> > > >  include/hw/mem/dimm.h              |   99 ++++
> > > >  include/hw/pci-host/piix.h         |   29 ++
> > > >  include/hw/pci-host/q35.h          |    1 +
> > > >  include/hw/pci/pci.h               |   11 +-
> > > >  include/hw/pci/pci_bus.h           |    2 +-
> > > >  include/hw/qdev-core.h             |    9 +
> > > >  include/sysemu/hostmem.h           |  102 +++++
> > > >  include/sysemu/sysemu.h            |    3 +
> > > >  monitor.c                          |    1 +
> > > >  qapi-schema.json                   |   18 +
> > > >  qapi/string-input-visitor.c        |   18 +
> > > >  qemu-options.hx                    |   16 +-
> > > >  qmp-commands.hx                    |   27 ++
> > > >  ui/console.c                       |    3 +-
> > > >  vl.c                               |   98 ++++-
> > > >  50 files changed, 3040 insertions(+), 140 deletions(-)
> > > >  create mode 100644 backends/hostmem.c
> > > >  create mode 100644 backends/hostmem_compat_ram.c
> > > >  create mode 100644 docs/specs/acpi_mem_hotplug.txt
> > > >  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/mem/dimm.h
> > > >  create mode 100644 include/hw/pci-host/piix.h
> > > >  create mode 100644 include/sysemu/hostmem.h
> 

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-21 14:21     ` Igor Mammedov
@ 2013-11-21 14:38       ` Michael S. Tsirkin
  2013-11-22 17:14         ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21 14:38 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:21:37PM +0100, Igor Mammedov wrote:
> On Thu, 21 Nov 2013 11:42:02 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Nov 21, 2013 at 03:38:34AM +0100, 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
> > > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > >  docs/specs/acpi_mem_hotplug.txt |   38 ++++++++++
> > >  hw/acpi/core.c                  |  144 +++++++++++++++++++++++++++++++++++++++
> > >  include/hw/acpi/acpi.h          |   24 +++++++
> > >  3 files changed, 206 insertions(+), 0 deletions(-)
> > >  create mode 100644 docs/specs/acpi_mem_hotplug.txt
> > > 
> > > diff --git a/docs/specs/acpi_mem_hotplug.txt b/docs/specs/acpi_mem_hotplug.txt
> > > new file mode 100644
> > > index 0000000..fc34142
> > > --- /dev/null
> > > +++ b/docs/specs/acpi_mem_hotplug.txt
> > > @@ -0,0 +1,38 @@
> > > +QEMU<->ACPI BIOS memory hotplug interface
> > > +--------------------------------------
> > > +
> > > +ACPI BIOS GPE.3 handler is dedicated for notifying OS about memory hot-add
> > > +or hot-remove 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
> > > +      [0x14] highest memory hot-plug interface version supported by QEMU
> > 
> > So this can make guest fail gracefully but it appears that
> > detecting guest version would be nicer?
> > It would let us actually support old guests ...
> 
> my idea of how to it was,
> guest writes its version into [0x14] register and reads QEMU version
> from it back, if they do not match then than BIOS ignores GPE.3 event
> effectively disabling hotplug on guest side.
> I haven't thought about supporting multiple implementations in QEMU though.
> Do we really want it?

I'm talking about old bios which does not read acpi from qemu.
We want it to work even if it can't see hotplugged memory.

> > 
> > > +      [0x15] Memory device status fields
> > > +          bits:
> > > +              1: device is enabled and may be used by guest
> > > +              2: device insert event, used by ACPI BIOS to distinguish
> > > +                 device for which no device check event to OSPM was issued
> > 
> > what does the above mean?
> After OSPM issued device check on selected device it clears this bit to mark event
> as handled.
> It allows to avoid keeping this state in ASL (as it's done for CPU hotplug, see CPON)

That's fine.

> > what if device is not present?
> ASL will issue device check and clear bit, it might be a bug since _STA would report
> not present but no eject event was issued.
> 
> Papering over it ASL could check present bit first and issue device check only if
> it's present.

Is this a problem? If yes - that will still be racy won't it?


Also, should guest reset eject memory that we requested unplug for?

> > 
> > > +      [0x16-0x17] reserved
> > > +
> > > +  write access:
> > > +      [0x0-0x3] Memory device slot selector, selects active memory device.
> > > +                All following accesses to other registers in 0xaf80-0xaf97
> > > +                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
> > > +      [0x15] Memory device status fields
> > 
> > this is control, not status?
> Thanks, I'll fix it.
> 
> > 
> > > +          bits:
> > > +              2: if set to 1 clears device insert event, set by ACPI BIOS
> > > +                 after it has sent device check event to OSPM for
> > > +                 seleted memory device
> > 
> > selected?
> see "write access: [0x0-0x3]"

yes but you have a typo above

> > 
> > How about we actually require guest to enable memory?
> > 
> > This way if we hotplug, but old guest does not enable
> > and puts a PCI device there, it just works.
> I've lost you here, could you elaborate pls?


Assume qemu adds memory by hotplug.
Is it immediately enabled?
I suggest it's not enabled, and only enable after ACPI
enables it (or after reboot?)

> > 
> > > +
> > > +Selecting memory device slot beyond present range has no effect on platform:
> > > +   - not documented above write accesses to memory hot-plug registers
> > > +     are ignored;
> > > +   - not documented above read accesses to memory hot-plug registers return 0xFF
> > 
> > 00 would be cleaner (matches not enabled - no event)?
> I'm following pattern, where reading from not present IO port returns 0xFF on hardware.
> Fact that ASL reads 0xFF could be used as not supported indication.

But isn't this a valid pattern when all bits are set?

> > 
> > > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > > index 8c0d48c..18e169c 100644
> > > --- a/hw/acpi/core.c
> > > +++ b/hw/acpi/core.c
> > > @@ -680,3 +680,147 @@ void acpi_update_sci(ACPIREGS *regs, qemu_irq irq, uint32_t gpe0_sts_mask)
> > >                         (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> > >                         !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
> > >  }
> > > +
> > > +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: /* intf version */
> > > +        val = 1;
> > > +        break;
> > > +    case 0x15: /* pack and return is_* fields */
> > > +        val |= mdev->is_enabled   ? 1 : 0;
> > > +        val |= mdev->is_inserting ? 2 : 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 0x15:
> > > +        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(Object *owner, MemoryRegion *io,
> > > +                              MemHotplugState *state)
> > > +{
> > > +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
> > > +    g_assert(opts);
> > > +
> > > +    state->dev_count = qemu_opt_get_number(opts, "slots", 0);
> > > +
> > > +    if (!state->dev_count) {
> > > +        return;
> > > +    }
> > > +
> > > +    state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count);
> > > +    memory_region_init_io(io, owner, &acpi_memory_hotplug_ops, state,
> > > +                          "apci-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN);
> > > +}
> > > +
> > > +int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
> > > +                           DeviceState *dev, HotplugState state)
> > > +{
> > > +    MemStatus *mdev;
> > > +    Error *local_err = NULL;
> > > +    int slot = object_property_get_int(OBJECT(dev), "slot", &local_err);
> > > +
> > > +    if (error_is_set(&local_err)) {
> > > +        qerror_report_err(local_err);
> > > +        error_free(local_err);
> > > +        return -1;
> > > +    }
> > > +
> > > +    if (slot >= mem_st->dev_count) {
> > > +        char *dev_path = object_get_canonical_path(OBJECT(dev));
> > > +        qerror_report(ERROR_CLASS_GENERIC_ERROR, "acpi_memory_hotplug_cb: "
> > > +                      "device [%s] returned invalid memory slot[%d]",
> > > +                      dev_path, slot);
> > > +        g_free(dev_path);
> > > +        return -1;
> > > +    }
> > > +
> > > +    mdev = &mem_st->devs[slot];
> > > +    if (state == HOTPLUG_ENABLED) {
> > > +        mdev->dimm = dev;
> > > +        mdev->is_enabled = true;
> > > +        mdev->is_inserting = true;
> > > +    }
> > > +
> > > +    /* do ACPI magic */
> > > +    regs->gpe.sts[0] |= ACPI_MEMORY_HOTPLUG_STATUS;
> > > +    return 0;
> > > +}
> > > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > > index c4ae7d7..e5717df 100644
> > > --- a/include/hw/acpi/acpi.h
> > > +++ b/include/hw/acpi/acpi.h
> > > @@ -168,6 +168,30 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
> > >  
> > >  void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
> > >  
> > > +#define ACPI_MEMORY_HOTPLUG_IO_LEN 24
> > > +#define ACPI_MEMORY_HOTPLUG_BASE 0x0a00
> > > +
> > > +#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 {
> > > +    uint32_t selector;
> > > +    uint32_t dev_count;
> > > +    MemStatus *devs;
> > > +} MemHotplugState;
> > > +
> > > +void acpi_memory_hotplug_init(Object *owner, MemoryRegion *io,
> > > +                              MemHotplugState *state);
> > > +
> > > +int acpi_memory_hotplug_cb(ACPIREGS *regs, MemHotplugState *mem_st,
> > > +                           DeviceState *dev, HotplugState state);
> > >  /* acpi.c */
> > >  extern int acpi_enabled;
> > >  extern char unsigned *acpi_tables;
> > > -- 
> > > 1.7.1

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21 14:34       ` Igor Mammedov
@ 2013-11-21 14:39         ` Michael S. Tsirkin
  2013-11-21 16:09         ` Andreas Färber
  1 sibling, 0 replies; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21 14:39 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, stefanb, hutao, quintela, mjt, armbru,
	qemu-devel, vasilis.liaskovitis, chegu_vinod, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, stefanha, Andreas Färber,
	Li Guang

On Thu, Nov 21, 2013 at 03:34:53PM +0100, Igor Mammedov wrote:
> On Thu, 21 Nov 2013 15:13:12 +0100
> Andreas Färber <afaerber@suse.de> wrote:
> 
> > Am 21.11.2013 06:48, schrieb Li Guang:
> > > Hi, Igor
> > > 
> > > Igor Mammedov wrote:
> > >> Add DimmBus for memory hotplug below 4Gb or above 4Gb depending
> > >> on initial memory size and hotplug memory size.
> > >>    
> > > ...
> > >> +static
> > >> +void pc_hotplug_memory_init_impl(Object *owner,
> > >> +                                 MemoryRegion *system_memory,
> > >> +                                 ram_addr_t low_hotplug_mem_start,
> > >> +                                 ram_addr_t low_hotplug_mem_end,
> > >> +                                 DimmBus *hotplug_mem_bus,
> > >> +                                 ram_addr_t *high_mem_end)
> > >> +{
> > >> +    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"),
> > >> NULL);
> > >> +    ram_addr_t ram_size = qemu_opt_get_size(opts, "mem", 0);
> > >> +    ram_addr_t maxmem = qemu_opt_get_size(opts, "maxmem", 0);
> > >> +    ram_addr_t hotplug_mem_size;
> > >> +
> > >> +    if (maxmem<= ram_size) {
> > >> +        /* Disable ACPI migration code and creation of memory devices
> > >> in SSDT */
> > >>    
> > > 
> > > Why not give the memory that not be hot-added a chance to be placed on
> > > one memory slot?
> > 
> > Seconded, I believe I requested that on the previous version already.
> Because current initial memory allocation is a mess and this already
> large series would become even more large and intrusive, so far series
> it relatively not intrusive and self contained.
> 
> I believe re-factoring of initial memory to use Dimm devices should be
> done later on top of infrastructure this series provides.

Kind of makes sense, it looks like a feature request rather than
a bug report.
Maybe add some comments in code/commit logs?

> > Andreas
> > 
> > > if all memory can be hot-added and hot-removed, then we can bring in
> > > more flexibility for
> > > memory hotplug feature.
> > 

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

* Re: [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug
  2013-11-21 14:37       ` Igor Mammedov
@ 2013-11-21 14:45         ` Michael S. Tsirkin
  2013-11-25 10:09           ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21 14:45 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, marcel.a, armbru, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, hutao, pbonzini, lcapitulino, chegu_vinod, afaerber

On Thu, Nov 21, 2013 at 03:37:55PM +0100, Igor Mammedov wrote:
> On Thu, 21 Nov 2013 15:43:27 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Nov 21, 2013 at 02:39:10PM +0100, Igor Mammedov wrote:
> > > On Thu, 21 Nov 2013 08:20:56 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > 
> > > > On Thu, Nov 21, 2013 at 03:38:21AM +0100, Igor Mammedov wrote:
> > > > > ---
> > > > > What's new since v6:
> > > > > 
> > > > > * DIMM device is split to backend and frontend. Therefore following
> > > > >   command/options were added for supporting it:
> > > > > 
> > > > >   For memdev backend:
> > > > >       CLI: -memdev-add
> > > > >       Monitor/QMP: memdev-add
> > > > >           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'
> > > > > 
> > > > > * Added Q35 support
> > > > > * Added support for 32 bit guests
> > > > > * build for i386 emulator (not tested)
> > > > 
> > > > OK so a large patchset so did not review yet.  One question
> > > > due to the dependency on bios honouring etc/reserved-memory-end: is
> > > > there some way to detect old BIOS and fail memory hotplug?
> > > version negotiation between ASL and hardware could be used to that effect.
> > > 
> > > QEMU could start with present but disabled memory hotplug and if
> > > QEMU and BIOS ASL could come in agreement that both support it in
> > > compatible way, it could be enabled.
> > 
> > So at the moment there's no negotiation, is there?
> Nope, I surely can add it in next iteration.

I'm not sure about this - if we add this we should make it
a generic mechanism I think.
It does not have to be part of this series.
So maybe drop version for now ...

> > 
> > > > 
> > > > > ---
> > > > > 
> > > > > 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:
> > > > > 
> > > > >   memdev-add 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
> > > > >  - Windows 2008DCx32
> > > > > 
> > > > > Known limitations/bugs/TODOs:
> > > > >  - only hot-add supported
> > > > >  - 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) 
> > > > >  - failed hotplug action consumes 1 slot (device_add doesn't delete
> > > > >    device properly if realize failed)
> > > > >  - 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.
> > > > > 
> > > > > Series is based on mst's PCI tree and requires following SeaBIOS patch:
> > > > >   http://patchwork.ozlabs.org/patch/292614/
> > > > >   on top of patches to load ACPI tables from QEMU
> > > > >   working SeaBIOS tree for testing is available at:
> > > > >     https://github.com/imammedo/seabios/commits/memhp-wip
> > > > > 
> > > > > QEMU git tree for testing is available at:
> > > > >   https://github.com/imammedo/qemu/commits/memory-hotplug-v7
> > > > > 
> > > > > Example QEMU cmd line:
> > > > >   qemu-system-x86_64 -enable-kvm -monitor unix:/tmp/mon,server,nowait \ 
> > > > >      -m 4096,slots=4,maxmem=8G -L /custome_seabios guest.img
> > > > > 
> > > > > PS:
> > > > >   Windows guest requires SRAT table for hotplug to work so add extra option:
> > > > >    -numa node
> > > > >   to QEMU command line.
> > > > > 
> > > > > 
> > > > > Igor Mammedov (26):
> > > > >   acpi: factor out common pm_update_sci() into acpi core
> > > > >   rename pci_hotplug_fn to hotplug_fn and make it available for other
> > > > >     devices
> > > > >   pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
> > > > >   vl: convert -m to qemu_opts_parse()
> > > > >   qapi: add SIZE type parser to string_input_visitor
> > > > >   get reference to /backend container via qemu_get_backend()
> > > > >   add memdev backend infrastructure
> > > > >   dimm: map DimmDevice into DimBus provided address space
> > > > >   dimm: add busy slot check and slot auto-allocation
> > > > >   dimm: add busy address check and address auto-allocation
> > > > >   dimm: add hotplug callback to DimmBus
> > > > >   acpi: memory hotplug ACPI hardware implementation
> > > > >   acpi: initialize memory hotplug ACPI PIIX4 hardware
> > > > >   acpi: piix4: add memory-hotplug-io-base property to piix4_pm
> > > > >   acpi: ich9: allow guest to clear SCI rised by GPE
> > > > >   acpi: initialize memory hotplug ACPI ICH9 hardware
> > > > >   acpi: ich9: add memory-hotplug-io-base property to ich9_pm
> > > > >   acpi: piix4/ich9: add optional vmstate field for MemHotplugState
> > > > >     migration
> > > > >   pc: piix: make PCII440FXState type public
> > > > >   pc: add memory hotplug 440fx machine
> > > > >   pc: add memory hotplug Q35 machine
> > > > >   pc: ACPI BIOS: implement memory hotplug interface
> > > > >   pc: ACPI BIOS: add ssdt-mem.hex.generated and update
> > > > >     ssdt-misc.hex.generated
> > > > >   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
> > > > > 
> > > > > Vasilis Liaskovitis (1):
> > > > >   dimm: implement dimm device abstraction
> > > > > 
> > > > >  backends/Makefile.objs             |    2 +
> > > > >  backends/hostmem.c                 |  275 +++++++++++
> > > > >  backends/hostmem_compat_ram.c      |   42 ++
> > > > >  default-configs/i386-softmmu.mak   |    1 +
> > > > >  default-configs/x86_64-softmmu.mak |    1 +
> > > > >  docs/specs/acpi_mem_hotplug.txt    |   38 ++
> > > > >  hmp-commands.hx                    |   13 +
> > > > >  hw/Makefile.objs                   |    1 +
> > > > >  hw/acpi/core.c                     |  189 ++++++++
> > > > >  hw/acpi/ich9.c                     |   57 ++-
> > > > >  hw/acpi/pcihp.c                    |    6 +-
> > > > >  hw/acpi/piix4.c                    |   91 +++--
> > > > >  hw/i386/Makefile.objs              |    3 +-
> > > > >  hw/i386/acpi-build.c               |   91 ++++-
> > > > >  hw/i386/acpi-dsdt.dsl              |    5 +-
> > > > >  hw/i386/pc.c                       |   90 ++++-
> > > > >  hw/i386/pc_piix.c                  |    7 +-
> > > > >  hw/i386/pc_q35.c                   |    4 +
> > > > >  hw/i386/q35-acpi-dsdt.dsl          |    5 +-
> > > > >  hw/i386/ssdt-mem.dsl               |   75 +++
> > > > >  hw/i386/ssdt-mem.hex.generated     |  197 ++++++++
> > > > >  hw/i386/ssdt-misc.dsl              |  179 ++++++++
> > > > >  hw/i386/ssdt-misc.hex.generated    |  881 +++++++++++++++++++++++++++++++++++-
> > > > >  hw/mem/Makefile.objs               |    1 +
> > > > >  hw/mem/dimm.c                      |  321 +++++++++++++
> > > > >  hw/pci-host/piix.c                 |   36 +-
> > > > >  hw/pci-host/q35.c                  |   19 +-
> > > > >  hw/pci/pci.c                       |   12 +-
> > > > >  hw/pci/pcie.c                      |    7 +-
> > > > >  hw/pci/shpc.c                      |    9 +-
> > > > >  include/hw/acpi/acpi.h             |   42 ++
> > > > >  include/hw/acpi/ich9.h             |    6 +
> > > > >  include/hw/acpi/pcihp.h            |    2 +-
> > > > >  include/hw/acpi/piix4.h            |    2 +
> > > > >  include/hw/i386/pc.h               |   33 ++-
> > > > >  include/hw/mem/dimm.h              |   99 ++++
> > > > >  include/hw/pci-host/piix.h         |   29 ++
> > > > >  include/hw/pci-host/q35.h          |    1 +
> > > > >  include/hw/pci/pci.h               |   11 +-
> > > > >  include/hw/pci/pci_bus.h           |    2 +-
> > > > >  include/hw/qdev-core.h             |    9 +
> > > > >  include/sysemu/hostmem.h           |  102 +++++
> > > > >  include/sysemu/sysemu.h            |    3 +
> > > > >  monitor.c                          |    1 +
> > > > >  qapi-schema.json                   |   18 +
> > > > >  qapi/string-input-visitor.c        |   18 +
> > > > >  qemu-options.hx                    |   16 +-
> > > > >  qmp-commands.hx                    |   27 ++
> > > > >  ui/console.c                       |    3 +-
> > > > >  vl.c                               |   98 ++++-
> > > > >  50 files changed, 3040 insertions(+), 140 deletions(-)
> > > > >  create mode 100644 backends/hostmem.c
> > > > >  create mode 100644 backends/hostmem_compat_ram.c
> > > > >  create mode 100644 docs/specs/acpi_mem_hotplug.txt
> > > > >  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/mem/dimm.h
> > > > >  create mode 100644 include/hw/pci-host/piix.h
> > > > >  create mode 100644 include/sysemu/hostmem.h
> > 

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21 14:34       ` Igor Mammedov
  2013-11-21 14:39         ` Michael S. Tsirkin
@ 2013-11-21 16:09         ` Andreas Färber
  2013-11-21 16:17           ` Michael S. Tsirkin
  2013-11-25 10:41           ` Igor Mammedov
  1 sibling, 2 replies; 143+ messages in thread
From: Andreas Färber @ 2013-11-21 16:09 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, hutao, stefanb, mjt, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, stefanha, Li Guang

Am 21.11.2013 15:34, schrieb Igor Mammedov:
> On Thu, 21 Nov 2013 15:13:12 +0100
> Andreas Färber <afaerber@suse.de> wrote:
>> Am 21.11.2013 06:48, schrieb Li Guang:
>>> Why not give the memory that not be hot-added a chance to be placed on
>>> one memory slot?
>>
>> Seconded, I believe I requested that on the previous version already.
> Because current initial memory allocation is a mess and this already
> large series would become even more large and intrusive, so far series
> it relatively not intrusive and self contained.
> 
> I believe re-factoring of initial memory to use Dimm devices should be
> done later on top of infrastructure this series provides.

My problem with that is that that would be a semantically incompatible
modeling change. With your series we might have /machine/dimm.0/child[0]
be the first hot-plugged memory and once such a refactoring is done,
child[0] silently becomes -m and child[1] is the hot-added one.

So if we know that we want/need to change the infrastructure, why not
add a single patch (?) to allocate one additional object on the bus now?
Unless we actually write the code, we won't know whether there are some
incorrect hot-plug assumptions in the dimm code.

Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21 16:09         ` Andreas Färber
@ 2013-11-21 16:17           ` Michael S. Tsirkin
  2013-11-25 10:41           ` Igor Mammedov
  1 sibling, 0 replies; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-21 16:17 UTC (permalink / raw)
  To: Andreas Färber
  Cc: peter.maydell, mdroth, stefanb, hutao, quintela, mjt, armbru,
	qemu-devel, vasilis.liaskovitis, chegu_vinod, kraxel, aliguori,
	pbonzini, Igor Mammedov, marcel.a, lcapitulino, stefanha,
	Li Guang

On Thu, Nov 21, 2013 at 05:09:27PM +0100, Andreas Färber wrote:
> Am 21.11.2013 15:34, schrieb Igor Mammedov:
> > On Thu, 21 Nov 2013 15:13:12 +0100
> > Andreas Färber <afaerber@suse.de> wrote:
> >> Am 21.11.2013 06:48, schrieb Li Guang:
> >>> Why not give the memory that not be hot-added a chance to be placed on
> >>> one memory slot?
> >>
> >> Seconded, I believe I requested that on the previous version already.
> > Because current initial memory allocation is a mess and this already
> > large series would become even more large and intrusive, so far series
> > it relatively not intrusive and self contained.
> > 
> > I believe re-factoring of initial memory to use Dimm devices should be
> > done later on top of infrastructure this series provides.
> 
> My problem with that is that that would be a semantically incompatible
> modeling change.

Yes but we are not merging this for 1.7, time enough to make
changes before 1.8.

> With your series we might have /machine/dimm.0/child[0]
> be the first hot-plugged memory and once such a refactoring is done,
> child[0] silently becomes -m and child[1] is the hot-added one.
> 
> So if we know that we want/need to change the infrastructure, why not
> add a single patch (?) to allocate one additional object on the bus now?
> Unless we actually write the code, we won't know whether there are some
> incorrect hot-plug assumptions in the dimm code.
> 
> Andreas
> -- 
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21  9:43             ` Michael S. Tsirkin
@ 2013-11-22  0:57               ` Li Guang
  2013-11-25 11:13                 ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Li Guang @ 2013-11-22  0:57 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, marcel.a, qemu-devel, Hu Tao, stefanb,
	mjt, mdroth, armbru, vasilis.liaskovitis, quintela, kraxel,
	stefanha, Igor Mammedov, pbonzini, lcapitulino, chegu_vinod,
	afaerber

Michael S. Tsirkin wrote:
> On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
>    
>> Michael S. Tsirkin wrote:
>>      
>>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
>>>        
>>>> Hu Tao wrote:
>>>>          
>>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
>>>>>            
>>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
>>>>>>              
>>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
>>>>>>> after it has been handled when it clears GPE event.
>>>>>>>
>>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
>>>>>>>                
>>>>>> The storm is only on memory hotplug right?
>>>>>>              
>>>>> IIRC, it happens on cpu hotplug, too.
>>>>>
>>>>>
>>>>>
>>>>>            
>>>> :-), that made remember EC implementation,
>>>> with EC, SCI will be safer, I think.
>>>>          
>>> Hmm you are saying let's use EC for memory hotplug?
>>>
>>>
>>>        
>> It can be a bridge between guest and QEMU,
>> with it, we may don't have to bother ASL writing
>> and south-bridge hardware related work(or very
>> little) if we implement EC correctly.
>>
>>
>>      
>
> I'd like to see that. Can you write a document (just text)
> for an imaginary EC support for memory hotplug?
>
>
>
>    

Hmm..., with EC,

For memory hotplug, at least,
ASL at [PATCH 27/27] can be replaced
by a simple Method(_Qx) under EC device,
IO base operations at [PATCH 15/27]
are dispensable,  we can relay data
by standard operations of EC space

and also for SCI, all device changes want to
notify guest OS can share same SCI with EC,
and the operations are specified at ACPI SPEC.

likewise, for CPU hotplug, pvpanic,
and even debugcon.

and, for odd devices, like pvpanic, guest OS may complain
about it, and we may also have to bother on maintaining state of
it at QEMU, and writing a driver for guest OS,
with EC, functions of device like pvpanic may be implemented silently,
and EC is ACPI standard device, each ACPI compatible OS will
have a driver for it natively.

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-21 13:19             ` Igor Mammedov
@ 2013-11-22  1:03               ` Li Guang
  0 siblings, 0 replies; 143+ messages in thread
From: Li Guang @ 2013-11-22  1:03 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, qemu-devel, Hu Tao,
	Michael S. Tsirkin, mjt, mdroth, armbru, vasilis.liaskovitis,
	quintela, kraxel, stefanha, pbonzini, marcel.a, lcapitulino,
	chegu_vinod, afaerber

Igor Mammedov wrote:
> On Thu, 21 Nov 2013 16:32:27 +0800
> Li Guang<lig.fnst@cn.fujitsu.com>  wrote:
>
>    
>> Michael S. Tsirkin wrote:
>>      
>>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
>>>
>>>        
>>>> Hu Tao wrote:
>>>>
>>>>          
>>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
>>>>>
>>>>>            
>>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
>>>>>>
>>>>>>              
>>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
>>>>>>> after it has been handled when it clears GPE event.
>>>>>>>
>>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
>>>>>>>
>>>>>>>                
>>>>>> The storm is only on memory hotplug right?
>>>>>>
>>>>>>              
>>>>> IIRC, it happens on cpu hotplug, too.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>            
>>>> :-), that made remember EC implementation,
>>>> with EC, SCI will be safer, I think.
>>>>
>>>>          
>>> Hmm you are saying let's use EC for memory hotplug?
>>>
>>>
>>>
>>>        
>> It can be a bridge between guest and QEMU,
>> with it, we may don't have to bother ASL writing
>> and south-bridge hardware related work(or very
>> little) if we implement EC correctly.
>>
>>      
> Wouldn't it require guest driver though?
> Beauty of ASL/GPE it's that it supported by Windows and Linux
> out of box.
>
>    

it did require guest driver, but as a ACPI standard device,
the driver is natively implemented by ACPI compatible OS.

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine Igor Mammedov
  2013-11-21  5:48   ` Li Guang
@ 2013-11-22 14:23   ` Gerd Hoffmann
  2013-11-25 11:00     ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Gerd Hoffmann @ 2013-11-22 14:23 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, aliguori,
	hutao, pbonzini, marcel.a, lcapitulino, afaerber

On Do, 2013-11-21 at 03:38 +0100, Igor Mammedov wrote:
> Add DimmBus for memory hotplug below 4Gb or above 4Gb depending
> on initial memory size and hotplug memory size.
> 
> * if ram_size is less than 32-bit PCI hole start, reserve
>   hotplug memory region as [ram_size,32bit-PCIhole-start)
>   if hotplug memory region fits there,
>   otherwise reserve hotplug memory region after "0x100000000ULL
>   + above_4g_mem_size"

Hmm, 32-bit pci hole start depends on ram size ...

Does it make sense to hotplug memory above 4g unconditionally to
simplify things?

cheers,
  Gerd

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-21 14:38       ` Michael S. Tsirkin
@ 2013-11-22 17:14         ` Igor Mammedov
  2013-11-24 10:58           ` Michael S. Tsirkin
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-22 17:14 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, 21 Nov 2013 16:38:47 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:21:37PM +0100, Igor Mammedov wrote:
> > On Thu, 21 Nov 2013 11:42:02 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
[...]
> > > > +      [0x14] highest memory hot-plug interface version supported by QEMU
> > > 
> > > So this can make guest fail gracefully but it appears that
> > > detecting guest version would be nicer?
> > > It would let us actually support old guests ...
> > 
> > my idea of how to it was,
> > guest writes its version into [0x14] register and reads QEMU version
> > from it back, if they do not match then than BIOS ignores GPE.3 event
> > effectively disabling hotplug on guest side.
> > I haven't thought about supporting multiple implementations in QEMU though.
> > Do we really want it?
> 
> I'm talking about old bios which does not read acpi from qemu.
> We want it to work even if it can't see hotplugged memory.
to sum up cases that were discussed on IRC.

 * migration from NEW to OLD machine leads us to state when we run new BIOS with
   ACPI tables supporting memory hotplug on OLD machine.
   In general should work since NEW machine has to be started without memory
   hotplug enabled, which leads to disabling related ASL handler in ACPI tables.
   Case where NEW machine with memory hotplug enabled migrating to OLD machine
   without memory hotplug is invalid since migration will fail early due to
   missing devices (DimmBus/DIMM devices)

 * running OLD BIOS on new machine with memory hotplug turned on at QEMU CLI
        qemu -m X,slots=Y,maxmem=Z -bios old-bios-image -M pc-1.8

   Problem here is that OLD BIOS doesn't know about 'etc/reserved-memory-end' fwcfg,
   so it can start mapping PCI BARs right after high memory (i.e. in memory hotplug
   reserved space)

   That's fine as far as there is no DIMM devices since access will fall through
   hotplug-mem container to PCI address space.

   But if DIMM device added at startup or runtime, its MemoryRegion will overshadow
   PCI BARs mapped at its range.

   If it were only hotadd case, then QEMU could start with enabled but not active
   memory hotplug and require BIOS to acknowledge (activate) hotlug so that adding
   DIMM devices wouldn't be possible without hotplug enabled BIOS. 
   That would guarantee empty hotplug-mem container for OLD BIOS since it can't
   activate hotplug and avoid conflict.

   But if there are cold-plugged DIMM devices on QEMU CLI, that wouldn't work
   because OLD BIOS has no idea about them (i.e. it reads above4gb memory CMOS value)
   and it is bound to map 64-bit BARs in invalid place.
 
   It would be nice to run OLD BIOS on new machine and it will even work IF memory
   hotplug is not enabled.
   But I'm not sure we should care about case when not compatible BIOS is running
   on machine with active memory hotplug.

> 
> > > 
> > > > +      [0x15] Memory device status fields
> > > > +          bits:
> > > > +              1: device is enabled and may be used by guest
> > > > +              2: device insert event, used by ACPI BIOS to distinguish
> > > > +                 device for which no device check event to OSPM was issued
> > > 
> > > what does the above mean?
> > After OSPM issued device check on selected device it clears this bit to mark event
> > as handled.
> > It allows to avoid keeping this state in ASL (as it's done for CPU hotplug, see CPON)
> 
> That's fine.
> 
> > > what if device is not present?
> > ASL will issue device check and clear bit, it might be a bug since _STA would report
> > not present but no eject event was issued.
> > 
> > Papering over it ASL could check present bit first and issue device check only if
> > it's present.
> 
> Is this a problem? If yes - that will still be racy won't it?
I thought about it some more and I don't see why it would be racy.
bit 0x15.1 is set when there is initialized DIMM device in slot so 0x15.2 couldn't
be set if 0x15.1 == 0.

May be following description would be better:

   2: device insert event, used by ACPI BIOS to distinguish
      device for which no device check event to OSPM was issued.
      Bit is valid only when 0x15.1 bit is set.

It's possible to remove is_inserting bit altogether and just send device check to
each present memory device. Device check will be NOP for memory devices that OSPM
processed.
That will work fine with small amount of slots but would increase load on guest
in case of 1000s devices. That's the main reason for dedicated is_inserting bit,
allowing to handle hotadd effectively.

      
> 
> 
> Also, should guest reset eject memory that we requested unplug for?
I'm not sure what you saying here in general.
In particular unplug is not part of this series.


[...]
> > > selected?
> > see "write access: [0x0-0x3]"
> 
> yes but you have a typo above
Ahh, blind me. Thanks, I'll fix it.

> 
> > > 
> > > How about we actually require guest to enable memory?
> > > 
> > > This way if we hotplug, but old guest does not enable
> > > and puts a PCI device there, it just works.
> > I've lost you here, could you elaborate pls?
> 
> 
> Assume qemu adds memory by hotplug.
> Is it immediately enabled?
> I suggest it's not enabled, and only enable after ACPI
> enables it (or after reboot?)
I guess answer is in "running OLD BIOS on new machine with memory hotplug turned on"
case above. i.e. Don't run not compatible BIOS with turned on memory hotplug.
I think simpler interface/work-flow is better than a more complicated one,
that is required to support not totally sane configuration that is bound to be broken anyway.

> 
> > > 
> > > > +
> > > > +Selecting memory device slot beyond present range has no effect on platform:
> > > > +   - not documented above write accesses to memory hot-plug registers
> > > > +     are ignored;
> > > > +   - not documented above read accesses to memory hot-plug registers return 0xFF
> > > 
> > > 00 would be cleaner (matches not enabled - no event)?
> > I'm following pattern, where reading from not present IO port returns 0xFF on hardware.
> > Fact that ASL reads 0xFF could be used as not supported indication.
> 
> But isn't this a valid pattern when all bits are set?
It's to the same extent as 0x0. I'll change it to 0x0 if you still think it's better.

[...]

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-22 17:14         ` Igor Mammedov
@ 2013-11-24 10:58           ` Michael S. Tsirkin
  2013-11-25  7:27             ` Markus Armbruster
  2013-11-25 13:56             ` Igor Mammedov
  0 siblings, 2 replies; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-24 10:58 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Fri, Nov 22, 2013 at 06:14:46PM +0100, Igor Mammedov wrote:
> On Thu, 21 Nov 2013 16:38:47 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Nov 21, 2013 at 03:21:37PM +0100, Igor Mammedov wrote:
> > > On Thu, 21 Nov 2013 11:42:02 +0200
> > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> [...]
> > > > > +      [0x14] highest memory hot-plug interface version supported by QEMU
> > > > 
> > > > So this can make guest fail gracefully but it appears that
> > > > detecting guest version would be nicer?
> > > > It would let us actually support old guests ...
> > > 
> > > my idea of how to it was,
> > > guest writes its version into [0x14] register and reads QEMU version
> > > from it back, if they do not match then than BIOS ignores GPE.3 event
> > > effectively disabling hotplug on guest side.
> > > I haven't thought about supporting multiple implementations in QEMU though.
> > > Do we really want it?
> > 
> > I'm talking about old bios which does not read acpi from qemu.
> > We want it to work even if it can't see hotplugged memory.
> to sum up cases that were discussed on IRC.
> 
>  * migration from NEW to OLD machine leads us to state when we run new BIOS with
>    ACPI tables supporting memory hotplug on OLD machine.
>    In general should work since NEW machine has to be started without memory
>    hotplug enabled, which leads to disabling related ASL handler in ACPI tables.
>    Case where NEW machine with memory hotplug enabled migrating to OLD machine
>    without memory hotplug is invalid since migration will fail early due to
>    missing devices (DimmBus/DIMM devices)
> 
>  * running OLD BIOS on new machine with memory hotplug turned on at QEMU CLI
>         qemu -m X,slots=Y,maxmem=Z -bios old-bios-image -M pc-1.8
> 
>    Problem here is that OLD BIOS doesn't know about 'etc/reserved-memory-end' fwcfg,
>    so it can start mapping PCI BARs right after high memory (i.e. in memory hotplug
>    reserved space)
> 
>    That's fine as far as there is no DIMM devices since access will fall through
>    hotplug-mem container to PCI address space.
> 
>    But if DIMM device added at startup or runtime, its MemoryRegion will overshadow
>    PCI BARs mapped at its range.
> 
>    If it were only hotadd case, then QEMU could start with enabled but not active
>    memory hotplug and require BIOS to acknowledge (activate) hotlug so that adding
>    DIMM devices wouldn't be possible without hotplug enabled BIOS. 
>    That would guarantee empty hotplug-mem container for OLD BIOS since it can't
>    activate hotplug and avoid conflict.
> 
>    But if there are cold-plugged DIMM devices on QEMU CLI, that wouldn't work
>    because OLD BIOS has no idea about them (i.e. it reads above4gb memory CMOS value)
>    and it is bound to map 64-bit BARs in invalid place.
>  
>    It would be nice to run OLD BIOS on new machine and it will even work IF memory
>    hotplug is not enabled.
>    But I'm not sure we should care about case when not compatible BIOS is running
>    on machine with active memory hotplug.

It's not a must, I agree. It's just a useful excercise that might
help us think of potential problems.

Here this made me think of the following question:
should not memory available on boot be listed in CMOS?
Let's assume new BIOS gets interrupt telling it there's new memory.
It clears the interrupt and then system is reset.

Will system after reset detect the new hotplugged memory?
How?

> > 
> > > > 
> > > > > +      [0x15] Memory device status fields
> > > > > +          bits:
> > > > > +              1: device is enabled and may be used by guest
> > > > > +              2: device insert event, used by ACPI BIOS to distinguish
> > > > > +                 device for which no device check event to OSPM was issued
> > > > 
> > > > what does the above mean?
> > > After OSPM issued device check on selected device it clears this bit to mark event
> > > as handled.
> > > It allows to avoid keeping this state in ASL (as it's done for CPU hotplug, see CPON)
> > 
> > That's fine.
> > 
> > > > what if device is not present?
> > > ASL will issue device check and clear bit, it might be a bug since _STA would report
> > > not present but no eject event was issued.
> > > 
> > > Papering over it ASL could check present bit first and issue device check only if
> > > it's present.
> > 
> > Is this a problem? If yes - that will still be racy won't it?
> I thought about it some more and I don't see why it would be racy.
> bit 0x15.1 is set when there is initialized DIMM device in slot so 0x15.2 couldn't
> be set if 0x15.1 == 0.
> 
> May be following description would be better:
> 
>    2: device insert event, used by ACPI BIOS to distinguish
>       device for which no device check event to OSPM was issued.
>       Bit is valid only when 0x15.1 bit is set.
> 
> It's possible to remove is_inserting bit altogether and just send device check to
> each present memory device. Device check will be NOP for memory devices that OSPM
> processed.
> That will work fine with small amount of slots but would increase load on guest
> in case of 1000s devices. That's the main reason for dedicated is_inserting bit,
> allowing to handle hotadd effectively.
> 
>       
> > 
> > 
> > Also, should guest reset eject memory that we requested unplug for?
> I'm not sure what you saying here in general.
> In particular unplug is not part of this series.
> 
> 
> [...]
> > > > selected?
> > > see "write access: [0x0-0x3]"
> > 
> > yes but you have a typo above
> Ahh, blind me. Thanks, I'll fix it.
> 
> > 
> > > > 
> > > > How about we actually require guest to enable memory?
> > > > 
> > > > This way if we hotplug, but old guest does not enable
> > > > and puts a PCI device there, it just works.
> > > I've lost you here, could you elaborate pls?
> > 
> > 
> > Assume qemu adds memory by hotplug.
> > Is it immediately enabled?
> > I suggest it's not enabled, and only enable after ACPI
> > enables it (or after reboot?)
> I guess answer is in "running OLD BIOS on new machine with memory hotplug turned on"
> case above. i.e. Don't run not compatible BIOS with turned on memory hotplug.
> I think simpler interface/work-flow is better than a more complicated one,
> that is required to support not totally sane configuration that is bound to be broken anyway.
> 
> > 
> > > > 
> > > > > +
> > > > > +Selecting memory device slot beyond present range has no effect on platform:
> > > > > +   - not documented above write accesses to memory hot-plug registers
> > > > > +     are ignored;
> > > > > +   - not documented above read accesses to memory hot-plug registers return 0xFF
> > > > 
> > > > 00 would be cleaner (matches not enabled - no event)?
> > > I'm following pattern, where reading from not present IO port returns 0xFF on hardware.
> > > Fact that ASL reads 0xFF could be used as not supported indication.
> > 
> > But isn't this a valid pattern when all bits are set?
> It's to the same extent as 0x0. I'll change it to 0x0 if you still think it's better.
> 
> [...]

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-24 10:58           ` Michael S. Tsirkin
@ 2013-11-25  7:27             ` Markus Armbruster
  2013-11-25 13:45               ` Paolo Bonzini
  2013-11-25 13:56             ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Markus Armbruster @ 2013-11-25  7:27 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, stefanb, hutao, marcel.a, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, pbonzini, Igor Mammedov, lcapitulino, chegu_vinod,
	afaerber

"Michael S. Tsirkin" <mst@redhat.com> writes:

[...]
> Here this made me think of the following question:
> should not memory available on boot be listed in CMOS?
> Let's assume new BIOS gets interrupt telling it there's new memory.
> It clears the interrupt and then system is reset.
>
> Will system after reset detect the new hotplugged memory?
> How?

Do physical systems with hot-pluggable memory exist?  How do they
behave?

[...]

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

* Re: [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug
  2013-11-21 14:45         ` Michael S. Tsirkin
@ 2013-11-25 10:09           ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 10:09 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, mdroth, stefanb, hutao, marcel.a, mjt, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, lcapitulino, stefanha, afaerber

On Thu, 21 Nov 2013 16:45:20 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:37:55PM +0100, Igor Mammedov wrote:
> > On Thu, 21 Nov 2013 15:43:27 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Nov 21, 2013 at 02:39:10PM +0100, Igor Mammedov wrote:
> > > > On Thu, 21 Nov 2013 08:20:56 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > > > 
> > > > > On Thu, Nov 21, 2013 at 03:38:21AM +0100, Igor Mammedov wrote:
> > > > > > ---
> > > > > > What's new since v6:
> > > > > > 
> > > > > > * DIMM device is split to backend and frontend. Therefore following
> > > > > >   command/options were added for supporting it:
> > > > > > 
> > > > > >   For memdev backend:
> > > > > >       CLI: -memdev-add
> > > > > >       Monitor/QMP: memdev-add
> > > > > >           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'
> > > > > > 
> > > > > > * Added Q35 support
> > > > > > * Added support for 32 bit guests
> > > > > > * build for i386 emulator (not tested)
> > > > > 
> > > > > OK so a large patchset so did not review yet.  One question
> > > > > due to the dependency on bios honouring etc/reserved-memory-end: is
> > > > > there some way to detect old BIOS and fail memory hotplug?
> > > > version negotiation between ASL and hardware could be used to that effect.
> > > > 
> > > > QEMU could start with present but disabled memory hotplug and if
> > > > QEMU and BIOS ASL could come in agreement that both support it in
> > > > compatible way, it could be enabled.
> > > 
> > > So at the moment there's no negotiation, is there?
> > Nope, I surely can add it in next iteration.
> 
> I'm not sure about this - if we add this we should make it
> a generic mechanism I think.
> It does not have to be part of this series.
> So maybe drop version for now ...
> 
Ok, I'll drop it for now.

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

* Re: [Qemu-devel] [PATCH 26/27] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole
  2013-11-21  7:18   ` Michael S. Tsirkin
@ 2013-11-25 10:11     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 10:11 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, 21 Nov 2013 09:18:40 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:38:47AM +0100, Igor Mammedov wrote:
> > Needed for Windows to use hotplugged memory device, otherwise
> > it complains that server is not configured for memory hotplug.
> > Tests shows that aftewards it uses dynamically provided
> > proximity value from _PXM() method if available.
> > 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> Maybe add comment in code?
> Someone reading the spec might well wonder.
Ok.

> 
> > ---
> >  hw/i386/acpi-build.c |   33 +++++++++++++++++++++++++++++++++
> >  1 files changed, 33 insertions(+), 0 deletions(-)
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 86c1372..ab8e923 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -50,6 +50,7 @@
> >  
> >  #include "qapi/qmp/qint.h"
> >  #include "qom/qom-qobject.h"
> > +#include "hw/mem/dimm.h"
> >  
> >  typedef struct AcpiCpuInfo {
> >      DECLARE_BITMAP(found_cpus, MAX_CPUMASK_BITS + 1);
> > @@ -1058,6 +1059,31 @@ acpi_build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
> >      numamem->range_length = cpu_to_le64(len);
> >  }
> >  
> > +typedef struct {
> > +    AcpiSratMemoryAffinity **numamem;
> > +    GArray *table_data;
> > +} AcpiSratHotplugMemoryArg;
> > +
> > +static int acpi_add_hotplug_memory_region_entry(Object *obj, void *opaque)
> > +{
> > +    AcpiSratHotplugMemoryArg *arg = opaque;
> > +    DimmBus *bus = (DimmBus *)object_dynamic_cast(obj, TYPE_DIMM_BUS);
> > +
> > +    if (bus) {
> > +        uint64_t size = memory_region_size(&bus->as);
> > +        if (size) {
> > +            *arg->numamem = acpi_data_push(arg->table_data,
> > +                                           sizeof **arg->numamem);
> > +            acpi_build_srat_memory(*arg->numamem, bus->base, size, 0,
> > +                                   HOT_PLUGGABLE_MEM | ENABLED_MEM);
> > +        }
> > +    }
> > +
> > +    object_child_foreach(obj, acpi_add_hotplug_memory_region_entry,
> > +                         opaque);
> > +   return 0;
> > +}
> > +
> >  static void
> >  build_srat(GArray *table_data, GArray *linker,
> >             AcpiCpuInfo *cpu, PcGuestInfo *guest_info)
> > @@ -1133,6 +1159,13 @@ build_srat(GArray *table_data, GArray *linker,
> >          acpi_build_srat_memory(numamem, 0, 0, 0, NOFLAGS_MEM);
> >      }
> >  
> > +    {
> > +        AcpiSratHotplugMemoryArg arg = { .numamem = &numamem,
> > +                                         .table_data = table_data };
> > +        object_child_foreach(qdev_get_machine(),
> > +                             acpi_add_hotplug_memory_region_entry, &arg);
> > +    }
> > +
> >      build_header(linker, table_data,
> >                   (void *)(table_data->data + srat_start),
> >                   ACPI_SRAT_SIGNATURE,
> > -- 
> > 1.7.1

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

* Re: [Qemu-devel] [PATCH 25/27] pc: ACPI BIOS: use enum for defining memory affinity flags
  2013-11-21  7:20   ` Michael S. Tsirkin
@ 2013-11-25 10:11     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 10:11 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, 21 Nov 2013 09:20:18 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:38:46AM +0100, Igor Mammedov wrote:
> > 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 |   22 +++++++++++++++-------
> >  1 files changed, 15 insertions(+), 7 deletions(-)
> > 
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index d41fd81..86c1372 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -1038,15 +1038,22 @@ build_hpet(GArray *table_data, GArray *linker)
> >                   (void *)hpet, ACPI_HPET_SIGNATURE, sizeof(*hpet), 1);
> >  }
> >  
> > +typedef enum {
> > +    NOFLAGS_MEM       = 0,
> > +    ENABLED_MEM       = (1 << 0),
> > +    HOT_PLUGGABLE_MEM = (1 << 1),
> > +    NON_VOLATILE_MEM  = (1 << 2),
> > +} MemoryAffinityFlags;
> 
> Absolutely but please use prefixes not suffixes, and make them
> a bit more specific.
> E.g.  MEM_AFFINITY_NOFLAGS
I'll do it, thanks!

> 
> > +
> >  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);
> >  }
> > @@ -1094,7 +1101,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, ENABLED_MEM);
> >      next_base = 1024 * 1024;
> >      for (i = 1; i < guest_info->numa_nodes + 1; ++i) {
> >          mem_base = next_base;
> > @@ -1110,19 +1117,20 @@ build_srat(GArray *table_data, GArray *linker,
> >              mem_len -= next_base - guest_info->ram_size;
> >              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,
> > +                                       ENABLED_MEM);
> >              }
> >              mem_base = 1ULL << 32;
> >              mem_len = next_base - guest_info->ram_size;
> >              next_base += (1ULL << 32) - guest_info->ram_size;
> >          }
> >          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, ENABLED_MEM);
> >      }
> >      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, NOFLAGS_MEM);
> >      }
> >  
> >      build_header(linker, table_data,
> > -- 
> > 1.7.1

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-21 16:09         ` Andreas Färber
  2013-11-21 16:17           ` Michael S. Tsirkin
@ 2013-11-25 10:41           ` Igor Mammedov
  2013-11-25 17:00             ` Andreas Färber
  1 sibling, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 10:41 UTC (permalink / raw)
  To: Andreas Färber
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, hutao, mst, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, Li Guang

On Thu, 21 Nov 2013 17:09:27 +0100
Andreas Färber <afaerber@suse.de> wrote:

> Am 21.11.2013 15:34, schrieb Igor Mammedov:
> > On Thu, 21 Nov 2013 15:13:12 +0100
> > Andreas Färber <afaerber@suse.de> wrote:
> >> Am 21.11.2013 06:48, schrieb Li Guang:
> >>> Why not give the memory that not be hot-added a chance to be placed on
> >>> one memory slot?
> >>
> >> Seconded, I believe I requested that on the previous version already.
> > Because current initial memory allocation is a mess and this already
> > large series would become even more large and intrusive, so far series
> > it relatively not intrusive and self contained.
> > 
> > I believe re-factoring of initial memory to use Dimm devices should be
> > done later on top of infrastructure this series provides.
> 
> My problem with that is that that would be a semantically incompatible
> modeling change. With your series we might have /machine/dimm.0/child[0]
> be the first hot-plugged memory and once such a refactoring is done,
> child[0] silently becomes -m and child[1] is the hot-added one.

I think there won't be silent change in child[0], since most likely
initial RAM would require additional DimmBus (maybe even 2)
for it's devices.

But anyway, why would this be an issue?

> So if we know that we want/need to change the infrastructure, why not
> add a single patch (?) to allocate one additional object on the bus now?
> Unless we actually write the code, we won't know whether there are some
> incorrect hot-plug assumptions in the dimm code.
It wouldn't be a single simple patch for PC, I'm afraid.
I don't see point in adding dummy DIMM device for initial memory and then
do re-aliasing of its memory region in GPA as it's done in current code.

As I see it (taking in account Marcolo's/Paolo's alignment path), current
single MR for initial RAM should be split in 1-4 separate MRs depending on
initial RAM amount and alignment requirements between HPA/GPA addresses.

That would probably introduce additional, non hotlugable DimmBus-es (1-2)
for low and high memory, which would be incompatible with old machine types
devices and GPA layout, so why care about what
/machine/dimm.0/child[0] would be in new machine version?

> Andreas
> 

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-22 14:23   ` Gerd Hoffmann
@ 2013-11-25 11:00     ` Igor Mammedov
  2013-11-25 11:39       ` Gerd Hoffmann
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 11:00 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: peter.maydell, aliguori, stefanb, qemu-devel, hutao, mst, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, stefanha,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Fri, 22 Nov 2013 15:23:56 +0100
Gerd Hoffmann <kraxel@redhat.com> wrote:

> On Do, 2013-11-21 at 03:38 +0100, Igor Mammedov wrote:
> > Add DimmBus for memory hotplug below 4Gb or above 4Gb depending
> > on initial memory size and hotplug memory size.
> > 
> > * if ram_size is less than 32-bit PCI hole start, reserve
> >   hotplug memory region as [ram_size,32bit-PCIhole-start)
> >   if hotplug memory region fits there,
> >   otherwise reserve hotplug memory region after "0x100000000ULL
> >   + above_4g_mem_size"
> 
> Hmm, 32-bit pci hole start depends on ram size ...
> 
> Does it make sense to hotplug memory above 4g unconditionally to
> simplify things?
It does and it was so in v6 RFC,
But it would rule out hotplug for 32-bit guests that doesn't support
more then 4Gb.

As use case 32-bit guest could start whit small initial memory
and hotplug additional memory if needed up to point where 32-bit
PCI hole starts. That would allow guests to launch with small amount
but baloon up upto 2-3.5 Gb depending on machine type.
I could drop 32-bit guest support and do only high mem hotplug if
this case it not interesting to the comunity, any suggestions?

I'm now experimenting with removing pci-info and allowing BIOS to
do placement of 32-bit PCI bars akin it was done with 64-bit BARs,
(I'm looking to using E820 reservations for it but I'm not sure it
will work with every guest OS, so it needs more testing).

> cheers,
>   Gerd
> 
> 
> 

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-22  0:57               ` Li Guang
@ 2013-11-25 11:13                 ` Igor Mammedov
  2013-11-26  0:29                   ` Li Guang
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 11:13 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, aliguori, stefanb, qemu-devel, Hu Tao,
	Michael S. Tsirkin, mjt, mdroth, armbru, vasilis.liaskovitis,
	quintela, kraxel, stefanha, pbonzini, marcel.a, lcapitulino,
	chegu_vinod, afaerber

On Fri, 22 Nov 2013 08:57:40 +0800
Li Guang <lig.fnst@cn.fujitsu.com> wrote:

> Michael S. Tsirkin wrote:
> > On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
> >    
> >> Michael S. Tsirkin wrote:
> >>      
> >>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
> >>>        
> >>>> Hu Tao wrote:
> >>>>          
> >>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> >>>>>            
> >>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> >>>>>>              
> >>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
> >>>>>>> after it has been handled when it clears GPE event.
> >>>>>>>
> >>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
> >>>>>>>                
> >>>>>> The storm is only on memory hotplug right?
> >>>>>>              
> >>>>> IIRC, it happens on cpu hotplug, too.
> >>>>>
> >>>>>
> >>>>>
> >>>>>            
> >>>> :-), that made remember EC implementation,
> >>>> with EC, SCI will be safer, I think.
> >>>>          
> >>> Hmm you are saying let's use EC for memory hotplug?
> >>>
> >>>
> >>>        
> >> It can be a bridge between guest and QEMU,
> >> with it, we may don't have to bother ASL writing
> >> and south-bridge hardware related work(or very
> >> little) if we implement EC correctly.
> >>
> >>
> >>      
> >
> > I'd like to see that. Can you write a document (just text)
> > for an imaginary EC support for memory hotplug?
> >
> >
> >
> >    
> 
> Hmm..., with EC,
> 
> For memory hotplug, at least,
> ASL at [PATCH 27/27] can be replaced
> by a simple Method(_Qx) under EC device,
> IO base operations at [PATCH 15/27]
> are dispensable,  we can relay data
> by standard operations of EC space
> 
> and also for SCI, all device changes want to
> notify guest OS can share same SCI with EC,
> and the operations are specified at ACPI SPEC.
> 
> likewise, for CPU hotplug, pvpanic,
> and even debugcon.
> 
> and, for odd devices, like pvpanic, guest OS may complain
> about it, and we may also have to bother on maintaining state of
> it at QEMU, and writing a driver for guest OS,
> with EC, functions of device like pvpanic may be implemented silently,
> and EC is ACPI standard device, each ACPI compatible OS will
> have a driver for it natively.
> 
From what I remember about them EC was adding essentially another
side-channel but more sophisticated for OSPM communication with
platform but for not benefit so far, since what we need from ACPI
for hotplug could be implemented by using GPE handlers without
adding any EC.

I think there was EC patches on list (perhaps yours) but I couldn't
find them. Could you point me to them if they are demonstrating
how hotplug could be done with EC approach.

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-25 11:00     ` Igor Mammedov
@ 2013-11-25 11:39       ` Gerd Hoffmann
  2013-11-25 13:34         ` Igor Mammedov
  2013-11-25 13:35         ` Paolo Bonzini
  0 siblings, 2 replies; 143+ messages in thread
From: Gerd Hoffmann @ 2013-11-25 11:39 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, qemu-devel, hutao, mst, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, stefanha,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

> > Does it make sense to hotplug memory above 4g unconditionally to
> > simplify things?
> It does and it was so in v6 RFC,
> But it would rule out hotplug for 32-bit guests that doesn't support
> more then 4Gb.

Indeed.

> As use case 32-bit guest could start whit small initial memory
> and hotplug additional memory if needed up to point where 32-bit
> PCI hole starts. That would allow guests to launch with small amount
> but baloon up upto 2-3.5 Gb depending on machine type.
> I could drop 32-bit guest support and do only high mem hotplug if
> this case it not interesting to the comunity, any suggestions?

32bit limits start to hurt with 1GB already.  Kernel address space is 1G
on 32bit, so the kernel can't map all RAM all the time any more.  Which
in turn adds overhead for mapping/unmapping pages if the kernel must
access highmem pages.  So it's better to run 64bit guests even with alot
less than 4G of memory.

I'd tend to just not support 32bit guests, I think it simply isn't worth
the trouble.

cheers,
  Gerd

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

* Re: [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices Igor Mammedov
@ 2013-11-25 12:49   ` Paolo Bonzini
  2013-11-25 13:11     ` Paolo Bonzini
  2013-11-25 15:57     ` Igor Mammedov
  0 siblings, 2 replies; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 12:49 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> +typedef enum {
> +    HOTPLUG_DISABLED,
> +    HOTPLUG_ENABLED,
> +    COLDPLUG_ENABLED,
> +} HotplugState;
> +
> +typedef int (*hotplug_fn)(DeviceState *hotplug_dev, DeviceState *dev,
> +                          HotplugState state);

I don't think this is a particularly useful interface, because it
reinvents a lot of what already exists in qdev/qbus.

The cold/hotplug_enabled differentiation is not particularly useful
when dev->hotplugged already exists, and the interface leaves one to
wonder why COLDPLUG_ENABLED doesn't have a matching COLDPLUG_DISABLED
(until one looks at the code).

Take for example this:

static void enable_device(PIIX4PMState *s, int slot)
{
    s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
    s->pci0_slot_device_present |= (1U << slot);
}

static void disable_device(PIIX4PMState *s, int slot)
{
    s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
    s->pci0_status.down |= (1U << slot);
}

static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
                                PCIHotplugState state)
{
    int slot = PCI_SLOT(dev->devfn);
    PIIX4PMState *s = PIIX4_PM(qdev);

    /* Don't send event when device is enabled during qemu machine creation:
     * it is present on boot, no hotplug event is necessary. We do send an
     * event when the device is disabled later. */
    if (state == PCI_COLDPLUG_ENABLED) {
        s->pci0_slot_device_present |= (1U << slot);
        return 0;
    }

    if (state == PCI_HOTPLUG_ENABLED) {
        enable_device(s, slot);
    } else {
        disable_device(s, slot);
    }

    pm_update_sci(s);

    return 0;
}


In my opinion, it is much clearer this way---separating enable/disabled
rather than hotplug/coldplug:

static void piix4_pci_send_event(PIIX4PMState *s)
{
    s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
    pm_update_sci(s);
}

static int piix4_device_hotplug(DeviceState *qdev, DeviceState *dev)
{
    PCIDevice *pci = PCI_DEVICE(dev);
    int slot = PCI_SLOT(pci->devfn);
    PIIX4PMState *s = PIIX4_PM(qdev);

    s->pci0_slot_device_present |= (1U << slot);
    /* Don't send event when device is enabled during qemu machine creation:
     * it is present on boot, no hotplug event is necessary. We do send an
     * event when the device is disabled later. */
    if (dev->hotplugged) {
        piix4_pci_send_event(s);
    }
    return 0;
}

static int piix4_device_hot_unplug(DeviceState *qdev, DeviceState *dev)
{
    PCIDevice *pci = PCI_DEVICE(dev);
    int slot = PCI_SLOT(pci->devfn);
    PIIX4PMState *s = PIIX4_PM(qdev);

    s->pci0_status.down |= (1U << slot);
    piix4_pci_send_event(s);
    return 0;
}

This is of course just an example, I'm not asking you to reimplement hotplug
for all buses in QEMU.  However, my point is that this shouldn't be a "core"
enum and interface.  If you want to have a core interface in BusClass, I'd
rather add ->hotplug and ->hot_unplug to BusClass, similar to how the SCSI
bus does it (note: I only maintain it, I didn't write that code) and so
that BusClass's methods match ->init/->exit on the device side.

Paolo

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Igor Mammedov
  2013-11-21  6:01   ` Li Guang
  2013-11-21 10:12   ` Markus Armbruster
@ 2013-11-25 12:51   ` Paolo Bonzini
  2013-11-27  0:32     ` Igor Mammedov
  2 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 12:51 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> Along with conversion extend -m option to support following parameters:
>   "mem" - startup memory amount
>   "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 usable.

Strictly speaking, slots and maxmem should be added later, not in this
patch.  Not a blocker, though.

Paolo

> v2:
>   make sure maxmem is not less than ram size
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---
>  qemu-options.hx |    9 +++++-
>  vl.c            |   73 ++++++++++++++++++++++++++++++++++++++++++++++---------
>  2 files changed, 68 insertions(+), 14 deletions(-)
> 
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 8b94264..fe4559b 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -210,8 +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 [mem=]megs[,slots=n,maxmem=size]\n"
> +    "                set virtual RAM size to megs MB [default="
> +    stringify(DEFAULT_RAM_SIZE) "]\n"
> +    "                mem=start-up memory amount\n"
> +    "                slots=maximum number of hotplug slots\n"
> +    "                maxmem=maximum total amount of memory\n",
> +    QEMU_ARCH_ALL)
>  STEXI
>  @item -m @var{megs}
>  @findex -m
> diff --git a/vl.c b/vl.c
> index f28674f..5974f0f 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -529,6 +529,28 @@ static QemuOptsList qemu_msg_opts = {
>      },
>  };
>  
> +static QemuOptsList qemu_mem_opts = {
> +    .name = "memory-opts",
> +    .implied_opt_name = "mem",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
> +    .merge_lists = true,
> +    .desc = {
> +        {
> +            .name = "mem",
> +            .type = QEMU_OPT_SIZE,
> +        },
> +        {
> +            .name = "slots",
> +            .type = QEMU_OPT_NUMBER,
> +        },
> +        {
> +            .name = "maxmem",
> +            .type = QEMU_OPT_SIZE,
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
>  /**
>   * Get machine options
>   *
> @@ -2816,6 +2838,14 @@ static int object_create(QemuOpts *opts, void *opaque)
>      return 0;
>  }
>  
> +static void qemu_init_default_mem_opts(uint64_t size)
> +{
> +    QemuOpts *opts = qemu_opts_create_nofail(&qemu_mem_opts);
> +    qemu_opt_set_number(opts, "mem", size);
> +    qemu_opt_set_number(opts, "maxmem", size);
> +    qemu_opt_set_number(opts, "slots", 0);
> +}
> +
>  int main(int argc, char **argv, char **envp)
>  {
>      int i;
> @@ -2887,6 +2917,7 @@ int main(int argc, char **argv, char **envp)
>      qemu_add_opts(&qemu_tpmdev_opts);
>      qemu_add_opts(&qemu_realtime_opts);
>      qemu_add_opts(&qemu_msg_opts);
> +    qemu_add_opts(&qemu_mem_opts);
>  
>      runstate_init();
>  
> @@ -2901,7 +2932,8 @@ int main(int argc, char **argv, char **envp)
>      module_call_init(MODULE_INIT_MACHINE);
>      machine = find_default_machine();
>      cpu_model = NULL;
> -    ram_size = 0;
> +    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
> +    qemu_init_default_mem_opts(ram_size);
>      snapshot = 0;
>      cyls = heads = secs = 0;
>      translation = BIOS_ATA_TRANSLATION_AUTO;
> @@ -3178,21 +3210,43 @@ 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 *end;
> +                char *s;
>  
> -                value = strtosz(optarg, &end);
> -                if (value < 0 || *end) {
> -                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
> +                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
> +                                       optarg, 1);
> +                if (!opts) {
>                      exit(1);
>                  }
> -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
> +
> +                /* fixup legacy sugffix-less format */
> +                end = qemu_opt_get(opts, "mem");
> +                if (g_ascii_isdigit(end[strlen(end) - 1])) {
> +                    s = g_strconcat(end, "M", NULL);
> +                    qemu_opt_set(opts, "mem", s);
> +                    g_free(s);
> +                }
> +
> +                sz = QEMU_ALIGN_UP(qemu_opt_get_size(opts, "mem", ram_size),
> +                                   8192);
> +                /* compatibility behaviour for case "-m 0" */
> +                if (sz == 0) {
> +                    sz = DEFAULT_RAM_SIZE * 1024 * 1024;
> +                }
> +
>                  ram_size = sz;
>                  if (ram_size != sz) {
>                      fprintf(stderr, "qemu: ram size too large\n");
>                      exit(1);
>                  }
> +                /* store aligned value for future use */
> +                qemu_opt_set_number(opts, "mem", ram_size);
> +
> +                sz = qemu_opt_get_size(opts, "maxmem", ram_size);
> +                if (sz < ram_size) {
> +                    qemu_opt_set_number(opts, "maxmem", ram_size);
> +                }
>                  break;
>              }
>  #ifdef CONFIG_TPM
> @@ -4029,11 +4083,6 @@ int main(int argc, char **argv, char **envp)
>          exit(1);
>      }
>  
> -    /* init the memory */
> -    if (ram_size == 0) {
> -        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
> -    }
> -
>      if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
>          != 0) {
>          exit(0);
> 

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure Igor Mammedov
@ 2013-11-25 12:54   ` Paolo Bonzini
  2013-11-25 16:01     ` Igor Mammedov
  2013-11-27 15:25   ` Eric Blake
  1 sibling, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 12:54 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> +
> +    /* verify properties correctnes and initialize backend */
> +    bc = MEMORY_BACKEND_GET_CLASS(obj);
> +    if (bc->get_memory) {
> +        HostMemoryBackend *backend = MEMORY_BACKEND(obj);
> +        if (!bc->get_memory(backend, &local_err)) {
> +            goto out;
> +        }
> +    }

So this is why you need a new command-line option.

I think we need a generic mechanism for post-initialization of whatever
is given on the command line.  Perhaps you can do that with an
interface, and get rid of -memdev and memdev_add altogether?

MemoryBackend's implementation of the interface's sole method would call
get_memory, of course.

Paolo

> +    /* make backend available to the world via QOM tree */
> +    object_property_add_child(container_get(qemu_get_backend(), "/memdev"),
> +                              qemu_opts_id(opts), obj, &local_err);

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

* Re: [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction Igor Mammedov
@ 2013-11-25 12:57   ` Paolo Bonzini
  2013-11-25 15:10     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 12:57 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> +static void dimm_initfn(Object *obj)
> +{
> +    object_property_add(obj, "memdev", "string", dimm_get_memdev,
> +                        dimm_set_memdev, NULL, NULL, NULL);

Perhaps, instead of relying on memory_region_owner, you could have
separate pointers for the MemoryBackend* and MemoryRegion*.  Then this
property could be a link<MemoryBackend> type (it looks like a link, and
quacks like a link).

Paolo

> +    object_property_add(obj, "size", "int", dimm_get_size,
> +                        NULL, NULL, NULL, NULL);
> +}
> +

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

* Re: [Qemu-devel] [PATCH 12/27] dimm: add hotplug callback to DimmBus
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 12/27] dimm: add hotplug callback to DimmBus Igor Mammedov
@ 2013-11-25 13:01   ` Paolo Bonzini
  2013-11-25 14:40     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 13:01 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
> index abedae2..b655006 100644
> --- a/include/hw/mem/dimm.h
> +++ b/include/hw/mem/dimm.h
> @@ -65,11 +65,15 @@ typedef struct DimmDeviceClass {
>   * @parent_obj: opaque parent object container
>   * @base: address from which to start mapping @DimmDevice
>   * @as: hot-plugabble memory area where @DimmDevice-s are attached
> + * @hotplug_dev: device that hotplugs realized DimmDevice
> + * @hotplug: hotplug callback set by the board
>   */
>  typedef struct DimmBus {
>      BusState parent_obj;
>      hwaddr base;
>      MemoryRegion as;
> +    DeviceState *hotplug_dev;
> +    hotplug_fn hotplug;
>  } DimmBus;
>  
>  /**
> 

So the alternatives here would be:

(1) have DimmDevice call hotplug/hot_unplug in DimmBus; add a
ACPIHotplugDimmBus subclass that connects to ACPI.

(2) have DeviceState call hotplug/hot_unplug in BusState; DimmBus does
nothing with it, and a ACPIHotplugDimmBus subclass implements it.

Paolo

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

* Re: [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices
  2013-11-25 12:49   ` Paolo Bonzini
@ 2013-11-25 13:11     ` Paolo Bonzini
  2013-11-25 15:57     ` Igor Mammedov
  1 sibling, 0 replies; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 13:11 UTC (permalink / raw)
  Cc: peter.maydell, aliguori, mst, qemu-devel, hutao, stefanb, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, kraxel, stefanha,
	Igor Mammedov, marcel.a, lcapitulino, chegu_vinod, afaerber

Il 25/11/2013 13:49, Paolo Bonzini ha scritto:
> Il 21/11/2013 03:38, Igor Mammedov ha scritto:
>> +typedef enum {
>> +    HOTPLUG_DISABLED,
>> +    HOTPLUG_ENABLED,
>> +    COLDPLUG_ENABLED,
>> +} HotplugState;
>> +
>> +typedef int (*hotplug_fn)(DeviceState *hotplug_dev, DeviceState *dev,
>> +                          HotplugState state);
> 
> I don't think this is a particularly useful interface, because it
> reinvents a lot of what already exists in qdev/qbus.
> 
> The cold/hotplug_enabled differentiation is not particularly useful
> when dev->hotplugged already exists, and the interface leaves one to
> wonder why COLDPLUG_ENABLED doesn't have a matching COLDPLUG_DISABLED
> (until one looks at the code).
> 
> Take for example this:
> 
> static void enable_device(PIIX4PMState *s, int slot)
> {
>     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
>     s->pci0_slot_device_present |= (1U << slot);
> }
> 
> static void disable_device(PIIX4PMState *s, int slot)
> {
>     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
>     s->pci0_status.down |= (1U << slot);
> }
> 
> static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
>                                 PCIHotplugState state)
> {
>     int slot = PCI_SLOT(dev->devfn);
>     PIIX4PMState *s = PIIX4_PM(qdev);
> 
>     /* Don't send event when device is enabled during qemu machine creation:
>      * it is present on boot, no hotplug event is necessary. We do send an
>      * event when the device is disabled later. */
>     if (state == PCI_COLDPLUG_ENABLED) {
>         s->pci0_slot_device_present |= (1U << slot);
>         return 0;
>     }
> 
>     if (state == PCI_HOTPLUG_ENABLED) {
>         enable_device(s, slot);
>     } else {
>         disable_device(s, slot);
>     }
> 
>     pm_update_sci(s);
> 
>     return 0;
> }
> 
> 
> In my opinion, it is much clearer this way---separating enable/disabled
> rather than hotplug/coldplug:
> 
> static void piix4_pci_send_event(PIIX4PMState *s)
> {
>     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
>     pm_update_sci(s);
> }
> 
> static int piix4_device_hotplug(DeviceState *qdev, DeviceState *dev)
> {
>     PCIDevice *pci = PCI_DEVICE(dev);
>     int slot = PCI_SLOT(pci->devfn);
>     PIIX4PMState *s = PIIX4_PM(qdev);
> 
>     s->pci0_slot_device_present |= (1U << slot);
>     /* Don't send event when device is enabled during qemu machine creation:
>      * it is present on boot, no hotplug event is necessary. We do send an
>      * event when the device is disabled later. */
>     if (dev->hotplugged) {
>         piix4_pci_send_event(s);
>     }
>     return 0;
> }
> 
> static int piix4_device_hot_unplug(DeviceState *qdev, DeviceState *dev)
> {
>     PCIDevice *pci = PCI_DEVICE(dev);
>     int slot = PCI_SLOT(pci->devfn);
>     PIIX4PMState *s = PIIX4_PM(qdev);
> 
>     s->pci0_status.down |= (1U << slot);
>     piix4_pci_send_event(s);
>     return 0;
> }
> 
> This is of course just an example, I'm not asking you to reimplement hotplug
> for all buses in QEMU.  However, my point is that this shouldn't be a "core"
> enum and interface.  If you want to have a core interface in BusClass, I'd
> rather add ->hotplug and ->hot_unplug to BusClass, similar to how the SCSI
> bus does it (note: I only maintain it, I didn't write that code) and so
> that BusClass's methods match ->init/->exit on the device side.

I reviewed the user now.

I understand why you want to reuse the same idiom.  Perhaps you can move
this to include/hw/hotplug.h instead?  I would still prefer DimmBus or
BusClass to use the more common hotplug/hot_unplug interface, but
ACPIHotpluggableDimmBus can map it to an hotplug_fn.

Paolo

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-25 11:39       ` Gerd Hoffmann
@ 2013-11-25 13:34         ` Igor Mammedov
  2013-11-25 13:35         ` Paolo Bonzini
  1 sibling, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 13:34 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: peter.maydell, aliguori, stefanb, qemu-devel, hutao, mst, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, stefanha,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Mon, 25 Nov 2013 12:39:05 +0100
Gerd Hoffmann <kraxel@redhat.com> wrote:

> > > Does it make sense to hotplug memory above 4g unconditionally to
> > > simplify things?
> > It does and it was so in v6 RFC,
> > But it would rule out hotplug for 32-bit guests that doesn't support
> > more then 4Gb.
> 
> Indeed.
> 
> > As use case 32-bit guest could start whit small initial memory
> > and hotplug additional memory if needed up to point where 32-bit
> > PCI hole starts. That would allow guests to launch with small amount
> > but baloon up upto 2-3.5 Gb depending on machine type.
> > I could drop 32-bit guest support and do only high mem hotplug if
> > this case it not interesting to the comunity, any suggestions?
> 
> 32bit limits start to hurt with 1GB already.  Kernel address space is 1G
> on 32bit, so the kernel can't map all RAM all the time any more.  Which
> in turn adds overhead for mapping/unmapping pages if the kernel must
> access highmem pages.  So it's better to run 64bit guests even with alot
> less than 4G of memory.
> 
> I'd tend to just not support 32bit guests, I think it simply isn't worth
> the trouble.
Fine with me, If there isn't abjection to it, I'll drop 32-bit guest support
on the next respin.

> cheers,
>   Gerd
> 
> 

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-25 11:39       ` Gerd Hoffmann
  2013-11-25 13:34         ` Igor Mammedov
@ 2013-11-25 13:35         ` Paolo Bonzini
  2013-11-25 14:24           ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 13:35 UTC (permalink / raw)
  To: Gerd Hoffmann
  Cc: peter.maydell, stefanha, stefanb, hutao, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, aliguori, Igor Mammedov,
	marcel.a, lcapitulino, chegu_vinod, afaerber, armbru

Il 25/11/2013 12:39, Gerd Hoffmann ha scritto:
>> > As use case 32-bit guest could start whit small initial memory
>> > and hotplug additional memory if needed up to point where 32-bit
>> > PCI hole starts. That would allow guests to launch with small amount
>> > but baloon up upto 2-3.5 Gb depending on machine type.
>> > I could drop 32-bit guest support and do only high mem hotplug if
>> > this case it not interesting to the comunity, any suggestions?
> 32bit limits start to hurt with 1GB already.  Kernel address space is 1G
> on 32bit, so the kernel can't map all RAM all the time any more.  Which
> in turn adds overhead for mapping/unmapping pages if the kernel must
> access highmem pages.  So it's better to run 64bit guests even with alot
> less than 4G of memory.
> 
> I'd tend to just not support 32bit guests, I think it simply isn't worth
> the trouble.

Also because it's just non-PAE 32-bit guests, no?  PAE guests would
support hotplug just fine.

Paolo

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

* Re: [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
  2013-11-21  9:37   ` Michael S. Tsirkin
@ 2013-11-25 13:42   ` Paolo Bonzini
  2013-11-25 14:26     ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 13:42 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, armbru, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha, hutao,
	marcel.a, lcapitulino, chegu_vinod, afaerber

Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> +                // 64-bit math: MAX = MIN + LEN - 1
> +                Add(MINL, LENL, MAXL)
> +                Add(MINH, LENH, MAXH)
> +                If (Or(LLess(MAXL, MINL), LLess(MAXL, LENL))) {

The Or is not necessary, LLess(MAXL, MINL) is enough.

> +                    Add(MAXH, 1, MAXH)

One?  (Just for consistency, iasl does it already).

> +                }

> +                // Ignore (MAXL == 0 & MAXH == 0) case
> +                If (LEqual(MAXL, Zero)) {
> +                    Subtract(MAXH, One, MAXH)
> +                    Store(0xFFFFFFFF, MAXL)
> +                } Else {
> +                    Subtract(MAXL, One, MAXL)
> +                }
> +

Why not this:

                   If (LLess(MAXL, One)) {
                       Subtract(MAXH, One, MAXH)
                   }
                   Subtract(MAXL, One, MAXL)

Paolo

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-25  7:27             ` Markus Armbruster
@ 2013-11-25 13:45               ` Paolo Bonzini
  2013-11-25 14:18                 ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 13:45 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: peter.maydell, stefanha, marcel.a, hutao, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela,
	Michael S. Tsirkin, kraxel, aliguori, Igor Mammedov, lcapitulino,
	chegu_vinod, afaerber

Il 25/11/2013 08:27, Markus Armbruster ha scritto:
> "Michael S. Tsirkin" <mst@redhat.com> writes:
> 
> [...]
>> Here this made me think of the following question:
>> should not memory available on boot be listed in CMOS?
>> Let's assume new BIOS gets interrupt telling it there's new memory.
>> It clears the interrupt and then system is reset.
>>
>> Will system after reset detect the new hotplugged memory?

Can it just scan all slots from MHPD._INI?

For example on reset all slots could be disabled by the
ACPIHotpluggableDimmBus (even coldplugged ones), and scanned + enabled
by ASL.

>> How?
> 
> Do physical systems with hot-pluggable memory exist?  How do they
> behave?

I guess they assume BIOS is updated in lockstep with the introduction of
the feature.

Paolo

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-24 10:58           ` Michael S. Tsirkin
  2013-11-25  7:27             ` Markus Armbruster
@ 2013-11-25 13:56             ` Igor Mammedov
  1 sibling, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 13:56 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Sun, 24 Nov 2013 12:58:57 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Fri, Nov 22, 2013 at 06:14:46PM +0100, Igor Mammedov wrote:
> > On Thu, 21 Nov 2013 16:38:47 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Nov 21, 2013 at 03:21:37PM +0100, Igor Mammedov wrote:
> > > > On Thu, 21 Nov 2013 11:42:02 +0200
> > > > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > [...]
> > > > > > +      [0x14] highest memory hot-plug interface version supported by QEMU
> > > > > 
> > > > > So this can make guest fail gracefully but it appears that
> > > > > detecting guest version would be nicer?
> > > > > It would let us actually support old guests ...
> > > > 
> > > > my idea of how to it was,
> > > > guest writes its version into [0x14] register and reads QEMU version
> > > > from it back, if they do not match then than BIOS ignores GPE.3 event
> > > > effectively disabling hotplug on guest side.
> > > > I haven't thought about supporting multiple implementations in QEMU though.
> > > > Do we really want it?
> > > 
> > > I'm talking about old bios which does not read acpi from qemu.
> > > We want it to work even if it can't see hotplugged memory.
> > to sum up cases that were discussed on IRC.
> > 
> >  * migration from NEW to OLD machine leads us to state when we run new BIOS with
> >    ACPI tables supporting memory hotplug on OLD machine.
> >    In general should work since NEW machine has to be started without memory
> >    hotplug enabled, which leads to disabling related ASL handler in ACPI tables.
> >    Case where NEW machine with memory hotplug enabled migrating to OLD machine
> >    without memory hotplug is invalid since migration will fail early due to
> >    missing devices (DimmBus/DIMM devices)
> > 
> >  * running OLD BIOS on new machine with memory hotplug turned on at QEMU CLI
> >         qemu -m X,slots=Y,maxmem=Z -bios old-bios-image -M pc-1.8
> > 
> >    Problem here is that OLD BIOS doesn't know about 'etc/reserved-memory-end' fwcfg,
> >    so it can start mapping PCI BARs right after high memory (i.e. in memory hotplug
> >    reserved space)
> > 
> >    That's fine as far as there is no DIMM devices since access will fall through
> >    hotplug-mem container to PCI address space.
> > 
> >    But if DIMM device added at startup or runtime, its MemoryRegion will overshadow
> >    PCI BARs mapped at its range.
> > 
> >    If it were only hotadd case, then QEMU could start with enabled but not active
> >    memory hotplug and require BIOS to acknowledge (activate) hotlug so that adding
> >    DIMM devices wouldn't be possible without hotplug enabled BIOS. 
> >    That would guarantee empty hotplug-mem container for OLD BIOS since it can't
> >    activate hotplug and avoid conflict.
> > 
> >    But if there are cold-plugged DIMM devices on QEMU CLI, that wouldn't work
> >    because OLD BIOS has no idea about them (i.e. it reads above4gb memory CMOS value)
> >    and it is bound to map 64-bit BARs in invalid place.
> >  
> >    It would be nice to run OLD BIOS on new machine and it will even work IF memory
> >    hotplug is not enabled.
> >    But I'm not sure we should care about case when not compatible BIOS is running
> >    on machine with active memory hotplug.
> 
> It's not a must, I agree. It's just a useful excercise that might
> help us think of potential problems.
> 
> Here this made me think of the following question:
> should not memory available on boot be listed in CMOS?
> Let's assume new BIOS gets interrupt telling it there's new memory.
> It clears the interrupt and then system is reset.
> 
> Will system after reset detect the new hotplugged memory?
> How?

I don't have memory hotplug enabled real hardware and can only deduce what is
needed from guest behavior. So here is my observations:
 * windows: hotpluggable memory doesn't have to be in E820, OS sees
   and automatically onlines present hotpluggable memory.
 * linux: kernel enumerates present memory devices and sends events to udev.
   It's up to user space to provide udev scripts for onlining hotpluggable
   memory now.

So in general rebooting at any time shouldn't hurt, and guest would see
hotplugged memory. But linux kernel won't use it until udev onlines it.

I see adding present at boot hotpluggable memory to E820 as a nice additional
feature which is not must have but I'm looking to implementing it as follow-up,
along with moving generation of related smbios tables into QEMU as you have
done for ACPI tables.

> > > 
> > > > > 
> > > > > > +      [0x15] Memory device status fields
> > > > > > +          bits:
> > > > > > +              1: device is enabled and may be used by guest
> > > > > > +              2: device insert event, used by ACPI BIOS to distinguish
> > > > > > +                 device for which no device check event to OSPM was issued
> > > > > 
> > > > > what does the above mean?
> > > > After OSPM issued device check on selected device it clears this bit to mark event
> > > > as handled.
> > > > It allows to avoid keeping this state in ASL (as it's done for CPU hotplug, see CPON)
> > > 
> > > That's fine.
> > > 
> > > > > what if device is not present?
> > > > ASL will issue device check and clear bit, it might be a bug since _STA would report
> > > > not present but no eject event was issued.
> > > > 
> > > > Papering over it ASL could check present bit first and issue device check only if
> > > > it's present.
> > > 
> > > Is this a problem? If yes - that will still be racy won't it?
> > I thought about it some more and I don't see why it would be racy.
> > bit 0x15.1 is set when there is initialized DIMM device in slot so 0x15.2 couldn't
> > be set if 0x15.1 == 0.
> > 
> > May be following description would be better:
> > 
> >    2: device insert event, used by ACPI BIOS to distinguish
> >       device for which no device check event to OSPM was issued.
> >       Bit is valid only when 0x15.1 bit is set.
> > 
> > It's possible to remove is_inserting bit altogether and just send device check to
> > each present memory device. Device check will be NOP for memory devices that OSPM
> > processed.
> > That will work fine with small amount of slots but would increase load on guest
> > in case of 1000s devices. That's the main reason for dedicated is_inserting bit,
> > allowing to handle hotadd effectively.
> > 
> >       
> > > 
> > > 
> > > Also, should guest reset eject memory that we requested unplug for?
> > I'm not sure what you saying here in general.
> > In particular unplug is not part of this series.
> > 
> > 
> > [...]
> > > > > selected?
> > > > see "write access: [0x0-0x3]"
> > > 
> > > yes but you have a typo above
> > Ahh, blind me. Thanks, I'll fix it.
> > 
> > > 
> > > > > 
> > > > > How about we actually require guest to enable memory?
> > > > > 
> > > > > This way if we hotplug, but old guest does not enable
> > > > > and puts a PCI device there, it just works.
> > > > I've lost you here, could you elaborate pls?
> > > 
> > > 
> > > Assume qemu adds memory by hotplug.
> > > Is it immediately enabled?
> > > I suggest it's not enabled, and only enable after ACPI
> > > enables it (or after reboot?)
> > I guess answer is in "running OLD BIOS on new machine with memory hotplug turned on"
> > case above. i.e. Don't run not compatible BIOS with turned on memory hotplug.
> > I think simpler interface/work-flow is better than a more complicated one,
> > that is required to support not totally sane configuration that is bound to be broken anyway.
> > 
> > > 
> > > > > 
> > > > > > +
> > > > > > +Selecting memory device slot beyond present range has no effect on platform:
> > > > > > +   - not documented above write accesses to memory hot-plug registers
> > > > > > +     are ignored;
> > > > > > +   - not documented above read accesses to memory hot-plug registers return 0xFF
> > > > > 
> > > > > 00 would be cleaner (matches not enabled - no event)?
> > > > I'm following pattern, where reading from not present IO port returns 0xFF on hardware.
> > > > Fact that ASL reads 0xFF could be used as not supported indication.
> > > 
> > > But isn't this a valid pattern when all bits are set?
> > It's to the same extent as 0x0. I'll change it to 0x0 if you still think it's better.
> > 
> > [...]

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-25 13:45               ` Paolo Bonzini
@ 2013-11-25 14:18                 ` Igor Mammedov
  2013-11-25 14:31                   ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 14:18 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, stefanb, hutao, Michael S. Tsirkin, mjt,
	Markus Armbruster, qemu-devel, vasilis.liaskovitis, quintela,
	chegu_vinod, kraxel, aliguori, marcel.a, lcapitulino, stefanha,
	afaerber

On Mon, 25 Nov 2013 14:45:15 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 25/11/2013 08:27, Markus Armbruster ha scritto:
> > "Michael S. Tsirkin" <mst@redhat.com> writes:
> > 
> > [...]
> >> Here this made me think of the following question:
> >> should not memory available on boot be listed in CMOS?
> >> Let's assume new BIOS gets interrupt telling it there's new memory.
> >> It clears the interrupt and then system is reset.
> >>
> >> Will system after reset detect the new hotplugged memory?
> 
> Can it just scan all slots from MHPD._INI?
> 
> For example on reset all slots could be disabled by the
> ACPIHotpluggableDimmBus (even coldplugged ones), and scanned + enabled
> by ASL.
memory devices are scanned by OSPM during ACPI tables parsing and 
guest (can) use present devices right away.

Currently I don't see necessity for enabling individual memory devices from
ASL since it adds one more round trip for QEMU<->guest protocol for no
particular benefit. The only use case Michael suggested would be running
OLD BIOS (without memory hotplug support) on machine with actively used
memory hotplug (if OLD BIOS runs on machine with memory hotplug but there is
no hotplugged memory devices, it runs just fine), so case looks like not worth
an effort and complexity it would bring.

I believe having completely functional DIMM device after its realize() method
is completed is more strait-forward and easier to understand/support than
having guest to complete it's initialization.
That would allow later to put present at boot DIMMs into E820 (way before ASL
is executed) if that would be necessary and also help to convert initial
memory into hotpluggable one as well.

> 
> >> How?
> > 
> > Do physical systems with hot-pluggable memory exist?  How do they
> > behave?
> 
> I guess they assume BIOS is updated in lockstep with the introduction of
> the feature.
> 
> Paolo
> 

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-25 13:35         ` Paolo Bonzini
@ 2013-11-25 14:24           ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 14:24 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, aliguori, mst, hutao, stefanb, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, Gerd Hoffmann, stefanha,
	marcel.a, lcapitulino, chegu_vinod, afaerber, armbru

On Mon, 25 Nov 2013 14:35:18 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 25/11/2013 12:39, Gerd Hoffmann ha scritto:
> >> > As use case 32-bit guest could start whit small initial memory
> >> > and hotplug additional memory if needed up to point where 32-bit
> >> > PCI hole starts. That would allow guests to launch with small amount
> >> > but baloon up upto 2-3.5 Gb depending on machine type.
> >> > I could drop 32-bit guest support and do only high mem hotplug if
> >> > this case it not interesting to the comunity, any suggestions?
> > 32bit limits start to hurt with 1GB already.  Kernel address space is 1G
> > on 32bit, so the kernel can't map all RAM all the time any more.  Which
> > in turn adds overhead for mapping/unmapping pages if the kernel must
> > access highmem pages.  So it's better to run 64bit guests even with alot
> > less than 4G of memory.
> > 
> > I'd tend to just not support 32bit guests, I think it simply isn't worth
> > the trouble.
> 
> Also because it's just non-PAE 32-bit guests, no?  PAE guests would
> support hotplug just fine.
Yes, it shouldn't be issue for PAE in general.

but it might not work for Windows Server 2003 (including 64-bit one), since
it BSODed when it sees 64bit CRS (we saw it playing with 64-bit PCI window).
Not sure if we care about it though. 

> Paolo
> 

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

* Re: [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface
  2013-11-25 13:42   ` Paolo Bonzini
@ 2013-11-25 14:26     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 14:26 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, aliguori, stefanb, armbru, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha, hutao,
	marcel.a, lcapitulino, chegu_vinod, afaerber

On Mon, 25 Nov 2013 14:42:44 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> > +                // 64-bit math: MAX = MIN + LEN - 1
> > +                Add(MINL, LENL, MAXL)
> > +                Add(MINH, LENH, MAXH)
> > +                If (Or(LLess(MAXL, MINL), LLess(MAXL, LENL))) {
> 
> The Or is not necessary, LLess(MAXL, MINL) is enough.
ok, I'll fix it.

> 
> > +                    Add(MAXH, 1, MAXH)
> 
> One?  (Just for consistency, iasl does it already).
sure

> 
> > +                }
> 
> > +                // Ignore (MAXL == 0 & MAXH == 0) case
> > +                If (LEqual(MAXL, Zero)) {
> > +                    Subtract(MAXH, One, MAXH)
> > +                    Store(0xFFFFFFFF, MAXL)
> > +                } Else {
> > +                    Subtract(MAXL, One, MAXL)
> > +                }
> > +
> 
> Why not this:
> 
>                    If (LLess(MAXL, One)) {
>                        Subtract(MAXH, One, MAXH)
>                    }
>                    Subtract(MAXL, One, MAXL)
I'll try it, thanks!

> 
> Paolo

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-25 14:18                 ` Igor Mammedov
@ 2013-11-25 14:31                   ` Paolo Bonzini
  2013-11-25 14:57                     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 14:31 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, stefanb, hutao, Michael S. Tsirkin, mjt,
	Markus Armbruster, qemu-devel, vasilis.liaskovitis, quintela,
	chegu_vinod, kraxel, aliguori, marcel.a, lcapitulino, stefanha,
	afaerber

Il 25/11/2013 15:18, Igor Mammedov ha scritto:
>> > For example on reset all slots could be disabled by the
>> > ACPIHotpluggableDimmBus (even coldplugged ones), and scanned + enabled
>> > by ASL.
> memory devices are scanned by OSPM during ACPI tables parsing and 
> guest (can) use present devices right away.

Yes, what I'm saying is scan them to enable them so that OSPM sees them
already as online.

> Currently I don't see necessity for enabling individual memory devices from
> ASL since it adds one more round trip for QEMU<->guest protocol for no
> particular benefit. The only use case Michael suggested would be running
> OLD BIOS (without memory hotplug support) on machine with actively used
> memory hotplug (if OLD BIOS runs on machine with memory hotplug but there is
> no hotplugged memory devices, it runs just fine), so case looks like not worth
     ^^^^^^^^^^

*Hotpluggable*, not hotplugged.  It would also break just with
coldplugged memory devices.

> That would allow later to put present at boot DIMMs into E820 (way before ASL
> is executed) if that would be necessary and also help to convert initial
> memory into hotpluggable one as well.

I am afraid that mixing hot-unplug with E820 could cause some
unanticipated trouble.  OSes may not expect memory in the E820 ranges to
disappear.

But since we're speaking about e820, do guests work if you make the
hotpluggable memory region reserved in the e820?  That should work with
old BIOS too using QEMU_CFG_E820_TABLE.  If that works, I see no need
for an "enabled" bit either.

Paolo

> an effort and complexity it would bring.

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

* Re: [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface
  2013-11-21  9:37   ` Michael S. Tsirkin
@ 2013-11-25 14:39     ` Igor Mammedov
  2013-12-16 19:50       ` Michael S. Tsirkin
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 14:39 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, marcel.a, armbru, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, hutao, pbonzini, lcapitulino, chegu_vinod, afaerber

On Thu, 21 Nov 2013 11:37:01 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:38:44AM +0100, 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>
> > ---
[...]

> > diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
> > index a4484b8..b0c581e 100644
> > --- a/hw/i386/ssdt-misc.dsl
> > +++ b/hw/i386/ssdt-misc.dsl
> > @@ -116,4 +116,183 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
> >              }
> >          }
> >      }
> > +
> > +    External(MTFY, MethodObj)
> > +
> > +    Scope(\_SB) {
> > +        Device(MHPD) {
> > +            Name(_HID, EISAID("PNP0C08"))
> > +
> > +            ACPI_EXTRACT_NAME_WORD_CONST ssdt_mctrl_port
> > +            Name(MHPP, 0xFFFF)
> > +
> > +            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
> > +            Name(MDNR, 0x12345678)
> > +
> > +            /* Memory hotplug IO registers */
> > +            OperationRegion(HPMR, SystemIO, MHPP, 24)
> > +
> > +            Method(_CRS, 0, Serialized) {
> > +                Name(CRS, ResourceTemplate() {
> > +                    IO(Decode16, 0x00, 0x00, 0x01, 24, IO)
> > +                })
> 
> 
> Declaring name makes us serialize it.
> Can't we use a local variable?
If that works, I'll change it.

But I have a question of my own perhaps to Paolo or Gerd,
Do we really need this _CRS, because if you look at next hunk
_STA should report not present but functioning to avoid windows BSOD.
So there is not guaranties that OSPM would care or even query it
and honor _CRS provided range.


[...]
> > +
> > +            Method(_STA, 0) {
> > +                If (LEqual(MDNR, Zero)) {
> > +                    Return(0x0)
> > +                }
> > +                /* Leave bit 0 cleared to avoid Windows BSOD */
> > +                Return(0xA)
> > +            }
[...]

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

* Re: [Qemu-devel] [PATCH 12/27] dimm: add hotplug callback to DimmBus
  2013-11-25 13:01   ` Paolo Bonzini
@ 2013-11-25 14:40     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 14:40 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

On Mon, 25 Nov 2013 14:01:51 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> > diff --git a/include/hw/mem/dimm.h b/include/hw/mem/dimm.h
> > index abedae2..b655006 100644
> > --- a/include/hw/mem/dimm.h
> > +++ b/include/hw/mem/dimm.h
> > @@ -65,11 +65,15 @@ typedef struct DimmDeviceClass {
> >   * @parent_obj: opaque parent object container
> >   * @base: address from which to start mapping @DimmDevice
> >   * @as: hot-plugabble memory area where @DimmDevice-s are attached
> > + * @hotplug_dev: device that hotplugs realized DimmDevice
> > + * @hotplug: hotplug callback set by the board
> >   */
> >  typedef struct DimmBus {
> >      BusState parent_obj;
> >      hwaddr base;
> >      MemoryRegion as;
> > +    DeviceState *hotplug_dev;
> > +    hotplug_fn hotplug;
> >  } DimmBus;
> >  
> >  /**
> > 
> 
> So the alternatives here would be:
> 
> (1) have DimmDevice call hotplug/hot_unplug in DimmBus; add a
> ACPIHotplugDimmBus subclass that connects to ACPI.
> 
> (2) have DeviceState call hotplug/hot_unplug in BusState; DimmBus does
> nothing with it, and a ACPIHotplugDimmBus subclass implements it.

Thanks,
I'll try to implement it this way.

> Paolo

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-25 14:31                   ` Paolo Bonzini
@ 2013-11-25 14:57                     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 14:57 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, stefanb, hutao, Michael S. Tsirkin, mjt,
	Markus Armbruster, qemu-devel, vasilis.liaskovitis, quintela,
	chegu_vinod, kraxel, aliguori, marcel.a, lcapitulino, stefanha,
	afaerber

On Mon, 25 Nov 2013 15:31:22 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 25/11/2013 15:18, Igor Mammedov ha scritto:
> >> > For example on reset all slots could be disabled by the
> >> > ACPIHotpluggableDimmBus (even coldplugged ones), and scanned + enabled
> >> > by ASL.
> > memory devices are scanned by OSPM during ACPI tables parsing and 
> > guest (can) use present devices right away.
> 
> Yes, what I'm saying is scan them to enable them so that OSPM sees them
> already as online.
> 
> > Currently I don't see necessity for enabling individual memory devices from
> > ASL since it adds one more round trip for QEMU<->guest protocol for no
> > particular benefit. The only use case Michael suggested would be running
> > OLD BIOS (without memory hotplug support) on machine with actively used
> > memory hotplug (if OLD BIOS runs on machine with memory hotplug but there is
> > no hotplugged memory devices, it runs just fine), so case looks like not worth
>      ^^^^^^^^^^
> 
> *Hotpluggable*, not hotplugged.  It would also break just with
> coldplugged memory devices.
> 
> > That would allow later to put present at boot DIMMs into E820 (way before ASL
> > is executed) if that would be necessary and also help to convert initial
> > memory into hotpluggable one as well.
> 
> I am afraid that mixing hot-unplug with E820 could cause some
> unanticipated trouble.  OSes may not expect memory in the E820 ranges to
> disappear.
> 
> But since we're speaking about e820, do guests work if you make the
> hotpluggable memory region reserved in the e820?  That should work with
> old BIOS too using QEMU_CFG_E820_TABLE.  If that works, I see no need
> for an "enabled" bit either.
It's on my to do list to make more code reading/experiments/testing to see if
that is ok with guest. I can't say it right now, that's why E820 changes is
not part of this series.

As for OLD BIOS it should be aware about not continuous memory ranges and
calculate present ram below/above4g via E820, there was Gerd's patch
to introduce new E820 fwcfg from QEMU and I hope to use/extend it for
telling BIOS about present coldplugged DIMMs. But I guess it's not for
OLD BIOS anyway, since it OLD SeaBIOS uses CMOS for getting ram sizes.

> 
> Paolo
> 
> > an effort and complexity it would bring.
> 

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

* Re: [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction
  2013-11-25 12:57   ` Paolo Bonzini
@ 2013-11-25 15:10     ` Igor Mammedov
  2013-11-25 15:16       ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 15:10 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

On Mon, 25 Nov 2013 13:57:17 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> > +static void dimm_initfn(Object *obj)
> > +{
> > +    object_property_add(obj, "memdev", "string", dimm_get_memdev,
> > +                        dimm_set_memdev, NULL, NULL, NULL);
> 
> Perhaps, instead of relying on memory_region_owner, you could have
> separate pointers for the MemoryBackend* and MemoryRegion*.  Then this
> property could be a link<MemoryBackend> type (it looks like a link, and
> quacks like a link).

In initial implementation I had 'backend' property which was exactly
just link<> to backend.

but when adding dimm (CLI/Moinitor), I had to specify full QOM path
to backend which looked like -device dimm,id=foo1,backend=/backend/memdev[foo2]
which was ugly. So I moved to a currently used model by netdev
and replaced it with 'memdev' property.

But since then backend path has changed to /backend/memdev/foo
so I guess it should be possible to use backend=foo for partial
path resolving should yield object without full path.
The only downside would be backend instance name in global name space.

> Paolo
> 
> > +    object_property_add(obj, "size", "int", dimm_get_size,
> > +                        NULL, NULL, NULL, NULL);
> > +}
> > +
> 

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

* Re: [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction
  2013-11-25 15:10     ` Igor Mammedov
@ 2013-11-25 15:16       ` Paolo Bonzini
  0 siblings, 0 replies; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 15:16 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 25/11/2013 16:10, Igor Mammedov ha scritto:
> In initial implementation I had 'backend' property which was exactly
> just link<> to backend.
> 
> but when adding dimm (CLI/Moinitor), I had to specify full QOM path
> to backend which looked like -device dimm,id=foo1,backend=/backend/memdev[foo2]
> which was ugly. So I moved to a currently used model by netdev
> and replaced it with 'memdev' property.
> 
> But since then backend path has changed to /backend/memdev/foo
> so I guess it should be possible to use backend=foo for partial
> path resolving should yield object without full path.

Yes.

> The only downside would be backend instance name in global name space.

Two possibilities here:

(1) accept that -object has a global namespace

(2) in the aforementioned interface that helps command-line processing,
add a method that returns the place where the object should be added in
the QOM object tree.  For memdevs this can return /backend/memdev.

Paolo

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-21 10:15   ` Markus Armbruster
@ 2013-11-25 15:36     ` Igor Mammedov
  2013-11-25 16:04       ` Michael S. Tsirkin
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 15:36 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: peter.maydell, stefanha, mst, hutao, stefanb, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Thu, 21 Nov 2013 11:15:06 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> Igor Mammedov <imammedo@redhat.com> writes:
> 
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  qapi/string-input-visitor.c |   18 ++++++++++++++++++
> >  1 files changed, 18 insertions(+), 0 deletions(-)
> >
> > diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
> > index 8f1bc41..a152f5d 100644
> > --- a/qapi/string-input-visitor.c
> > +++ b/qapi/string-input-visitor.c
> > @@ -97,6 +97,23 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
> >      *obj = val;
> >  }
> >  
> > +static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
> > +                            Error **errp)
> > +{
> > +    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
> > +    int64_t val;
> > +    char *endp;
> > +
> > +    val = strtosz_suffix(siv->string ? siv->string : "", &endp,
> > +                         STRTOSZ_DEFSUFFIX_B);
> > +    if (val < 0 || *endp != '\0') {
> > +        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name,
> > +                  "a size value representible as a non-negative int64");
> > +        return;
> > +    }
> > +    *obj = val;
> > +}
> > +
> >  static void parse_start_optional(Visitor *v, bool *present,
> >                                   const char *name, Error **errp)
> >  {
> > @@ -131,6 +148,7 @@ StringInputVisitor *string_input_visitor_new(const char *str)
> >      v->visitor.type_bool = parse_type_bool;
> >      v->visitor.type_str = parse_type_str;
> >      v->visitor.type_number = parse_type_number;
> > +    v->visitor.type_size = parse_type_size;
> >      v->visitor.start_optional = parse_start_optional;
> >  
> >      v->string = str;
> 
> Does this put syntax like "value": "128M" in QMP?  If yes, NAK.  QMP
> does not want fancy syntax for numbers, only plain numbers.
> 

I thought QMP uses its own qmp_visitor, so it shouldn't affect general QMP,
if I'm not mistaken.

but it allows to use unified memdev_add parser for all interfaces (CLI/HMP/QMP) and
it's more user friendly to have on CLI/HMP size=1G vs long integer to express it.

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

* Re: [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices
  2013-11-25 12:49   ` Paolo Bonzini
  2013-11-25 13:11     ` Paolo Bonzini
@ 2013-11-25 15:57     ` Igor Mammedov
  1 sibling, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 15:57 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

On Mon, 25 Nov 2013 13:49:29 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> > +typedef enum {
> > +    HOTPLUG_DISABLED,
> > +    HOTPLUG_ENABLED,
> > +    COLDPLUG_ENABLED,
> > +} HotplugState;
> > +
> > +typedef int (*hotplug_fn)(DeviceState *hotplug_dev, DeviceState *dev,
> > +                          HotplugState state);
> 
> I don't think this is a particularly useful interface, because it
> reinvents a lot of what already exists in qdev/qbus.
> 
> The cold/hotplug_enabled differentiation is not particularly useful
> when dev->hotplugged already exists, and the interface leaves one to
> wonder why COLDPLUG_ENABLED doesn't have a matching COLDPLUG_DISABLED
> (until one looks at the code).
Yes, it's a bit weird but I've opted in favor of unifying currently
used by piix4/ich9_acpi approach so it could be reused vs rewriting
yet another part of QEMU and Michael also uses this in his new PCIEHP
patches.
Maybe rewriting it as you suggest should be made as a separate series.


But I have unrelated to this question, regarding patch
 "[PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core"

in old pm_update_sci() we have:
    sci_level = (((pmsts & s->ar.pm1.evt.en) &
                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
                   ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) &
          (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS)) != 0);

where we mask out currently not supported GPE status bits,
can we just drop (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS) mask
altogether and rely on gpe.sts & gpe.en only for rising SCI?
Why there were need to mask SCI at all?

> Take for example this:
> 
> static void enable_device(PIIX4PMState *s, int slot)
> {
>     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
>     s->pci0_slot_device_present |= (1U << slot);
> }
> 
> static void disable_device(PIIX4PMState *s, int slot)
> {
>     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
>     s->pci0_status.down |= (1U << slot);
> }
> 
> static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
>                                 PCIHotplugState state)
> {
>     int slot = PCI_SLOT(dev->devfn);
>     PIIX4PMState *s = PIIX4_PM(qdev);
> 
>     /* Don't send event when device is enabled during qemu machine creation:
>      * it is present on boot, no hotplug event is necessary. We do send an
>      * event when the device is disabled later. */
>     if (state == PCI_COLDPLUG_ENABLED) {
>         s->pci0_slot_device_present |= (1U << slot);
>         return 0;
>     }
> 
>     if (state == PCI_HOTPLUG_ENABLED) {
>         enable_device(s, slot);
>     } else {
>         disable_device(s, slot);
>     }
> 
>     pm_update_sci(s);
> 
>     return 0;
> }
> 
> 
> In my opinion, it is much clearer this way---separating enable/disabled
> rather than hotplug/coldplug:
> 
> static void piix4_pci_send_event(PIIX4PMState *s)
> {
>     s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
>     pm_update_sci(s);
> }
> 
> static int piix4_device_hotplug(DeviceState *qdev, DeviceState *dev)
> {
>     PCIDevice *pci = PCI_DEVICE(dev);
>     int slot = PCI_SLOT(pci->devfn);
>     PIIX4PMState *s = PIIX4_PM(qdev);
> 
>     s->pci0_slot_device_present |= (1U << slot);
>     /* Don't send event when device is enabled during qemu machine creation:
>      * it is present on boot, no hotplug event is necessary. We do send an
>      * event when the device is disabled later. */
>     if (dev->hotplugged) {
>         piix4_pci_send_event(s);
>     }
>     return 0;
> }
> 
> static int piix4_device_hot_unplug(DeviceState *qdev, DeviceState *dev)
> {
>     PCIDevice *pci = PCI_DEVICE(dev);
>     int slot = PCI_SLOT(pci->devfn);
>     PIIX4PMState *s = PIIX4_PM(qdev);
> 
>     s->pci0_status.down |= (1U << slot);
>     piix4_pci_send_event(s);
>     return 0;
> }
> 
> This is of course just an example, I'm not asking you to reimplement hotplug
> for all buses in QEMU.  However, my point is that this shouldn't be a "core"
> enum and interface.  If you want to have a core interface in BusClass, I'd
> rather add ->hotplug and ->hot_unplug to BusClass, similar to how the SCSI
> bus does it (note: I only maintain it, I didn't write that code) and so
> that BusClass's methods match ->init/->exit on the device side.
> 
> Paolo

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-25 12:54   ` Paolo Bonzini
@ 2013-11-25 16:01     ` Igor Mammedov
  2013-11-25 16:09       ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-25 16:01 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

On Mon, 25 Nov 2013 13:54:10 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> > +
> > +    /* verify properties correctnes and initialize backend */
> > +    bc = MEMORY_BACKEND_GET_CLASS(obj);
> > +    if (bc->get_memory) {
> > +        HostMemoryBackend *backend = MEMORY_BACKEND(obj);
> > +        if (!bc->get_memory(backend, &local_err)) {
> > +            goto out;
> > +        }
> > +    }
> 
> So this is why you need a new command-line option.
> 
> I think we need a generic mechanism for post-initialization of whatever
> is given on the command line.  Perhaps you can do that with an
> interface, and get rid of -memdev and memdev_add altogether?
> 
> MemoryBackend's implementation of the interface's sole method would call
> get_memory, of course.

What I would use instead of memdev_add in CLI/HMP/QMP?
Could you explain it a bit more, please?

> Paolo
> 
> > +    /* make backend available to the world via QOM tree */
> > +    object_property_add_child(container_get(qemu_get_backend(), "/memdev"),
> > +                              qemu_opts_id(opts), obj, &local_err);
> 

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-25 15:36     ` Igor Mammedov
@ 2013-11-25 16:04       ` Michael S. Tsirkin
  2013-11-25 16:32         ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-11-25 16:04 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, stefanb, hutao, quintela, mjt,
	Markus Armbruster, qemu-devel, vasilis.liaskovitis, chegu_vinod,
	kraxel, aliguori, pbonzini, marcel.a, lcapitulino, stefanha,
	afaerber

On Mon, Nov 25, 2013 at 04:36:42PM +0100, Igor Mammedov wrote:
> On Thu, 21 Nov 2013 11:15:06 +0100
> Markus Armbruster <armbru@redhat.com> wrote:
> 
> > Igor Mammedov <imammedo@redhat.com> writes:
> > 
> > > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > > ---
> > >  qapi/string-input-visitor.c |   18 ++++++++++++++++++
> > >  1 files changed, 18 insertions(+), 0 deletions(-)
> > >
> > > diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
> > > index 8f1bc41..a152f5d 100644
> > > --- a/qapi/string-input-visitor.c
> > > +++ b/qapi/string-input-visitor.c
> > > @@ -97,6 +97,23 @@ static void parse_type_number(Visitor *v, double *obj, const char *name,
> > >      *obj = val;
> > >  }
> > >  
> > > +static void parse_type_size(Visitor *v, uint64_t *obj, const char *name,
> > > +                            Error **errp)
> > > +{
> > > +    StringInputVisitor *siv = DO_UPCAST(StringInputVisitor, visitor, v);
> > > +    int64_t val;
> > > +    char *endp;
> > > +
> > > +    val = strtosz_suffix(siv->string ? siv->string : "", &endp,
> > > +                         STRTOSZ_DEFSUFFIX_B);
> > > +    if (val < 0 || *endp != '\0') {
> > > +        error_set(errp, QERR_INVALID_PARAMETER_VALUE, name,
> > > +                  "a size value representible as a non-negative int64");
> > > +        return;
> > > +    }
> > > +    *obj = val;
> > > +}
> > > +
> > >  static void parse_start_optional(Visitor *v, bool *present,
> > >                                   const char *name, Error **errp)
> > >  {
> > > @@ -131,6 +148,7 @@ StringInputVisitor *string_input_visitor_new(const char *str)
> > >      v->visitor.type_bool = parse_type_bool;
> > >      v->visitor.type_str = parse_type_str;
> > >      v->visitor.type_number = parse_type_number;
> > > +    v->visitor.type_size = parse_type_size;
> > >      v->visitor.start_optional = parse_start_optional;
> > >  
> > >      v->string = str;
> > 
> > Does this put syntax like "value": "128M" in QMP?  If yes, NAK.  QMP
> > does not want fancy syntax for numbers, only plain numbers.
> > 
> 
> I thought QMP uses its own qmp_visitor, so it shouldn't affect general QMP,
> if I'm not mistaken.
> 
> but it allows to use unified memdev_add parser for all interfaces (CLI/HMP/QMP) and
> it's more user friendly to have on CLI/HMP size=1G vs long integer to express it.

Yes please. Firing up a calculator to figure out how much is 1G is not
friendly, neither is firing it up to figure out what did management do
with QMP. It should be a text based interface not a binary one.


-- 
MST

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-25 16:01     ` Igor Mammedov
@ 2013-11-25 16:09       ` Paolo Bonzini
  2013-11-27 14:37         ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 16:09 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 25/11/2013 17:01, Igor Mammedov ha scritto:
>> > So this is why you need a new command-line option.
>> > 
>> > I think we need a generic mechanism for post-initialization of whatever
>> > is given on the command line.  Perhaps you can do that with an
>> > interface, and get rid of -memdev and memdev_add altogether?
>> > 
>> > MemoryBackend's implementation of the interface's sole method would call
>> > get_memory, of course.
> 
> What I would use instead of memdev_add in CLI/HMP/QMP?

We could add a new object_add command.

> Could you explain it a bit more, please?

The interface would look like

struct QOMCommandLineIface {
    void complete(Object *object, Error **errp);
    Object *get_base_path(void);
}

MemoryBackend could implement it like this:

void memory_backend_complete(Object *object, Error **errp)
{
    MemoryBackend *backend = MEMORY_BACKEND(object);
    MemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(obj);
    if (bc->get_memory) {
        bc->get_memory(backend, errp);
    }
}

Object *memory_backend_get_base_path(void);
{
    return container_get(qdev_get_backend(), "/memdev"),
}

A default implementation can be added to RNGBackend and TPMBackend.
vl.c can use the interface like this in object_create:

    obj = object_new(type);
    QOMCommandLineIface *cmdline_iface;

    if (IS_QOM_COMMAND_LINE(obj)) {
        object_unref(obj);
        error...
        return -1;
    }

    if (qemu_opt_foreach(opts, object_set_property, obj, 1) < 0) {
        object_unref(obj);
        return -1;
    }

    cmdline_iface = QOM_COMMAND_LINE_GET_IFACE(obj);
    cmdline_iface->complete(obj, &local_err);
    if (local_err)) {
        error_propagate(...)
        object_unref(obj);
        return -1;
    }

    object_property_add_child(cmdline_iface->get_base_path(),
                              id, obj, NULL);

Then you can just use -object instead of -memdev.

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-25 16:04       ` Michael S. Tsirkin
@ 2013-11-25 16:32         ` Paolo Bonzini
  2013-11-25 16:43           ` Eric Blake
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 16:32 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, mdroth, stefanb, hutao, quintela, mjt,
	Markus Armbruster, qemu-devel, vasilis.liaskovitis, chegu_vinod,
	kraxel, aliguori, Igor Mammedov, marcel.a, lcapitulino, stefanha,
	afaerber

Il 25/11/2013 17:04, Michael S. Tsirkin ha scritto:
>>> > > 
>>> > > Does this put syntax like "value": "128M" in QMP?  If yes, NAK.  QMP
>>> > > does not want fancy syntax for numbers, only plain numbers.
>>> > > 
>> > 
>> > I thought QMP uses its own qmp_visitor, so it shouldn't affect general QMP,
>> > if I'm not mistaken.
>> > 
>> > but it allows to use unified memdev_add parser for all interfaces (CLI/HMP/QMP) and
>> > it's more user friendly to have on CLI/HMP size=1G vs long integer to express it.
> Yes please. Firing up a calculator to figure out how much is 1G is not
> friendly, neither is firing it up to figure out what did management do
> with QMP. It should be a text based interface not a binary one.

Wait. :)

Command-line and *HMP* object_add (and if we add them, qom_get/qom_set)
should be a text based interface.  Right now it could be implemented
using object_property_parse/print which use the
string-input/output-visitor.  This is the visitor that this patch touches.

QMP object_add (like qom_get/qom-set) should not be at all a text based
interface.  As Igor says, it should use the QDict-based visitor.

This is unfortunately a counter-example to the rule that HMP commands
should always be implemented in terms of their QMP counterparts.  I do
not believe this is really a problem.  It can be fixed later; for now, I
think "perfect is the enemy of good" applies.

Paolo

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-25 16:32         ` Paolo Bonzini
@ 2013-11-25 16:43           ` Eric Blake
  2013-11-25 17:01             ` Paolo Bonzini
                               ` (2 more replies)
  0 siblings, 3 replies; 143+ messages in thread
From: Eric Blake @ 2013-11-25 16:43 UTC (permalink / raw)
  To: Paolo Bonzini, Michael S. Tsirkin
  Cc: peter.maydell, stefanha, quintela, qemu-devel, hutao, stefanb,
	mjt, mdroth, Markus Armbruster, vasilis.liaskovitis, kraxel,
	aliguori, Igor Mammedov, marcel.a, lcapitulino, chegu_vinod,
	afaerber

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

On 11/25/2013 09:32 AM, Paolo Bonzini wrote:

>> Yes please. Firing up a calculator to figure out how much is 1G is not
>> friendly, neither is firing it up to figure out what did management do
>> with QMP. It should be a text based interface not a binary one.

Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
prefers passing a value in 'bytes', rather than risking confusion on
whether a value in G was rounded (up, down? to nearest power of 10 or
power of 2?).  Unfortunately, yes, that means you need a calculator when
parsing QMP logs to see whether the 1073741824 passed by libvirt is the
1G you had in mind.

HMP, qtest, and any other decent shell around raw QMP is more than
welcome to provide human-usable wrappers that takes "1G" as a string and
turns it into the raw int used by the underlying QMP.  In fact, I
encourage it.

> This is unfortunately a counter-example to the rule that HMP commands
> should always be implemented in terms of their QMP counterparts.  I do
> not believe this is really a problem.  It can be fixed later; for now, I
> think "perfect is the enemy of good" applies.

Hey - I just realized that now that we have anonymous unions, we could
theoretically extend QMP to allow a union between 'int' and 'string' -
if an 'int' is passed, it is in bytes; if a 'string' is passed, then
parse it the way HMP would (so the string "1G" would be equivalent to
the raw int 1073741824).  But I don't know if it will help you (libvirt
will still prefer to use raw ints in any QMP log you read off of libvirt
interactions).

-- 
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: 621 bytes --]

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-25 10:41           ` Igor Mammedov
@ 2013-11-25 17:00             ` Andreas Färber
  2013-11-26 20:26               ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Andreas Färber @ 2013-11-25 17:00 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, hutao, mst, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, Li Guang

Am 25.11.2013 11:41, schrieb Igor Mammedov:
> On Thu, 21 Nov 2013 17:09:27 +0100
> Andreas Färber <afaerber@suse.de> wrote:
> 
>> Am 21.11.2013 15:34, schrieb Igor Mammedov:
>>> On Thu, 21 Nov 2013 15:13:12 +0100
>>> Andreas Färber <afaerber@suse.de> wrote:
>>>> Am 21.11.2013 06:48, schrieb Li Guang:
>>>>> Why not give the memory that not be hot-added a chance to be placed on
>>>>> one memory slot?
>>>>
>>>> Seconded, I believe I requested that on the previous version already.
>>> Because current initial memory allocation is a mess and this already
>>> large series would become even more large and intrusive, so far series
>>> it relatively not intrusive and self contained.
>>>
>>> I believe re-factoring of initial memory to use Dimm devices should be
>>> done later on top of infrastructure this series provides.
>>
>> My problem with that is that that would be a semantically incompatible
>> modeling change. With your series we might have /machine/dimm.0/child[0]
>> be the first hot-plugged memory and once such a refactoring is done,
>> child[0] silently becomes -m and child[1] is the hot-added one.
> 
> I think there won't be silent change in child[0], since most likely
> initial RAM would require additional DimmBus (maybe even 2)
> for it's devices.
> 
> But anyway, why would this be an issue?
> 
>> So if we know that we want/need to change the infrastructure, why not
>> add a single patch (?) to allocate one additional object on the bus now?
>> Unless we actually write the code, we won't know whether there are some
>> incorrect hot-plug assumptions in the dimm code.
> It wouldn't be a single simple patch for PC, I'm afraid.
> I don't see point in adding dummy DIMM device for initial memory and then
> do re-aliasing of its memory region in GPA as it's done in current code.
> 
> As I see it (taking in account Marcolo's/Paolo's alignment path), current
> single MR for initial RAM should be split in 1-4 separate MRs depending on
> initial RAM amount and alignment requirements between HPA/GPA addresses.
> 
> That would probably introduce additional, non hotlugable DimmBus-es (1-2)
> for low and high memory, which would be incompatible with old machine types
> devices and GPA layout, so why care about what
> /machine/dimm.0/child[0] would be in new machine version?

I feel we're talking about two very different things here.

What I am talking about is the user experience. A mainboard has 4 or
maybe 8 DIMM slots where the user can plug in greenish memory bars.
That's what I would like to see implemented in QEMU because that's
understandable without reading code and ACPI specs.

What you seem to be talking about by contrast is your DimmBus
implementation and its limitations/assumptions. You can easily use
dev->hotplugged to distinguish between initial and hot-plugged devices
as done elsewhere, including PCI and ICC bus, no?

In short, what I am fighting against is having a machine with 4 slots:

slot[0] = 42
slot[1] = 0
slot[2] = 0
slot[3] = 0

meaning 42 + implicit -m now, later getting fixed to explicit:

slot[0] = -m
slot[1] = 42
slot[2] = 0
slot[3] = 0

Whether -m maps to one or more slots can easily be scaled in the
example, I had previously asked whether there were upper limits per slot
but believe that got denied from an ACPI perspective; my point is the
slot offset and the inconsistent sum exposed via QOM/QMP.

On your ICC bus we had the initial -smp CPUs alongside hot-plugged CPUs
right from the start.

I can't think of a reason why there would be multiple DimmBuses in a
single machine from a user's point of view.
Different implementations for different memory controllers / machines
make perfect sense of course. But even from a developer's point of view
multiple buses don't make that much sense either if we keep
http://wiki.qemu.org/Features/QOM#TODO in mind - devices exposing
multiple buses need to be split up and in the end we just have named
link<> properties on some container object as sketched in the example
above - question then becomes should we have multiple containers, and I
think the answer for a PC will be no.

Embedded systems with a mix of small on-chip SRAM and on-board SDRAM may
be a different beast to model, but well beyond the scope of this series
anyway, which IIUC doesn't expose any DimmBus outside of the two PCs.

Also, once memory has been hot-plugged and the machine gets rebooted,
shouldn't that be the same to BIOS/ACPI as if the memory was cold-plugged?

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-25 16:43           ` Eric Blake
@ 2013-11-25 17:01             ` Paolo Bonzini
  2013-11-27 14:15             ` Markus Armbruster
  2013-12-19 14:40             ` Michael S. Tsirkin
  2 siblings, 0 replies; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-25 17:01 UTC (permalink / raw)
  To: Eric Blake
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, hutao, quintela,
	mjt, mdroth, Markus Armbruster, vasilis.liaskovitis,
	Michael S. Tsirkin, kraxel, aliguori, Igor Mammedov, marcel.a,
	lcapitulino, chegu_vinod, afaerber

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Il 25/11/2013 17:43, Eric Blake ha scritto:
>>> This is unfortunately a counter-example to the rule that HMP 
>>> commands should always be implemented in terms of their QMP 
>>> counterparts.  I do not believe this is really a problem.  It 
>>> can be fixed later; for now, I think "perfect is the enemy of 
>>> good" applies.
> Hey - I just realized that now that we have anonymous unions, we 
> could theoretically extend QMP to allow a union between 'int' and 
> 'string' - if an 'int' is passed, it is in bytes; if a 'string' is 
> passed, then parse it the way HMP would (so the string "1G" would 
> be equivalent to the raw int 1073741824).  But I don't know if it 
> will help you (libvirt will still prefer to use raw ints in any
> QMP log you read off of libvirt interactions).

No, I think this is not the right solution.  The parsing should not be
handled at the schema level, because there is really no fixed schema
(like device_add for example).

Right now, we have (almost) always:

    HMP                             QMP
     |                               |
     |                               |
  hmp_cont (manually written)    qmp_marshal_cont (generated)
      \                             /
       \                           /
        qmp_cont (manually written)

where hmp_cont and qmp_marshal_cont both take QDicts, while qmp_cont
takes a list of parameters.

object_add cannot be described by a schema, so the implementation
should take a Visitor instead, and the would have to be written by
hand too:

    HMP                                 QMP
     |                                   |
     |                                   |
  hmp_object_add (manually written)    qmp_object_add (manually written)
          \                             /
           \                           /
        qapi_object_add(const char *type, const char *id, Visitor *v,
                        Error **errp)

However, we don't have the infrastructure to do it; hmp_object_add and
qmp_object_add cannot yet be simple wrappers around a common function.
 We can fix that in due time.

Paolo
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJSk4KFAAoJEBvWZb6bTYbyyJQP/AlDytO9om7XNu/+/7XGNVYj
HxiQSpOo3OgOeyLqJLSV2iBxP1F2YPG3IQ1MQE6aWbPdraMtBt0bnpEQDW5GinX6
f91cnpZi3Yf+3v2/rzmtEs1+3ACOjrn1rVBQiGrbbPiFr7Oa49RD5gWo06M2vZin
mfNt3hfUHrmS096IzxGF/sjFstDacnigJZYHHHImqWdHv7BS1I1fK4JptU8ESTEV
lLxvphcPKUGoTkLuDSy/6+TwLpr87aLjXFH7GrDUPdmGC/IcJYIDLMP3kjX3KdaA
sizqN/pATsxDpOMi/cxnD5onZsFi0J1RiIKxXRbdSLMD0udJUuRrcy19AnUvxhAI
gcJy32vj1QWff58S21O7ZbMPCHGClbed3j350wsciumObXneQbcd9iCU//L+Kcfh
DqAJmEqSn/kC6vny2JIKL2ZPzETxX6BtnRYIK1lQpYHhy/WC8x9pEs4wltWlVyEQ
sY6qq1brNKzCfBpe2WQiHHKHkZ3sw59Pt5bT0ToIpPODIqAyCoeFWh2yXdIEIKmp
U7VfBsjk7D6mSqCONgz74Qkjl8olNjlX4vCCXvjTiXghghF84dohNJG7klie75ad
arAVmRUTNeR39AY7BCnEKBGFt/OBQal++2ZN/r4AJk7xODs35qF6FMKioAHstt0Z
buoUSQmj9X7iuQV3Jriv
=fuqh
-----END PGP SIGNATURE-----

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-25 11:13                 ` Igor Mammedov
@ 2013-11-26  0:29                   ` Li Guang
  2013-11-26 22:36                     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Li Guang @ 2013-11-26  0:29 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, Michael S. Tsirkin, Hu Tao, stefanb,
	mjt, qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber,
	armbru

Igor Mammedov wrote:
> On Fri, 22 Nov 2013 08:57:40 +0800
> Li Guang<lig.fnst@cn.fujitsu.com>  wrote:
>
>    
>> Michael S. Tsirkin wrote:
>>      
>>> On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
>>>
>>>        
>>>> Michael S. Tsirkin wrote:
>>>>
>>>>          
>>>>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
>>>>>
>>>>>            
>>>>>> Hu Tao wrote:
>>>>>>
>>>>>>              
>>>>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
>>>>>>>
>>>>>>>                
>>>>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
>>>>>>>>
>>>>>>>>                  
>>>>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
>>>>>>>>> after it has been handled when it clears GPE event.
>>>>>>>>>
>>>>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
>>>>>>>>>
>>>>>>>>>                    
>>>>>>>> The storm is only on memory hotplug right?
>>>>>>>>
>>>>>>>>                  
>>>>>>> IIRC, it happens on cpu hotplug, too.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>> :-), that made remember EC implementation,
>>>>>> with EC, SCI will be safer, I think.
>>>>>>
>>>>>>              
>>>>> Hmm you are saying let's use EC for memory hotplug?
>>>>>
>>>>>
>>>>>
>>>>>            
>>>> It can be a bridge between guest and QEMU,
>>>> with it, we may don't have to bother ASL writing
>>>> and south-bridge hardware related work(or very
>>>> little) if we implement EC correctly.
>>>>
>>>>
>>>>
>>>>          
>>> I'd like to see that. Can you write a document (just text)
>>> for an imaginary EC support for memory hotplug?
>>>
>>>
>>>
>>>
>>>        
>> Hmm..., with EC,
>>
>> For memory hotplug, at least,
>> ASL at [PATCH 27/27] can be replaced
>> by a simple Method(_Qx) under EC device,
>> IO base operations at [PATCH 15/27]
>> are dispensable,  we can relay data
>> by standard operations of EC space
>>
>> and also for SCI, all device changes want to
>> notify guest OS can share same SCI with EC,
>> and the operations are specified at ACPI SPEC.
>>
>> likewise, for CPU hotplug, pvpanic,
>> and even debugcon.
>>
>> and, for odd devices, like pvpanic, guest OS may complain
>> about it, and we may also have to bother on maintaining state of
>> it at QEMU, and writing a driver for guest OS,
>> with EC, functions of device like pvpanic may be implemented silently,
>> and EC is ACPI standard device, each ACPI compatible OS will
>> have a driver for it natively.
>>
>>      
>  From what I remember about them EC was adding essentially another
> side-channel but more sophisticated for OSPM communication with
> platform but for not benefit so far, since what we need from ACPI
> for hotplug could be implemented by using GPE handlers without
> adding any EC.
>
> I think there was EC patches on list (perhaps yours) but I couldn't
> find them. Could you point me to them if they are demonstrating
> how hotplug could be done with EC approach.
>
>
>
>    
you can find my previous raw patch-set here,
http://lists.gnu.org/archive/html/qemu-devel/2013-05/msg02845.html

Thanks!
Li Guang

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-21 10:12   ` Markus Armbruster
@ 2013-11-26 13:17     ` Igor Mammedov
  2013-11-26 14:49       ` Markus Armbruster
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-26 13:17 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: kwolf, peter.maydell, aliguori, stefanb, hutao, mst, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Thu, 21 Nov 2013 11:12:43 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> Igor Mammedov <imammedo@redhat.com> writes:
> 
> > Along with conversion extend -m option to support following parameters:
> 
> Please split this into two patches: first conversion to QemuOpts, then
> extension.
> 
> >   "mem" - startup memory amount
> >   "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 usable.
> >
> > v2:
> >   make sure maxmem is not less than ram size
> >
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> > ---
> >  qemu-options.hx |    9 +++++-
> >  vl.c            |   73 ++++++++++++++++++++++++++++++++++++++++++++++---------
> >  2 files changed, 68 insertions(+), 14 deletions(-)
> >
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 8b94264..fe4559b 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -210,8 +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 [mem=]megs[,slots=n,maxmem=size]\n"
> > +    "                set virtual RAM size to megs MB [default="
> > +    stringify(DEFAULT_RAM_SIZE) "]\n"
> > +    "                mem=start-up memory amount\n"
> > +    "                slots=maximum number of hotplug slots\n"
> > +    "                maxmem=maximum total amount of memory\n",
> > +    QEMU_ARCH_ALL)
> 
> Help text is confusing, because it discusses megs twice.  Fits right in,
> as output of -help is generally confusing (to put it politely).
> 
> What about something like this:
> 
> -m [mem=]megs[,slots=n,maxmem=size]
>                 configure guest RAM
>                 mem: initial amount of guest memory (default: XXX)
>                 slots: number of hotplug slots (default: none)
>                 maxmem: maximum amount of guest memory (default: mem)
Sure, I'll fix it.

> >  STEXI
> >  @item -m @var{megs}
> >  @findex -m
> > diff --git a/vl.c b/vl.c
> > index f28674f..5974f0f 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -529,6 +529,28 @@ static QemuOptsList qemu_msg_opts = {
> >      },
> >  };
> >  
> > +static QemuOptsList qemu_mem_opts = {
> > +    .name = "memory-opts",
> > +    .implied_opt_name = "mem",
> > +    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
> > +    .merge_lists = true,
> 
> Yes, because multiple -m need to accumulate.
> 
> > +    .desc = {
> > +        {
> > +            .name = "mem",
> > +            .type = QEMU_OPT_SIZE,
> > +        },
> > +        {
> > +            .name = "slots",
> > +            .type = QEMU_OPT_NUMBER,
> > +        },
> > +        {
> > +            .name = "maxmem",
> > +            .type = QEMU_OPT_SIZE,
> > +        },
> > +        { /* end of list */ }
> > +    },
> > +};
> > +
> >  /**
> >   * Get machine options
> >   *
> > @@ -2816,6 +2838,14 @@ static int object_create(QemuOpts *opts, void *opaque)
> >      return 0;
> >  }
> >  
> > +static void qemu_init_default_mem_opts(uint64_t size)
> > +{
> > +    QemuOpts *opts = qemu_opts_create_nofail(&qemu_mem_opts);
> > +    qemu_opt_set_number(opts, "mem", size);
> > +    qemu_opt_set_number(opts, "maxmem", size);
> > +    qemu_opt_set_number(opts, "slots", 0);
> > +}
> > +
> 
> We usually don't put defaults in QemuOpts.  Instead, the code querying
> QemuOpts detects and handles absence of the parameter.  Can be as simple
> as qemu_opt_get_size(opts, "mem", DEFAULT_RAM_SIZE * 1024 * 1024).
It allows to make number of uses a bit simpler:

for example v6:
    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
    if (!opts) { /* no -m x,... was passed to cmd line so no mem hotplug */
        return;
    }
    mem_st->dev_count = qemu_opt_get_number(opts, "slots", 0);

becomes"
    QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
    state->dev_count = qemu_opt_get_number(opts, "slots", 0);
    
and eliminates need to pepper code with DEFAULT_RAM_SIZE * 1024 * 1024 or
like constants wherever qemu_opt_get_..() is called, that was main reason
to set defaults. i.e. set defaults only once instead of spreading them in
every place qemu_opt_get_..() is called.

> 
> See also below.
> 
> >  int main(int argc, char **argv, char **envp)
> >  {
> >      int i;
> > @@ -2887,6 +2917,7 @@ int main(int argc, char **argv, char **envp)
> >      qemu_add_opts(&qemu_tpmdev_opts);
> >      qemu_add_opts(&qemu_realtime_opts);
> >      qemu_add_opts(&qemu_msg_opts);
> > +    qemu_add_opts(&qemu_mem_opts);
> >  
> >      runstate_init();
> >  
> > @@ -2901,7 +2932,8 @@ int main(int argc, char **argv, char **envp)
> >      module_call_init(MODULE_INIT_MACHINE);
> >      machine = find_default_machine();
> >      cpu_model = NULL;
> > -    ram_size = 0;
> > +    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
> > +    qemu_init_default_mem_opts(ram_size);
> >      snapshot = 0;
> >      cyls = heads = secs = 0;
> >      translation = BIOS_ATA_TRANSLATION_AUTO;
> > @@ -3178,21 +3210,43 @@ 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 *end;
> > +                char *s;
> >  
> > -                value = strtosz(optarg, &end);
> > -                if (value < 0 || *end) {
> > -                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
> > +                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
> > +                                       optarg, 1);
> > +                if (!opts) {
> >                      exit(1);
> >                  }
> > -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
> > +
> > +                /* fixup legacy sugffix-less format */
> 
> /* fix up legacy suffix-less format */
> 
> The problem here is that OPT_SIZE treats values without a size suffix as
> bytes, but we need to default to MiB for backward compatibility.
> 
> > +                end = qemu_opt_get(opts, "mem");
> > +                if (g_ascii_isdigit(end[strlen(end) - 1])) {
> > +                    s = g_strconcat(end, "M", NULL);
> > +                    qemu_opt_set(opts, "mem", s);
> > +                    g_free(s);
> > +                }
> 
> Ugly.
> 
> Why is the variable called 'end'?
would be 'suffix' better?

> 
> qemu_opt_set() appends to the list of options.  The un-fixed-up option
> remains in the list.  qemu_opt_unset() could fix that, but it asserts
> opts_accepts_any() for unclear reasons.  git-blame points to Kevin.
it would be cleaner to unset it but it works event without unsetting it,
since qemu_opt_set...() adds to tail and qemu_opt_get...() finds options
from tail to head.

Nevertheless, Kevin do you recall reasons for assert in 0dd6c526:

int qemu_opt_unset(QemuOpts *opts, const char *name)
...
    assert(opts_accepts_any(opts));

would it be ok if I remove it?

> 
> Have you considered qemu_opt_set_number()?
it was code left from v6 when I didn't know about it. Sorry, I'll
use it instead.

> 
> If this "need a default suffix" pattern exists elsewhere, we should
> consider extending QemuOptDesc to cover it.
I haven't seen/don't recall need for it anywhere else, but it would be
cleanest solution. But it would introduce temptation for users
to shrug off suffixes which is wrong in my opinion. -m 1024 is confusing
unless you know that it's in Mb.

it would be better not to introduce mechanism, that would allow to do such
thing in favor of explicit suffixes.

> 
> > +
> > +                sz = QEMU_ALIGN_UP(qemu_opt_get_size(opts, "mem", ram_size),
> > +                                   8192);
> > +                /* compatibility behaviour for case "-m 0" */
> > +                if (sz == 0) {
> > +                    sz = DEFAULT_RAM_SIZE * 1024 * 1024;
> > +                }
> > +
> 
> Yes, this is needed.  Our command line is bonkers.
> 
> >                  ram_size = sz;
> >                  if (ram_size != sz) {
> >                      fprintf(stderr, "qemu: ram size too large\n");
> >                      exit(1);
> >                  }
> > +                /* store aligned value for future use */
> > +                qemu_opt_set_number(opts, "mem", ram_size);
> 
> Here, you use qemu_opt_set_number().
> 
> Again, this appends to the list, and leaves the non-aligned value in.
it's not an issue since the last appended opt is used in qemu_opt_get_size().

> 
> > +
> > +                sz = qemu_opt_get_size(opts, "maxmem", ram_size);
> > +                if (sz < ram_size) {
> > +                    qemu_opt_set_number(opts, "maxmem", ram_size);
> > +                }
> >                  break;
> >              }
> 
> Looks like you want to fix up something like "-m 1024", so that maxmem
> stays equal to mem.  I'm afraid you also "fix" user errors like "-m
> mem=1024M,maxmem=512M".
Perhaps it would be better to bail out with error here.

> 
> If you refrain from putting defaults into opts, you can distinguish the
> cases "user didn't specify maxmem, so assume mem", and "user specified
> maxmem, so check it's >= mem".
So foar, there is no point in distinguishing above cases,
since maxmem <= mem is invalid value and hotplug should be disabled.
So setting default maxmem to mem or anything less effectively disables hotplug.

> 
> >  #ifdef CONFIG_TPM
> > @@ -4029,11 +4083,6 @@ int main(int argc, char **argv, char **envp)
> >          exit(1);
> >      }
> >  
> > -    /* init the memory */
> > -    if (ram_size == 0) {
> > -        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
> > -    }
> > -
> >      if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
> >          != 0) {
> >          exit(0);

Thanks for review!

-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-26 13:17     ` Igor Mammedov
@ 2013-11-26 14:49       ` Markus Armbruster
  2013-11-26 16:55         ` Igor Mammedov
  2013-11-27  0:27         ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Igor Mammedov
  0 siblings, 2 replies; 143+ messages in thread
From: Markus Armbruster @ 2013-11-26 14:49 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: kwolf, peter.maydell, stefanha, mst, hutao, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

Igor Mammedov <imammedo@redhat.com> writes:

> On Thu, 21 Nov 2013 11:12:43 +0100
> Markus Armbruster <armbru@redhat.com> wrote:
>
>> Igor Mammedov <imammedo@redhat.com> writes:
>> 
>> > Along with conversion extend -m option to support following parameters:
>> 
>> Please split this into two patches: first conversion to QemuOpts, then
>> extension.
>> 
>> >   "mem" - startup memory amount
>> >   "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 usable.
>> >
>> > v2:
>> >   make sure maxmem is not less than ram size
>> >
>> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
>> > ---
>> >  qemu-options.hx |    9 +++++-
>> >  vl.c            |   73 ++++++++++++++++++++++++++++++++++++++++++++++---------
>> >  2 files changed, 68 insertions(+), 14 deletions(-)
>> >
>> > diff --git a/qemu-options.hx b/qemu-options.hx
>> > index 8b94264..fe4559b 100644
>> > --- a/qemu-options.hx
>> > +++ b/qemu-options.hx
>> > @@ -210,8 +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 [mem=]megs[,slots=n,maxmem=size]\n"
>> > +    "                set virtual RAM size to megs MB [default="
>> > +    stringify(DEFAULT_RAM_SIZE) "]\n"
>> > +    "                mem=start-up memory amount\n"
>> > +    "                slots=maximum number of hotplug slots\n"
>> > +    "                maxmem=maximum total amount of memory\n",
>> > +    QEMU_ARCH_ALL)
>> 
>> Help text is confusing, because it discusses megs twice.  Fits right in,
>> as output of -help is generally confusing (to put it politely).
>> 
>> What about something like this:
>> 
>> -m [mem=]megs[,slots=n,maxmem=size]
>>                 configure guest RAM
>>                 mem: initial amount of guest memory (default: XXX)
>>                 slots: number of hotplug slots (default: none)
>>                 maxmem: maximum amount of guest memory (default: mem)
> Sure, I'll fix it.
>
>> >  STEXI
>> >  @item -m @var{megs}
>> >  @findex -m
>> > diff --git a/vl.c b/vl.c
>> > index f28674f..5974f0f 100644
>> > --- a/vl.c
>> > +++ b/vl.c
>> > @@ -529,6 +529,28 @@ static QemuOptsList qemu_msg_opts = {
>> >      },
>> >  };
>> >  
>> > +static QemuOptsList qemu_mem_opts = {
>> > +    .name = "memory-opts",
>> > +    .implied_opt_name = "mem",
>> > +    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
>> > +    .merge_lists = true,
>> 
>> Yes, because multiple -m need to accumulate.
>> 
>> > +    .desc = {
>> > +        {
>> > +            .name = "mem",
>> > +            .type = QEMU_OPT_SIZE,
>> > +        },
>> > +        {
>> > +            .name = "slots",
>> > +            .type = QEMU_OPT_NUMBER,
>> > +        },
>> > +        {
>> > +            .name = "maxmem",
>> > +            .type = QEMU_OPT_SIZE,
>> > +        },
>> > +        { /* end of list */ }
>> > +    },
>> > +};
>> > +
>> >  /**
>> >   * Get machine options
>> >   *
>> > @@ -2816,6 +2838,14 @@ static int object_create(QemuOpts *opts, void *opaque)
>> >      return 0;
>> >  }
>> >  
>> > +static void qemu_init_default_mem_opts(uint64_t size)
>> > +{
>> > +    QemuOpts *opts = qemu_opts_create_nofail(&qemu_mem_opts);
>> > +    qemu_opt_set_number(opts, "mem", size);
>> > +    qemu_opt_set_number(opts, "maxmem", size);
>> > +    qemu_opt_set_number(opts, "slots", 0);
>> > +}
>> > +
>> 
>> We usually don't put defaults in QemuOpts.  Instead, the code querying
>> QemuOpts detects and handles absence of the parameter.  Can be as simple
>> as qemu_opt_get_size(opts, "mem", DEFAULT_RAM_SIZE * 1024 * 1024).
> It allows to make number of uses a bit simpler:
>
> for example v6:
>     QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
>     if (!opts) { /* no -m x,... was passed to cmd line so no mem hotplug */
>         return;
>     }
>     mem_st->dev_count = qemu_opt_get_number(opts, "slots", 0);
>
> becomes"
>     QemuOpts *opts = qemu_opts_find(qemu_find_opts("memory-opts"), NULL);
>     state->dev_count = qemu_opt_get_number(opts, "slots", 0);
>     
> and eliminates need to pepper code with DEFAULT_RAM_SIZE * 1024 * 1024 or
> like constants wherever qemu_opt_get_..() is called, that was main reason
> to set defaults. i.e. set defaults only once instead of spreading them in
> every place qemu_opt_get_..() is called.

Two separate issues here:

1. The "no qemu_mem_opts have been specified" case

   This is equivalent to "empty options".  Therefore, the case can be
   eliminated by pre-creating empty options.  No objection.

   The three existing merge_lists users don't do that.  Perhaps they
   should.

2. How to provide default values

   Supplying defaults is left to the caller of qemu_opt_get_FOO() by
   design.

   Pre-creating option parameters deviates from that pattern.  You
   justify it by saying it "eliminates need to pepper code with
   DEFAULT_RAM_SIZE * 1024 * 1024".  How many occurrences?

   Drawback: you lose the ability to see whether the user gave a value.
   See below.

>> See also below.
>> 
>> >  int main(int argc, char **argv, char **envp)
>> >  {
>> >      int i;
>> > @@ -2887,6 +2917,7 @@ int main(int argc, char **argv, char **envp)
>> >      qemu_add_opts(&qemu_tpmdev_opts);
>> >      qemu_add_opts(&qemu_realtime_opts);
>> >      qemu_add_opts(&qemu_msg_opts);
>> > +    qemu_add_opts(&qemu_mem_opts);
>> >  
>> >      runstate_init();
>> >  
>> > @@ -2901,7 +2932,8 @@ int main(int argc, char **argv, char **envp)
>> >      module_call_init(MODULE_INIT_MACHINE);
>> >      machine = find_default_machine();
>> >      cpu_model = NULL;
>> > -    ram_size = 0;
>> > +    ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
>> > +    qemu_init_default_mem_opts(ram_size);
>> >      snapshot = 0;
>> >      cyls = heads = secs = 0;
>> >      translation = BIOS_ATA_TRANSLATION_AUTO;
>> > @@ -3178,21 +3210,43 @@ 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 *end;
>> > +                char *s;
>> >  
>> > -                value = strtosz(optarg, &end);
>> > -                if (value < 0 || *end) {
>> > -                    fprintf(stderr, "qemu: invalid ram size: %s\n", optarg);
>> > +                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
>> > +                                       optarg, 1);
>> > +                if (!opts) {
>> >                      exit(1);
>> >                  }
>> > -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
>> > +
>> > +                /* fixup legacy sugffix-less format */
>> 
>> /* fix up legacy suffix-less format */
>> 
>> The problem here is that OPT_SIZE treats values without a size suffix as
>> bytes, but we need to default to MiB for backward compatibility.
>> 
>> > +                end = qemu_opt_get(opts, "mem");
>> > +                if (g_ascii_isdigit(end[strlen(end) - 1])) {
>> > +                    s = g_strconcat(end, "M", NULL);
>> > +                    qemu_opt_set(opts, "mem", s);
>> > +                    g_free(s);
>> > +                }
>> 
>> Ugly.
>> 
>> Why is the variable called 'end'?
> would be 'suffix' better?

end points to the whole value string, not the end of anything, and
neither to a suffix of anything.

>> qemu_opt_set() appends to the list of options.  The un-fixed-up option
>> remains in the list.  qemu_opt_unset() could fix that, but it asserts
>> opts_accepts_any() for unclear reasons.  git-blame points to Kevin.
> it would be cleaner to unset it but it works event without unsetting it,
> since qemu_opt_set...() adds to tail and qemu_opt_get...() finds options
> from tail to head.
>
> Nevertheless, Kevin do you recall reasons for assert in 0dd6c526:
>
> int qemu_opt_unset(QemuOpts *opts, const char *name)
> ...
>     assert(opts_accepts_any(opts));
>
> would it be ok if I remove it?
>
>> 
>> Have you considered qemu_opt_set_number()?
> it was code left from v6 when I didn't know about it. Sorry, I'll
> use it instead.
>
>> 
>> If this "need a default suffix" pattern exists elsewhere, we should
>> consider extending QemuOptDesc to cover it.
> I haven't seen/don't recall need for it anywhere else, but it would be
> cleanest solution. But it would introduce temptation for users
> to shrug off suffixes which is wrong in my opinion. -m 1024 is confusing
> unless you know that it's in Mb.
>
> it would be better not to introduce mechanism, that would allow to do such
> thing in favor of explicit suffixes.

I'm afraid that horse as left the barn long ago:

* -numa mem=VAL accepts an optional suffix, defaulting it to 'M'.

* Likewise, HMP commands block_resize, block_stream,
  block_job_set_speed, migrate_set_cache_size, migrate_set_speed.

But point taken.

>> > +
>> > + sz = QEMU_ALIGN_UP(qemu_opt_get_size(opts, "mem", ram_size),
>> > +                                   8192);
>> > +                /* compatibility behaviour for case "-m 0" */
>> > +                if (sz == 0) {
>> > +                    sz = DEFAULT_RAM_SIZE * 1024 * 1024;
>> > +                }
>> > +
>> 
>> Yes, this is needed.  Our command line is bonkers.
>> 
>> >                  ram_size = sz;
>> >                  if (ram_size != sz) {
>> >                      fprintf(stderr, "qemu: ram size too large\n");
>> >                      exit(1);
>> >                  }
>> > +                /* store aligned value for future use */
>> > +                qemu_opt_set_number(opts, "mem", ram_size);
>> 
>> Here, you use qemu_opt_set_number().
>> 
>> Again, this appends to the list, and leaves the non-aligned value in.
> it's not an issue since the last appended opt is used in qemu_opt_get_size().
>
>> 
>> > +
>> > +                sz = qemu_opt_get_size(opts, "maxmem", ram_size);
>> > +                if (sz < ram_size) {
>> > +                    qemu_opt_set_number(opts, "maxmem", ram_size);
>> > +                }
>> >                  break;
>> >              }
>> 
>> Looks like you want to fix up something like "-m 1024", so that maxmem
>> stays equal to mem.  I'm afraid you also "fix" user errors like "-m
>> mem=1024M,maxmem=512M".
> Perhaps it would be better to bail out with error here.
>
>> 
>> If you refrain from putting defaults into opts, you can distinguish the
>> cases "user didn't specify maxmem, so assume mem", and "user specified
>> maxmem, so check it's >= mem".
> So foar, there is no point in distinguishing above cases,
> since maxmem <= mem is invalid value and hotplug should be disabled.
> So setting default maxmem to mem or anything less effectively disables hotplug.

Yes, setting maxmem < mem is invalid and should be rejected, but not
setting maxmem at all should be accepted even when you set mem.

Your patch like this pseudo-code:

    mem = DEFAULT_RAM_SIZE * 1024 * 1024
    maxmem = mem

    if user specifies mem:
        mem = user's mem
    if user specifes max-mem:
        mem = user's max-mem

    if max-mem < mem
        what now?
        should error our if max-mem and mem were specified by the user
        shouldn't if user didn't specify max-mem!
        but can't say whether he did

I'd do it this way:

    mem = unset
    maxmem = unset

    if user specifies mem:
        mem = user's mem
    if user specifes max-mem:
        mem = user's max-mem

    if mem != unset && max-mem != unset && max-mem < mem
        error

I'd use QemuOpts for the user's command line, and no more.  For anything
beyond that, I'd use ordinary variables, such as ram_size.

>> >  #ifdef CONFIG_TPM
>> > @@ -4029,11 +4083,6 @@ int main(int argc, char **argv, char **envp)
>> >          exit(1);
>> >      }
>> >  
>> > -    /* init the memory */
>> > -    if (ram_size == 0) {
>> > -        ram_size = DEFAULT_RAM_SIZE * 1024 * 1024;
>> > -    }
>> > -
>> >      if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
>> >          != 0) {
>> >          exit(0);
>
> Thanks for review!

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-26 14:49       ` Markus Armbruster
@ 2013-11-26 16:55         ` Igor Mammedov
  2013-11-27 14:35           ` Markus Armbruster
  2013-11-27  0:27         ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-26 16:55 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: kwolf, peter.maydell, aliguori, stefanb, hutao, mst, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Tue, 26 Nov 2013 15:49:05 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> Igor Mammedov <imammedo@redhat.com> writes:
> 
> > On Thu, 21 Nov 2013 11:12:43 +0100
> > Markus Armbruster <armbru@redhat.com> wrote:
> >
> >> Igor Mammedov <imammedo@redhat.com> writes:
> >> 
[...]
> Two separate issues here:
> 
> 1. The "no qemu_mem_opts have been specified" case
> 
>    This is equivalent to "empty options".  Therefore, the case can be
>    eliminated by pre-creating empty options.  No objection.
> 
>    The three existing merge_lists users don't do that.  Perhaps they
>    should.
> 
> 2. How to provide default values
> 
>    Supplying defaults is left to the caller of qemu_opt_get_FOO() by
>    design.
> 
>    Pre-creating option parameters deviates from that pattern.  You
>    justify it by saying it "eliminates need to pepper code with
>    DEFAULT_RAM_SIZE * 1024 * 1024".  How many occurrences?
beside of vl.c for:
  mem & maxmem 1 in hw/i386/pc.c
  slots - 6 in several files

see below for continuation:

> 
>    Drawback: you lose the ability to see whether the user gave a value.
>    See below.
> 
[...]
> >> Ugly.
> >> 
> >> Why is the variable called 'end'?
> > would be 'suffix' better?
> 
> end points to the whole value string, not the end of anything, and
> neither to a suffix of anything.
Any suggestions?
 
[...]
> >> If you refrain from putting defaults into opts, you can distinguish the
> >> cases "user didn't specify maxmem, so assume mem", and "user specified
> >> maxmem, so check it's >= mem".
> > So foar, there is no point in distinguishing above cases,
> > since maxmem <= mem is invalid value and hotplug should be disabled.
> > So setting default maxmem to mem or anything less effectively disables hotplug.
> 
> Yes, setting maxmem < mem is invalid and should be rejected, but not
> setting maxmem at all should be accepted even when you set mem.
> 
> Your patch like this pseudo-code:
> 
>     mem = DEFAULT_RAM_SIZE * 1024 * 1024
>     maxmem = mem
> 
>     if user specifies mem:
>         mem = user's mem
>     if user specifes max-mem:
>         mem = user's max-mem
> 
>     if max-mem < mem
>         what now?
>         should error our if max-mem and mem were specified by the user
>         shouldn't if user didn't specify max-mem!
>         but can't say whether he did
> 
> I'd do it this way:
> 
>     mem = unset
>     maxmem = unset
> 
>     if user specifies mem:
>         mem = user's mem
>     if user specifes max-mem:
>         mem = user's max-mem
> 
>     if mem != unset && max-mem != unset && max-mem < mem
>         error
>
> I'd use QemuOpts for the user's command line, and no more.  For anything
> beyond that, I'd use ordinary variables, such as ram_size.
Ok, I'll revert to the old code where options users check for option
availability, it's not that much code.


As for using QemuOpts as global store for global variables:

 * using local variables would require changing of machine init or/and
   QEMUMachine and changing functions signature pass them down the stack to
   consumers.

 * adding "slots" readonly property to i440fx & q35 for consumption in
   ACPI hotplug code and building ACPI tables. It would be essentially another
   global lookup for i440fx & q35  object and pulling "slots" property,
   which is much longer way/complex way to get global value. That's a lot of
   boilerplate code for the same outcome.

 * about setting default for "mem" value: if default "mem" is not set and
   no -m is provided on CLI, we get case where
      ram_size = foo & "mem" unset  
   And if I recall correctly there was an effort to provide interface for
   currently used QemuOpts to external users. So "mem" would get inconsistent
   with what QEMU uses.

To sum up above said:
 * I'd like to continue using QemuOpts as global constant value store, it
   saves from adding a lot of boilerplate-code that would do the same.
   Doing
     "git grep qemu_get_machine_opts"
   gets us several precedents that already use it that way.

 * I believe that setting default in QemuOpts for "mem" is a good thing that
   leads to consistent meaning of "mem" with what QEMU actually uses.

-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine
  2013-11-25 17:00             ` Andreas Färber
@ 2013-11-26 20:26               ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-26 20:26 UTC (permalink / raw)
  To: Andreas Färber
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, hutao, mst, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, Li Guang

On Mon, 25 Nov 2013 18:00:56 +0100
Andreas Färber <afaerber@suse.de> wrote:

> Am 25.11.2013 11:41, schrieb Igor Mammedov:
> > On Thu, 21 Nov 2013 17:09:27 +0100
> > Andreas Färber <afaerber@suse.de> wrote:
> > 
> >> Am 21.11.2013 15:34, schrieb Igor Mammedov:
> >>> On Thu, 21 Nov 2013 15:13:12 +0100
> >>> Andreas Färber <afaerber@suse.de> wrote:
> >>>> Am 21.11.2013 06:48, schrieb Li Guang:
> >>>>> Why not give the memory that not be hot-added a chance to be placed on
> >>>>> one memory slot?
> >>>>
> >>>> Seconded, I believe I requested that on the previous version already.
> >>> Because current initial memory allocation is a mess and this already
> >>> large series would become even more large and intrusive, so far series
> >>> it relatively not intrusive and self contained.
> >>>
> >>> I believe re-factoring of initial memory to use Dimm devices should be
> >>> done later on top of infrastructure this series provides.
> >>
> >> My problem with that is that that would be a semantically incompatible
> >> modeling change. With your series we might have /machine/dimm.0/child[0]
> >> be the first hot-plugged memory and once such a refactoring is done,
> >> child[0] silently becomes -m and child[1] is the hot-added one.
> > 
> > I think there won't be silent change in child[0], since most likely
> > initial RAM would require additional DimmBus (maybe even 2)
> > for it's devices.
> > 
> > But anyway, why would this be an issue?
> > 
> >> So if we know that we want/need to change the infrastructure, why not
> >> add a single patch (?) to allocate one additional object on the bus now?
> >> Unless we actually write the code, we won't know whether there are some
> >> incorrect hot-plug assumptions in the dimm code.
> > It wouldn't be a single simple patch for PC, I'm afraid.
> > I don't see point in adding dummy DIMM device for initial memory and then
> > do re-aliasing of its memory region in GPA as it's done in current code.
> > 
> > As I see it (taking in account Marcolo's/Paolo's alignment path), current
> > single MR for initial RAM should be split in 1-4 separate MRs depending on
> > initial RAM amount and alignment requirements between HPA/GPA addresses.
> > 
> > That would probably introduce additional, non hotlugable DimmBus-es (1-2)
> > for low and high memory, which would be incompatible with old machine types
> > devices and GPA layout, so why care about what
> > /machine/dimm.0/child[0] would be in new machine version?
> 
> I feel we're talking about two very different things here.
> 
> What I am talking about is the user experience. A mainboard has 4 or
> maybe 8 DIMM slots where the user can plug in greenish memory bars.
> That's what I would like to see implemented in QEMU because that's
> understandable without reading code and ACPI specs.
> 
> What you seem to be talking about by contrast is your DimmBus
> implementation and its limitations/assumptions. You can easily use
> dev->hotplugged to distinguish between initial and hot-plugged devices
> as done elsewhere, including PCI and ICC bus, no?
Yes, That what user would be interested in when doing hot-unplug. I'll add
properties to DimmDevice so user could see if it's "hotplugable" &
"hotplugged". 

> 
> In short, what I am fighting against is having a machine with 4 slots:
> 
> slot[0] = 42
> slot[1] = 0
> slot[2] = 0
> slot[3] = 0
> 
> meaning 42 + implicit -m now, later getting fixed to explicit:
> 
> slot[0] = -m
> slot[1] = 42
> slot[2] = 0
> slot[3] = 0
> 
> Whether -m maps to one or more slots can easily be scaled in the
> example, I had previously asked whether there were upper limits per slot
> but believe that got denied from an ACPI perspective; my point is the
> slot offset and the inconsistent sum exposed via QOM/QMP.
such change would be machine incompatible, so why the slot offset would be
important? Depending on initial memory size, slot offset would change.
Depending on stable offset to do something would be a just wrong use of
interface.

I see issue with a sum exposed via QOM/QMP whether it's links or bus based
implementation, but it looks like an additional feature not related to
memory hotplug:
 "let me count all present memory"
this series doesn't provide it, it only provides
 "current hotplug memory enumeration"


> 
> On your ICC bus we had the initial -smp CPUs alongside hot-plugged CPUs
> right from the start.
As Michael said 1.8 is not in freeze yet, so if there will be time I'll
try to convert initial memory to DIMMs as well for the sake of
cleaning up mess it's now and not producing yet another migration
incompatible machine.
But it's not trivial and not directly related to memory hotplug.
Doing dummy conversion would help SUM case from above but it will make
current code even messier. So I'd rather do it incrementally cleaning
it up in process vs making it messier.
 
> 
> I can't think of a reason why there would be multiple DimmBuses in a
> single machine from a user's point of view.
> Different implementations for different memory controllers / machines
> make perfect sense of course. But even from a developer's point of view
> multiple buses don't make that much sense either if we keep
> http://wiki.qemu.org/Features/QOM#TODO in mind - devices exposing
> multiple buses need to be split up and in the end we just have named
> link<> properties on some container object as sketched in the example
> above - question then becomes should we have multiple containers, and I
> think the answer for a PC will be no.
in pc we have to have container memory regions to contain DIMMs since the
split below / above 4Gb memory organization. One way would be to replace
current initial Memory region with non hotplugable bus that will hold initial
memory DIMMs.
In case when buses are to be converted to links<> with all hotplug
machinery around ready, it could be reorganized to 1 container with 2 MR
containers.

> Embedded systems with a mix of small on-chip SRAM and on-board SDRAM may
> be a different beast to model, but well beyond the scope of this series
> anyway, which IIUC doesn't expose any DimmBus outside of the two PCs.
> 
> Also, once memory has been hot-plugged and the machine gets rebooted,
> shouldn't that be the same to BIOS/ACPI as if the memory was cold-plugged?
Guest sees earlier hotplugged memory after reboot during enumeration of ACPI
memory device objects. Windows & Linux work with it just fine (the only
difference is that Linux doesn't online them automaticaly, it's up to udev
to deal with it).

I also have TODO item to evaluate if it's acceptable to add them and
reservation to E820 table so that guest could see them even before ACPI is
processed. 

> 
> Regards,
> Andreas
> 
> -- 
> SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
> GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-26  0:29                   ` Li Guang
@ 2013-11-26 22:36                     ` Igor Mammedov
  2013-11-27  0:15                       ` Li Guang
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-26 22:36 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, stefanha, Michael S. Tsirkin, Hu Tao, stefanb,
	mjt, qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber,
	armbru

On Tue, 26 Nov 2013 08:29:27 +0800
Li Guang <lig.fnst@cn.fujitsu.com> wrote:

> Igor Mammedov wrote:
> > On Fri, 22 Nov 2013 08:57:40 +0800
> > Li Guang<lig.fnst@cn.fujitsu.com>  wrote:
> >
> >    
> >> Michael S. Tsirkin wrote:
> >>      
> >>> On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
> >>>
> >>>        
> >>>> Michael S. Tsirkin wrote:
> >>>>
> >>>>          
> >>>>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
> >>>>>
> >>>>>            
> >>>>>> Hu Tao wrote:
> >>>>>>
> >>>>>>              
> >>>>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> >>>>>>>
> >>>>>>>                
> >>>>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> >>>>>>>>
> >>>>>>>>                  
> >>>>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
> >>>>>>>>> after it has been handled when it clears GPE event.
> >>>>>>>>>
> >>>>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
> >>>>>>>>>
> >>>>>>>>>                    
> >>>>>>>> The storm is only on memory hotplug right?
> >>>>>>>>
> >>>>>>>>                  
> >>>>>>> IIRC, it happens on cpu hotplug, too.
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>                
> >>>>>> :-), that made remember EC implementation,
> >>>>>> with EC, SCI will be safer, I think.
> >>>>>>
> >>>>>>              
> >>>>> Hmm you are saying let's use EC for memory hotplug?
> >>>>>
> >>>>>
> >>>>>
> >>>>>            
> >>>> It can be a bridge between guest and QEMU,
> >>>> with it, we may don't have to bother ASL writing
> >>>> and south-bridge hardware related work(or very
> >>>> little) if we implement EC correctly.
> >>>>
> >>>>
> >>>>
> >>>>          
> >>> I'd like to see that. Can you write a document (just text)
> >>> for an imaginary EC support for memory hotplug?
> >>>
> >>>
> >>>
> >>>
> >>>        
> >> Hmm..., with EC,
> >>
> >> For memory hotplug, at least,
> >> ASL at [PATCH 27/27] can be replaced
> >> by a simple Method(_Qx) under EC device,
> >> IO base operations at [PATCH 15/27]
> >> are dispensable,  we can relay data
> >> by standard operations of EC space
> >>
> >> and also for SCI, all device changes want to
> >> notify guest OS can share same SCI with EC,
> >> and the operations are specified at ACPI SPEC.
> >>
> >> likewise, for CPU hotplug, pvpanic,
> >> and even debugcon.
> >>
> >> and, for odd devices, like pvpanic, guest OS may complain
> >> about it, and we may also have to bother on maintaining state of
> >> it at QEMU, and writing a driver for guest OS,
> >> with EC, functions of device like pvpanic may be implemented silently,
> >> and EC is ACPI standard device, each ACPI compatible OS will
> >> have a driver for it natively.
> >>
> >>      
> >  From what I remember about them EC was adding essentially another
> > side-channel but more sophisticated for OSPM communication with
> > platform but for not benefit so far, since what we need from ACPI
> > for hotplug could be implemented by using GPE handlers without
> > adding any EC.
> >
> > I think there was EC patches on list (perhaps yours) but I couldn't
> > find them. Could you point me to them if they are demonstrating
> > how hotplug could be done with EC approach.
> >
> >
> >
> >    
> you can find my previous raw patch-set here,
> http://lists.gnu.org/archive/html/qemu-devel/2013-05/msg02845.html
There you are trying to overcome linux kernel limitation with help of EC
AND additional guest driver to online CPU.
Memory hotplug essentially has the same issue, UDEV is responsible for
onlining hot added ranges. So it's upto userspace policy whether to do
it automatically or not.

But even discarding qemu specific kernel driver, it boils down to using
_Qxx handler vs _Exx one with basically the same ASL code.

So question becomes: Why using EC would be better than using already
present GPE registers for handling event?

> Thanks!
> Li Guang
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-26 22:36                     ` Igor Mammedov
@ 2013-11-27  0:15                       ` Li Guang
  2013-11-27  0:57                         ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Li Guang @ 2013-11-27  0:15 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, Hu Tao, Michael S. Tsirkin,
	mjt, qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber,
	armbru

Igor Mammedov wrote:
> On Tue, 26 Nov 2013 08:29:27 +0800
> Li Guang<lig.fnst@cn.fujitsu.com>  wrote:
>
>    
>> Igor Mammedov wrote:
>>      
>>> On Fri, 22 Nov 2013 08:57:40 +0800
>>> Li Guang<lig.fnst@cn.fujitsu.com>   wrote:
>>>
>>>
>>>        
>>>> Michael S. Tsirkin wrote:
>>>>
>>>>          
>>>>> On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
>>>>>
>>>>>
>>>>>            
>>>>>> Michael S. Tsirkin wrote:
>>>>>>
>>>>>>
>>>>>>              
>>>>>>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>>>> Hu Tao wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>                  
>>>>>>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                    
>>>>>>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                      
>>>>>>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
>>>>>>>>>>> after it has been handled when it clears GPE event.
>>>>>>>>>>>
>>>>>>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>                        
>>>>>>>>>> The storm is only on memory hotplug right?
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                      
>>>>>>>>> IIRC, it happens on cpu hotplug, too.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                    
>>>>>>>> :-), that made remember EC implementation,
>>>>>>>> with EC, SCI will be safer, I think.
>>>>>>>>
>>>>>>>>
>>>>>>>>                  
>>>>>>> Hmm you are saying let's use EC for memory hotplug?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>> It can be a bridge between guest and QEMU,
>>>>>> with it, we may don't have to bother ASL writing
>>>>>> and south-bridge hardware related work(or very
>>>>>> little) if we implement EC correctly.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>              
>>>>> I'd like to see that. Can you write a document (just text)
>>>>> for an imaginary EC support for memory hotplug?
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>            
>>>> Hmm..., with EC,
>>>>
>>>> For memory hotplug, at least,
>>>> ASL at [PATCH 27/27] can be replaced
>>>> by a simple Method(_Qx) under EC device,
>>>> IO base operations at [PATCH 15/27]
>>>> are dispensable,  we can relay data
>>>> by standard operations of EC space
>>>>
>>>> and also for SCI, all device changes want to
>>>> notify guest OS can share same SCI with EC,
>>>> and the operations are specified at ACPI SPEC.
>>>>
>>>> likewise, for CPU hotplug, pvpanic,
>>>> and even debugcon.
>>>>
>>>> and, for odd devices, like pvpanic, guest OS may complain
>>>> about it, and we may also have to bother on maintaining state of
>>>> it at QEMU, and writing a driver for guest OS,
>>>> with EC, functions of device like pvpanic may be implemented silently,
>>>> and EC is ACPI standard device, each ACPI compatible OS will
>>>> have a driver for it natively.
>>>>
>>>>
>>>>          
>>>    From what I remember about them EC was adding essentially another
>>> side-channel but more sophisticated for OSPM communication with
>>> platform but for not benefit so far, since what we need from ACPI
>>> for hotplug could be implemented by using GPE handlers without
>>> adding any EC.
>>>
>>> I think there was EC patches on list (perhaps yours) but I couldn't
>>> find them. Could you point me to them if they are demonstrating
>>> how hotplug could be done with EC approach.
>>>
>>>
>>>
>>>
>>>        
>> you can find my previous raw patch-set here,
>> http://lists.gnu.org/archive/html/qemu-devel/2013-05/msg02845.html
>>      
> There you are trying to overcome linux kernel limitation with help of EC
> AND additional guest driver to online CPU.
> Memory hotplug essentially has the same issue, UDEV is responsible for
> onlining hot added ranges. So it's upto userspace policy whether to do
> it automatically or not.
>    

really?
AFAIK, all hotplug-able  memory can be described at SRAT,
and you can plug and unplug, just need a GPE.

> But even discarding qemu specific kernel driver, it boils down to using
> _Qxx handler vs _Exx one with basically the same ASL code.
>
> So question becomes: Why using EC would be better than using already
> present GPE registers for handling event?
>
>    
1. we didn't need to bother IO memory operations,
      because we relay data via EC
2. we didn't need to bother GPE handling,
      because EC can do it for us
3. for extension, if need like pvpanic device, can be satisfied
     by EC operations easily

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

* [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts
  2013-11-26 14:49       ` Markus Armbruster
  2013-11-26 16:55         ` Igor Mammedov
@ 2013-11-27  0:27         ` Igor Mammedov
  2013-11-27  0:27           ` [Qemu-devel] [PATCH 05/28] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
  2013-12-10  7:23           ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Paolo Bonzini
  1 sibling, 2 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27  0:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, hutao, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, afaerber

Adds option to -m
 "mem" - 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>
---
 qemu-options.hx |  7 +++++--
 vl.c            | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
 2 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index 8b94264..d923995 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -210,8 +210,11 @@ 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 [mem=]megs\n"
+    "                configure guest RAM\n"
+    "                mem: initial amount of guest memory (default: "
+    stringify(DEFAULT_RAM_SIZE) "Mb)\n",
+    QEMU_ARCH_ALL)
 STEXI
 @item -m @var{megs}
 @findex -m
diff --git a/vl.c b/vl.c
index f28674f..44cc4ed 100644
--- a/vl.c
+++ b/vl.c
@@ -529,6 +529,20 @@ static QemuOptsList qemu_msg_opts = {
     },
 };
 
+static QemuOptsList qemu_mem_opts = {
+    .name = "memory-opts",
+    .implied_opt_name = "mem",
+    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
+    .merge_lists = true,
+    .desc = {
+        {
+            .name = "mem",
+            .type = QEMU_OPT_SIZE,
+        },
+        { /* end of list */ }
+    },
+};
+
 /**
  * Get machine options
  *
@@ -2852,6 +2866,7 @@ 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 = DEFAULT_RAM_SIZE * 1024 * 1024;
 
     atexit(qemu_run_exit_notifiers);
     error_set_progname(argv[0]);
@@ -2887,6 +2902,8 @@ int main(int argc, char **argv, char **envp)
     qemu_add_opts(&qemu_tpmdev_opts);
     qemu_add_opts(&qemu_realtime_opts);
     qemu_add_opts(&qemu_msg_opts);
+    qemu_add_opts(&qemu_mem_opts);
+    qemu_opts_create_nofail(&qemu_mem_opts);
 
     runstate_init();
 
@@ -2901,7 +2918,7 @@ int main(int argc, char **argv, char **envp)
     module_call_init(MODULE_INIT_MACHINE);
     machine = 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;
@@ -3178,16 +3195,32 @@ 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);
+                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
+                                       optarg, 1);
+
+                mem_str = qemu_opt_get(opts, "mem");
+                if (!mem_str) {
+                    fprintf(stderr, "qemu: invalid -m option, missing "
+                            " 'mem' option\n");
                     exit(1);
                 }
-                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
+
+                sz = qemu_opt_get_size(opts, "mem", ram_size);
+
+                /* Fix up legacy suffix-less format */
+                if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
+                    sz <<= 20;
+                }
+
+                /* backward compatibility behaviour for case "-m 0" */
+                if (sz == 0) {
+                    sz = default_ram_size;
+                }
+
+                sz = QEMU_ALIGN_UP(sz, 8192);
                 ram_size = sz;
                 if (ram_size != sz) {
                     fprintf(stderr, "qemu: ram size too large\n");
@@ -4029,10 +4062,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(opts, "mem", ram_size);
 
     if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
         != 0) {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH 05/28] vl.c: extend -m option to support options for memory hotplug
  2013-11-27  0:27         ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Igor Mammedov
@ 2013-11-27  0:27           ` Igor Mammedov
  2013-12-10  7:23           ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Paolo Bonzini
  1 sibling, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27  0:27 UTC (permalink / raw)
  To: qemu-devel
  Cc: peter.maydell, stefanha, mst, hutao, stefanb, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, 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>
---
 qemu-options.hx |  7 +++++--
 vl.c            | 45 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/qemu-options.hx b/qemu-options.hx
index d923995..0eb1587 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 [mem=]megs\n"
+    "-m [mem=]megs[,slots=n,maxmem=size]\n"
     "                configure guest RAM\n"
     "                mem: initial amount of guest memory (default: "
-    stringify(DEFAULT_RAM_SIZE) "Mb)\n",
+    stringify(DEFAULT_RAM_SIZE) "Mb)\n"
+    "                slots=number of hotplug slots (default: none)\n"
+    "                maxmem=maximum amount of guest memory (default: none)\n"
+    "                slots and maxmem must be used together\n",
     QEMU_ARCH_ALL)
 STEXI
 @item -m @var{megs}
diff --git a/vl.c b/vl.c
index 44cc4ed..1611ea0 100644
--- a/vl.c
+++ b/vl.c
@@ -539,6 +539,14 @@ static QemuOptsList qemu_mem_opts = {
             .name = "mem",
             .type = QEMU_OPT_SIZE,
         },
+        {
+            .name = "slots",
+            .type = QEMU_OPT_NUMBER,
+        },
+        {
+            .name = "maxmem",
+            .type = QEMU_OPT_SIZE,
+        },
         { /* end of list */ }
     },
 };
@@ -3197,6 +3205,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-opts"),
                                        optarg, 1);
@@ -3226,6 +3235,42 @@ int main(int argc, char **argv, char **envp)
                     fprintf(stderr, "qemu: ram size too large\n");
                     exit(1);
                 }
+
+                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(1);
+                    }
+
+                    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(1);
+                    }
+
+                    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(1);
+                    }
+                } 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(1);
+                }
                 break;
             }
 #ifdef CONFIG_TPM
-- 
1.8.3.1

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-25 12:51   ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Paolo Bonzini
@ 2013-11-27  0:32     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27  0:32 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

On Mon, 25 Nov 2013 13:51:03 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 21/11/2013 03:38, Igor Mammedov ha scritto:
> > Along with conversion extend -m option to support following parameters:
> >   "mem" - startup memory amount
> >   "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 usable.
> 
> Strictly speaking, slots and maxmem should be added later, not in this
> patch.  Not a blocker, though.
I've split patch taking in account most of Markus' comments
and added extra error checks for option values.
Amended patches are posted as reply to this thread.

> Paolo
> 
[...]


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-27  0:15                       ` Li Guang
@ 2013-11-27  0:57                         ` Igor Mammedov
  2013-11-27  1:48                           ` Li Guang
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27  0:57 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, aliguori, stefanb, Hu Tao, Michael S. Tsirkin,
	mjt, qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber,
	armbru

On Wed, 27 Nov 2013 08:15:31 +0800
Li Guang <lig.fnst@cn.fujitsu.com> wrote:

> Igor Mammedov wrote:
> > On Tue, 26 Nov 2013 08:29:27 +0800
> > Li Guang<lig.fnst@cn.fujitsu.com>  wrote:
> >
> >    
> >> Igor Mammedov wrote:
> >>      
> >>> On Fri, 22 Nov 2013 08:57:40 +0800
> >>> Li Guang<lig.fnst@cn.fujitsu.com>   wrote:
> >>>
> >>>
> >>>        
> >>>> Michael S. Tsirkin wrote:
> >>>>
> >>>>          
> >>>>> On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
> >>>>>
> >>>>>
> >>>>>            
> >>>>>> Michael S. Tsirkin wrote:
> >>>>>>
> >>>>>>
> >>>>>>              
> >>>>>>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
> >>>>>>>
> >>>>>>>
> >>>>>>>                
> >>>>>>>> Hu Tao wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>                  
> >>>>>>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>                    
> >>>>>>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>                      
> >>>>>>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
> >>>>>>>>>>> after it has been handled when it clears GPE event.
> >>>>>>>>>>>
> >>>>>>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
> >>>>>>>>>>>
> >>>>>>>>>>>
> >>>>>>>>>>>                        
> >>>>>>>>>> The storm is only on memory hotplug right?
> >>>>>>>>>>
> >>>>>>>>>>
> >>>>>>>>>>                      
> >>>>>>>>> IIRC, it happens on cpu hotplug, too.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>                    
> >>>>>>>> :-), that made remember EC implementation,
> >>>>>>>> with EC, SCI will be safer, I think.
> >>>>>>>>
> >>>>>>>>
> >>>>>>>>                  
> >>>>>>> Hmm you are saying let's use EC for memory hotplug?
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>>                
> >>>>>> It can be a bridge between guest and QEMU,
> >>>>>> with it, we may don't have to bother ASL writing
> >>>>>> and south-bridge hardware related work(or very
> >>>>>> little) if we implement EC correctly.
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>>              
> >>>>> I'd like to see that. Can you write a document (just text)
> >>>>> for an imaginary EC support for memory hotplug?
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>>            
> >>>> Hmm..., with EC,
> >>>>
> >>>> For memory hotplug, at least,
> >>>> ASL at [PATCH 27/27] can be replaced
> >>>> by a simple Method(_Qx) under EC device,
> >>>> IO base operations at [PATCH 15/27]
> >>>> are dispensable,  we can relay data
> >>>> by standard operations of EC space
> >>>>
> >>>> and also for SCI, all device changes want to
> >>>> notify guest OS can share same SCI with EC,
> >>>> and the operations are specified at ACPI SPEC.
> >>>>
> >>>> likewise, for CPU hotplug, pvpanic,
> >>>> and even debugcon.
> >>>>
> >>>> and, for odd devices, like pvpanic, guest OS may complain
> >>>> about it, and we may also have to bother on maintaining state of
> >>>> it at QEMU, and writing a driver for guest OS,
> >>>> with EC, functions of device like pvpanic may be implemented silently,
> >>>> and EC is ACPI standard device, each ACPI compatible OS will
> >>>> have a driver for it natively.
> >>>>
> >>>>
> >>>>          
> >>>    From what I remember about them EC was adding essentially another
> >>> side-channel but more sophisticated for OSPM communication with
> >>> platform but for not benefit so far, since what we need from ACPI
> >>> for hotplug could be implemented by using GPE handlers without
> >>> adding any EC.
> >>>
> >>> I think there was EC patches on list (perhaps yours) but I couldn't
> >>> find them. Could you point me to them if they are demonstrating
> >>> how hotplug could be done with EC approach.
> >>>
> >>>
> >>>
> >>>
> >>>        
> >> you can find my previous raw patch-set here,
> >> http://lists.gnu.org/archive/html/qemu-devel/2013-05/msg02845.html
> >>      
> > There you are trying to overcome linux kernel limitation with help of EC
> > AND additional guest driver to online CPU.
> > Memory hotplug essentially has the same issue, UDEV is responsible for
> > onlining hot added ranges. So it's upto userspace policy whether to do
> > it automatically or not.
> >    
> 
> really?
> AFAIK, all hotplug-able  memory can be described at SRAT,
> and you can plug and unplug, just need a GPE.
Just try it :)
kernel creates entries for hotplugged memory but userspace has to online
it manually, issue doesn't have any relation to SRAT table.

> > But even discarding qemu specific kernel driver, it boils down to using
> > _Qxx handler vs _Exx one with basically the same ASL code.
> >
> > So question becomes: Why using EC would be better than using already
> > present GPE registers for handling event?
> >
> >    
> 1. we didn't need to bother IO memory operations,
>       because we relay data via EC
I guess we will have to write/read EC's IO memory instead, serializing data
into byte stream [as in proposed earlier impl.], which will complicate
ACPI interface part of memory hotplug. On QEMU side reader/writer handler might
look different but will implement the same logic as now, EC will not implement
it magically for us.

> 2. we didn't need to bother GPE handling,
>       because EC can do it for us
It will do EC handling instead, aren't it?

Looks like discussion turned into just arguing.
You have on hand this series, would you demonstrate with patches that EC
allows to implement series simpler/better so we could evaluate alternative?

> 3. for extension, if need like pvpanic device, can be satisfied
>      by EC operations easily
> 
> 


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-27  0:57                         ` Igor Mammedov
@ 2013-11-27  1:48                           ` Li Guang
  2013-11-27  9:43                             ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Li Guang @ 2013-11-27  1:48 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, Michael S. Tsirkin, Hu Tao, stefanb,
	mjt, qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber,
	armbru

Igor Mammedov wrote:
> On Wed, 27 Nov 2013 08:15:31 +0800
> Li Guang<lig.fnst@cn.fujitsu.com>  wrote:
>
>    
>> Igor Mammedov wrote:
>>      
>>> On Tue, 26 Nov 2013 08:29:27 +0800
>>> Li Guang<lig.fnst@cn.fujitsu.com>   wrote:
>>>
>>>
>>>        
>>>> Igor Mammedov wrote:
>>>>
>>>>          
>>>>> On Fri, 22 Nov 2013 08:57:40 +0800
>>>>> Li Guang<lig.fnst@cn.fujitsu.com>    wrote:
>>>>>
>>>>>
>>>>>
>>>>>            
>>>>>> Michael S. Tsirkin wrote:
>>>>>>
>>>>>>
>>>>>>              
>>>>>>> On Thu, Nov 21, 2013 at 04:32:27PM +0800, Li Guang wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>>>> Michael S. Tsirkin wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                  
>>>>>>>>> On Thu, Nov 21, 2013 at 04:18:45PM +0800, Li Guang wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                    
>>>>>>>>>> Hu Tao wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                      
>>>>>>>>>>> On Thu, Nov 21, 2013 at 09:14:18AM +0200, Michael S. Tsirkin wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>                        
>>>>>>>>>>>> On Thu, Nov 21, 2013 at 03:38:37AM +0100, Igor Mammedov wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>                          
>>>>>>>>>>>>> it fixes IRQ storm since guest isn't able to lower SCI IRQ
>>>>>>>>>>>>> after it has been handled when it clears GPE event.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Signed-off-by: Igor Mammedov<imammedo@redhat.com>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>                            
>>>>>>>>>>>> The storm is only on memory hotplug right?
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>                          
>>>>>>>>>>> IIRC, it happens on cpu hotplug, too.
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>                        
>>>>>>>>>> :-), that made remember EC implementation,
>>>>>>>>>> with EC, SCI will be safer, I think.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>                      
>>>>>>>>> Hmm you are saying let's use EC for memory hotplug?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                    
>>>>>>>> It can be a bridge between guest and QEMU,
>>>>>>>> with it, we may don't have to bother ASL writing
>>>>>>>> and south-bridge hardware related work(or very
>>>>>>>> little) if we implement EC correctly.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                  
>>>>>>> I'd like to see that. Can you write a document (just text)
>>>>>>> for an imaginary EC support for memory hotplug?
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>                
>>>>>> Hmm..., with EC,
>>>>>>
>>>>>> For memory hotplug, at least,
>>>>>> ASL at [PATCH 27/27] can be replaced
>>>>>> by a simple Method(_Qx) under EC device,
>>>>>> IO base operations at [PATCH 15/27]
>>>>>> are dispensable,  we can relay data
>>>>>> by standard operations of EC space
>>>>>>
>>>>>> and also for SCI, all device changes want to
>>>>>> notify guest OS can share same SCI with EC,
>>>>>> and the operations are specified at ACPI SPEC.
>>>>>>
>>>>>> likewise, for CPU hotplug, pvpanic,
>>>>>> and even debugcon.
>>>>>>
>>>>>> and, for odd devices, like pvpanic, guest OS may complain
>>>>>> about it, and we may also have to bother on maintaining state of
>>>>>> it at QEMU, and writing a driver for guest OS,
>>>>>> with EC, functions of device like pvpanic may be implemented silently,
>>>>>> and EC is ACPI standard device, each ACPI compatible OS will
>>>>>> have a driver for it natively.
>>>>>>
>>>>>>
>>>>>>
>>>>>>              
>>>>>      From what I remember about them EC was adding essentially another
>>>>> side-channel but more sophisticated for OSPM communication with
>>>>> platform but for not benefit so far, since what we need from ACPI
>>>>> for hotplug could be implemented by using GPE handlers without
>>>>> adding any EC.
>>>>>
>>>>> I think there was EC patches on list (perhaps yours) but I couldn't
>>>>> find them. Could you point me to them if they are demonstrating
>>>>> how hotplug could be done with EC approach.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>            
>>>> you can find my previous raw patch-set here,
>>>> http://lists.gnu.org/archive/html/qemu-devel/2013-05/msg02845.html
>>>>
>>>>          
>>> There you are trying to overcome linux kernel limitation with help of EC
>>> AND additional guest driver to online CPU.
>>> Memory hotplug essentially has the same issue, UDEV is responsible for
>>> onlining hot added ranges. So it's upto userspace policy whether to do
>>> it automatically or not.
>>>
>>>        
>> really?
>> AFAIK, all hotplug-able  memory can be described at SRAT,
>> and you can plug and unplug, just need a GPE.
>>      
> Just try it :)
> kernel creates entries for hotplugged memory but userspace has to online
> it manually, issue doesn't have any relation to SRAT table.
>
>    
>>> But even discarding qemu specific kernel driver, it boils down to using
>>> _Qxx handler vs _Exx one with basically the same ASL code.
>>>
>>> So question becomes: Why using EC would be better than using already
>>> present GPE registers for handling event?
>>>
>>>
>>>        
>> 1. we didn't need to bother IO memory operations,
>>        because we relay data via EC
>>      
> I guess we will have to write/read EC's IO memory instead,

the premise is supposed EC is implemented already.

> serializing data
> into byte stream [as in proposed earlier impl.], which will complicate
> ACPI interface part of memory hotplug. On QEMU side reader/writer handler might
> look different but will implement the same logic as now, EC will not implement
> it magically for us.
>
>    

Yes, of course, but, as you can see,  info relay will turn into standard
EC r/w operations.

>> 2. we didn't need to bother GPE handling,
>>        because EC can do it for us
>>      
> It will do EC handling instead, aren't it?
>    
Yes.
> Looks like discussion turned into just arguing.
>    

:-),  I just answer your questions.

> You have on hand this series, would you demonstrate with patches that EC
> allows to implement series simpler/better so we could evaluate alternative?
>
>    

I am never going say EC is deemed to be simpler or better,
for me,  it's just flexible.

The mainly approach be demoed at my previous patch-set
for cpu-hotplug.

Thanks!
Li Guang
>> 3. for extension, if need like pvpanic device, can be satisfied
>>       by EC operations easily
>>
>>
>>      
>
>    

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

* Re: [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE
  2013-11-27  1:48                           ` Li Guang
@ 2013-11-27  9:43                             ` Paolo Bonzini
  0 siblings, 0 replies; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-27  9:43 UTC (permalink / raw)
  To: Li Guang
  Cc: peter.maydell, stefanha, stefanb, Hu Tao, Michael S. Tsirkin,
	mjt, qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	aliguori, Igor Mammedov, marcel.a, lcapitulino, chegu_vinod,
	afaerber, armbru

Il 27/11/2013 02:48, Li Guang ha scritto:
> I am never going say EC is deemed to be simpler or better,
> for me,  it's just flexible.

I think it's entirely the same.  Instead of the I/O address space you
would use EC OperationRegions, instead of _Exx you would use _Qxx.

If we had an embedded controller device model perhaps it would make
sense to use it for all of PCI hotplug, CPU hotplug, memory hotplug.  We
don't, hence it makes sense to use I/O and GPE for all three of them.

Paolo

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-25 16:43           ` Eric Blake
  2013-11-25 17:01             ` Paolo Bonzini
@ 2013-11-27 14:15             ` Markus Armbruster
  2013-11-27 15:17               ` Paolo Bonzini
  2013-12-19 14:40             ` Michael S. Tsirkin
  2 siblings, 1 reply; 143+ messages in thread
From: Markus Armbruster @ 2013-11-27 14:15 UTC (permalink / raw)
  To: Eric Blake
  Cc: peter.maydell, aliguori, quintela, hutao, Michael S. Tsirkin,
	mjt, qemu-devel, stefanb, mdroth, vasilis.liaskovitis, kraxel,
	stefanha, Igor Mammedov, Paolo Bonzini, marcel.a, lcapitulino,
	chegu_vinod, afaerber

Eric Blake <eblake@redhat.com> writes:

> On 11/25/2013 09:32 AM, Paolo Bonzini wrote:
>
>>> Yes please. Firing up a calculator to figure out how much is 1G is not
>>> friendly, neither is firing it up to figure out what did management do
>>> with QMP. It should be a text based interface not a binary one.
>
> Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
> prefers passing a value in 'bytes', rather than risking confusion on
> whether a value in G was rounded (up, down? to nearest power of 10 or
> power of 2?).  Unfortunately, yes, that means you need a calculator when
> parsing QMP logs to see whether the 1073741824 passed by libvirt is the
> 1G you had in mind.

This is by design.

> HMP, qtest, and any other decent shell around raw QMP is more than
> welcome to provide human-usable wrappers that takes "1G" as a string and
> turns it into the raw int used by the underlying QMP.  In fact, I
> encourage it.

Me too, as long as the units suffixes are used consistently.

>> This is unfortunately a counter-example to the rule that HMP commands
>> should always be implemented in terms of their QMP counterparts.  I do
>> not believe this is really a problem.  It can be fixed later; for now, I
>> think "perfect is the enemy of good" applies.

I don't get why there's a counter-example.

The rules are

1. A QMP command handler (which needs to be of type int (*)(Monitor *,
const QDict *params, QObject **ret_data)) should be a thin wrapper
around a function with a type appropriate for C that contains all the
logic.  The wrapper merely translates.

2. HMP commands are to be built on top of these functions, not their
handler wrappers.

> Hey - I just realized that now that we have anonymous unions, we could
> theoretically extend QMP to allow a union between 'int' and 'string' -
> if an 'int' is passed, it is in bytes; if a 'string' is passed, then
> parse it the way HMP would (so the string "1G" would be equivalent to
> the raw int 1073741824).  But I don't know if it will help you (libvirt
> will still prefer to use raw ints in any QMP log you read off of libvirt
> interactions).

Please do not complicate QMP's wire format just to help humans deal with
it.  It's for machines.  We intentionally picked a machine-readable
syntax that is still readable and writable for humans (feature!), but
that's as far as we should go in supporting human use.

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-26 16:55         ` Igor Mammedov
@ 2013-11-27 14:35           ` Markus Armbruster
  2013-11-27 15:28             ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Markus Armbruster @ 2013-11-27 14:35 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: kwolf, peter.maydell, stefanha, mst, hutao, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

Igor Mammedov <imammedo@redhat.com> writes:

> On Tue, 26 Nov 2013 15:49:05 +0100
> Markus Armbruster <armbru@redhat.com> wrote:
>
>> Igor Mammedov <imammedo@redhat.com> writes:
>> 
>> > On Thu, 21 Nov 2013 11:12:43 +0100
>> > Markus Armbruster <armbru@redhat.com> wrote:
>> >
>> >> Igor Mammedov <imammedo@redhat.com> writes:
>> >> 
> [...]
>> Two separate issues here:
>> 
>> 1. The "no qemu_mem_opts have been specified" case
>> 
>>    This is equivalent to "empty options".  Therefore, the case can be
>>    eliminated by pre-creating empty options.  No objection.
>> 
>>    The three existing merge_lists users don't do that.  Perhaps they
>>    should.
>> 
>> 2. How to provide default values
>> 
>>    Supplying defaults is left to the caller of qemu_opt_get_FOO() by
>>    design.
>> 
>>    Pre-creating option parameters deviates from that pattern.  You
>>    justify it by saying it "eliminates need to pepper code with
>>    DEFAULT_RAM_SIZE * 1024 * 1024".  How many occurrences?
> beside of vl.c for:
>   mem & maxmem 1 in hw/i386/pc.c
>   slots - 6 in several files

Could the common code be factored out the old-fashioned way?

Precedence: qemu_get_machine_opts() encapsulates some QemuOpts-related
details, so its many users don't have to deal with them.

> see below for continuation:
>
>> 
>>    Drawback: you lose the ability to see whether the user gave a value.
>>    See below.
>> 
> [...]
>> >> Ugly.
>> >> 
>> >> Why is the variable called 'end'?
>> > would be 'suffix' better?
>> 
>> end points to the whole value string, not the end of anything, and
>> neither to a suffix of anything.
> Any suggestions?

What about val?

> [...]
>> >> If you refrain from putting defaults into opts, you can distinguish the
>> >> cases "user didn't specify maxmem, so assume mem", and "user specified
>> >> maxmem, so check it's >= mem".
>> > So foar, there is no point in distinguishing above cases,
>> > since maxmem <= mem is invalid value and hotplug should be disabled.
>> > So setting default maxmem to mem or anything less effectively
>> > disables hotplug.
>> 
>> Yes, setting maxmem < mem is invalid and should be rejected, but not
>> setting maxmem at all should be accepted even when you set mem.
>> 
>> Your patch like this pseudo-code:
>> 
>>     mem = DEFAULT_RAM_SIZE * 1024 * 1024
>>     maxmem = mem
>> 
>>     if user specifies mem:
>>         mem = user's mem
>>     if user specifes max-mem:
>>         mem = user's max-mem
>> 
>>     if max-mem < mem
>>         what now?
>>         should error our if max-mem and mem were specified by the user
>>         shouldn't if user didn't specify max-mem!
>>         but can't say whether he did
>> 
>> I'd do it this way:
>> 
>>     mem = unset
>>     maxmem = unset
>> 
>>     if user specifies mem:
>>         mem = user's mem
>>     if user specifes max-mem:
>>         mem = user's max-mem
>> 
>>     if mem != unset && max-mem != unset && max-mem < mem
>>         error
>>
>> I'd use QemuOpts for the user's command line, and no more.  For anything
>> beyond that, I'd use ordinary variables, such as ram_size.
> Ok, I'll revert to the old code where options users check for option
> availability, it's not that much code.
>
>
> As for using QemuOpts as global store for global variables:
>
>  * using local variables would require changing of machine init or/and
>    QEMUMachine and changing functions signature pass them down the stack to
>    consumers.

Extending QEMUMachineInitArgs should suffice.  Once you're inside the
board code, passing stuff around as C parameters is probably an
improvement over passing around QemuOpts.

>  * adding "slots" readonly property to i440fx & q35 for consumption in
>    ACPI hotplug code and building ACPI tables. It would be essentially another
>    global lookup for i440fx & q35  object and pulling "slots" property,
>    which is much longer way/complex way to get global value. That's a lot of
>    boilerplate code for the same outcome.

Can't say without seeing the code.

>  * about setting default for "mem" value: if default "mem" is not set and
>    no -m is provided on CLI, we get case where
>       ram_size = foo & "mem" unset  
>    And if I recall correctly there was an effort to provide interface for
>    currently used QemuOpts to external users. So "mem" would get inconsistent
>    with what QEMU uses.

QemuOpts do not record what QEMU uses.  They record what the user asked
for.

> To sum up above said:
>  * I'd like to continue using QemuOpts as global constant value store, it
>    saves from adding a lot of boilerplate-code that would do the same.

Keeping the user's configuration just in QemuOpts is fine.  What I don't
like is messing with it there.  This includes storing defaults.

Here's another reason: -writeconfig should write out exactly the user's
configuration.  If you mess with it, it may write out messed up
configuration, depending on *when* you mess with it.

>    Doing
>      "git grep qemu_get_machine_opts"
>    gets us several precedents that already use it that way.

Note that it does *not* store defaults in QemuOpts, it only creates
empty opts.  I'm not sure that was a good idea.

>  * I believe that setting default in QemuOpts for "mem" is a good thing that
>    leads to consistent meaning of "mem" with what QEMU actually uses.

I'm not sure I got this argument.

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-25 16:09       ` Paolo Bonzini
@ 2013-11-27 14:37         ` Igor Mammedov
  2013-11-27 15:21           ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27 14:37 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

On Mon, 25 Nov 2013 17:09:37 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 25/11/2013 17:01, Igor Mammedov ha scritto:
> >> > So this is why you need a new command-line option.
> >> > 
> >> > I think we need a generic mechanism for post-initialization of whatever
> >> > is given on the command line.  Perhaps you can do that with an
> >> > interface, and get rid of -memdev and memdev_add altogether?
> >> > 
> >> > MemoryBackend's implementation of the interface's sole method would call
> >> > get_memory, of course.
> > 
> > What I would use instead of memdev_add in CLI/HMP/QMP?
> 
> We could add a new object_add command.
> 
> > Could you explain it a bit more, please?
> 
> The interface would look like
> 
> struct QOMCommandLineIface {
>     void complete(Object *object, Error **errp);
>     Object *get_base_path(void);
> }
> 
> MemoryBackend could implement it like this:
> 
> void memory_backend_complete(Object *object, Error **errp)
> {
>     MemoryBackend *backend = MEMORY_BACKEND(object);
>     MemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(obj);
>     if (bc->get_memory) {
>         bc->get_memory(backend, errp);
>     }
> }
> 
> Object *memory_backend_get_base_path(void);
> {
>     return container_get(qdev_get_backend(), "/memdev"),
> }
> 
> A default implementation can be added to RNGBackend and TPMBackend.
> vl.c can use the interface like this in object_create:
> 
>     obj = object_new(type);
>     QOMCommandLineIface *cmdline_iface;
> 
>     if (IS_QOM_COMMAND_LINE(obj)) {
>         object_unref(obj);
>         error...
>         return -1;
>     }
> 
>     if (qemu_opt_foreach(opts, object_set_property, obj, 1) < 0) {
>         object_unref(obj);
>         return -1;
>     }
> 
>     cmdline_iface = QOM_COMMAND_LINE_GET_IFACE(obj);
>     cmdline_iface->complete(obj, &local_err);
>     if (local_err)) {
>         error_propagate(...)
>         object_unref(obj);
>         return -1;
>     }
> 
>     object_property_add_child(cmdline_iface->get_base_path(),
>                               id, obj, NULL);
> 
> Then you can just use -object instead of -memdev.
It looks like "realize" for -object / object-add implemented via
an interface.

Maybe it should be renamed from QOMCommandLineIface to QOMRealizeIface
and s/complete/realize/ so anyone who knows about Device.realize would
get meaning without digging in complete() implementations.

Alternative would be to behave just like Rng/Tpm do, i.e. use -object
to do late initialization in a backend user (DimmDevice.realize).
Draw back of it would be user won't get error during the first command
"object-add" and only will get error when creating DimmDevice calling
"device_add".

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-27 14:15             ` Markus Armbruster
@ 2013-11-27 15:17               ` Paolo Bonzini
  2013-11-27 17:02                 ` Markus Armbruster
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-27 15:17 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: peter.maydell, aliguori, quintela, hutao, Michael S. Tsirkin,
	mjt, qemu-devel, mdroth, vasilis.liaskovitis, chegu_vinod,
	kraxel, stefanha, Igor Mammedov, stefanb, marcel.a, lcapitulino,
	afaerber

Il 27/11/2013 15:15, Markus Armbruster ha scritto:
>>> >> This is unfortunately a counter-example to the rule that HMP commands
>>> >> should always be implemented in terms of their QMP counterparts.  I do
>>> >> not believe this is really a problem.  It can be fixed later; for now, I
>>> >> think "perfect is the enemy of good" applies.
> I don't get why there's a counter-example.

Take as an example the current implementation of netdev_add.

void hmp_netdev_add(Monitor *mon, const QDict *qdict)
{
    ...
    QemuOpts *opts = qemu_opts_from_qdict(qemu_find_opts("netdev"), qdict, &err);
    netdev_add(opts, &err);
    ...
}

int qmp_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret)
{
    opts_list = qemu_find_opts_err("netdev", &local_err);
    opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
    netdev_add(opts, &local_err);
    ...
    return 0;

exit_err:
    ...
}

These obey the rules you have below (there's just the weirdness that the QMP
command handler is not autogenerated).

But as you see above, this is really the same code for both handlers,
they only differ in error handling minutiae.  This is possible with
netdev_add (and you could do the same for device_add) because the QMP
interface sucks and it is not well defined unless you make all values
strings (qemu_opts_from_dict tries to do something meaningful for integers
and floats, but given the existence of qdev property types such as hex32
I wouldn't trust it too much).

If we want a really different interface between HMP and QMP, one
human-oriented and the other JSON-oriented, I'm not sure that you can
share much code between the two implementation.

Paolo

> The rules are
> 
> 1. A QMP command handler (which needs to be of type int (*)(Monitor *,
> const QDict *params, QObject **ret_data)) should be a thin wrapper
> around a function with a type appropriate for C that contains all the
> logic.  The wrapper merely translates.
> 
> 2. HMP commands are to be built on top of these functions, not their
> handler wrappers.

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-27 14:37         ` Igor Mammedov
@ 2013-11-27 15:21           ` Paolo Bonzini
  2013-11-27 15:57             ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-27 15:21 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

Il 27/11/2013 15:37, Igor Mammedov ha scritto:
> It looks like "realize" for -object / object-add implemented via
> an interface.

It does---but without unrealize and with the additional get_base_path.

> Maybe it should be renamed from QOMCommandLineIface to QOMRealizeIface
> and s/complete/realize/ so anyone who knows about Device.realize would
> get meaning without digging in complete() implementations.

There is an important difference; realize is an internal method in
Device, the external interface is the property.  So perhaps it's the
other way round; if Device implements QOMCommandLineIface you could
start creating devices with -object.

> Alternative would be to behave just like Rng/Tpm do, i.e. use -object
> to do late initialization in a backend user (DimmDevice.realize).
> Draw back of it would be user won't get error during the first command
> "object-add" and only will get error when creating DimmDevice calling
> "device_add".

That's also a possibility.  But again, maybe it's the other way round
and Rng/Tpm could enjoy better error handling if we add the interface.

Paolo

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure Igor Mammedov
  2013-11-25 12:54   ` Paolo Bonzini
@ 2013-11-27 15:25   ` Eric Blake
  2013-11-27 16:09     ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Eric Blake @ 2013-11-27 15:25 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, stefanha, stefanb, hutao, mst, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

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

On 11/20/2013 07:38 PM, Igor Mammedov wrote:
> Provides framework for splitting host RAM allocation/
> policies into a separate backend that could be used
> by devices. It would allow to separate host specific
> options from device model like it's done for netdev & co.

Just an interface review:

> +++ b/hmp-commands.hx
> @@ -1719,3 +1719,16 @@ ETEXI
>  STEXI
>  @end table
>  ETEXI
> +
> +    {
> +        .name       = "memdev-add",

Typically, we've been naming HMP commands with underscore: memdev_add

> +++ b/qapi-schema.json
> @@ -4212,3 +4212,21 @@
>  # Since: 1.7
>  ##
>  { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
> +
> +##
> +# @memdev_add:

Whereas QMP commands have a dash: memdev-add

> +#
> +# Add a host memory backend.
> +#
> +# @id: the name of the new memory backend
> +# @size: amount of memory backend should allocate

Maybe add "in bytes" somewhere in the phrase to make it clear

> +# @type: backend type. [default: compat-ram-host-memory]

That's the default, but what other types are valid?  I'd much rather
have an enum of valid types than an open-coded string.

> +#
> +# Since: 1.8
> +#
> +# Returns: Nothing on success
> +##
> +{ 'command': 'memdev-add',

Ah, you did name the QMP command with dash, so it's the docs above that
are wrong.

> +  'data': {'id': 'str', 'size': 'size', '*type': 'str'},
> +  'gen': 'no'
> +}

> +Arguments:
> +
> +- "id": the device's ID, must be unique (json-string)
> +- "size": amount of memory backend should allocate (json-int)
> +- "type": backend type (json-string, optional), default: compat-ram-host-memory
> +
> +Example:
>  
> +-> { "execute": "memdev-add",
> +     "arguments": { "id": "memdev1",
> +                    "size": "1G",

I don't think this is valid QMP; you want to be passing sizes in bytes
as an integer, not as a string that requires further parsing.

-- 
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: 621 bytes --]

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-27 14:35           ` Markus Armbruster
@ 2013-11-27 15:28             ` Igor Mammedov
  2013-11-27 17:31               ` Markus Armbruster
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27 15:28 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: kwolf, peter.maydell, stefanha, mst, hutao, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	aliguori, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Wed, 27 Nov 2013 15:35:09 +0100
Markus Armbruster <armbru@redhat.com> wrote:

> Igor Mammedov <imammedo@redhat.com> writes:
> 
> > On Tue, 26 Nov 2013 15:49:05 +0100
> > Markus Armbruster <armbru@redhat.com> wrote:
> >
> >> Igor Mammedov <imammedo@redhat.com> writes:
> >> 
> >> > On Thu, 21 Nov 2013 11:12:43 +0100
> >> > Markus Armbruster <armbru@redhat.com> wrote:
> >> >
> >> >> Igor Mammedov <imammedo@redhat.com> writes:
> >> >> 
> > [...]
> >> Two separate issues here:
> >> 
> >> 1. The "no qemu_mem_opts have been specified" case
> >> 
> >>    This is equivalent to "empty options".  Therefore, the case can be
> >>    eliminated by pre-creating empty options.  No objection.
> >> 
> >>    The three existing merge_lists users don't do that.  Perhaps they
> >>    should.
> >> 
> >> 2. How to provide default values
> >> 
> >>    Supplying defaults is left to the caller of qemu_opt_get_FOO() by
> >>    design.
> >> 
> >>    Pre-creating option parameters deviates from that pattern.  You
> >>    justify it by saying it "eliminates need to pepper code with
> >>    DEFAULT_RAM_SIZE * 1024 * 1024".  How many occurrences?
> > beside of vl.c for:
> >   mem & maxmem 1 in hw/i386/pc.c
> >   slots - 6 in several files
> 
> Could the common code be factored out the old-fashioned way?
replacing one one-liner with another might help a little but
won't change a thing in general. It will be essentially the same.

> 
> Precedence: qemu_get_machine_opts() encapsulates some QemuOpts-related
> details, so its many users don't have to deal with them.
> 
> > see below for continuation:
> >
> >> 
> >>    Drawback: you lose the ability to see whether the user gave a value.
> >>    See below.
> >> 
> > [...]
> >> >> Ugly.
> >> >> 
> >> >> Why is the variable called 'end'?
> >> > would be 'suffix' better?
> >> 
> >> end points to the whole value string, not the end of anything, and
> >> neither to a suffix of anything.
> > Any suggestions?
> 
> What about val?
I've replaced it with "mem_str" see
"[PATCH 04/28] vl: convert -m to QemuOpts"

> 
> > [...]
> >> >> If you refrain from putting defaults into opts, you can distinguish the
> >> >> cases "user didn't specify maxmem, so assume mem", and "user specified
> >> >> maxmem, so check it's >= mem".
> >> > So foar, there is no point in distinguishing above cases,
> >> > since maxmem <= mem is invalid value and hotplug should be disabled.
> >> > So setting default maxmem to mem or anything less effectively
> >> > disables hotplug.
> >> 
> >> Yes, setting maxmem < mem is invalid and should be rejected, but not
> >> setting maxmem at all should be accepted even when you set mem.
> >> 
> >> Your patch like this pseudo-code:
> >> 
> >>     mem = DEFAULT_RAM_SIZE * 1024 * 1024
> >>     maxmem = mem
> >> 
> >>     if user specifies mem:
> >>         mem = user's mem
> >>     if user specifes max-mem:
> >>         mem = user's max-mem
> >> 
> >>     if max-mem < mem
> >>         what now?
> >>         should error our if max-mem and mem were specified by the user
> >>         shouldn't if user didn't specify max-mem!
> >>         but can't say whether he did
> >> 
> >> I'd do it this way:
> >> 
> >>     mem = unset
> >>     maxmem = unset
> >> 
> >>     if user specifies mem:
> >>         mem = user's mem
> >>     if user specifes max-mem:
> >>         mem = user's max-mem
> >> 
> >>     if mem != unset && max-mem != unset && max-mem < mem
> >>         error
> >>
> >> I'd use QemuOpts for the user's command line, and no more.  For anything
> >> beyond that, I'd use ordinary variables, such as ram_size.
> > Ok, I'll revert to the old code where options users check for option
> > availability, it's not that much code.
> >
> >
> > As for using QemuOpts as global store for global variables:
> >
> >  * using local variables would require changing of machine init or/and
> >    QEMUMachine and changing functions signature pass them down the stack to
> >    consumers.
> 
> Extending QEMUMachineInitArgs should suffice.  Once you're inside the
> board code, passing stuff around as C parameters is probably an
> improvement over passing around QemuOpts.
> 
> >  * adding "slots" readonly property to i440fx & q35 for consumption in
> >    ACPI hotplug code and building ACPI tables. It would be essentially another
> >    global lookup for i440fx & q35  object and pulling "slots" property,
> >    which is much longer way/complex way to get global value. That's a lot of
> >    boilerplate code for the same outcome.
> 
> Can't say without seeing the code.
> 
> >  * about setting default for "mem" value: if default "mem" is not set and
> >    no -m is provided on CLI, we get case where
> >       ram_size = foo & "mem" unset  
> >    And if I recall correctly there was an effort to provide interface for
> >    currently used QemuOpts to external users. So "mem" would get inconsistent
> >    with what QEMU uses.
> 
> QemuOpts do not record what QEMU uses.  They record what the user asked
> for.
> 
> > To sum up above said:
> >  * I'd like to continue using QemuOpts as global constant value store, it
> >    saves from adding a lot of boilerplate-code that would do the same.
> 
> Keeping the user's configuration just in QemuOpts is fine.  What I don't
> like is messing with it there.  This includes storing defaults.
> 
> Here's another reason: -writeconfig should write out exactly the user's
> configuration.  If you mess with it, it may write out messed up
> configuration, depending on *when* you mess with it.
> 
> >    Doing
> >      "git grep qemu_get_machine_opts"
> >    gets us several precedents that already use it that way.
> 
> Note that it does *not* store defaults in QemuOpts, it only creates
> empty opts.  I'm not sure that was a good idea.
I've dropped completely defaults setting in QemuOpts please see:
 "[PATCH 04/28] vl: convert -m to QemuOpts"
 "[PATCH 05/28] vl.c: extend -m option to support options for memory hotplug"

As for ">it only creates empty opts." I'm confused.
qemu_opt_get(qemu_get_machine_opts(), "foo")  pattern showed by grep  is the same
as I use to get "slots/maxmem":

exec.c:    if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
hw/arm/boot.c:    info->dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
hw/ppc/spapr.c:    const char *drivename = qemu_opt_get(qemu_get_machine_opts(), "nvram");
hw/ppc/virtex_ml507.c:    dtb_filename = qemu_opt_get(qemu_get_machine_opts(), "dtb");
include/sysemu/sysemu.h:QemuOpts *qemu_get_machine_opts(void);
kvm-all.c:    if (!qemu_opt_get_bool(qemu_get_machine_opts(), "kernel_irqchip", true) ||
target-i386/kvm.c:    shadow_mem = qemu_opt_get_size(qemu_get_machine_opts(),

probably it is there because passing them as C parameters is more intrusive than 
just using user supplied values directly.

> >  * I believe that setting default in QemuOpts for "mem" is a good thing that
> >    leads to consistent meaning of "mem" with what QEMU actually uses.
> 
> I'm not sure I got this argument.
I can easily drop this hunk from "[PATCH 04/28] vl: convert -m to QemuOpts",
I've posted tonight as reply to this thread,
since ram_size is already passed to machine_init(), it's not worth arguing.

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-27 15:21           ` Paolo Bonzini
@ 2013-11-27 15:57             ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27 15:57 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, mdroth, mst, mjt, stefanb, stefanha, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, hutao, marcel.a, lcapitulino, afaerber

On Wed, 27 Nov 2013 16:21:23 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 27/11/2013 15:37, Igor Mammedov ha scritto:
> > It looks like "realize" for -object / object-add implemented via
> > an interface.
> 
> It does---but without unrealize and with the additional get_base_path.
> 
> > Maybe it should be renamed from QOMCommandLineIface to QOMRealizeIface
> > and s/complete/realize/ so anyone who knows about Device.realize would
> > get meaning without digging in complete() implementations.
> 
> There is an important difference; realize is an internal method in
> Device, the external interface is the property.  So perhaps it's the
> other way round; if Device implements QOMCommandLineIface you could
> start creating devices with -object.
> 
> > Alternative would be to behave just like Rng/Tpm do, i.e. use -object
> > to do late initialization in a backend user (DimmDevice.realize).
> > Draw back of it would be user won't get error during the first command
> > "object-add" and only will get error when creating DimmDevice calling
> > "device_add".
> 
> That's also a possibility.  But again, maybe it's the other way round
> and Rng/Tpm could enjoy better error handling if we add the interface.

Sure, I'll try to do as you described, it's much better to get error
earlier and from command/object that throws it than via proxy.

Thanks for suggestion, looking at netdev-add I even haven't thought
about using -object.

> Paolo

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

* Re: [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure
  2013-11-27 15:25   ` Eric Blake
@ 2013-11-27 16:09     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-11-27 16:09 UTC (permalink / raw)
  To: Eric Blake
  Cc: peter.maydell, stefanha, mst, qemu-devel, hutao, stefanb, mjt,
	mdroth, armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

On Wed, 27 Nov 2013 08:25:22 -0700
Eric Blake <eblake@redhat.com> wrote:

> On 11/20/2013 07:38 PM, Igor Mammedov wrote:
> > Provides framework for splitting host RAM allocation/
> > policies into a separate backend that could be used
> > by devices. It would allow to separate host specific
> > options from device model like it's done for netdev & co.
> 
> Just an interface review:
> 
> > +++ b/hmp-commands.hx
> > @@ -1719,3 +1719,16 @@ ETEXI
> >  STEXI
> >  @end table
> >  ETEXI
> > +
> > +    {
> > +        .name       = "memdev-add",
> 
> Typically, we've been naming HMP commands with underscore: memdev_add
there is several DASH command in HMP and I thought we stopped to
do UNDERSCORE and that DASH is preffered way now.

> 
> > +++ b/qapi-schema.json
> > @@ -4212,3 +4212,21 @@
> >  # Since: 1.7
> >  ##
> >  { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
> > +
> > +##
> > +# @memdev_add:
> 
> Whereas QMP commands have a dash: memdev-add
I'll fix it.

> 
> > +#
> > +# Add a host memory backend.
> > +#
> > +# @id: the name of the new memory backend
> > +# @size: amount of memory backend should allocate
> 
> Maybe add "in bytes" somewhere in the phrase to make it clear
Sure 
> 
> > +# @type: backend type. [default: compat-ram-host-memory]
> 
> That's the default, but what other types are valid?  I'd much rather
> have an enum of valid types than an open-coded string.
there is only one so far, I plan to add additional hugepage backend later.

> 
> > +#
> > +# Since: 1.8
> > +#
> > +# Returns: Nothing on success
> > +##
> > +{ 'command': 'memdev-add',
> 
> Ah, you did name the QMP command with dash, so it's the docs above that
> are wrong.
> 
> > +  'data': {'id': 'str', 'size': 'size', '*type': 'str'},
> > +  'gen': 'no'
> > +}
> 
> > +Arguments:
> > +
> > +- "id": the device's ID, must be unique (json-string)
> > +- "size": amount of memory backend should allocate (json-int)
> > +- "type": backend type (json-string, optional), default: compat-ram-host-memory
> > +
> > +Example:
> >  
> > +-> { "execute": "memdev-add",
> > +     "arguments": { "id": "memdev1",
> > +                    "size": "1G",
> 
> I don't think this is valid QMP; you want to be passing sizes in bytes
> as an integer, not as a string that requires further parsing.
I'll amend it.

Thanks!

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-27 15:17               ` Paolo Bonzini
@ 2013-11-27 17:02                 ` Markus Armbruster
  2013-11-27 17:10                   ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Markus Armbruster @ 2013-11-27 17:02 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, stefanha, Michael S. Tsirkin, hutao, quintela,
	mjt, qemu-devel, stefanb, mdroth, vasilis.liaskovitis, kraxel,
	aliguori, Igor Mammedov, marcel.a, lcapitulino, chegu_vinod,
	afaerber

Paolo Bonzini <pbonzini@redhat.com> writes:

> Il 27/11/2013 15:15, Markus Armbruster ha scritto:
>>>> >> This is unfortunately a counter-example to the rule that HMP commands
>>>> >> should always be implemented in terms of their QMP counterparts.  I do
>>>> >> not believe this is really a problem.  It can be fixed later; for now, I
>>>> >> think "perfect is the enemy of good" applies.
>> I don't get why there's a counter-example.
>
> Take as an example the current implementation of netdev_add.
>
> void hmp_netdev_add(Monitor *mon, const QDict *qdict)
> {
>     ...
>     QemuOpts *opts = qemu_opts_from_qdict(qemu_find_opts("netdev"),
> qdict, &err);
>     netdev_add(opts, &err);
>     ...
> }
>
> int qmp_netdev_add(Monitor *mon, const QDict *qdict, QObject **ret)
> {
>     opts_list = qemu_find_opts_err("netdev", &local_err);
>     opts = qemu_opts_from_qdict(opts_list, qdict, &local_err);
>     netdev_add(opts, &local_err);
>     ...
>     return 0;
>
> exit_err:
>     ...
> }
>
> These obey the rules you have below (there's just the weirdness that the QMP
> command handler is not autogenerated).
>
> But as you see above, this is really the same code for both handlers,
> they only differ in error handling minutiae.  This is possible with
> netdev_add (and you could do the same for device_add) because the QMP
> interface sucks and it is not well defined unless you make all values
> strings (qemu_opts_from_dict tries to do something meaningful for integers
> and floats, but given the existence of qdev property types such as hex32
> I wouldn't trust it too much).

netdev_add is a problematic example, because its a horrible, horrbible
QMP command.  I may say that, because I committed the crime :)

hmp_netdev_add() is the HMP command handler, and qmp_netdev_add() is the
QMP command handler.

Their error handling differs only because the former still implements
the legacy handler interface.

HMP's netdev_add parses arguments into a QemuOpts, exactly like -netdev.

I have to admit I can't tell offhand what the heck QMP's netdev_add
accepts, because I don't understand what "'*props:': '**'" means in
qapi-schema.json.  Even today, we permit code to serve as documentation
and specification for new features.  I wish we didn't.

Anyway, whatever it parses ends up in a QDict, as usual.

The part that sucks is the use of QemuOpts as netdev_add() parameter,

It made some sense when it was done, because then the command line was
the only user, its data type for option parameters was (and is)
QemuOpts, and QemuOpts was the least inconvenient way to do a function
that wants a a discriminated union of parameters, like netdev_add does.

It stopped making sense when we started using it from QMP, whose data
type for parameters is QDict.  I shoehorned netdev_add into QMP in its
early days.  Hinsight 20/20...

In my opinion, use of QemuOpts for anything but parsing parameter
strings has become a mistake.

Laszlo converted net.c to saner internal interfaces (commit
d195325..1a0c095).  Perhaps we can build on that.

> If we want a really different interface between HMP and QMP, one
> human-oriented and the other JSON-oriented, I'm not sure that you can
> share much code between the two implementation.

You should be able to share everything but the QMP marshalling, and the
HMP parsing and printing.

> Paolo
>
>> The rules are
>> 
>> 1. A QMP command handler (which needs to be of type int (*)(Monitor *,
>> const QDict *params, QObject **ret_data)) should be a thin wrapper
>> around a function with a type appropriate for C that contains all the
>> logic.  The wrapper merely translates.
>> 
>> 2. HMP commands are to be built on top of these functions, not their
>> handler wrappers.

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-27 17:02                 ` Markus Armbruster
@ 2013-11-27 17:10                   ` Paolo Bonzini
  0 siblings, 0 replies; 143+ messages in thread
From: Paolo Bonzini @ 2013-11-27 17:10 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: peter.maydell, stefanha, Michael S. Tsirkin, hutao, quintela,
	mjt, qemu-devel, stefanb, mdroth, vasilis.liaskovitis, kraxel,
	aliguori, Igor Mammedov, marcel.a, lcapitulino, chegu_vinod,
	afaerber

Il 27/11/2013 18:02, Markus Armbruster ha scritto:
> I have to admit I can't tell offhand what the heck QMP's netdev_add
> accepts, because I don't understand what "'*props:': '**'" means in
> qapi-schema.json.  Even today, we permit code to serve as documentation
> and specification for new features.  I wish we didn't.

It is ignored, because qmp_netdev_add does not use an
automatically-generated unmarshaler.

> Anyway, whatever it parses ends up in a QDict, as usual.

The QDict comes straight from the monitor dispatch.  It is the QDict
that ordinarily would be unmarshaled by automatically-generated code.

> The part that sucks is the use of QemuOpts as netdev_add() parameter,
> 
> It made some sense when it was done, because then the command line was
> the only user, its data type for option parameters was (and is)
> QemuOpts, and QemuOpts was the least inconvenient way to do a function
> that wants a a discriminated union of parameters, like netdev_add does.
> 
> It stopped making sense when we started using it from QMP, whose data
> type for parameters is QDict.  I shoehorned netdev_add into QMP in its
> early days.  Hinsight 20/20...

Yes.

> In my opinion, use of QemuOpts for anything but parsing parameter
> strings has become a mistake.

Yes.  OTOH QemuOpts is the only reason why QMP and HMP can use a common
back-end (netdev_add).  With object-add you don't use QemuOpts (for good
reasons: you want to separate the human-oriented parsing and the
JSON-oriented parsing) and thus you need separate code for QMP and
HMP---at least for now.

The HMP code can use QemuOpts just like vl.c.  The QMP code would use
qdict_iter or qdict_first/next and call object_set_property for each
element of the dictionary.

> Laszlo converted net.c to saner internal interfaces (commit
> d195325..1a0c095).  Perhaps we can build on that.

Yeah, that could be an idea.  Another is to convert netdevs to QOM
(reusing Laszlo's data structures of course) and then just use
object-add and -object.

Paolo

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

* Re: [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse()
  2013-11-27 15:28             ` Igor Mammedov
@ 2013-11-27 17:31               ` Markus Armbruster
  0 siblings, 0 replies; 143+ messages in thread
From: Markus Armbruster @ 2013-11-27 17:31 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: kwolf, peter.maydell, aliguori, stefanb, hutao, mst, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

Igor Mammedov <imammedo@redhat.com> writes:

> On Wed, 27 Nov 2013 15:35:09 +0100
> Markus Armbruster <armbru@redhat.com> wrote:
>
>> Igor Mammedov <imammedo@redhat.com> writes:
>> 
>> > On Tue, 26 Nov 2013 15:49:05 +0100
>> > Markus Armbruster <armbru@redhat.com> wrote:
>> >
>> >> Igor Mammedov <imammedo@redhat.com> writes:
>> >> 
>> >> > On Thu, 21 Nov 2013 11:12:43 +0100
>> >> > Markus Armbruster <armbru@redhat.com> wrote:
>> >> >
>> >> >> Igor Mammedov <imammedo@redhat.com> writes:
>> >> >> 
>> > [...]
>> >> Two separate issues here:
>> >> 
>> >> 1. The "no qemu_mem_opts have been specified" case
>> >> 
>> >>    This is equivalent to "empty options".  Therefore, the case can be
>> >>    eliminated by pre-creating empty options.  No objection.
>> >> 
>> >>    The three existing merge_lists users don't do that.  Perhaps they
>> >>    should.
>> >> 
>> >> 2. How to provide default values
>> >> 
>> >>    Supplying defaults is left to the caller of qemu_opt_get_FOO() by
>> >>    design.
>> >> 
>> >>    Pre-creating option parameters deviates from that pattern.  You
>> >>    justify it by saying it "eliminates need to pepper code with
>> >>    DEFAULT_RAM_SIZE * 1024 * 1024".  How many occurrences?
>> > beside of vl.c for:
>> >   mem & maxmem 1 in hw/i386/pc.c
>> >   slots - 6 in several files
>> 
>> Could the common code be factored out the old-fashioned way?
> replacing one one-liner with another might help a little but
> won't change a thing in general. It will be essentially the same.

Need to review your latest to have an opinion here :)

>> Precedence: qemu_get_machine_opts() encapsulates some QemuOpts-related
>> details, so its many users don't have to deal with them.
>> 
>> > see below for continuation:
>> >
>> >> 
>> >>    Drawback: you lose the ability to see whether the user gave a value.
>> >>    See below.
>> >> 
>> > [...]
>> >> >> Ugly.
>> >> >> 
>> >> >> Why is the variable called 'end'?
>> >> > would be 'suffix' better?
>> >> 
>> >> end points to the whole value string, not the end of anything, and
>> >> neither to a suffix of anything.
>> > Any suggestions?
>> 
>> What about val?
> I've replaced it with "mem_str" see
> "[PATCH 04/28] vl: convert -m to QemuOpts"

Works for me.

>> > [...]
>> >> >> If you refrain from putting defaults into opts, you can distinguish the
>> >> >> cases "user didn't specify maxmem, so assume mem", and "user specified
>> >> >> maxmem, so check it's >= mem".
>> >> > So foar, there is no point in distinguishing above cases,
>> >> > since maxmem <= mem is invalid value and hotplug should be disabled.
>> >> > So setting default maxmem to mem or anything less effectively
>> >> > disables hotplug.
>> >> 
>> >> Yes, setting maxmem < mem is invalid and should be rejected, but not
>> >> setting maxmem at all should be accepted even when you set mem.
>> >> 
>> >> Your patch like this pseudo-code:
>> >> 
>> >>     mem = DEFAULT_RAM_SIZE * 1024 * 1024
>> >>     maxmem = mem
>> >> 
>> >>     if user specifies mem:
>> >>         mem = user's mem
>> >>     if user specifes max-mem:
>> >>         mem = user's max-mem
>> >> 
>> >>     if max-mem < mem
>> >>         what now?
>> >>         should error our if max-mem and mem were specified by the user
>> >>         shouldn't if user didn't specify max-mem!
>> >>         but can't say whether he did
>> >> 
>> >> I'd do it this way:
>> >> 
>> >>     mem = unset
>> >>     maxmem = unset
>> >> 
>> >>     if user specifies mem:
>> >>         mem = user's mem
>> >>     if user specifes max-mem:
>> >>         mem = user's max-mem
>> >> 
>> >>     if mem != unset && max-mem != unset && max-mem < mem
>> >>         error
>> >>
>> >> I'd use QemuOpts for the user's command line, and no more.  For anything
>> >> beyond that, I'd use ordinary variables, such as ram_size.
>> > Ok, I'll revert to the old code where options users check for option
>> > availability, it's not that much code.
>> >
>> >
>> > As for using QemuOpts as global store for global variables:
>> >
>> >  * using local variables would require changing of machine init or/and
>> >    QEMUMachine and changing functions signature pass them down the stack to
>> >    consumers.
>> 
>> Extending QEMUMachineInitArgs should suffice.  Once you're inside the
>> board code, passing stuff around as C parameters is probably an
>> improvement over passing around QemuOpts.
>> 
>> >  * adding "slots" readonly property to i440fx & q35 for consumption in
>> >    ACPI hotplug code and building ACPI tables. It would be
>> > essentially another
>> >    global lookup for i440fx & q35  object and pulling "slots" property,
>> >    which is much longer way/complex way to get global value. That's a lot of
>> >    boilerplate code for the same outcome.
>> 
>> Can't say without seeing the code.
>> 
>> >  * about setting default for "mem" value: if default "mem" is not set and
>> >    no -m is provided on CLI, we get case where
>> >       ram_size = foo & "mem" unset  
>> >    And if I recall correctly there was an effort to provide interface for
>> >    currently used QemuOpts to external users. So "mem" would get inconsistent
>> >    with what QEMU uses.
>> 
>> QemuOpts do not record what QEMU uses.  They record what the user asked
>> for.
>> 
>> > To sum up above said:
>> >  * I'd like to continue using QemuOpts as global constant value store, it
>> >    saves from adding a lot of boilerplate-code that would do the same.
>> 
>> Keeping the user's configuration just in QemuOpts is fine.  What I don't
>> like is messing with it there.  This includes storing defaults.
>> 
>> Here's another reason: -writeconfig should write out exactly the user's
>> configuration.  If you mess with it, it may write out messed up
>> configuration, depending on *when* you mess with it.
>> 
>> >    Doing
>> >      "git grep qemu_get_machine_opts"
>> >    gets us several precedents that already use it that way.
>> 
>> Note that it does *not* store defaults in QemuOpts, it only creates
>> empty opts.  I'm not sure that was a good idea.
> I've dropped completely defaults setting in QemuOpts please see:
>  "[PATCH 04/28] vl: convert -m to QemuOpts"
>  "[PATCH 05/28] vl.c: extend -m option to support options for memory hotplug"
>
> As for ">it only creates empty opts." I'm confused.
> qemu_opt_get(qemu_get_machine_opts(), "foo") pattern showed by grep is
> the same
> as I use to get "slots/maxmem":
>
> exec.c:    if (!qemu_opt_get_bool(qemu_get_machine_opts(), "mem-merge", true)) {
> hw/arm/boot.c: info->dtb_filename =
> qemu_opt_get(qemu_get_machine_opts(), "dtb");
> hw/ppc/spapr.c: const char *drivename =
> qemu_opt_get(qemu_get_machine_opts(), "nvram");
> hw/ppc/virtex_ml507.c: dtb_filename =
> qemu_opt_get(qemu_get_machine_opts(), "dtb");
> include/sysemu/sysemu.h:QemuOpts *qemu_get_machine_opts(void);
> kvm-all.c: if (!qemu_opt_get_bool(qemu_get_machine_opts(),
> "kernel_irqchip", true) ||
> target-i386/kvm.c:    shadow_mem = qemu_opt_get_size(qemu_get_machine_opts(),
>
> probably it is there because passing them as C parameters is more
> intrusive than
> just using user supplied values directly.

qemu_get_machine_opts() is precedent for factoring out common
opts-querying code.

It has one aspect that may have been a bad idea: it creates empty
machine opts when the user didn't specify any option creating machine
opts.

Hope this unconfuses you.  If not, I guess we should just move on to
discussing your revised patch :)

>> >  * I believe that setting default in QemuOpts for "mem" is a good thing that
>> >    leads to consistent meaning of "mem" with what QEMU actually uses.
>> 
>> I'm not sure I got this argument.
> I can easily drop this hunk from "[PATCH 04/28] vl: convert -m to QemuOpts",
> I've posted tonight as reply to this thread,
> since ram_size is already passed to machine_init(), it's not worth arguing.

Okay.

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

* Re: [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
  2013-11-21  9:42   ` Michael S. Tsirkin
@ 2013-11-27 17:59   ` Eric Blake
  1 sibling, 0 replies; 143+ messages in thread
From: Eric Blake @ 2013-11-27 17:59 UTC (permalink / raw)
  To: Igor Mammedov, qemu-devel
  Cc: peter.maydell, stefanha, stefanb, hutao, mst, mjt, mdroth,
	armbru, vasilis.liaskovitis, quintela, kraxel, aliguori,
	pbonzini, marcel.a, lcapitulino, chegu_vinod, afaerber

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

On 11/20/2013 07:38 PM, 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
> 
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> ---

> +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
> +      [0x14] highest memory hot-plug interface version supported by QEMU

Nothing about [0x10-0x13]? [Ah, I see you mention it later]

> +      [0x15] Memory device status fields
> +          bits:
> +              1: device is enabled and may be used by guest
> +              2: device insert event, used by ACPI BIOS to distinguish
> +                 device for which no device check event to OSPM was issued

Why start at bit 1 instead of bit 0?  Also, should you document that
remaining bits (2-7) should be ignored on read?

> +      [0x16-0x17] reserved
> +
> +  write access:
> +      [0x0-0x3] Memory device slot selector, selects active memory device.
> +                All following accesses to other registers in 0xaf80-0xaf97
> +                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
> +      [0x15] Memory device status fields

Nothing about behavior of [0xc-0x14]?  Is it an error to write there, or
are the writes just ignored, or...?

> +          bits:
> +              2: if set to 1 clears device insert event, set by ACPI BIOS
> +                 after it has sent device check event to OSPM for
> +                 seleted memory device

s/seleted/selected/

What must be written into the other bits?  Must reserved bits be written
as 0, or the user do a read-modify-write, or...?

> +
> +Selecting memory device slot beyond present range has no effect on platform:
> +   - not documented above write accesses to memory hot-plug registers
> +     are ignored;

Reads awkwardly.  Better is:

write accesses to memory hot-plug registers not documented above are ignored

> +   - not documented above read accesses to memory hot-plug registers return 0xFF

Similar awkward wording.

> +    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;

This wasn't documented.

> +    case 0x14: /* intf version */
> +        val = 1;
> +        break;
> +    case 0x15: /* pack and return is_* fields */
> +        val |= mdev->is_enabled   ? 1 : 0;
> +        val |= mdev->is_inserting ? 2 : 0;

This is bit 0 and 1, not bit 1 and 2.

-- 
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: 621 bytes --]

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

* Re: [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core Igor Mammedov
@ 2013-12-05 12:37   ` Michael S. Tsirkin
  2013-12-05 15:11     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-12-05 12:37 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:22AM +0100, Igor Mammedov wrote:
> Signed-off-by: Igor Mammedov <imammedo@redhat.com>

Sorry doesn't apply.
Can you rebase on top of latest tree please?

> ---
> perhaps this patch sholud go before "piix4: add acpi pci hotplug support"
> so that there were no need in this rename in piix4_acpi_pci_hotplug()
> here.
> 
> s/pm_update_sci/acpi_update_sci/
> ---
>  hw/acpi/core.c         |   18 ++++++++++++++++++
>  hw/acpi/ich9.c         |   23 ++---------------------
>  hw/acpi/piix4.c        |   34 ++++++++++------------------------
>  include/hw/acpi/acpi.h |    8 ++++++++
>  4 files changed, 38 insertions(+), 45 deletions(-)
> 
> diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> index 58308a3..8c0d48c 100644
> --- a/hw/acpi/core.c
> +++ b/hw/acpi/core.c
> @@ -662,3 +662,21 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
>  
>      return val;
>  }
> +
> +void acpi_update_sci(ACPIREGS *regs, qemu_irq irq, uint32_t gpe0_sts_mask)
> +{
> +    int sci_level, pm1a_sts;
> +
> +    pm1a_sts = acpi_pm1_evt_get_sts(regs);
> +
> +    sci_level = ((pm1a_sts &
> +                  regs->pm1.evt.en & ACPI_BITMASK_PM1_COMMON_ENABLED) != 0) ||
> +                ((regs->gpe.sts[0] & regs->gpe.en[0] & gpe0_sts_mask) != 0);
> +
> +    qemu_set_irq(irq, sci_level);
> +
> +    /* schedule a timer interruption if needed */
> +    acpi_pm_tmr_update(regs,
> +                       (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> +                       !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
> +}
> diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> index 7e0429e..e59688b 100644
> --- a/hw/acpi/ich9.c
> +++ b/hw/acpi/ich9.c
> @@ -44,29 +44,10 @@ do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0)
>  #define ICH9_DEBUG(fmt, ...)    do { } while (0)
>  #endif
>  
> -static void pm_update_sci(ICH9LPCPMRegs *pm)
> -{
> -    int sci_level, pm1a_sts;
> -
> -    pm1a_sts = acpi_pm1_evt_get_sts(&pm->acpi_regs);
> -
> -    sci_level = (((pm1a_sts & pm->acpi_regs.pm1.evt.en) &
> -                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
> -                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
> -                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
> -                   ACPI_BITMASK_TIMER_ENABLE)) != 0);
> -    qemu_set_irq(pm->irq, sci_level);
> -
> -    /* schedule a timer interruption if needed */
> -    acpi_pm_tmr_update(&pm->acpi_regs,
> -                       (pm->acpi_regs.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> -                       !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
> -}
> -
>  static void ich9_pm_update_sci_fn(ACPIREGS *regs)
>  {
>      ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs);
> -    pm_update_sci(pm);
> +    acpi_update_sci(&pm->acpi_regs, pm->irq, 0);
>  }
>  
>  static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width)
> @@ -193,7 +174,7 @@ static void pm_reset(void *opaque)
>          pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
>      }
>  
> -    pm_update_sci(pm);
> +    acpi_update_sci(&pm->acpi_regs, pm->irq, 0);
>  }
>  
>  static void pm_powerdown_req(Notifier *n, void *opaque)
> diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> index 0be385e..b6dfa71 100644
> --- a/hw/acpi/piix4.c
> +++ b/hw/acpi/piix4.c
> @@ -117,29 +117,11 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
>  #define ACPI_ENABLE 0xf1
>  #define ACPI_DISABLE 0xf0
>  
> -static void pm_update_sci(PIIX4PMState *s)
> -{
> -    int sci_level, pmsts;
> -
> -    pmsts = acpi_pm1_evt_get_sts(&s->ar);
> -    sci_level = (((pmsts & s->ar.pm1.evt.en) &
> -                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
> -                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
> -                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
> -                   ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
> -        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) &
> -          (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS)) != 0);
> -
> -    qemu_set_irq(s->irq, sci_level);
> -    /* schedule a timer interruption if needed */
> -    acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> -                       !(pmsts & ACPI_BITMASK_TIMER_STATUS));
> -}
> -
>  static void pm_tmr_timer(ACPIREGS *ar)
>  {
>      PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
> -    pm_update_sci(s);
> +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> +                    PIIX4_CPU_HOTPLUG_STATUS);
>  }
>  
>  static void apm_ctrl_changed(uint32_t val, void *arg)
> @@ -429,7 +411,8 @@ static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev,
>      }
>      s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
>  
> -    pm_update_sci(s);
> +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> +                    PIIX4_CPU_HOTPLUG_STATUS);
>      return 0;
>  }
>  
> @@ -629,7 +612,8 @@ static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
>      PIIX4PMState *s = opaque;
>  
>      acpi_gpe_ioport_writeb(&s->ar, addr, val);
> -    pm_update_sci(s);
> +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> +                    PIIX4_CPU_HOTPLUG_STATUS);
>  
>      PIIX4_DPRINTF("gpe write %" HWADDR_PRIx " <== %" PRIu64 "\n", addr, val);
>  }
> @@ -745,7 +729,8 @@ static void piix4_cpu_hotplug_req(PIIX4PMState *s, CPUState *cpu,
>      } else {
>          g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
>      }
> -    pm_update_sci(s);
> +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> +                    PIIX4_CPU_HOTPLUG_STATUS);
>  }
>  
>  static void piix4_cpu_added_req(Notifier *n, void *opaque)
> @@ -823,7 +808,8 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
>          disable_device(s, slot);
>      }
>  
> -    pm_update_sci(s);
> +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> +                    PIIX4_CPU_HOTPLUG_STATUS);
>  
>      return 0;
>  }
> diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> index 6bbcb17..c4ae7d7 100644
> --- a/include/hw/acpi/acpi.h
> +++ b/include/hw/acpi/acpi.h
> @@ -69,6 +69,12 @@
>  #define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
>  #define ACPI_BITMASK_PCIEXP_WAKE_DISABLE        0x4000	/* ACPI 3.0 */
>  
> +#define ACPI_BITMASK_PM1_COMMON_ENABLED         ( \
> +        ACPI_BITMASK_RT_CLOCK_ENABLE        | \
> +        ACPI_BITMASK_POWER_BUTTON_ENABLE    | \
> +        ACPI_BITMASK_GLOBAL_LOCK_ENABLE     | \
> +        ACPI_BITMASK_TIMER_ENABLE)
> +
>  /* PM1x_CNT */
>  #define ACPI_BITMASK_SCI_ENABLE                 0x0001
>  #define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
> @@ -160,6 +166,8 @@ void acpi_gpe_reset(ACPIREGS *ar);
>  void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
>  uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
>  
> +void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
> +
>  /* acpi.c */
>  extern int acpi_enabled;
>  extern char unsigned *acpi_tables;
> -- 
> 1.7.1

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

* Re: [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core
  2013-12-05 12:37   ` Michael S. Tsirkin
@ 2013-12-05 15:11     ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-12-05 15:11 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, marcel.a, armbru, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, hutao, pbonzini, lcapitulino, chegu_vinod, afaerber

On Thu, 5 Dec 2013 14:37:01 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:38:22AM +0100, Igor Mammedov wrote:
> > Signed-off-by: Igor Mammedov <imammedo@redhat.com>
> 
> Sorry doesn't apply.
> Can you rebase on top of latest tree please?
I just tried to rebase on top of updated pci tree.
There were no conflicts in this patch and it applied cleanly :/

> 
> > ---
> > perhaps this patch sholud go before "piix4: add acpi pci hotplug support"
> > so that there were no need in this rename in piix4_acpi_pci_hotplug()
> > here.
> > 
> > s/pm_update_sci/acpi_update_sci/
> > ---
> >  hw/acpi/core.c         |   18 ++++++++++++++++++
> >  hw/acpi/ich9.c         |   23 ++---------------------
> >  hw/acpi/piix4.c        |   34 ++++++++++------------------------
> >  include/hw/acpi/acpi.h |    8 ++++++++
> >  4 files changed, 38 insertions(+), 45 deletions(-)
> > 
> > diff --git a/hw/acpi/core.c b/hw/acpi/core.c
> > index 58308a3..8c0d48c 100644
> > --- a/hw/acpi/core.c
> > +++ b/hw/acpi/core.c
> > @@ -662,3 +662,21 @@ uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr)
> >  
> >      return val;
> >  }
> > +
> > +void acpi_update_sci(ACPIREGS *regs, qemu_irq irq, uint32_t gpe0_sts_mask)
> > +{
> > +    int sci_level, pm1a_sts;
> > +
> > +    pm1a_sts = acpi_pm1_evt_get_sts(regs);
> > +
> > +    sci_level = ((pm1a_sts &
> > +                  regs->pm1.evt.en & ACPI_BITMASK_PM1_COMMON_ENABLED) != 0) ||
> > +                ((regs->gpe.sts[0] & regs->gpe.en[0] & gpe0_sts_mask) != 0);
> > +
> > +    qemu_set_irq(irq, sci_level);
> > +
> > +    /* schedule a timer interruption if needed */
> > +    acpi_pm_tmr_update(regs,
> > +                       (regs->pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> > +                       !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
> > +}
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index 7e0429e..e59688b 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -44,29 +44,10 @@ do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0)
> >  #define ICH9_DEBUG(fmt, ...)    do { } while (0)
> >  #endif
> >  
> > -static void pm_update_sci(ICH9LPCPMRegs *pm)
> > -{
> > -    int sci_level, pm1a_sts;
> > -
> > -    pm1a_sts = acpi_pm1_evt_get_sts(&pm->acpi_regs);
> > -
> > -    sci_level = (((pm1a_sts & pm->acpi_regs.pm1.evt.en) &
> > -                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
> > -                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
> > -                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
> > -                   ACPI_BITMASK_TIMER_ENABLE)) != 0);
> > -    qemu_set_irq(pm->irq, sci_level);
> > -
> > -    /* schedule a timer interruption if needed */
> > -    acpi_pm_tmr_update(&pm->acpi_regs,
> > -                       (pm->acpi_regs.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> > -                       !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS));
> > -}
> > -
> >  static void ich9_pm_update_sci_fn(ACPIREGS *regs)
> >  {
> >      ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs);
> > -    pm_update_sci(pm);
> > +    acpi_update_sci(&pm->acpi_regs, pm->irq, 0);
> >  }
> >  
> >  static uint64_t ich9_gpe_readb(void *opaque, hwaddr addr, unsigned width)
> > @@ -193,7 +174,7 @@ static void pm_reset(void *opaque)
> >          pm->smi_en |= ICH9_PMIO_SMI_EN_APMC_EN;
> >      }
> >  
> > -    pm_update_sci(pm);
> > +    acpi_update_sci(&pm->acpi_regs, pm->irq, 0);
> >  }
> >  
> >  static void pm_powerdown_req(Notifier *n, void *opaque)
> > diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
> > index 0be385e..b6dfa71 100644
> > --- a/hw/acpi/piix4.c
> > +++ b/hw/acpi/piix4.c
> > @@ -117,29 +117,11 @@ static void piix4_acpi_system_hot_add_init(MemoryRegion *parent,
> >  #define ACPI_ENABLE 0xf1
> >  #define ACPI_DISABLE 0xf0
> >  
> > -static void pm_update_sci(PIIX4PMState *s)
> > -{
> > -    int sci_level, pmsts;
> > -
> > -    pmsts = acpi_pm1_evt_get_sts(&s->ar);
> > -    sci_level = (((pmsts & s->ar.pm1.evt.en) &
> > -                  (ACPI_BITMASK_RT_CLOCK_ENABLE |
> > -                   ACPI_BITMASK_POWER_BUTTON_ENABLE |
> > -                   ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
> > -                   ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
> > -        (((s->ar.gpe.sts[0] & s->ar.gpe.en[0]) &
> > -          (PIIX4_PCI_HOTPLUG_STATUS | PIIX4_CPU_HOTPLUG_STATUS)) != 0);
> > -
> > -    qemu_set_irq(s->irq, sci_level);
> > -    /* schedule a timer interruption if needed */
> > -    acpi_pm_tmr_update(&s->ar, (s->ar.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) &&
> > -                       !(pmsts & ACPI_BITMASK_TIMER_STATUS));
> > -}
> > -
> >  static void pm_tmr_timer(ACPIREGS *ar)
> >  {
> >      PIIX4PMState *s = container_of(ar, PIIX4PMState, ar);
> > -    pm_update_sci(s);
> > +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> > +                    PIIX4_CPU_HOTPLUG_STATUS);
> >  }
> >  
> >  static void apm_ctrl_changed(uint32_t val, void *arg)
> > @@ -429,7 +411,8 @@ static int piix4_acpi_pci_hotplug(DeviceState *qdev, PCIDevice *dev,
> >      }
> >      s->ar.gpe.sts[0] |= PIIX4_PCI_HOTPLUG_STATUS;
> >  
> > -    pm_update_sci(s);
> > +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> > +                    PIIX4_CPU_HOTPLUG_STATUS);
> >      return 0;
> >  }
> >  
> > @@ -629,7 +612,8 @@ static void gpe_writeb(void *opaque, hwaddr addr, uint64_t val,
> >      PIIX4PMState *s = opaque;
> >  
> >      acpi_gpe_ioport_writeb(&s->ar, addr, val);
> > -    pm_update_sci(s);
> > +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> > +                    PIIX4_CPU_HOTPLUG_STATUS);
> >  
> >      PIIX4_DPRINTF("gpe write %" HWADDR_PRIx " <== %" PRIu64 "\n", addr, val);
> >  }
> > @@ -745,7 +729,8 @@ static void piix4_cpu_hotplug_req(PIIX4PMState *s, CPUState *cpu,
> >      } else {
> >          g->sts[cpu_id / 8] &= ~(1 << (cpu_id % 8));
> >      }
> > -    pm_update_sci(s);
> > +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> > +                    PIIX4_CPU_HOTPLUG_STATUS);
> >  }
> >  
> >  static void piix4_cpu_added_req(Notifier *n, void *opaque)
> > @@ -823,7 +808,8 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev,
> >          disable_device(s, slot);
> >      }
> >  
> > -    pm_update_sci(s);
> > +    acpi_update_sci(&s->ar, s->irq, PIIX4_PCI_HOTPLUG_STATUS |
> > +                    PIIX4_CPU_HOTPLUG_STATUS);
> >  
> >      return 0;
> >  }
> > diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
> > index 6bbcb17..c4ae7d7 100644
> > --- a/include/hw/acpi/acpi.h
> > +++ b/include/hw/acpi/acpi.h
> > @@ -69,6 +69,12 @@
> >  #define ACPI_BITMASK_RT_CLOCK_ENABLE            0x0400
> >  #define ACPI_BITMASK_PCIEXP_WAKE_DISABLE        0x4000	/* ACPI 3.0 */
> >  
> > +#define ACPI_BITMASK_PM1_COMMON_ENABLED         ( \
> > +        ACPI_BITMASK_RT_CLOCK_ENABLE        | \
> > +        ACPI_BITMASK_POWER_BUTTON_ENABLE    | \
> > +        ACPI_BITMASK_GLOBAL_LOCK_ENABLE     | \
> > +        ACPI_BITMASK_TIMER_ENABLE)
> > +
> >  /* PM1x_CNT */
> >  #define ACPI_BITMASK_SCI_ENABLE                 0x0001
> >  #define ACPI_BITMASK_BUS_MASTER_RLD             0x0002
> > @@ -160,6 +166,8 @@ void acpi_gpe_reset(ACPIREGS *ar);
> >  void acpi_gpe_ioport_writeb(ACPIREGS *ar, uint32_t addr, uint32_t val);
> >  uint32_t acpi_gpe_ioport_readb(ACPIREGS *ar, uint32_t addr);
> >  
> > +void acpi_update_sci(ACPIREGS *acpi_regs, qemu_irq irq, uint32_t gpe0_sts_mask);
> > +
> >  /* acpi.c */
> >  extern int acpi_enabled;
> >  extern char unsigned *acpi_tables;
> > -- 
> > 1.7.1
> 

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

* Re: [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts
  2013-11-27  0:27         ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Igor Mammedov
  2013-11-27  0:27           ` [Qemu-devel] [PATCH 05/28] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
@ 2013-12-10  7:23           ` Paolo Bonzini
  2013-12-10 10:53             ` Igor Mammedov
  1 sibling, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-12-10  7:23 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, stefanb, hutao, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha,
	marcel.a, lcapitulino, afaerber, armbru

Il 27/11/2013 01:27, Igor Mammedov ha scritto:
> Adds option to -m
>  "mem" - 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>
> ---
>  qemu-options.hx |  7 +++++--
>  vl.c            | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
>  2 files changed, 47 insertions(+), 13 deletions(-)
> 
> diff --git a/qemu-options.hx b/qemu-options.hx
> index 8b94264..d923995 100644
> --- a/qemu-options.hx
> +++ b/qemu-options.hx
> @@ -210,8 +210,11 @@ 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 [mem=]megs\n"
> +    "                configure guest RAM\n"
> +    "                mem: initial amount of guest memory (default: "
> +    stringify(DEFAULT_RAM_SIZE) "Mb)\n",
> +    QEMU_ARCH_ALL)
>  STEXI
>  @item -m @var{megs}
>  @findex -m
> diff --git a/vl.c b/vl.c
> index f28674f..44cc4ed 100644
> --- a/vl.c
> +++ b/vl.c
> @@ -529,6 +529,20 @@ static QemuOptsList qemu_msg_opts = {
>      },
>  };
>  
> +static QemuOptsList qemu_mem_opts = {
> +    .name = "memory-opts",
> +    .implied_opt_name = "mem",
> +    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
> +    .merge_lists = true,
> +    .desc = {
> +        {
> +            .name = "mem",
> +            .type = QEMU_OPT_SIZE,
> +        },
> +        { /* end of list */ }
> +    },
> +};
> +
>  /**
>   * Get machine options
>   *
> @@ -2852,6 +2866,7 @@ 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 = DEFAULT_RAM_SIZE * 1024 * 1024;
>  
>      atexit(qemu_run_exit_notifiers);
>      error_set_progname(argv[0]);
> @@ -2887,6 +2902,8 @@ int main(int argc, char **argv, char **envp)
>      qemu_add_opts(&qemu_tpmdev_opts);
>      qemu_add_opts(&qemu_realtime_opts);
>      qemu_add_opts(&qemu_msg_opts);
> +    qemu_add_opts(&qemu_mem_opts);
> +    qemu_opts_create_nofail(&qemu_mem_opts);
>  
>      runstate_init();
>  
> @@ -2901,7 +2918,7 @@ int main(int argc, char **argv, char **envp)
>      module_call_init(MODULE_INIT_MACHINE);
>      machine = 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;
> @@ -3178,16 +3195,32 @@ 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);
> +                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
> +                                       optarg, 1);
> +
> +                mem_str = qemu_opt_get(opts, "mem");
> +                if (!mem_str) {
> +                    fprintf(stderr, "qemu: invalid -m option, missing "
> +                            " 'mem' option\n");
>                      exit(1);
>                  }
> -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
> +
> +                sz = qemu_opt_get_size(opts, "mem", ram_size);
> +
> +                /* Fix up legacy suffix-less format */
> +                if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
> +                    sz <<= 20;
> +                }
> +
> +                /* backward compatibility behaviour for case "-m 0" */
> +                if (sz == 0) {
> +                    sz = default_ram_size;
> +                }
> +
> +                sz = QEMU_ALIGN_UP(sz, 8192);
>                  ram_size = sz;
>                  if (ram_size != sz) {
>                      fprintf(stderr, "qemu: ram size too large\n");
> @@ -4029,10 +4062,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(opts, "mem", ram_size);
>  
>      if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
>          != 0) {
> 

I'm applying this patch and "qapi: add SIZE type parser to
string_input_visitor", to include them in the same pull request as
Wanlong Gao's first batch of NUMA patches.

Paolo

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

* Re: [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts
  2013-12-10  7:23           ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Paolo Bonzini
@ 2013-12-10 10:53             ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-12-10 10:53 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, aliguori, stefanb, hutao, mst, mjt, qemu-devel,
	mdroth, vasilis.liaskovitis, quintela, kraxel, stefanha,
	marcel.a, lcapitulino, afaerber, armbru

On Tue, 10 Dec 2013 08:23:34 +0100
Paolo Bonzini <pbonzini@redhat.com> wrote:

> Il 27/11/2013 01:27, Igor Mammedov ha scritto:
> > Adds option to -m
> >  "mem" - 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>
> > ---
> >  qemu-options.hx |  7 +++++--
> >  vl.c            | 53 ++++++++++++++++++++++++++++++++++++++++++-----------
> >  2 files changed, 47 insertions(+), 13 deletions(-)
> > 
> > diff --git a/qemu-options.hx b/qemu-options.hx
> > index 8b94264..d923995 100644
> > --- a/qemu-options.hx
> > +++ b/qemu-options.hx
> > @@ -210,8 +210,11 @@ 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 [mem=]megs\n"
> > +    "                configure guest RAM\n"
> > +    "                mem: initial amount of guest memory (default: "
> > +    stringify(DEFAULT_RAM_SIZE) "Mb)\n",
> > +    QEMU_ARCH_ALL)
> >  STEXI
> >  @item -m @var{megs}
> >  @findex -m
> > diff --git a/vl.c b/vl.c
> > index f28674f..44cc4ed 100644
> > --- a/vl.c
> > +++ b/vl.c
> > @@ -529,6 +529,20 @@ static QemuOptsList qemu_msg_opts = {
> >      },
> >  };
> >  
> > +static QemuOptsList qemu_mem_opts = {
> > +    .name = "memory-opts",
> > +    .implied_opt_name = "mem",
> > +    .head = QTAILQ_HEAD_INITIALIZER(qemu_mem_opts.head),
> > +    .merge_lists = true,
> > +    .desc = {
> > +        {
> > +            .name = "mem",
> > +            .type = QEMU_OPT_SIZE,
> > +        },
> > +        { /* end of list */ }
> > +    },
> > +};
> > +
> >  /**
> >   * Get machine options
> >   *
> > @@ -2852,6 +2866,7 @@ 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 = DEFAULT_RAM_SIZE * 1024 * 1024;
> >  
> >      atexit(qemu_run_exit_notifiers);
> >      error_set_progname(argv[0]);
> > @@ -2887,6 +2902,8 @@ int main(int argc, char **argv, char **envp)
> >      qemu_add_opts(&qemu_tpmdev_opts);
> >      qemu_add_opts(&qemu_realtime_opts);
> >      qemu_add_opts(&qemu_msg_opts);
> > +    qemu_add_opts(&qemu_mem_opts);
> > +    qemu_opts_create_nofail(&qemu_mem_opts);
> >  
> >      runstate_init();
> >  
> > @@ -2901,7 +2918,7 @@ int main(int argc, char **argv, char **envp)
> >      module_call_init(MODULE_INIT_MACHINE);
> >      machine = 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;
> > @@ -3178,16 +3195,32 @@ 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);
> > +                opts = qemu_opts_parse(qemu_find_opts("memory-opts"),
> > +                                       optarg, 1);
> > +
> > +                mem_str = qemu_opt_get(opts, "mem");
> > +                if (!mem_str) {
> > +                    fprintf(stderr, "qemu: invalid -m option, missing "
> > +                            " 'mem' option\n");
> >                      exit(1);
> >                  }
> > -                sz = QEMU_ALIGN_UP((uint64_t)value, 8192);
> > +
> > +                sz = qemu_opt_get_size(opts, "mem", ram_size);
> > +
> > +                /* Fix up legacy suffix-less format */
> > +                if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {
> > +                    sz <<= 20;
> > +                }
> > +
> > +                /* backward compatibility behaviour for case "-m 0" */
> > +                if (sz == 0) {
> > +                    sz = default_ram_size;
> > +                }
> > +
> > +                sz = QEMU_ALIGN_UP(sz, 8192);
> >                  ram_size = sz;
> >                  if (ram_size != sz) {
> >                      fprintf(stderr, "qemu: ram size too large\n");
> > @@ -4029,10 +4062,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(opts, "mem", ram_size);
> >  
> >      if (qemu_opts_foreach(qemu_find_opts("device"), device_help_func, NULL, 0)
> >          != 0) {
> > 
> 
> I'm applying this patch and "qapi: add SIZE type parser to
> string_input_visitor", to include them in the same pull request as
> Wanlong Gao's first batch of NUMA patches.
> 
> Paolo
Thanks

-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface
  2013-11-25 14:39     ` Igor Mammedov
@ 2013-12-16 19:50       ` Michael S. Tsirkin
  2013-12-16 21:42         ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-12-16 19:50 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, mdroth, stefanb, hutao, marcel.a, mjt, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, lcapitulino, stefanha, afaerber

On Mon, Nov 25, 2013 at 03:39:13PM +0100, Igor Mammedov wrote:
> On Thu, 21 Nov 2013 11:37:01 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Nov 21, 2013 at 03:38:44AM +0100, 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>
> > > ---
> [...]
> 
> > > diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
> > > index a4484b8..b0c581e 100644
> > > --- a/hw/i386/ssdt-misc.dsl
> > > +++ b/hw/i386/ssdt-misc.dsl
> > > @@ -116,4 +116,183 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
> > >              }
> > >          }
> > >      }
> > > +
> > > +    External(MTFY, MethodObj)
> > > +
> > > +    Scope(\_SB) {
> > > +        Device(MHPD) {
> > > +            Name(_HID, EISAID("PNP0C08"))
> > > +
> > > +            ACPI_EXTRACT_NAME_WORD_CONST ssdt_mctrl_port
> > > +            Name(MHPP, 0xFFFF)
> > > +
> > > +            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
> > > +            Name(MDNR, 0x12345678)
> > > +
> > > +            /* Memory hotplug IO registers */
> > > +            OperationRegion(HPMR, SystemIO, MHPP, 24)
> > > +
> > > +            Method(_CRS, 0, Serialized) {
> > > +                Name(CRS, ResourceTemplate() {
> > > +                    IO(Decode16, 0x00, 0x00, 0x01, 24, IO)
> > > +                })
> > 
> > 
> > Declaring name makes us serialize it.
> > Can't we use a local variable?
> If that works, I'll change it.
> 
> But I have a question of my own perhaps to Paolo or Gerd,
> Do we really need this _CRS, because if you look at next hunk
> _STA should report not present but functioning to avoid windows BSOD.
> So there is not guaranties that OSPM would care or even query it
> and honor _CRS provided range.
> 

Yes this worries me too.
Making _STA non present looks wrong.
I suspect we need to look for some other way to make
windows not crash that will make it respect the _CRS.
Also which windows? All of them?


> [...]
> > > +
> > > +            Method(_STA, 0) {
> > > +                If (LEqual(MDNR, Zero)) {
> > > +                    Return(0x0)
> > > +                }
> > > +                /* Leave bit 0 cleared to avoid Windows BSOD */
> > > +                Return(0xA)
> > > +            }
> [...]

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

* Re: [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface
  2013-12-16 19:50       ` Michael S. Tsirkin
@ 2013-12-16 21:42         ` Igor Mammedov
  0 siblings, 0 replies; 143+ messages in thread
From: Igor Mammedov @ 2013-12-16 21:42 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, mdroth, stefanb, hutao, marcel.a, mjt, armbru,
	qemu-devel, vasilis.liaskovitis, quintela, chegu_vinod, kraxel,
	aliguori, pbonzini, lcapitulino, stefanha, afaerber

On Mon, 16 Dec 2013 21:50:53 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Mon, Nov 25, 2013 at 03:39:13PM +0100, Igor Mammedov wrote:
> > On Thu, 21 Nov 2013 11:37:01 +0200
> > "Michael S. Tsirkin" <mst@redhat.com> wrote:
> > 
> > > On Thu, Nov 21, 2013 at 03:38:44AM +0100, 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>
> > > > ---
> > [...]
> > 
> > > > diff --git a/hw/i386/ssdt-misc.dsl b/hw/i386/ssdt-misc.dsl
> > > > index a4484b8..b0c581e 100644
> > > > --- a/hw/i386/ssdt-misc.dsl
> > > > +++ b/hw/i386/ssdt-misc.dsl
> > > > @@ -116,4 +116,183 @@ DefinitionBlock ("ssdt-misc.aml", "SSDT", 0x01, "BXPC", "BXSSDTSUSP", 0x1)
> > > >              }
> > > >          }
> > > >      }
> > > > +
> > > > +    External(MTFY, MethodObj)
> > > > +
> > > > +    Scope(\_SB) {
> > > > +        Device(MHPD) {
> > > > +            Name(_HID, EISAID("PNP0C08"))
> > > > +
> > > > +            ACPI_EXTRACT_NAME_WORD_CONST ssdt_mctrl_port
> > > > +            Name(MHPP, 0xFFFF)
> > > > +
> > > > +            ACPI_EXTRACT_NAME_DWORD_CONST ssdt_mctrl_nr_slots
> > > > +            Name(MDNR, 0x12345678)
> > > > +
> > > > +            /* Memory hotplug IO registers */
> > > > +            OperationRegion(HPMR, SystemIO, MHPP, 24)
> > > > +
> > > > +            Method(_CRS, 0, Serialized) {
> > > > +                Name(CRS, ResourceTemplate() {
> > > > +                    IO(Decode16, 0x00, 0x00, 0x01, 24, IO)
> > > > +                })
> > > 
> > > 
> > > Declaring name makes us serialize it.
> > > Can't we use a local variable?
> > If that works, I'll change it.
> > 
> > But I have a question of my own perhaps to Paolo or Gerd,
> > Do we really need this _CRS, because if you look at next hunk
> > _STA should report not present but functioning to avoid windows BSOD.
> > So there is not guaranties that OSPM would care or even query it
> > and honor _CRS provided range.
> > 
> 
> Yes this worries me too.
> Making _STA non present looks wrong.
I've made status as not present and enabled/decoding and functioning, but that
doesn't mean that OSPM respects its _CRS.
 
> I suspect we need to look for some other way to make
> windows not crash that will make it respect the _CRS.
> Also which windows? All of them?
I've tested with WS2012DCx64,

PV panic doesn't crash windows because it's showed as Unknown device, which
also doesn't guaranty that windows would respects it's _CRS.

OSPM already knows that range is used by OperationRegion.
Question is do we really need to expose OperationRegion as _CRS?


> 
> 
> > [...]
> > > > +
> > > > +            Method(_STA, 0) {
> > > > +                If (LEqual(MDNR, Zero)) {
> > > > +                    Return(0x0)
> > > > +                }
> > > > +                /* Leave bit 0 cleared to avoid Windows BSOD */
> > > > +                Return(0xA)
> > > > +            }
> > [...]


-- 
Regards,
  Igor

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

* Re: [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  2013-11-21  2:38 ` [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
@ 2013-12-19 14:35   ` Michael S. Tsirkin
  2013-12-20 12:48     ` Igor Mammedov
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-12-19 14:35 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, chegu_vinod,
	marcel.a, mjt, mdroth, armbru, vasilis.liaskovitis, quintela,
	kraxel, aliguori, hutao, pbonzini, lcapitulino, afaerber

On Thu, Nov 21, 2013 at 03:38:24AM +0100, Igor Mammedov wrote:
> '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>
> ---
> v2:
>    * disable 'etc/reserved-memory-end' for 1.7 and older machine types
> ---
>  hw/i386/pc.c         |   27 +++++++++++++++++++++++++--
>  hw/i386/pc_piix.c    |    1 +
>  hw/i386/pc_q35.c     |    1 +
>  hw/pci-host/piix.c   |    3 ++-
>  hw/pci-host/q35.c    |    3 ++-
>  include/hw/i386/pc.h |   11 +++++++++--
>  6 files changed, 40 insertions(+), 6 deletions(-)
> 
> diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> index 6c82ada..ba82c67 100644
> --- a/hw/i386/pc.c
> +++ b/hw/i386/pc.c
> @@ -1094,14 +1094,37 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
>  }
>  
>  /* setup pci memory address space mapping into system address space */
> -void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
> -                            MemoryRegion *pci_address_space)
> +void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
> +                                MemoryRegion *pci_address_space,
> +                                uint64_t reserved_memory_end)
>  {
>      /* Set to lower priority than RAM */
>      memory_region_add_subregion_overlap(system_memory, 0x0,
>                                          pci_address_space, -1);
>  }
>  
> +static
> +void pc_pci_as_mapping_init_1_8(Object *owner, MemoryRegion *system_memory,
> +                                MemoryRegion *pci_address_space,
> +                                uint64_t reserved_memory_end)
> +{
> +    uint64_t *val;
> +    FWCfgState *fw_cfg = fw_cfg_find();
> +    g_assert(fw_cfg);
> +    /*
> +     *  Align address at 1G, this makes sure it can be exactly covered
> +     *  with a PAT entry even when using huge pages.
> +     */
> +    val = g_malloc(sizeof(*val));
> +    *val = cpu_to_le64(ROUND_UP(reserved_memory_end, 0x1ULL << 30));
> +    fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
> +
> +    pc_pci_as_mapping_init_1_7(owner, system_memory, pci_address_space,
> +                               reserved_memory_end);
> +}
> +
> +pc_pci_as_mapping_init_fn pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_8;
> +
>  void pc_acpi_init(const char *default_dsdt)
>  {
>      char *filename;
> diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> index 36f2495..e1fe85a 100644
> --- a/hw/i386/pc_piix.c
> +++ b/hw/i386/pc_piix.c
> @@ -249,6 +249,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
>  static void pc_compat_1_7(QEMUMachineInitArgs *args)
>  {
>      smbios_type1_defaults = false;
> +    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
>  }
>  
>  static void pc_compat_1_6(QEMUMachineInitArgs *args)
> diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> index 50ca458..5525465 100644
> --- a/hw/i386/pc_q35.c
> +++ b/hw/i386/pc_q35.c
> @@ -233,6 +233,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
>  static void pc_compat_1_7(QEMUMachineInitArgs *args)
>  {
>      smbios_type1_defaults = false;
> +    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
>  }
>  
>  static void pc_compat_1_6(QEMUMachineInitArgs *args)

I don't much like this: why not use a global flag like we do
for other properties?

Also, 1_8 should be replaced with 2_0 now.

> diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> index 63be7f6..615ab0d 100644
> --- a/hw/pci-host/piix.c
> +++ b/hw/pci-host/piix.c
> @@ -352,7 +352,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
>  
>      /* setup pci memory mapping */
>      pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
> -                           f->pci_address_space);
> +                           f->pci_address_space,
> +                           0x100000000ULL + above_4g_mem_size);
>  
>      memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
>                               f->pci_address_space, 0xa0000, 0x20000);
> diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> index 81c8240..6e28418 100644
> --- a/hw/pci-host/q35.c
> +++ b/hw/pci-host/q35.c
> @@ -359,7 +359,8 @@ static int mch_init(PCIDevice *d)
>  
>      /* setup pci memory mapping */
>      pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
> -                           mch->pci_address_space);
> +                           mch->pci_address_space,
> +                           0x100000000ULL + mch->above_4g_mem_size);
>  
>      /* smram */
>      cpu_smm_register(&mch_set_smm, mch);
> diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> index 9af09d3..c4e8048 100644
> --- a/include/hw/i386/pc.h
> +++ b/include/hw/i386/pc.h
> @@ -129,8 +129,15 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
>  #define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
>  
>  
> -void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
> -                            MemoryRegion *pci_address_space);
> +typedef
> +void (*pc_pci_as_mapping_init_fn)(Object *owner, MemoryRegion *system_memory,
> +                                  MemoryRegion *pci_address_space,
> +                                  uint64_t reserved_memory_end);
> +extern pc_pci_as_mapping_init_fn pc_pci_as_mapping_init;
> +
> +void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
> +                                MemoryRegion *pci_address_space,
> +                                uint64_t reserved_memory_end);
>  
>  FWCfgState *pc_memory_init(MemoryRegion *system_memory,
>                             const char *kernel_filename,
> -- 
> 1.7.1

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-11-25 16:43           ` Eric Blake
  2013-11-25 17:01             ` Paolo Bonzini
  2013-11-27 14:15             ` Markus Armbruster
@ 2013-12-19 14:40             ` Michael S. Tsirkin
  2013-12-19 15:14               ` Markus Armbruster
  2013-12-19 15:31               ` Paolo Bonzini
  2 siblings, 2 replies; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-12-19 14:40 UTC (permalink / raw)
  To: Eric Blake
  Cc: peter.maydell, stefanha, stefanb, qemu-devel, hutao, quintela,
	mjt, mdroth, Markus Armbruster, vasilis.liaskovitis, kraxel,
	aliguori, Igor Mammedov, Paolo Bonzini, marcel.a, lcapitulino,
	chegu_vinod, afaerber

On Mon, Nov 25, 2013 at 09:43:48AM -0700, Eric Blake wrote:
> On 11/25/2013 09:32 AM, Paolo Bonzini wrote:
> 
> >> Yes please. Firing up a calculator to figure out how much is 1G is not
> >> friendly, neither is firing it up to figure out what did management do
> >> with QMP. It should be a text based interface not a binary one.
> 
> Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
> prefers passing a value in 'bytes', rather than risking confusion on
> whether a value in G was rounded (up, down? to nearest power of 10 or
> power of 2?).  Unfortunately, yes, that means you need a calculator when
> parsing QMP logs to see whether the 1073741824 passed by libvirt is the
> 1G you had in mind.
> 
> HMP, qtest, and any other decent shell around raw QMP is more than
> welcome to provide human-usable wrappers that takes "1G" as a string and
> turns it into the raw int used by the underlying QMP.  In fact, I
> encourage it.

How will it know 1G is not e.g. an ID?

We can invent rules like "IDs should not start with a number", but these
rules are better enforced in a single place for consistency, and it's
likely too late to enforce that in HMP.

> > This is unfortunately a counter-example to the rule that HMP commands
> > should always be implemented in terms of their QMP counterparts.  I do
> > not believe this is really a problem.  It can be fixed later; for now, I
> > think "perfect is the enemy of good" applies.
> 
> Hey - I just realized that now that we have anonymous unions, we could
> theoretically extend QMP to allow a union between 'int' and 'string' -
> if an 'int' is passed, it is in bytes; if a 'string' is passed, then
> parse it the way HMP would (so the string "1G" would be equivalent to
> the raw int 1073741824).  But I don't know if it will help you (libvirt
> will still prefer to use raw ints in any QMP log you read off of libvirt
> interactions).

Yes, I think that would address the issue.

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

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-12-19 14:40             ` Michael S. Tsirkin
@ 2013-12-19 15:14               ` Markus Armbruster
  2013-12-19 15:32                 ` Michael S. Tsirkin
  2013-12-19 15:31               ` Paolo Bonzini
  1 sibling, 1 reply; 143+ messages in thread
From: Markus Armbruster @ 2013-12-19 15:14 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, stefanb, hutao, quintela, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, chegu_vinod, kraxel,
	stefanha, Paolo Bonzini, Igor Mammedov, marcel.a, lcapitulino,
	afaerber

"Michael S. Tsirkin" <mst@redhat.com> writes:

> On Mon, Nov 25, 2013 at 09:43:48AM -0700, Eric Blake wrote:
>> On 11/25/2013 09:32 AM, Paolo Bonzini wrote:
>> 
>> >> Yes please. Firing up a calculator to figure out how much is 1G is not
>> >> friendly, neither is firing it up to figure out what did management do
>> >> with QMP. It should be a text based interface not a binary one.
>> 
>> Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
>> prefers passing a value in 'bytes', rather than risking confusion on
>> whether a value in G was rounded (up, down? to nearest power of 10 or
>> power of 2?).  Unfortunately, yes, that means you need a calculator when
>> parsing QMP logs to see whether the 1073741824 passed by libvirt is the
>> 1G you had in mind.
>> 
>> HMP, qtest, and any other decent shell around raw QMP is more than
>> welcome to provide human-usable wrappers that takes "1G" as a string and
>> turns it into the raw int used by the underlying QMP.  In fact, I
>> encourage it.
>
> How will it know 1G is not e.g. an ID?
>
> We can invent rules like "IDs should not start with a number", but these
> rules are better enforced in a single place for consistency, and it's
> likely too late to enforce that in HMP.

This isn't how the human monitor works.

Its argument parsing is guided by the command's args_type, which
declares argument names and type codes.  For instance, type code 's'
expects a string argument (may be enclosed in quotes), 'i' a 32-bit
integer argument, 'o' a size argument (may be followed by a suffix such
as 'G').

If the current argument has type code 'o', then 1G is interpreted as the
number 2^30.  With type code 's', it's the string "1G".

As to rules for IDs: IDs are typically defined via QemuOpts, which
restricts them to letters, digits, '-', '.', '_', starting with a
letter.

>> > This is unfortunately a counter-example to the rule that HMP commands
>> > should always be implemented in terms of their QMP counterparts.  I do
>> > not believe this is really a problem.  It can be fixed later; for now, I
>> > think "perfect is the enemy of good" applies.
>> 
>> Hey - I just realized that now that we have anonymous unions, we could
>> theoretically extend QMP to allow a union between 'int' and 'string' -
>> if an 'int' is passed, it is in bytes; if a 'string' is passed, then
>> parse it the way HMP would (so the string "1G" would be equivalent to
>> the raw int 1073741824).  But I don't know if it will help you (libvirt
>> will still prefer to use raw ints in any QMP log you read off of libvirt
>> interactions).
>
> Yes, I think that would address the issue.

I object, because it goes against the design of QMP.

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-12-19 14:40             ` Michael S. Tsirkin
  2013-12-19 15:14               ` Markus Armbruster
@ 2013-12-19 15:31               ` Paolo Bonzini
  2013-12-19 15:40                 ` Michael S. Tsirkin
  1 sibling, 1 reply; 143+ messages in thread
From: Paolo Bonzini @ 2013-12-19 15:31 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, stefanha, quintela, qemu-devel, hutao, stefanb,
	mjt, mdroth, Markus Armbruster, vasilis.liaskovitis, chegu_vinod,
	kraxel, aliguori, Igor Mammedov, marcel.a, lcapitulino, afaerber

Il 19/12/2013 15:40, Michael S. Tsirkin ha scritto:
> On Mon, Nov 25, 2013 at 09:43:48AM -0700, Eric Blake wrote:
>> On 11/25/2013 09:32 AM, Paolo Bonzini wrote:
>>
>>>> Yes please. Firing up a calculator to figure out how much is 1G is not
>>>> friendly, neither is firing it up to figure out what did management do
>>>> with QMP. It should be a text based interface not a binary one.
>>
>> Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
>> prefers passing a value in 'bytes', rather than risking confusion on
>> whether a value in G was rounded (up, down? to nearest power of 10 or
>> power of 2?).  Unfortunately, yes, that means you need a calculator when
>> parsing QMP logs to see whether the 1073741824 passed by libvirt is the
>> 1G you had in mind.
>>
>> HMP, qtest, and any other decent shell around raw QMP is more than
>> welcome to provide human-usable wrappers that takes "1G" as a string and
>> turns it into the raw int used by the underlying QMP.  In fact, I
>> encourage it.
> 
> How will it know 1G is not e.g. an ID?

Because all properties are associated to a name.  In the case of a
memory device, the name could be "size" or "id".  When requesting the
id, QEMU will use visit_type_str.  When requesting the size, QEMU will
use visit_type_size.  Different functions are called, and the different
functions accept different input.

To explain further what Markus dismissed as "against the design of QMP",
there is another way to choose the way your input is parsed, and that is
simply by choosing a different visitor.

QMP uses strongly-typed JSON, so it uses a QmpInputVisitor.  HMP and
command-line just parse text, so it uses an OptsVisitor.

So we have:

   -object memory-ram,size=1M,id=foo           (command-line)
   object_add memory-ram,size=1M,id=foo        (HMP)

that use OptsVisitor and converts 1M to 1048576.  For QMP instead

   {'command': 'object-add', 'arguments': {
        'qom-type': 'memory-ram', 'id': 'foo',
        'props': {'size':1048576}}}

uses QmpInputVisitor which rejects any 'size' that is not a JSON
integer.  We definitely do not want to allow QMP input such as this:

   {'command': 'object-add', 'arguments': {
        'qom-type': 'memory-ram', 'id': 'foo',
        'props': {'size':'1M'}}}

That's against the idea of making QMP as strongly-typed as possible.

Paolo

> We can invent rules like "IDs should not start with a number", but these
> rules are better enforced in a single place for consistency, and it's
> likely too late to enforce that in HMP.
> 
>>> This is unfortunately a counter-example to the rule that HMP commands
>>> should always be implemented in terms of their QMP counterparts.  I do
>>> not believe this is really a problem.  It can be fixed later; for now, I
>>> think "perfect is the enemy of good" applies.
>>
>> Hey - I just realized that now that we have anonymous unions, we could
>> theoretically extend QMP to allow a union between 'int' and 'string' -
>> if an 'int' is passed, it is in bytes; if a 'string' is passed, then
>> parse it the way HMP would (so the string "1G" would be equivalent to
>> the raw int 1073741824).  But I don't know if it will help you (libvirt
>> will still prefer to use raw ints in any QMP log you read off of libvirt
>> interactions).
> 
> Yes, I think that would address the issue.
> 
>> Eric Blake   eblake redhat com    +1-919-301-3266
>> Libvirt virtualization library http://libvirt.org
>>
> 
> 

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-12-19 15:14               ` Markus Armbruster
@ 2013-12-19 15:32                 ` Michael S. Tsirkin
  0 siblings, 0 replies; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-12-19 15:32 UTC (permalink / raw)
  To: Markus Armbruster
  Cc: peter.maydell, aliguori, stefanb, hutao, quintela, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, chegu_vinod, kraxel,
	stefanha, Paolo Bonzini, Igor Mammedov, marcel.a, lcapitulino,
	afaerber

On Thu, Dec 19, 2013 at 04:14:56PM +0100, Markus Armbruster wrote:
> "Michael S. Tsirkin" <mst@redhat.com> writes:
> 
> > On Mon, Nov 25, 2013 at 09:43:48AM -0700, Eric Blake wrote:
> >> On 11/25/2013 09:32 AM, Paolo Bonzini wrote:
> >> 
> >> >> Yes please. Firing up a calculator to figure out how much is 1G is not
> >> >> friendly, neither is firing it up to figure out what did management do
> >> >> with QMP. It should be a text based interface not a binary one.
> >> 
> >> Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
> >> prefers passing a value in 'bytes', rather than risking confusion on
> >> whether a value in G was rounded (up, down? to nearest power of 10 or
> >> power of 2?).  Unfortunately, yes, that means you need a calculator when
> >> parsing QMP logs to see whether the 1073741824 passed by libvirt is the
> >> 1G you had in mind.
> >> 
> >> HMP, qtest, and any other decent shell around raw QMP is more than
> >> welcome to provide human-usable wrappers that takes "1G" as a string and
> >> turns it into the raw int used by the underlying QMP.  In fact, I
> >> encourage it.
> >
> > How will it know 1G is not e.g. an ID?
> >
> > We can invent rules like "IDs should not start with a number", but these
> > rules are better enforced in a single place for consistency, and it's
> > likely too late to enforce that in HMP.
> 
> This isn't how the human monitor works.

Yes but we were talking about a friendly shell for qemu using QMP
as a backend.

> Its argument parsing is guided by the command's args_type, which
> declares argument names and type codes.  For instance, type code 's'
> expects a string argument (may be enclosed in quotes), 'i' a 32-bit
> integer argument, 'o' a size argument (may be followed by a suffix such
> as 'G').
> 
> If the current argument has type code 'o', then 1G is interpreted as the
> number 2^30.  With type code 's', it's the string "1G".
> 
> As to rules for IDs: IDs are typically defined via QemuOpts, which
> restricts them to letters, digits, '-', '.', '_', starting with a
> letter.
> 
> >> > This is unfortunately a counter-example to the rule that HMP commands
> >> > should always be implemented in terms of their QMP counterparts.  I do
> >> > not believe this is really a problem.  It can be fixed later; for now, I
> >> > think "perfect is the enemy of good" applies.
> >> 
> >> Hey - I just realized that now that we have anonymous unions, we could
> >> theoretically extend QMP to allow a union between 'int' and 'string' -
> >> if an 'int' is passed, it is in bytes; if a 'string' is passed, then
> >> parse it the way HMP would (so the string "1G" would be equivalent to
> >> the raw int 1073741824).  But I don't know if it will help you (libvirt
> >> will still prefer to use raw ints in any QMP log you read off of libvirt
> >> interactions).
> >
> > Yes, I think that would address the issue.
> 
> I object, because it goes against the design of QMP.

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-12-19 15:31               ` Paolo Bonzini
@ 2013-12-19 15:40                 ` Michael S. Tsirkin
  2013-12-19 15:46                   ` Paolo Bonzini
  0 siblings, 1 reply; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-12-19 15:40 UTC (permalink / raw)
  To: Paolo Bonzini
  Cc: peter.maydell, aliguori, stefanb, hutao, quintela, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, kraxel, stefanha,
	Igor Mammedov, marcel.a, lcapitulino, chegu_vinod, afaerber,
	Markus Armbruster

On Thu, Dec 19, 2013 at 04:31:41PM +0100, Paolo Bonzini wrote:
> Il 19/12/2013 15:40, Michael S. Tsirkin ha scritto:
> > On Mon, Nov 25, 2013 at 09:43:48AM -0700, Eric Blake wrote:
> >> On 11/25/2013 09:32 AM, Paolo Bonzini wrote:
> >>
> >>>> Yes please. Firing up a calculator to figure out how much is 1G is not
> >>>> friendly, neither is firing it up to figure out what did management do
> >>>> with QMP. It should be a text based interface not a binary one.
> >>
> >> Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
> >> prefers passing a value in 'bytes', rather than risking confusion on
> >> whether a value in G was rounded (up, down? to nearest power of 10 or
> >> power of 2?).  Unfortunately, yes, that means you need a calculator when
> >> parsing QMP logs to see whether the 1073741824 passed by libvirt is the
> >> 1G you had in mind.
> >>
> >> HMP, qtest, and any other decent shell around raw QMP is more than
> >> welcome to provide human-usable wrappers that takes "1G" as a string and
> >> turns it into the raw int used by the underlying QMP.  In fact, I
> >> encourage it.
> > 
> > How will it know 1G is not e.g. an ID?
> 
> Because all properties are associated to a name.  In the case of a
> memory device, the name could be "size" or "id".  When requesting the
> id, QEMU will use visit_type_str.  When requesting the size, QEMU will
> use visit_type_size.  Different functions are called, and the different
> functions accept different input.

QEMU can do this, but if you want a frontend with QMP as backend,
it won't.
So you end up re-implementing this logic in all frontends:
instead of just passing on properties they need to know
where 1G is a number and where it's a name.


> To explain further what Markus dismissed as "against the design of QMP",
> there is another way to choose the way your input is parsed, and that is
> simply by choosing a different visitor.
> 
> QMP uses strongly-typed JSON, so it uses a QmpInputVisitor.  HMP and
> command-line just parse text, so it uses an OptsVisitor.
> 
> So we have:
> 
>    -object memory-ram,size=1M,id=foo           (command-line)
>    object_add memory-ram,size=1M,id=foo        (HMP)
> 
> that use OptsVisitor and converts 1M to 1048576.  For QMP instead
> 
>    {'command': 'object-add', 'arguments': {
>         'qom-type': 'memory-ram', 'id': 'foo',
>         'props': {'size':1048576}}}
> 
> uses QmpInputVisitor which rejects any 'size' that is not a JSON
> integer.  We definitely do not want to allow QMP input such as this:
> 
>    {'command': 'object-add', 'arguments': {
>         'qom-type': 'memory-ram', 'id': 'foo',
>         'props': {'size':'1M'}}}
> 
> That's against the idea of making QMP as strongly-typed as possible.
> 
> Paolo
> 
> > We can invent rules like "IDs should not start with a number", but these
> > rules are better enforced in a single place for consistency, and it's
> > likely too late to enforce that in HMP.
> > 
> >>> This is unfortunately a counter-example to the rule that HMP commands
> >>> should always be implemented in terms of their QMP counterparts.  I do
> >>> not believe this is really a problem.  It can be fixed later; for now, I
> >>> think "perfect is the enemy of good" applies.
> >>
> >> Hey - I just realized that now that we have anonymous unions, we could
> >> theoretically extend QMP to allow a union between 'int' and 'string' -
> >> if an 'int' is passed, it is in bytes; if a 'string' is passed, then
> >> parse it the way HMP would (so the string "1G" would be equivalent to
> >> the raw int 1073741824).  But I don't know if it will help you (libvirt
> >> will still prefer to use raw ints in any QMP log you read off of libvirt
> >> interactions).
> > 
> > Yes, I think that would address the issue.
> > 
> >> Eric Blake   eblake redhat com    +1-919-301-3266
> >> Libvirt virtualization library http://libvirt.org
> >>
> > 
> > 
> 

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

* Re: [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor
  2013-12-19 15:40                 ` Michael S. Tsirkin
@ 2013-12-19 15:46                   ` Paolo Bonzini
  0 siblings, 0 replies; 143+ messages in thread
From: Paolo Bonzini @ 2013-12-19 15:46 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, stefanb, hutao, quintela, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, kraxel, stefanha,
	Igor Mammedov, marcel.a, lcapitulino, chegu_vinod, afaerber,
	Markus Armbruster

Il 19/12/2013 16:40, Michael S. Tsirkin ha scritto:
> On Thu, Dec 19, 2013 at 04:31:41PM +0100, Paolo Bonzini wrote:
>> Il 19/12/2013 15:40, Michael S. Tsirkin ha scritto:
>>> On Mon, Nov 25, 2013 at 09:43:48AM -0700, Eric Blake wrote:
>>>> On 11/25/2013 09:32 AM, Paolo Bonzini wrote:
>>>>
>>>>>> Yes please. Firing up a calculator to figure out how much is 1G is not
>>>>>> friendly, neither is firing it up to figure out what did management do
>>>>>> with QMP. It should be a text based interface not a binary one.
>>>>
>>>> Right now, QMP takes an 'int', which does not allow a suffix.  Libvirt
>>>> prefers passing a value in 'bytes', rather than risking confusion on
>>>> whether a value in G was rounded (up, down? to nearest power of 10 or
>>>> power of 2?).  Unfortunately, yes, that means you need a calculator when
>>>> parsing QMP logs to see whether the 1073741824 passed by libvirt is the
>>>> 1G you had in mind.
>>>>
>>>> HMP, qtest, and any other decent shell around raw QMP is more than
>>>> welcome to provide human-usable wrappers that takes "1G" as a string and
>>>> turns it into the raw int used by the underlying QMP.  In fact, I
>>>> encourage it.
>>>
>>> How will it know 1G is not e.g. an ID?
>>
>> Because all properties are associated to a name.  In the case of a
>> memory device, the name could be "size" or "id".  When requesting the
>> id, QEMU will use visit_type_str.  When requesting the size, QEMU will
>> use visit_type_size.  Different functions are called, and the different
>> functions accept different input.
> 
> QEMU can do this, but if you want a frontend with QMP as backend,
> it won't.
> So you end up re-implementing this logic in all frontends:
> instead of just passing on properties they need to know
> where 1G is a number and where it's a name.

You have schema introspection that lets you know if a property is an int
or a size.

OptsVisitor chose to accept 1G, but this absolutely need not be
universal.  Human interfaces must not be designed according to QEMU's
own whims.  Another front-end may want to differentiate 1GB from 1GiB, a
graphical front-end may want to present different widgets; they can do
it because they see "size" in the schema but in any case the "final"
communication to QEMU via QMP will be an int.

Paolo

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

* Re: [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  2013-12-19 14:35   ` Michael S. Tsirkin
@ 2013-12-20 12:48     ` Igor Mammedov
  2013-12-22 11:20       ` Michael S. Tsirkin
  0 siblings, 1 reply; 143+ messages in thread
From: Igor Mammedov @ 2013-12-20 12:48 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: peter.maydell, aliguori, marcel.a, armbru, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, hutao, pbonzini, lcapitulino, chegu_vinod, afaerber

On Thu, 19 Dec 2013 16:35:05 +0200
"Michael S. Tsirkin" <mst@redhat.com> wrote:

> On Thu, Nov 21, 2013 at 03:38:24AM +0100, Igor Mammedov wrote:
> > '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>
> > ---
> > v2:
> >    * disable 'etc/reserved-memory-end' for 1.7 and older machine types
> > ---
> >  hw/i386/pc.c         |   27 +++++++++++++++++++++++++--
> >  hw/i386/pc_piix.c    |    1 +
> >  hw/i386/pc_q35.c     |    1 +
> >  hw/pci-host/piix.c   |    3 ++-
> >  hw/pci-host/q35.c    |    3 ++-
> >  include/hw/i386/pc.h |   11 +++++++++--
> >  6 files changed, 40 insertions(+), 6 deletions(-)
> > 
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index 6c82ada..ba82c67 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -1094,14 +1094,37 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
> >  }
> >  
> >  /* setup pci memory address space mapping into system address space */
> > -void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
> > -                            MemoryRegion *pci_address_space)
> > +void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
> > +                                MemoryRegion *pci_address_space,
> > +                                uint64_t reserved_memory_end)
> >  {
> >      /* Set to lower priority than RAM */
> >      memory_region_add_subregion_overlap(system_memory, 0x0,
> >                                          pci_address_space, -1);
> >  }
> >  
> > +static
> > +void pc_pci_as_mapping_init_1_8(Object *owner, MemoryRegion *system_memory,
> > +                                MemoryRegion *pci_address_space,
> > +                                uint64_t reserved_memory_end)
> > +{
> > +    uint64_t *val;
> > +    FWCfgState *fw_cfg = fw_cfg_find();
> > +    g_assert(fw_cfg);
> > +    /*
> > +     *  Align address at 1G, this makes sure it can be exactly covered
> > +     *  with a PAT entry even when using huge pages.
> > +     */
> > +    val = g_malloc(sizeof(*val));
> > +    *val = cpu_to_le64(ROUND_UP(reserved_memory_end, 0x1ULL << 30));
> > +    fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
> > +
> > +    pc_pci_as_mapping_init_1_7(owner, system_memory, pci_address_space,
> > +                               reserved_memory_end);
> > +}
> > +
> > +pc_pci_as_mapping_init_fn pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_8;
> > +
> >  void pc_acpi_init(const char *default_dsdt)
> >  {
> >      char *filename;
> > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> > index 36f2495..e1fe85a 100644
> > --- a/hw/i386/pc_piix.c
> > +++ b/hw/i386/pc_piix.c
> > @@ -249,6 +249,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
> >  static void pc_compat_1_7(QEMUMachineInitArgs *args)
> >  {
> >      smbios_type1_defaults = false;
> > +    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
> >  }
> >  
> >  static void pc_compat_1_6(QEMUMachineInitArgs *args)
> > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > index 50ca458..5525465 100644
> > --- a/hw/i386/pc_q35.c
> > +++ b/hw/i386/pc_q35.c
> > @@ -233,6 +233,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
> >  static void pc_compat_1_7(QEMUMachineInitArgs *args)
> >  {
> >      smbios_type1_defaults = false;
> > +    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
> >  }
> >  
> >  static void pc_compat_1_6(QEMUMachineInitArgs *args)
> 
> I don't much like this: why not use a global flag like we do
> for other properties?
because flag would add extra branching clattering code, while
overriding function makes caller cleaner and potentially maps
well into method override when machines are converted to QOM objects.
So why not to try this vs flags?

> 
> Also, 1_8 should be replaced with 2_0 now.
sure

> 
> > diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> > index 63be7f6..615ab0d 100644
> > --- a/hw/pci-host/piix.c
> > +++ b/hw/pci-host/piix.c
> > @@ -352,7 +352,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
> >  
> >      /* setup pci memory mapping */
> >      pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
> > -                           f->pci_address_space);
> > +                           f->pci_address_space,
> > +                           0x100000000ULL + above_4g_mem_size);
> >  
> >      memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
> >                               f->pci_address_space, 0xa0000, 0x20000);
> > diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> > index 81c8240..6e28418 100644
> > --- a/hw/pci-host/q35.c
> > +++ b/hw/pci-host/q35.c
> > @@ -359,7 +359,8 @@ static int mch_init(PCIDevice *d)
> >  
> >      /* setup pci memory mapping */
> >      pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
> > -                           mch->pci_address_space);
> > +                           mch->pci_address_space,
> > +                           0x100000000ULL + mch->above_4g_mem_size);
> >  
> >      /* smram */
> >      cpu_smm_register(&mch_set_smm, mch);
> > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > index 9af09d3..c4e8048 100644
> > --- a/include/hw/i386/pc.h
> > +++ b/include/hw/i386/pc.h
> > @@ -129,8 +129,15 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
> >  #define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
> >  
> >  
> > -void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
> > -                            MemoryRegion *pci_address_space);
> > +typedef
> > +void (*pc_pci_as_mapping_init_fn)(Object *owner, MemoryRegion *system_memory,
> > +                                  MemoryRegion *pci_address_space,
> > +                                  uint64_t reserved_memory_end);
> > +extern pc_pci_as_mapping_init_fn pc_pci_as_mapping_init;
> > +
> > +void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
> > +                                MemoryRegion *pci_address_space,
> > +                                uint64_t reserved_memory_end);
> >  
> >  FWCfgState *pc_memory_init(MemoryRegion *system_memory,
> >                             const char *kernel_filename,
> > -- 
> > 1.7.1
> 

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

* Re: [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS
  2013-12-20 12:48     ` Igor Mammedov
@ 2013-12-22 11:20       ` Michael S. Tsirkin
  0 siblings, 0 replies; 143+ messages in thread
From: Michael S. Tsirkin @ 2013-12-22 11:20 UTC (permalink / raw)
  To: Igor Mammedov
  Cc: peter.maydell, aliguori, marcel.a, armbru, stefanb, mjt,
	qemu-devel, mdroth, vasilis.liaskovitis, quintela, kraxel,
	stefanha, hutao, pbonzini, lcapitulino, chegu_vinod, afaerber

On Fri, Dec 20, 2013 at 01:48:47PM +0100, Igor Mammedov wrote:
> On Thu, 19 Dec 2013 16:35:05 +0200
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > On Thu, Nov 21, 2013 at 03:38:24AM +0100, Igor Mammedov wrote:
> > > '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>
> > > ---
> > > v2:
> > >    * disable 'etc/reserved-memory-end' for 1.7 and older machine types
> > > ---
> > >  hw/i386/pc.c         |   27 +++++++++++++++++++++++++--
> > >  hw/i386/pc_piix.c    |    1 +
> > >  hw/i386/pc_q35.c     |    1 +
> > >  hw/pci-host/piix.c   |    3 ++-
> > >  hw/pci-host/q35.c    |    3 ++-
> > >  include/hw/i386/pc.h |   11 +++++++++--
> > >  6 files changed, 40 insertions(+), 6 deletions(-)
> > > 
> > > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > > index 6c82ada..ba82c67 100644
> > > --- a/hw/i386/pc.c
> > > +++ b/hw/i386/pc.c
> > > @@ -1094,14 +1094,37 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
> > >  }
> > >  
> > >  /* setup pci memory address space mapping into system address space */
> > > -void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
> > > -                            MemoryRegion *pci_address_space)
> > > +void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
> > > +                                MemoryRegion *pci_address_space,
> > > +                                uint64_t reserved_memory_end)
> > >  {
> > >      /* Set to lower priority than RAM */
> > >      memory_region_add_subregion_overlap(system_memory, 0x0,
> > >                                          pci_address_space, -1);
> > >  }
> > >  
> > > +static
> > > +void pc_pci_as_mapping_init_1_8(Object *owner, MemoryRegion *system_memory,
> > > +                                MemoryRegion *pci_address_space,
> > > +                                uint64_t reserved_memory_end)
> > > +{
> > > +    uint64_t *val;
> > > +    FWCfgState *fw_cfg = fw_cfg_find();
> > > +    g_assert(fw_cfg);
> > > +    /*
> > > +     *  Align address at 1G, this makes sure it can be exactly covered
> > > +     *  with a PAT entry even when using huge pages.
> > > +     */
> > > +    val = g_malloc(sizeof(*val));
> > > +    *val = cpu_to_le64(ROUND_UP(reserved_memory_end, 0x1ULL << 30));
> > > +    fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val));
> > > +
> > > +    pc_pci_as_mapping_init_1_7(owner, system_memory, pci_address_space,
> > > +                               reserved_memory_end);
> > > +}
> > > +
> > > +pc_pci_as_mapping_init_fn pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_8;
> > > +
> > >  void pc_acpi_init(const char *default_dsdt)
> > >  {
> > >      char *filename;
> > > diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
> > > index 36f2495..e1fe85a 100644
> > > --- a/hw/i386/pc_piix.c
> > > +++ b/hw/i386/pc_piix.c
> > > @@ -249,6 +249,7 @@ static void pc_init_pci(QEMUMachineInitArgs *args)
> > >  static void pc_compat_1_7(QEMUMachineInitArgs *args)
> > >  {
> > >      smbios_type1_defaults = false;
> > > +    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
> > >  }
> > >  
> > >  static void pc_compat_1_6(QEMUMachineInitArgs *args)
> > > diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
> > > index 50ca458..5525465 100644
> > > --- a/hw/i386/pc_q35.c
> > > +++ b/hw/i386/pc_q35.c
> > > @@ -233,6 +233,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
> > >  static void pc_compat_1_7(QEMUMachineInitArgs *args)
> > >  {
> > >      smbios_type1_defaults = false;
> > > +    pc_pci_as_mapping_init = pc_pci_as_mapping_init_1_7;
> > >  }
> > >  
> > >  static void pc_compat_1_6(QEMUMachineInitArgs *args)
> > 
> > I don't much like this: why not use a global flag like we do
> > for other properties?
> because flag would add extra branching clattering code, while
> overriding function makes caller cleaner and potentially maps
> well into method override when machines are converted to QOM objects.
> So why not to try this vs flags?

For consistency with other code. We have too many unfinished
conversions across the codebase, they are a bigger problem
than some branches here and there.

So I would say let's delay these experiments until this QOM
cleanup happens.

> > 
> > Also, 1_8 should be replaced with 2_0 now.
> sure
> 
> > 
> > > diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
> > > index 63be7f6..615ab0d 100644
> > > --- a/hw/pci-host/piix.c
> > > +++ b/hw/pci-host/piix.c
> > > @@ -352,7 +352,8 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
> > >  
> > >      /* setup pci memory mapping */
> > >      pc_pci_as_mapping_init(OBJECT(f), f->system_memory,
> > > -                           f->pci_address_space);
> > > +                           f->pci_address_space,
> > > +                           0x100000000ULL + above_4g_mem_size);
> > >  
> > >      memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",
> > >                               f->pci_address_space, 0xa0000, 0x20000);
> > > diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
> > > index 81c8240..6e28418 100644
> > > --- a/hw/pci-host/q35.c
> > > +++ b/hw/pci-host/q35.c
> > > @@ -359,7 +359,8 @@ static int mch_init(PCIDevice *d)
> > >  
> > >      /* setup pci memory mapping */
> > >      pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory,
> > > -                           mch->pci_address_space);
> > > +                           mch->pci_address_space,
> > > +                           0x100000000ULL + mch->above_4g_mem_size);
> > >  
> > >      /* smram */
> > >      cpu_smm_register(&mch_set_smm, mch);
> > > diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
> > > index 9af09d3..c4e8048 100644
> > > --- a/include/hw/i386/pc.h
> > > +++ b/include/hw/i386/pc.h
> > > @@ -129,8 +129,15 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
> > >  #define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
> > >  
> > >  
> > > -void pc_pci_as_mapping_init(Object *owner, MemoryRegion *system_memory,
> > > -                            MemoryRegion *pci_address_space);
> > > +typedef
> > > +void (*pc_pci_as_mapping_init_fn)(Object *owner, MemoryRegion *system_memory,
> > > +                                  MemoryRegion *pci_address_space,
> > > +                                  uint64_t reserved_memory_end);
> > > +extern pc_pci_as_mapping_init_fn pc_pci_as_mapping_init;
> > > +
> > > +void pc_pci_as_mapping_init_1_7(Object *owner, MemoryRegion *system_memory,
> > > +                                MemoryRegion *pci_address_space,
> > > +                                uint64_t reserved_memory_end);
> > >  
> > >  FWCfgState *pc_memory_init(MemoryRegion *system_memory,
> > >                             const char *kernel_filename,
> > > -- 
> > > 1.7.1
> > 

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

end of thread, other threads:[~2013-12-22 11:17 UTC | newest]

Thread overview: 143+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-21  2:38 [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 01/27] acpi: factor out common pm_update_sci() into acpi core Igor Mammedov
2013-12-05 12:37   ` Michael S. Tsirkin
2013-12-05 15:11     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 02/27] rename pci_hotplug_fn to hotplug_fn and make it available for other devices Igor Mammedov
2013-11-25 12:49   ` Paolo Bonzini
2013-11-25 13:11     ` Paolo Bonzini
2013-11-25 15:57     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 03/27] pc: add 'etc/reserved-memory-end' fw_cfg interface for SeaBIOS Igor Mammedov
2013-12-19 14:35   ` Michael S. Tsirkin
2013-12-20 12:48     ` Igor Mammedov
2013-12-22 11:20       ` Michael S. Tsirkin
2013-11-21  2:38 ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Igor Mammedov
2013-11-21  6:01   ` Li Guang
2013-11-21 13:45     ` Igor Mammedov
2013-11-21 10:12   ` Markus Armbruster
2013-11-26 13:17     ` Igor Mammedov
2013-11-26 14:49       ` Markus Armbruster
2013-11-26 16:55         ` Igor Mammedov
2013-11-27 14:35           ` Markus Armbruster
2013-11-27 15:28             ` Igor Mammedov
2013-11-27 17:31               ` Markus Armbruster
2013-11-27  0:27         ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Igor Mammedov
2013-11-27  0:27           ` [Qemu-devel] [PATCH 05/28] vl.c: extend -m option to support options for memory hotplug Igor Mammedov
2013-12-10  7:23           ` [Qemu-devel] [PATCH 04/28] vl: convert -m to QemuOpts Paolo Bonzini
2013-12-10 10:53             ` Igor Mammedov
2013-11-25 12:51   ` [Qemu-devel] [PATCH 04/27] vl: convert -m to qemu_opts_parse() Paolo Bonzini
2013-11-27  0:32     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 05/27] qapi: add SIZE type parser to string_input_visitor Igor Mammedov
2013-11-21 10:15   ` Markus Armbruster
2013-11-25 15:36     ` Igor Mammedov
2013-11-25 16:04       ` Michael S. Tsirkin
2013-11-25 16:32         ` Paolo Bonzini
2013-11-25 16:43           ` Eric Blake
2013-11-25 17:01             ` Paolo Bonzini
2013-11-27 14:15             ` Markus Armbruster
2013-11-27 15:17               ` Paolo Bonzini
2013-11-27 17:02                 ` Markus Armbruster
2013-11-27 17:10                   ` Paolo Bonzini
2013-12-19 14:40             ` Michael S. Tsirkin
2013-12-19 15:14               ` Markus Armbruster
2013-12-19 15:32                 ` Michael S. Tsirkin
2013-12-19 15:31               ` Paolo Bonzini
2013-12-19 15:40                 ` Michael S. Tsirkin
2013-12-19 15:46                   ` Paolo Bonzini
2013-11-21  2:38 ` [Qemu-devel] [PATCH 06/27] get reference to /backend container via qemu_get_backend() Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 07/27] add memdev backend infrastructure Igor Mammedov
2013-11-25 12:54   ` Paolo Bonzini
2013-11-25 16:01     ` Igor Mammedov
2013-11-25 16:09       ` Paolo Bonzini
2013-11-27 14:37         ` Igor Mammedov
2013-11-27 15:21           ` Paolo Bonzini
2013-11-27 15:57             ` Igor Mammedov
2013-11-27 15:25   ` Eric Blake
2013-11-27 16:09     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 08/27] dimm: implement dimm device abstraction Igor Mammedov
2013-11-25 12:57   ` Paolo Bonzini
2013-11-25 15:10     ` Igor Mammedov
2013-11-25 15:16       ` Paolo Bonzini
2013-11-21  2:38 ` [Qemu-devel] [PATCH 09/27] dimm: map DimmDevice into DimBus provided address space Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 10/27] dimm: add busy slot check and slot auto-allocation Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 11/27] dimm: add busy address check and address auto-allocation Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 12/27] dimm: add hotplug callback to DimmBus Igor Mammedov
2013-11-25 13:01   ` Paolo Bonzini
2013-11-25 14:40     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 13/27] acpi: memory hotplug ACPI hardware implementation Igor Mammedov
2013-11-21  9:42   ` Michael S. Tsirkin
2013-11-21 14:21     ` Igor Mammedov
2013-11-21 14:38       ` Michael S. Tsirkin
2013-11-22 17:14         ` Igor Mammedov
2013-11-24 10:58           ` Michael S. Tsirkin
2013-11-25  7:27             ` Markus Armbruster
2013-11-25 13:45               ` Paolo Bonzini
2013-11-25 14:18                 ` Igor Mammedov
2013-11-25 14:31                   ` Paolo Bonzini
2013-11-25 14:57                     ` Igor Mammedov
2013-11-25 13:56             ` Igor Mammedov
2013-11-27 17:59   ` Eric Blake
2013-11-21  2:38 ` [Qemu-devel] [PATCH 14/27] acpi: initialize memory hotplug ACPI PIIX4 hardware Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 15/27] acpi: piix4: add memory-hotplug-io-base property to piix4_pm Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 16/27] acpi: ich9: allow guest to clear SCI rised by GPE Igor Mammedov
2013-11-21  7:14   ` Michael S. Tsirkin
2013-11-21  8:12     ` Hu Tao
2013-11-21  8:18       ` Li Guang
2013-11-21  8:29         ` Michael S. Tsirkin
2013-11-21  8:32           ` Li Guang
2013-11-21  9:43             ` Michael S. Tsirkin
2013-11-22  0:57               ` Li Guang
2013-11-25 11:13                 ` Igor Mammedov
2013-11-26  0:29                   ` Li Guang
2013-11-26 22:36                     ` Igor Mammedov
2013-11-27  0:15                       ` Li Guang
2013-11-27  0:57                         ` Igor Mammedov
2013-11-27  1:48                           ` Li Guang
2013-11-27  9:43                             ` Paolo Bonzini
2013-11-21 13:19             ` Igor Mammedov
2013-11-22  1:03               ` Li Guang
2013-11-21  8:26       ` Michael S. Tsirkin
2013-11-21  8:28         ` Hu Tao
2013-11-21 13:31           ` Igor Mammedov
2013-11-21 13:21         ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 17/27] acpi: initialize memory hotplug ACPI ICH9 hardware Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 18/27] acpi: ich9: add memory-hotplug-io-base property to ich9_pm Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 19/27] acpi: piix4/ich9: add optional vmstate field for MemHotplugState migration Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 20/27] pc: piix: make PCII440FXState type public Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 21/27] pc: add memory hotplug 440fx machine Igor Mammedov
2013-11-21  5:48   ` Li Guang
2013-11-21 14:13     ` Andreas Färber
2013-11-21 14:34       ` Igor Mammedov
2013-11-21 14:39         ` Michael S. Tsirkin
2013-11-21 16:09         ` Andreas Färber
2013-11-21 16:17           ` Michael S. Tsirkin
2013-11-25 10:41           ` Igor Mammedov
2013-11-25 17:00             ` Andreas Färber
2013-11-26 20:26               ` Igor Mammedov
2013-11-22 14:23   ` Gerd Hoffmann
2013-11-25 11:00     ` Igor Mammedov
2013-11-25 11:39       ` Gerd Hoffmann
2013-11-25 13:34         ` Igor Mammedov
2013-11-25 13:35         ` Paolo Bonzini
2013-11-25 14:24           ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 22/27] pc: add memory hotplug Q35 machine Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 23/27] pc: ACPI BIOS: implement memory hotplug interface Igor Mammedov
2013-11-21  9:37   ` Michael S. Tsirkin
2013-11-25 14:39     ` Igor Mammedov
2013-12-16 19:50       ` Michael S. Tsirkin
2013-12-16 21:42         ` Igor Mammedov
2013-11-25 13:42   ` Paolo Bonzini
2013-11-25 14:26     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 24/27] pc: ACPI BIOS: add ssdt-mem.hex.generated and update ssdt-misc.hex.generated Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 25/27] pc: ACPI BIOS: use enum for defining memory affinity flags Igor Mammedov
2013-11-21  7:20   ` Michael S. Tsirkin
2013-11-25 10:11     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 26/27] pc: ACPI BIOS: reserve SRAT entry for hotplug mem hole Igor Mammedov
2013-11-21  7:18   ` Michael S. Tsirkin
2013-11-25 10:11     ` Igor Mammedov
2013-11-21  2:38 ` [Qemu-devel] [PATCH 27/27] pc: ACPI BIOS: make GPE.3 handle memory hotplug event on PIIX and Q35 machines Igor Mammedov
2013-11-21  6:20 ` [Qemu-devel] [PATCH 00/27 RFC v7] ACPI memory hotplug Michael S. Tsirkin
2013-11-21 13:39   ` Igor Mammedov
2013-11-21 13:43     ` Michael S. Tsirkin
2013-11-21 14:37       ` Igor Mammedov
2013-11-21 14:45         ` Michael S. Tsirkin
2013-11-25 10:09           ` Igor Mammedov

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