summaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
Diffstat (limited to 'hw')
-rw-r--r--hw/core/machine.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 8cea94537d..46b8d0effa 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -523,6 +523,78 @@ static void machine_set_hmat(Object *obj, bool value, Error **errp)
ms->numa_state->hmat_enabled = value;
}
+static void machine_get_mem(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+ MemorySizeConfiguration mem = {
+ .has_size = true,
+ .size = ms->ram_size,
+ .has_max_size = !!ms->ram_slots,
+ .max_size = ms->maxram_size,
+ .has_slots = !!ms->ram_slots,
+ .slots = ms->ram_slots,
+ };
+ MemorySizeConfiguration *p_mem = &mem;
+
+ visit_type_MemorySizeConfiguration(v, name, &p_mem, &error_abort);
+}
+
+static void machine_set_mem(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+ MachineClass *mc = MACHINE_GET_CLASS(obj);
+ MemorySizeConfiguration *mem;
+
+ ERRP_GUARD();
+
+ if (!visit_type_MemorySizeConfiguration(v, name, &mem, errp)) {
+ return;
+ }
+
+ if (!mem->has_size) {
+ mem->has_size = true;
+ mem->size = mc->default_ram_size;
+ }
+ mem->size = QEMU_ALIGN_UP(mem->size, 8192);
+ if (mc->fixup_ram_size) {
+ mem->size = mc->fixup_ram_size(mem->size);
+ }
+ if ((ram_addr_t)mem->size != mem->size) {
+ error_setg(errp, "ram size too large");
+ goto out_free;
+ }
+
+ if (mem->has_max_size) {
+ if (mem->max_size < mem->size) {
+ error_setg(errp, "invalid value of maxmem: "
+ "maximum memory size (0x%" PRIx64 ") must be at least "
+ "the initial memory size (0x%" PRIx64 ")",
+ mem->max_size, mem->size);
+ goto out_free;
+ }
+ if (mem->has_slots && mem->slots && mem->max_size == mem->size) {
+ error_setg(errp, "invalid value of maxmem: "
+ "memory slots were specified but maximum memory size "
+ "(0x%" PRIx64 ") is equal to the initial memory size "
+ "(0x%" PRIx64 ")", mem->max_size, mem->size);
+ goto out_free;
+ }
+ ms->maxram_size = mem->max_size;
+ } else {
+ if (mem->has_slots) {
+ error_setg(errp, "slots specified but no max-size");
+ goto out_free;
+ }
+ ms->maxram_size = mem->size;
+ }
+ ms->ram_size = mem->size;
+ ms->ram_slots = mem->has_slots ? mem->slots : 0;
+out_free:
+ qapi_free_MemorySizeConfiguration(mem);
+}
+
static char *machine_get_nvdimm_persistence(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
@@ -953,6 +1025,12 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "memory-backend",
"Set RAM backend"
"Valid value is ID of hostmem based backend");
+
+ object_class_property_add(oc, "memory", "MemorySizeConfiguration",
+ machine_get_mem, machine_set_mem,
+ NULL, NULL);
+ object_class_property_set_description(oc, "memory",
+ "Memory size configuration");
}
static void machine_class_base_init(ObjectClass *oc, void *data)
@@ -983,6 +1061,8 @@ static void machine_initfn(Object *obj)
ms->mem_merge = true;
ms->enable_graphics = true;
ms->kernel_cmdline = g_strdup("");
+ ms->ram_size = mc->default_ram_size;
+ ms->maxram_size = mc->default_ram_size;
if (mc->nvdimm_supported) {
Object *obj = OBJECT(ms);