On 03/31/2017 04:41 PM, Haozhong Zhang wrote:
If option 'reserved-size=RSVD' is present, QEMU will reserve an address range of size 'RSVD' after the ending address of pc-dimm device. For the following example, -object memory-backend-file,id=mem0,size=4G,... -device nvdimm,id=dimm0,memdev=mem0,reserved-size=4K,... -device pc-dimm,id=dimm1,... if dimm0 is allocated to address N ~ N+4G, the address range of dimm1 will start from N+4G+4K or higher. Its current usage is to reserve spaces for flush hint addresses of nvdimm devices. Signed-off-by: Haozhong Zhang <haozhong.zh...@intel.com> --- hw/mem/pc-dimm.c | 48 +++++++++++++++++++++++++++++++++++++++++++++--- include/hw/mem/pc-dimm.h | 2 ++ 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 9e8dab0..13dcd71 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -28,6 +28,7 @@ #include "sysemu/kvm.h" #include "trace.h" #include "hw/virtio/vhost.h" +#include "exec/address-spaces.h" typedef struct pc_dimms_capacity { uint64_t size; @@ -44,7 +45,12 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms, MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm); Error *local_err = NULL; uint64_t existing_dimms_capacity = 0; - uint64_t addr; + uint64_t addr, size = memory_region_size(mr); + + size += object_property_get_int(OBJECT(dimm), PC_DIMM_RSVD_PROP, &local_err); + if (local_err) { + goto out; + } addr = object_property_get_int(OBJECT(dimm), PC_DIMM_ADDR_PROP, &local_err); if (local_err) { @@ -54,7 +60,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms, addr = pc_dimm_get_free_addr(hpms->base, memory_region_size(&hpms->mr), !addr ? NULL : &addr, align, - memory_region_size(mr), &local_err); + size, &local_err); if (local_err) { goto out; } @@ -64,7 +70,7 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms, goto out; } - if (existing_dimms_capacity + memory_region_size(mr) > + if (existing_dimms_capacity + size > machine->maxram_size - machine->ram_size) { error_setg(&local_err, "not enough space, currently 0x%" PRIx64 " in use of total hot pluggable 0x" RAM_ADDR_FMT, @@ -315,6 +321,9 @@ uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, PCDIMMDevice *dimm = item->data; uint64_t dimm_size = object_property_get_int(OBJECT(dimm), PC_DIMM_SIZE_PROP, + errp) + + object_property_get_int(OBJECT(dimm), + PC_DIMM_RSVD_PROP, errp); if (errp && *errp) { goto out; @@ -382,6 +391,37 @@ static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name, error_propagate(errp, local_err); }
Should count the reserved size in pc_existing_dimms_capacity_internal() too.