From 4ab2aff624908e49b099f00609875f4d03e9e1ec Mon Sep 17 00:00:00 2001 From: Gavin Shan Date: Wed, 21 Dec 2022 08:48:45 +0800 Subject: [PATCH 6/8] hw/arm/virt: Add 'compact-highmem' property RH-Author: Gavin Shan RH-MergeRequest: 126: hw/arm/virt: Optimize high memory region address assignment RH-Bugzilla: 2113840 RH-Acked-by: Eric Auger RH-Acked-by: Cornelia Huck RH-Acked-by: Miroslav Rezanina RH-Commit: [6/8] 781506f3445493f05b511547370b6d88ef092457 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 After the improvement to high memory region address assignment is applied, the memory layout can be changed, introducing possible migration breakage. For example, VIRT_HIGH_PCIE_MMIO memory region is disabled or enabled when the optimization is applied or not, with the following configuration. The configuration is only achievable by modifying the source code until more properties are added to allow users selectively disable those high memory regions. pa_bits = 40; vms->highmem_redists = false; vms->highmem_ecam = false; vms->highmem_mmio = true; # qemu-system-aarch64 -accel kvm -cpu host \ -machine virt-7.2,compact-highmem={on, off} \ -m 4G,maxmem=511G -monitor stdio Region compact-highmem=off compact-highmem=on ---------------------------------------------------------------- MEM [1GB 512GB] [1GB 512GB] HIGH_GIC_REDISTS2 [512GB 512GB+64MB] [disabled] HIGH_PCIE_ECAM [512GB+256MB 512GB+512MB] [disabled] HIGH_PCIE_MMIO [disabled] [512GB 1TB] In order to keep backwords compatibility, we need to disable the optimization on machine, which is virt-7.1 or ealier than it. It means the optimization is enabled by default from virt-7.2. Besides, 'compact-highmem' property is added so that the optimization can be explicitly enabled or disabled on all machine types by users. Signed-off-by: Gavin Shan Reviewed-by: Eric Auger Reviewed-by: Cornelia Huck Reviewed-by: Marc Zyngier Tested-by: Zhenyu Zhang Message-id: 20221029224307.138822-7-gshan@redhat.com Signed-off-by: Peter Maydell (cherry picked from commit f40408a9fe5d1db70a75a33d2b26c8af8a5d57b0) Signed-off-by: Gavin Shan Conflicts: hw/arm/virt.c Comment out the handlers of property 'compact-highmem' since the property isn't exposed. --- docs/system/arm/virt.rst | 4 ++++ hw/arm/virt.c | 34 ++++++++++++++++++++++++++++++++++ include/hw/arm/virt.h | 1 + 3 files changed, 39 insertions(+) diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst index 20442ea2c1..4454706392 100644 --- a/docs/system/arm/virt.rst +++ b/docs/system/arm/virt.rst @@ -94,6 +94,10 @@ highmem address space above 32 bits. The default is ``on`` for machine types later than ``virt-2.12``. +compact-highmem + Set ``on``/``off`` to enable/disable the compact layout for high memory regions. + The default is ``on`` for machine types later than ``virt-7.2``. + gic-version Specify the version of the Generic Interrupt Controller (GIC) to provide. Valid values are: diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 6896e0ca0f..6087511ae9 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -216,6 +216,12 @@ static const MemMapEntry base_memmap[] = { * Note the extended_memmap is sized so that it eventually also includes the * base_memmap entries (VIRT_HIGH_GIC_REDIST2 index is greater than the last * index of base_memmap). + * + * The memory map for these Highmem IO Regions can be in legacy or compact + * layout, depending on 'compact-highmem' property. With legacy layout, the + * PA space for one specific region is always reserved, even if the region + * has been disabled or doesn't fit into the PA space. However, the PA space + * for the region won't be reserved in these circumstances with compact layout. */ static MemMapEntry extended_memmap[] = { /* Additional 64 MB redist region (can contain up to 512 redistributors) */ @@ -2400,6 +2406,22 @@ static void virt_set_highmem(Object *obj, bool value, Error **errp) vms->highmem = value; } +#if 0 /* Disabled for Red Hat Enterprise Linux */ +static bool virt_get_compact_highmem(Object *obj, Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + + return vms->highmem_compact; +} + +static void virt_set_compact_highmem(Object *obj, bool value, Error **errp) +{ + VirtMachineState *vms = VIRT_MACHINE(obj); + + vms->highmem_compact = value; +} +#endif /* disabled for RHEL */ + static bool virt_get_its(Object *obj, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); @@ -3023,6 +3045,13 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) "Set on/off to enable/disable using " "physical address space above 32 bits"); + object_class_property_add_bool(oc, "compact-highmem", + virt_get_compact_highmem, + virt_set_compact_highmem); + object_class_property_set_description(oc, "compact-highmem", + "Set on/off to enable/disable compact " + "layout for high memory regions"); + object_class_property_add_str(oc, "gic-version", virt_get_gic_version, virt_set_gic_version); object_class_property_set_description(oc, "gic-version", @@ -3107,6 +3136,7 @@ static void virt_instance_init(Object *obj) /* High memory is enabled by default */ vms->highmem = true; + vms->highmem_compact = !vmc->no_highmem_compact; vms->gic_version = VIRT_GIC_VERSION_NOSEL; vms->highmem_ecam = !vmc->no_highmem_ecam; @@ -3176,8 +3206,12 @@ DEFINE_VIRT_MACHINE_AS_LATEST(7, 2) static void virt_machine_7_1_options(MachineClass *mc) { + VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); + virt_machine_7_2_options(mc); compat_props_add(mc->compat_props, hw_compat_7_1, hw_compat_7_1_len); + /* Compact layout for high memory regions was introduced with 7.2 */ + vmc->no_highmem_compact = true; } DEFINE_VIRT_MACHINE(7, 1) diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 15bd291311..85e7d61868 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -125,6 +125,7 @@ struct VirtMachineClass { bool no_pmu; bool claim_edge_triggered_timers; bool smbios_old_sys_ver; + bool no_highmem_compact; bool no_highmem_ecam; bool no_ged; /* Machines < 4.2 have no support for ACPI GED device */ bool kvm_no_adjvtime; -- 2.31.1