Re: [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space

2014-04-17 Thread Hu Tao
On Wed, Apr 16, 2014 at 04:23:44PM +0200, Igor Mammedov wrote:
 On Wed, 16 Apr 2014 16:59:25 +0800
 Hu Tao hu...@cn.fujitsu.com wrote:
 
  On Fri, Apr 04, 2014 at 03:36:38PM +0200, Igor Mammedov wrote:
   initialize and map hotplug memory address space container
   into guest's RAM address space.
   
   Signed-off-by: Igor Mammedov imamm...@redhat.com
   ---
hw/i386/pc.c | 19 +--
include/hw/i386/pc.h | 10 ++
2 files changed, 27 insertions(+), 2 deletions(-)
   
   diff --git a/hw/i386/pc.c b/hw/i386/pc.c
   index 32b4003..69e4225 100644
   --- a/hw/i386/pc.c
   +++ b/hw/i386/pc.c
   @@ -1171,6 +1171,9 @@ FWCfgState *pc_memory_init(MemoryRegion 
   *system_memory,
MemoryRegion *ram, *option_rom_mr;
MemoryRegion *ram_below_4g, *ram_above_4g;
FWCfgState *fw_cfg;
   +ram_addr_t ram_size = below_4g_mem_size + above_4g_mem_size;
   +MachineState *machine = MACHINE(qdev_get_machine());
   +PCMachineState *pcms = PC_MACHINE(machine);

linux_boot = (kernel_filename != NULL);

   @@ -1179,8 +1182,7 @@ FWCfgState *pc_memory_init(MemoryRegion 
   *system_memory,
 * with older qemus that used qemu_ram_alloc().
 */
ram = g_malloc(sizeof(*ram));
   -memory_region_init_ram(ram, NULL, pc.ram,
   -   below_4g_mem_size + above_4g_mem_size);
   +memory_region_init_ram(ram, NULL, pc.ram, ram_size);
vmstate_register_ram_global(ram);
*ram_memory = ram;
ram_below_4g = g_malloc(sizeof(*ram_below_4g));
   @@ -1197,6 +1199,19 @@ FWCfgState *pc_memory_init(MemoryRegion 
   *system_memory,
e820_add_entry(0x1ULL, above_4g_mem_size, E820_RAM);
}

   +/* initialize hotplug memory address space */
   +if (ram_size  machine-init_args.maxram_size) {
   +ram_addr_t hotplug_mem_size =
   +machine-init_args.maxram_size - ram_size;
   +
   +pcms-hotplug_memory_base =
   +ROUND_UP(0x1ULL + above_4g_mem_size, 1ULL  30);
  
  -m maxmem should be limited otherwise hotplug_memory_base + maxmem can
  overflow(in dimm_get_free_addr()).
 If overflow happens than dimm_get_free_addr() will return error,
 if you look its end.
 
 dimm_get_free_addr() {
 ...
  if (new_start  address_space_start) {
 error_setg(...
 
 
 
 that of cause doesn't mean that maxmem limit shouldn't be set and verified
 with proper error reporting in case of one.

Yeah. With command line -object memory-ram,id=foo,size=512M -m 
512M,slots=4,maxmem=17179869183G
It reports an error can't add memory [0x1:0x2000] beyond 
0xa000 when hotplugging
memory-ram foo but shouldn't.

 Is there any suggestion as to what max supported RAM amount should be?

max ram shouldn't exceed unused memory range above 4g
(UINT64_MAX - 0x1 - above_4g_mem_size), that is:

maxram_size - ram_size = UINT64_MAX - 0x1 - above_4g_mem_size

Following patch does the check:

diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 1329a50..f55e8c6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -68,6 +68,20 @@ static bool smbios_type1_defaults = true;
 static bool gigabyte_align = true;
 static bool has_reserved_memory = true;
 
+ram_addr_t get_above_4g_mem_size(ram_addr_t ram_size)
+{
+ram_addr_t above_4g_mem_size;
+
+if (ram_size = 0xe000) {
+ram_addr_t lowmem = gigabyte_align ? 0xc000 : 0xe000;
+above_4g_mem_size = ram_size - lowmem;
+} else {
+above_4g_mem_size = 0;
+}
+
+return above_4g_mem_size;
+}
+
 /* PC hardware initialisation */
 static void pc_init1(QEMUMachineInitArgs *args,
  int pci_enabled,
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 88efdaa..b03fb64 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -273,6 +273,7 @@ void pc_system_firmware_init(MemoryRegion *rom_memory,
 
 /* pvpanic.c */
 uint16_t pvpanic_port(void);
+ram_addr_t get_above_4g_mem_size(ram_addr_t ram_size);
 
 /* e820 types */
 #define E820_RAM1
diff --git a/vl.c b/vl.c
index 8f7b04e..095068e 100644
--- a/vl.c
+++ b/vl.c
@@ -3378,6 +3378,14 @@ int main(int argc, char **argv, char **envp)
 exit(EXIT_FAILURE);
 }
 
+ram_addr_t above_4g_mem = get_above_4g_mem_size(ram_size);
+if (sz - ram_size  UINT64_MAX - 0x1 - 
above_4g_mem) {
+fprintf(stderr, qemu: invalid -m option value: maxmem 

+(% PRIu64 ) out of range.\n, sz);
+fprintf(stderr, maxmem: % PRIu64 \n, UINT64_MAX - 
0x1 - above_4g_mem + ram_size);
+exit(EXIT_FAILURE);
+}
+
 slots = qemu_opt_get_number(opts, slots, 0);
 if ((sz  ram_size)  !slots) {
 fprintf(stderr, qemu: invalid 

Re: [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space

2014-04-17 Thread Igor Mammedov
On Thu, 17 Apr 2014 14:17:37 +0800
Hu Tao hu...@cn.fujitsu.com wrote:

 max ram shouldn't exceed unused memory range above 4g
 (UINT64_MAX - 0x1 - above_4g_mem_size), that is:

max_ram is not amount of RAM after initial RAM, but rather
RAM limit including initial RAM.

There should be check at somewhere in pc_memory_init() that
the last RAM address won't got beyond arch supported limit.



Re: [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space

2014-04-16 Thread Hu Tao
On Fri, Apr 04, 2014 at 03:36:38PM +0200, Igor Mammedov wrote:
 initialize and map hotplug memory address space container
 into guest's RAM address space.
 
 Signed-off-by: Igor Mammedov imamm...@redhat.com
 ---
  hw/i386/pc.c | 19 +--
  include/hw/i386/pc.h | 10 ++
  2 files changed, 27 insertions(+), 2 deletions(-)
 
 diff --git a/hw/i386/pc.c b/hw/i386/pc.c
 index 32b4003..69e4225 100644
 --- a/hw/i386/pc.c
 +++ b/hw/i386/pc.c
 @@ -1171,6 +1171,9 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
  MemoryRegion *ram, *option_rom_mr;
  MemoryRegion *ram_below_4g, *ram_above_4g;
  FWCfgState *fw_cfg;
 +ram_addr_t ram_size = below_4g_mem_size + above_4g_mem_size;
 +MachineState *machine = MACHINE(qdev_get_machine());
 +PCMachineState *pcms = PC_MACHINE(machine);
  
  linux_boot = (kernel_filename != NULL);
  
 @@ -1179,8 +1182,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
   * with older qemus that used qemu_ram_alloc().
   */
  ram = g_malloc(sizeof(*ram));
 -memory_region_init_ram(ram, NULL, pc.ram,
 -   below_4g_mem_size + above_4g_mem_size);
 +memory_region_init_ram(ram, NULL, pc.ram, ram_size);
  vmstate_register_ram_global(ram);
  *ram_memory = ram;
  ram_below_4g = g_malloc(sizeof(*ram_below_4g));
 @@ -1197,6 +1199,19 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
  e820_add_entry(0x1ULL, above_4g_mem_size, E820_RAM);
  }
  
 +/* initialize hotplug memory address space */
 +if (ram_size  machine-init_args.maxram_size) {
 +ram_addr_t hotplug_mem_size =
 +machine-init_args.maxram_size - ram_size;
 +
 +pcms-hotplug_memory_base =
 +ROUND_UP(0x1ULL + above_4g_mem_size, 1ULL  30);

-m maxmem should be limited otherwise hotplug_memory_base + maxmem can
overflow(in dimm_get_free_addr()).




Re: [Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space

2014-04-16 Thread Igor Mammedov
On Wed, 16 Apr 2014 16:59:25 +0800
Hu Tao hu...@cn.fujitsu.com wrote:

 On Fri, Apr 04, 2014 at 03:36:38PM +0200, Igor Mammedov wrote:
  initialize and map hotplug memory address space container
  into guest's RAM address space.
  
  Signed-off-by: Igor Mammedov imamm...@redhat.com
  ---
   hw/i386/pc.c | 19 +--
   include/hw/i386/pc.h | 10 ++
   2 files changed, 27 insertions(+), 2 deletions(-)
  
  diff --git a/hw/i386/pc.c b/hw/i386/pc.c
  index 32b4003..69e4225 100644
  --- a/hw/i386/pc.c
  +++ b/hw/i386/pc.c
  @@ -1171,6 +1171,9 @@ FWCfgState *pc_memory_init(MemoryRegion 
  *system_memory,
   MemoryRegion *ram, *option_rom_mr;
   MemoryRegion *ram_below_4g, *ram_above_4g;
   FWCfgState *fw_cfg;
  +ram_addr_t ram_size = below_4g_mem_size + above_4g_mem_size;
  +MachineState *machine = MACHINE(qdev_get_machine());
  +PCMachineState *pcms = PC_MACHINE(machine);
   
   linux_boot = (kernel_filename != NULL);
   
  @@ -1179,8 +1182,7 @@ FWCfgState *pc_memory_init(MemoryRegion 
  *system_memory,
* with older qemus that used qemu_ram_alloc().
*/
   ram = g_malloc(sizeof(*ram));
  -memory_region_init_ram(ram, NULL, pc.ram,
  -   below_4g_mem_size + above_4g_mem_size);
  +memory_region_init_ram(ram, NULL, pc.ram, ram_size);
   vmstate_register_ram_global(ram);
   *ram_memory = ram;
   ram_below_4g = g_malloc(sizeof(*ram_below_4g));
  @@ -1197,6 +1199,19 @@ FWCfgState *pc_memory_init(MemoryRegion 
  *system_memory,
   e820_add_entry(0x1ULL, above_4g_mem_size, E820_RAM);
   }
   
  +/* initialize hotplug memory address space */
  +if (ram_size  machine-init_args.maxram_size) {
  +ram_addr_t hotplug_mem_size =
  +machine-init_args.maxram_size - ram_size;
  +
  +pcms-hotplug_memory_base =
  +ROUND_UP(0x1ULL + above_4g_mem_size, 1ULL  30);
 
 -m maxmem should be limited otherwise hotplug_memory_base + maxmem can
 overflow(in dimm_get_free_addr()).
If overflow happens than dimm_get_free_addr() will return error,
if you look its end.

dimm_get_free_addr() {
...
 if (new_start  address_space_start) {
error_setg(...



that of cause doesn't mean that maxmem limit shouldn't be set and verified
with proper error reporting in case of one.
Is there any suggestion as to what max supported RAM amount should be?



[Qemu-devel] [PATCH 13/35] pc: initialize memory hotplug address space

2014-04-04 Thread Igor Mammedov
initialize and map hotplug memory address space container
into guest's RAM address space.

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

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 32b4003..69e4225 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1171,6 +1171,9 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
 MemoryRegion *ram, *option_rom_mr;
 MemoryRegion *ram_below_4g, *ram_above_4g;
 FWCfgState *fw_cfg;
+ram_addr_t ram_size = below_4g_mem_size + above_4g_mem_size;
+MachineState *machine = MACHINE(qdev_get_machine());
+PCMachineState *pcms = PC_MACHINE(machine);
 
 linux_boot = (kernel_filename != NULL);
 
@@ -1179,8 +1182,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
  * with older qemus that used qemu_ram_alloc().
  */
 ram = g_malloc(sizeof(*ram));
-memory_region_init_ram(ram, NULL, pc.ram,
-   below_4g_mem_size + above_4g_mem_size);
+memory_region_init_ram(ram, NULL, pc.ram, ram_size);
 vmstate_register_ram_global(ram);
 *ram_memory = ram;
 ram_below_4g = g_malloc(sizeof(*ram_below_4g));
@@ -1197,6 +1199,19 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
 e820_add_entry(0x1ULL, above_4g_mem_size, E820_RAM);
 }
 
+/* initialize hotplug memory address space */
+if (ram_size  machine-init_args.maxram_size) {
+ram_addr_t hotplug_mem_size =
+machine-init_args.maxram_size - ram_size;
+
+pcms-hotplug_memory_base =
+ROUND_UP(0x1ULL + above_4g_mem_size, 1ULL  30);
+
+memory_region_init(pcms-hotplug_memory, OBJECT(pcms),
+   hotplug-memory, hotplug_mem_size);
+memory_region_add_subregion(system_memory, pcms-hotplug_memory_base,
+pcms-hotplug_memory);
+}
 
 /* Initialize PC system firmware */
 pc_system_firmware_init(rom_memory, guest_info-isapc_ram_fw);
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index b3bc0f7..a1f21ba 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -16,9 +16,19 @@
 
 #define HPET_INTCAP hpet-intcap
 
+/**
+ * PCMachineState:
+ * @hotplug_memory_base: address in guest RAM address space where hotplug 
memory
+ * address space begins.
+ * @hotplug_memory: hotplug memory addess space container
+ */
 struct PCMachineState {
 /* private */
 MachineState parent_obj;
+
+/* public */
+ram_addr_t hotplug_memory_base;
+MemoryRegion hotplug_memory;
 };
 
 struct PCMachineClass {
-- 
1.9.0