machine: make memory-backend a link property

Handle HostMemoryBackend creation and setting of ms->ram entirely in
machine_run_board_init.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Message-Id: <20220414165300.555321-5-pbonzini@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2022-04-14 12:52:59 -04:00
parent ce9d03fb3f
commit 26f88d84da
5 changed files with 74 additions and 69 deletions

View File

@ -36,6 +36,7 @@
#include "exec/confidential-guest-support.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-pci.h"
#include "qom/object_interfaces.h"
GlobalProperty hw_compat_7_0[] = {};
const size_t hw_compat_7_0_len = G_N_ELEMENTS(hw_compat_7_0);
@ -653,21 +654,6 @@ bool device_type_is_dynamic_sysbus(MachineClass *mc, const char *type)
return allowed;
}
static char *machine_get_memdev(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
return g_strdup(ms->ram_memdev_id);
}
static void machine_set_memdev(Object *obj, const char *value, Error **errp)
{
MachineState *ms = MACHINE(obj);
g_free(ms->ram_memdev_id);
ms->ram_memdev_id = g_strdup(value);
}
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
{
int i;
@ -1020,8 +1006,9 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "memory-encryption",
"Set memory encryption object to use");
object_class_property_add_str(oc, "memory-backend",
machine_get_memdev, machine_set_memdev);
object_class_property_add_link(oc, "memory-backend", TYPE_MEMORY_BACKEND,
offsetof(MachineState, memdev), object_property_allow_set_link,
OBJ_PROP_LINK_STRONG);
object_class_property_set_description(oc, "memory-backend",
"Set RAM backend"
"Valid value is ID of hostmem based backend");
@ -1270,7 +1257,40 @@ MemoryRegion *machine_consume_memdev(MachineState *machine,
return ret;
}
void machine_run_board_init(MachineState *machine)
static bool create_default_memdev(MachineState *ms, const char *path, Error **errp)
{
Object *obj;
MachineClass *mc = MACHINE_GET_CLASS(ms);
bool r = false;
obj = object_new(path ? TYPE_MEMORY_BACKEND_FILE : TYPE_MEMORY_BACKEND_RAM);
if (path) {
if (!object_property_set_str(obj, "mem-path", path, errp)) {
goto out;
}
}
if (!object_property_set_int(obj, "size", ms->ram_size, errp)) {
goto out;
}
object_property_add_child(object_get_objects_root(), mc->default_ram_id,
obj);
/* Ensure backend's memory region name is equal to mc->default_ram_id */
if (!object_property_set_bool(obj, "x-use-canonical-path-for-ramblock-id",
false, errp)) {
goto out;
}
if (!user_creatable_complete(USER_CREATABLE(obj), errp)) {
goto out;
}
r = object_property_set_link(OBJECT(ms), "memory-backend", obj, errp);
out:
object_unref(obj);
return r;
}
void machine_run_board_init(MachineState *machine, const char *mem_path, Error **errp)
{
MachineClass *machine_class = MACHINE_GET_CLASS(machine);
ObjectClass *oc = object_class_by_name(machine->cpu_type);
@ -1281,11 +1301,11 @@ void machine_run_board_init(MachineState *machine)
clock values from the log. */
replay_checkpoint(CHECKPOINT_INIT);
if (machine->ram_memdev_id) {
Object *o;
o = object_resolve_path_type(machine->ram_memdev_id,
TYPE_MEMORY_BACKEND, NULL);
machine->ram = machine_consume_memdev(machine, MEMORY_BACKEND(o));
if (machine_class->default_ram_id && machine->ram_size &&
numa_uses_legacy_mem() && !machine->memdev) {
if (!create_default_memdev(current_machine, mem_path, errp)) {
return;
}
}
if (machine->numa_state) {
@ -1295,6 +1315,10 @@ void machine_run_board_init(MachineState *machine)
}
}
if (!machine->ram && machine->memdev) {
machine->ram = machine_consume_memdev(machine, machine->memdev);
}
/* If the machine supports the valid_cpu_types check and the user
* specified a CPU with -cpu check here that the user CPU is supported.
*/

View File

@ -695,7 +695,7 @@ void numa_complete_configuration(MachineState *ms)
}
if (!numa_uses_legacy_mem() && mc->default_ram_id) {
if (ms->ram_memdev_id) {
if (ms->memdev) {
error_report("'-machine memory-backend' and '-numa memdev'"
" properties are mutually exclusive");
exit(1);

View File

@ -831,8 +831,7 @@ static void sun4m_hw_init(MachineState *machine)
SysBusDevice *s;
unsigned int smp_cpus = machine->smp.cpus;
unsigned int max_cpus = machine->smp.max_cpus;
Object *ram_memdev = object_resolve_path_type(machine->ram_memdev_id,
TYPE_MEMORY_BACKEND, NULL);
HostMemoryBackend *ram_memdev = machine->memdev;
NICInfo *nd = &nd_table[0];
if (machine->ram_size > hwdef->max_mem) {
@ -852,7 +851,7 @@ static void sun4m_hw_init(MachineState *machine)
/* Create and map RAM frontend */
dev = qdev_new("memory");
object_property_set_link(OBJECT(dev), "memdev", ram_memdev, &error_fatal);
object_property_set_link(OBJECT(dev), "memdev", OBJECT(ram_memdev), &error_fatal);
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0);

View File

@ -25,7 +25,7 @@ OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
extern MachineState *current_machine;
void machine_run_board_init(MachineState *machine);
void machine_run_board_init(MachineState *machine, const char *mem_path, Error **errp);
bool machine_usb(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
@ -339,7 +339,7 @@ struct MachineState {
bool suppress_vmdesc;
bool enable_graphics;
ConfidentialGuestSupport *cgs;
char *ram_memdev_id;
HostMemoryBackend *memdev;
/*
* convenience alias to ram_memdev_id backend memory region
* or to numa container memory region

View File

@ -160,6 +160,7 @@ static const char *incoming;
static const char *loadvm;
static const char *accelerators;
static bool have_custom_ram_size;
static const char *ram_memdev_id;
static QDict *machine_opts_dict;
static QTAILQ_HEAD(, ObjectOption) object_opts = QTAILQ_HEAD_INITIALIZER(object_opts);
static QTAILQ_HEAD(, DeviceOption) device_opts = QTAILQ_HEAD_INITIALIZER(device_opts);
@ -1768,6 +1769,19 @@ static void qemu_apply_legacy_machine_options(QDict *qdict)
qdict_del(qdict, "kernel-irqchip");
}
value = qdict_get_try_str(qdict, "memory-backend");
if (value) {
if (mem_path) {
error_report("'-mem-path' can't be used together with"
"'-machine memory-backend'");
exit(EXIT_FAILURE);
}
/* Resolved later. */
ram_memdev_id = g_strdup(value);
qdict_del(qdict, "memory-backend");
}
prop = qdict_get(qdict, "memory");
if (prop) {
have_custom_ram_size =
@ -2003,29 +2017,25 @@ static void qemu_create_late_backends(void)
static void qemu_resolve_machine_memdev(void)
{
if (current_machine->ram_memdev_id) {
if (ram_memdev_id) {
Object *backend;
ram_addr_t backend_size;
backend = object_resolve_path_type(current_machine->ram_memdev_id,
backend = object_resolve_path_type(ram_memdev_id,
TYPE_MEMORY_BACKEND, NULL);
if (!backend) {
error_report("Memory backend '%s' not found",
current_machine->ram_memdev_id);
error_report("Memory backend '%s' not found", ram_memdev_id);
exit(EXIT_FAILURE);
}
backend_size = object_property_get_uint(backend, "size", &error_abort);
if (have_custom_ram_size && backend_size != current_machine->ram_size) {
error_report("Size specified by -m option must match size of "
"explicitly specified 'memory-backend' property");
exit(EXIT_FAILURE);
}
if (mem_path) {
error_report("'-mem-path' can't be used together with"
"'-machine memory-backend'");
error_report("Size specified by -m option must match size of "
"explicitly specified 'memory-backend' property");
exit(EXIT_FAILURE);
}
current_machine->ram_size = backend_size;
object_property_set_link(OBJECT(current_machine),
"memory-backend", backend, &error_fatal);
}
if (!xen_enabled()) {
@ -2376,27 +2386,6 @@ static void configure_accelerators(const char *progname)
}
}
static void create_default_memdev(MachineState *ms, const char *path)
{
Object *obj;
MachineClass *mc = MACHINE_GET_CLASS(ms);
obj = object_new(path ? TYPE_MEMORY_BACKEND_FILE : TYPE_MEMORY_BACKEND_RAM);
if (path) {
object_property_set_str(obj, "mem-path", path, &error_fatal);
}
object_property_set_int(obj, "size", ms->ram_size, &error_fatal);
object_property_add_child(object_get_objects_root(), mc->default_ram_id,
obj);
/* Ensure backend's memory region name is equal to mc->default_ram_id */
object_property_set_bool(obj, "x-use-canonical-path-for-ramblock-id",
false, &error_fatal);
user_creatable_complete(USER_CREATABLE(obj), &error_fatal);
object_unref(obj);
object_property_set_str(OBJECT(ms), "memory-backend", mc->default_ram_id,
&error_fatal);
}
static void qemu_validate_options(const QDict *machine_opts)
{
const char *kernel_filename = qdict_get_try_str(machine_opts, "kernel");
@ -2581,18 +2570,11 @@ static void qemu_init_displays(void)
static void qemu_init_board(void)
{
MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
if (machine_class->default_ram_id && current_machine->ram_size &&
numa_uses_legacy_mem() && !current_machine->ram_memdev_id) {
create_default_memdev(current_machine, mem_path);
}
/* process plugin before CPUs are created, but once -smp has been parsed */
qemu_plugin_load_list(&plugin_list, &error_fatal);
/* From here on we enter MACHINE_PHASE_INITIALIZED. */
machine_run_board_init(current_machine);
machine_run_board_init(current_machine, mem_path, &error_fatal);
drive_check_orphaned();