11f070489SIgor Mammedov /* 21f070489SIgor Mammedov * QEMU Host Memory Backend 31f070489SIgor Mammedov * 41f070489SIgor Mammedov * Copyright (C) 2013-2014 Red Hat Inc 51f070489SIgor Mammedov * 61f070489SIgor Mammedov * Authors: 71f070489SIgor Mammedov * Igor Mammedov <imammedo@redhat.com> 81f070489SIgor Mammedov * 91f070489SIgor Mammedov * This work is licensed under the terms of the GNU GPL, version 2 or later. 101f070489SIgor Mammedov * See the COPYING file in the top-level directory. 111f070489SIgor Mammedov */ 121f070489SIgor Mammedov #include "sysemu/hostmem.h" 131f070489SIgor Mammedov #include "sysemu/sysemu.h" 141f070489SIgor Mammedov #include "qapi/visitor.h" 151f070489SIgor Mammedov #include "qapi/qmp/qerror.h" 161f070489SIgor Mammedov #include "qemu/config-file.h" 171f070489SIgor Mammedov #include "qom/object_interfaces.h" 181f070489SIgor Mammedov 191f070489SIgor Mammedov static void 2058f4662cSHu Tao host_memory_backend_get_size(Object *obj, Visitor *v, void *opaque, 211f070489SIgor Mammedov const char *name, Error **errp) 221f070489SIgor Mammedov { 231f070489SIgor Mammedov HostMemoryBackend *backend = MEMORY_BACKEND(obj); 241f070489SIgor Mammedov uint64_t value = backend->size; 251f070489SIgor Mammedov 261f070489SIgor Mammedov visit_type_size(v, &value, name, errp); 271f070489SIgor Mammedov } 281f070489SIgor Mammedov 291f070489SIgor Mammedov static void 3058f4662cSHu Tao host_memory_backend_set_size(Object *obj, Visitor *v, void *opaque, 311f070489SIgor Mammedov const char *name, Error **errp) 321f070489SIgor Mammedov { 331f070489SIgor Mammedov HostMemoryBackend *backend = MEMORY_BACKEND(obj); 341f070489SIgor Mammedov Error *local_err = NULL; 351f070489SIgor Mammedov uint64_t value; 361f070489SIgor Mammedov 371f070489SIgor Mammedov if (memory_region_size(&backend->mr)) { 381f070489SIgor Mammedov error_setg(&local_err, "cannot change property value"); 391f070489SIgor Mammedov goto out; 401f070489SIgor Mammedov } 411f070489SIgor Mammedov 421f070489SIgor Mammedov visit_type_size(v, &value, name, &local_err); 431f070489SIgor Mammedov if (local_err) { 441f070489SIgor Mammedov goto out; 451f070489SIgor Mammedov } 461f070489SIgor Mammedov if (!value) { 471f070489SIgor Mammedov error_setg(&local_err, "Property '%s.%s' doesn't take value '%" 481f070489SIgor Mammedov PRIu64 "'", object_get_typename(obj), name, value); 491f070489SIgor Mammedov goto out; 501f070489SIgor Mammedov } 511f070489SIgor Mammedov backend->size = value; 521f070489SIgor Mammedov out: 531f070489SIgor Mammedov error_propagate(errp, local_err); 541f070489SIgor Mammedov } 551f070489SIgor Mammedov 5658f4662cSHu Tao static void host_memory_backend_init(Object *obj) 571f070489SIgor Mammedov { 581f070489SIgor Mammedov object_property_add(obj, "size", "int", 5958f4662cSHu Tao host_memory_backend_get_size, 6058f4662cSHu Tao host_memory_backend_set_size, NULL, NULL, NULL); 611f070489SIgor Mammedov } 621f070489SIgor Mammedov 6358f4662cSHu Tao static void host_memory_backend_finalize(Object *obj) 641f070489SIgor Mammedov { 651f070489SIgor Mammedov HostMemoryBackend *backend = MEMORY_BACKEND(obj); 661f070489SIgor Mammedov 671f070489SIgor Mammedov if (memory_region_size(&backend->mr)) { 681f070489SIgor Mammedov memory_region_destroy(&backend->mr); 691f070489SIgor Mammedov } 701f070489SIgor Mammedov } 711f070489SIgor Mammedov 721f070489SIgor Mammedov MemoryRegion * 731f070489SIgor Mammedov host_memory_backend_get_memory(HostMemoryBackend *backend, Error **errp) 741f070489SIgor Mammedov { 751f070489SIgor Mammedov return memory_region_size(&backend->mr) ? &backend->mr : NULL; 761f070489SIgor Mammedov } 771f070489SIgor Mammedov 78*bd9262d9SHu Tao static void 79*bd9262d9SHu Tao host_memory_backend_memory_complete(UserCreatable *uc, Error **errp) 80*bd9262d9SHu Tao { 81*bd9262d9SHu Tao HostMemoryBackend *backend = MEMORY_BACKEND(uc); 82*bd9262d9SHu Tao HostMemoryBackendClass *bc = MEMORY_BACKEND_GET_CLASS(uc); 83*bd9262d9SHu Tao 84*bd9262d9SHu Tao if (bc->alloc) { 85*bd9262d9SHu Tao bc->alloc(backend, errp); 86*bd9262d9SHu Tao } 87*bd9262d9SHu Tao } 88*bd9262d9SHu Tao 89*bd9262d9SHu Tao static void 90*bd9262d9SHu Tao host_memory_backend_class_init(ObjectClass *oc, void *data) 91*bd9262d9SHu Tao { 92*bd9262d9SHu Tao UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); 93*bd9262d9SHu Tao 94*bd9262d9SHu Tao ucc->complete = host_memory_backend_memory_complete; 95*bd9262d9SHu Tao } 96*bd9262d9SHu Tao 9758f4662cSHu Tao static const TypeInfo host_memory_backend_info = { 981f070489SIgor Mammedov .name = TYPE_MEMORY_BACKEND, 991f070489SIgor Mammedov .parent = TYPE_OBJECT, 1001f070489SIgor Mammedov .abstract = true, 1011f070489SIgor Mammedov .class_size = sizeof(HostMemoryBackendClass), 102*bd9262d9SHu Tao .class_init = host_memory_backend_class_init, 1031f070489SIgor Mammedov .instance_size = sizeof(HostMemoryBackend), 10458f4662cSHu Tao .instance_init = host_memory_backend_init, 10558f4662cSHu Tao .instance_finalize = host_memory_backend_finalize, 1061f070489SIgor Mammedov .interfaces = (InterfaceInfo[]) { 1071f070489SIgor Mammedov { TYPE_USER_CREATABLE }, 1081f070489SIgor Mammedov { } 1091f070489SIgor Mammedov } 1101f070489SIgor Mammedov }; 1111f070489SIgor Mammedov 1121f070489SIgor Mammedov static void register_types(void) 1131f070489SIgor Mammedov { 11458f4662cSHu Tao type_register_static(&host_memory_backend_info); 1151f070489SIgor Mammedov } 1161f070489SIgor Mammedov 1171f070489SIgor Mammedov type_init(register_types); 118