aboutsummaryrefslogtreecommitdiff
path: root/hw/core
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2022-05-12 10:52:15 -0700
committerRichard Henderson <richard.henderson@linaro.org>2022-05-12 10:52:15 -0700
commit9de5f2b40860c5f8295e73fea9922df6f0b8d89a (patch)
tree042811440df6511a136fc2c40ffab0aeead1a568 /hw/core
parentb32b3897f8b8f2f17425c22ea229ea6ebcb7d552 (diff)
parent333dbac358acc6cc174029263d633a22f66584b4 (diff)
downloadqemu-9de5f2b40860c5f8295e73fea9922df6f0b8d89a.zip
qemu-9de5f2b40860c5f8295e73fea9922df6f0b8d89a.tar.gz
qemu-9de5f2b40860c5f8295e73fea9922df6f0b8d89a.tar.bz2
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* small cleanups for pc-bios/optionrom Makefiles * checkpatch: fix g_malloc check * fix mremap() and RDMA detection * confine igd-passthrough-isa-bridge to Xen-enabled builds * cover PCI in arm-virt machine qtests * add -M boot and -M mem compound properties * bump SLIRP submodule * support CFI with system libslirp (>= 4.7) * clean up CoQueue wakeup functions * fix vhost-vsock regression * fix --disable-vnc compilation * other minor bugfixes # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmJ8/KMUHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroNTTAf9Et1C8iZn+OlZi99wMEeMy8a4mIE5 # CpkBpFphhkBvt3AH7XNsCyL4Gea4QgsI7nOIEVUwvW7gPf85PiBUX8mjrIVg3x1k # bmMEwMKSTYPmDieAnYBP9zCqZQXNYP8L8WxVs2jFY2GXZ2ZogODYFbvCY4yEEB72 # UR6uIvQRdpiB6BEj8UZ+5i+sDtb0zxqrjzUz8T/PJC9/2JSNgi+sAWWQoQT3PPU7 # R7z2nmEa1VeVLPP6mUHvJKhBltVXF+LyIjQHvo+Tp9tSqp9JwXfFBNQ5W/MFes2D # skF47N7PdgKRH9Dp4r0j+MqBwoAq86+ao+MKsbQ1Gb91HhoCWt/MrVrVyg== # =1E6P # -----END PGP SIGNATURE----- # gpg: Signature made Thu 12 May 2022 05:25:07 AM PDT # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [undefined] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [undefined] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (27 commits) vmxcap: add tertiary execution controls vl: make machine type deprecation a warning meson: link libpng independent of vnc vhost-backend: do not depend on CONFIG_VHOST_VSOCK coroutine-lock: qemu_co_queue_restart_all is a coroutine-only qemu_co_enter_all coroutine-lock: introduce qemu_co_queue_enter_all coroutine-lock: qemu_co_queue_next is a coroutine-only qemu_co_enter_next net: slirp: allow CFI with libslirp >= 4.7 net: slirp: add support for CFI-friendly timer API net: slirp: switch to slirp_new net: slirp: introduce a wrapper struct for QemuTimer slirp: bump submodule past 4.7 release machine: move more memory validation to Machine object machine: make memory-backend a link property machine: add mem compound property machine: add boot compound property machine: use QAPI struct for boot configuration tests/qtest/libqos: Add generic pci host bridge in arm-virt machine tests/qtest/libqos: Skip hotplug tests if pci root bus is not hotpluggable tests/qtest/libqos/pci: Introduce pio_limit ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/core')
-rw-r--r--hw/core/machine.c241
-rw-r--r--hw/core/numa.c2
2 files changed, 216 insertions, 27 deletions
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 700c1e7..3264c1e 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -21,12 +21,14 @@
#include "qapi/qapi-visit-common.h"
#include "qapi/qapi-visit-machine.h"
#include "qapi/visitor.h"
+#include "qom/object_interfaces.h"
#include "hw/sysbus.h"
#include "sysemu/cpus.h"
#include "sysemu/sysemu.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "sysemu/numa.h"
+#include "sysemu/xen.h"
#include "qemu/error-report.h"
#include "sysemu/qtest.h"
#include "hw/pci/pci.h"
@@ -36,6 +38,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);
@@ -523,6 +526,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);
@@ -581,21 +656,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;
@@ -784,6 +844,65 @@ static void machine_set_smp(Object *obj, Visitor *v, const char *name,
machine_parse_smp_config(ms, config, errp);
}
+static void machine_get_boot(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+ BootConfiguration *config = &ms->boot_config;
+ visit_type_BootConfiguration(v, name, &config, &error_abort);
+}
+
+static void machine_free_boot_config(MachineState *ms)
+{
+ g_free(ms->boot_config.order);
+ g_free(ms->boot_config.once);
+ g_free(ms->boot_config.splash);
+}
+
+static void machine_copy_boot_config(MachineState *ms, BootConfiguration *config)
+{
+ MachineClass *machine_class = MACHINE_GET_CLASS(ms);
+
+ machine_free_boot_config(ms);
+ ms->boot_config = *config;
+ if (!config->has_order) {
+ ms->boot_config.has_order = true;
+ ms->boot_config.order = g_strdup(machine_class->default_boot_order);
+ }
+}
+
+static void machine_set_boot(Object *obj, Visitor *v, const char *name,
+ void *opaque, Error **errp)
+{
+ ERRP_GUARD();
+ MachineState *ms = MACHINE(obj);
+ BootConfiguration *config = NULL;
+
+ if (!visit_type_BootConfiguration(v, name, &config, errp)) {
+ return;
+ }
+ if (config->has_order) {
+ validate_bootdevices(config->order, errp);
+ if (*errp) {
+ goto out_free;
+ }
+ }
+ if (config->has_once) {
+ validate_bootdevices(config->once, errp);
+ if (*errp) {
+ goto out_free;
+ }
+ }
+
+ machine_copy_boot_config(ms, config);
+ /* Strings live in ms->boot_config. */
+ free(config);
+ return;
+
+out_free:
+ qapi_free_BootConfiguration(config);
+}
+
static void machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -822,6 +941,12 @@ static void machine_class_init(ObjectClass *oc, void *data)
object_class_property_set_description(oc, "dumpdtb",
"Dump current dtb to a file and quit");
+ object_class_property_add(oc, "boot", "BootConfiguration",
+ machine_get_boot, machine_set_boot,
+ NULL, NULL);
+ object_class_property_set_description(oc, "boot",
+ "Boot configuration");
+
object_class_property_add(oc, "smp", "SMPConfiguration",
machine_get_smp, machine_set_smp,
NULL, NULL);
@@ -883,11 +1008,18 @@ 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");
+
+ 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)
@@ -918,6 +1050,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);
@@ -955,12 +1089,15 @@ static void machine_initfn(Object *obj)
ms->smp.clusters = 1;
ms->smp.cores = 1;
ms->smp.threads = 1;
+
+ machine_copy_boot_config(ms, &(BootConfiguration){ 0 });
}
static void machine_finalize(Object *obj)
{
MachineState *ms = MACHINE(obj);
+ machine_free_boot_config(ms);
g_free(ms->kernel_filename);
g_free(ms->initrd_filename);
g_free(ms->kernel_cmdline);
@@ -1122,7 +1259,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);
@@ -1133,11 +1303,26 @@ 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 (!xen_enabled()) {
+ /* On 32-bit hosts, QEMU is limited by virtual address space */
+ if (machine->ram_size > (2047 << 20) && HOST_LONG_BITS == 32) {
+ error_setg(errp, "at most 2047 MB RAM can be simulated");
+ return;
+ }
+ }
+
+ if (machine->memdev) {
+ ram_addr_t backend_size = object_property_get_uint(OBJECT(machine->memdev),
+ "size", &error_abort);
+ if (backend_size != machine->ram_size) {
+ error_setg(errp, "Machine memory size does not match the size of the memory backend");
+ return;
+ }
+ } else if (machine_class->default_ram_id && machine->ram_size &&
+ numa_uses_legacy_mem()) {
+ if (!create_default_memdev(current_machine, mem_path, errp)) {
+ return;
+ }
}
if (machine->numa_state) {
@@ -1147,6 +1332,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.
*/
@@ -1229,9 +1418,9 @@ void qdev_machine_creation_done(void)
{
cpu_synchronize_all_post_init();
- if (current_machine->boot_once) {
- qemu_boot_set(current_machine->boot_once, &error_fatal);
- qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_order));
+ if (current_machine->boot_config.has_once) {
+ qemu_boot_set(current_machine->boot_config.once, &error_fatal);
+ qemu_register_reset(restore_boot_order, g_strdup(current_machine->boot_config.order));
}
/*
diff --git a/hw/core/numa.c b/hw/core/numa.c
index 1aa05dc..26d8e5f 100644
--- a/hw/core/numa.c
+++ b/hw/core/numa.c
@@ -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);