diff options
Diffstat (limited to 'qemu/hw/mem/pc-dimm.c')
-rw-r--r-- | qemu/hw/mem/pc-dimm.c | 61 |
1 files changed, 26 insertions, 35 deletions
diff --git a/qemu/hw/mem/pc-dimm.c b/qemu/hw/mem/pc-dimm.c index bb04862de..9e7de5682 100644 --- a/qemu/hw/mem/pc-dimm.c +++ b/qemu/hw/mem/pc-dimm.c @@ -18,13 +18,16 @@ * License along with this library; if not, see <http://www.gnu.org/licenses/> */ +#include "qemu/osdep.h" #include "hw/mem/pc-dimm.h" +#include "qapi/error.h" #include "qemu/config-file.h" #include "qapi/visitor.h" #include "qemu/range.h" #include "sysemu/numa.h" #include "sysemu/kvm.h" #include "trace.h" +#include "hw/virtio/vhost.h" typedef struct pc_dimms_capacity { uint64_t size; @@ -95,6 +98,12 @@ void pc_dimm_memory_plug(DeviceState *dev, MemoryHotplugState *hpms, goto out; } + if (!vhost_has_free_slot()) { + error_setg(&local_err, "a used vhost backend has no free" + " memory slots left"); + goto out; + } + memory_region_add_subregion(&hpms->mr, addr - hpms->base, mr); vmstate_register_ram(mr, dev); numa_set_mem_node_id(addr, memory_region_size(mr), dimm->node); @@ -172,7 +181,7 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque) NULL); di->memdev = object_get_canonical_path(OBJECT(dimm->hostmem)); - info->dimm = di; + info->u.dimm.data = di; elem->value = info; elem->next = NULL; **prev = elem; @@ -184,32 +193,6 @@ int qmp_pc_dimm_device_list(Object *obj, void *opaque) return 0; } -ram_addr_t get_current_ram_size(void) -{ - MemoryDeviceInfoList *info_list = NULL; - MemoryDeviceInfoList **prev = &info_list; - MemoryDeviceInfoList *info; - ram_addr_t size = ram_size; - - qmp_pc_dimm_device_list(qdev_get_machine(), &prev); - for (info = info_list; info; info = info->next) { - MemoryDeviceInfo *value = info->value; - - if (value) { - switch (value->kind) { - case MEMORY_DEVICE_INFO_KIND_DIMM: - size += value->dimm->size; - break; - default: - break; - } - } - } - qapi_free_MemoryDeviceInfoList(info_list); - - return size; -} - static int pc_dimm_slot2bitmap(Object *obj, void *opaque) { unsigned long *bitmap = opaque; @@ -365,8 +348,8 @@ static Property pc_dimm_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void pc_dimm_get_size(Object *obj, Visitor *v, void *opaque, - const char *name, Error **errp) +static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) { int64_t value; MemoryRegion *mr; @@ -375,22 +358,29 @@ static void pc_dimm_get_size(Object *obj, Visitor *v, void *opaque, mr = host_memory_backend_get_memory(dimm->hostmem, errp); value = memory_region_size(mr); - visit_type_int(v, &value, name, errp); + visit_type_int(v, name, &value, errp); } static void pc_dimm_check_memdev_is_busy(Object *obj, const char *name, Object *val, Error **errp) { MemoryRegion *mr; + Error *local_err = NULL; - mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), errp); + mr = host_memory_backend_get_memory(MEMORY_BACKEND(val), &local_err); + if (local_err) { + goto out; + } if (memory_region_is_mapped(mr)) { char *path = object_get_canonical_path_component(val); - error_setg(errp, "can't use already busy memdev: %s", path); + error_setg(&local_err, "can't use already busy memdev: %s", path); g_free(path); } else { - qdev_prop_allow_set_link_before_realize(obj, name, val, errp); + qdev_prop_allow_set_link_before_realize(obj, name, val, &local_err); } + +out: + error_propagate(errp, local_err); } static void pc_dimm_init(Object *obj) @@ -414,10 +404,11 @@ static void pc_dimm_realize(DeviceState *dev, Error **errp) error_setg(errp, "'" PC_DIMM_MEMDEV_PROP "' property is not set"); return; } - if ((nb_numa_nodes > 0) && (dimm->node >= nb_numa_nodes)) { + if (((nb_numa_nodes > 0) && (dimm->node >= nb_numa_nodes)) || + (!nb_numa_nodes && dimm->node)) { error_setg(errp, "'DIMM property " PC_DIMM_NODE_PROP " has value %" PRIu32 "' which exceeds the number of numa nodes: %d", - dimm->node, nb_numa_nodes); + dimm->node, nb_numa_nodes ? nb_numa_nodes : 1); return; } } |