From 5252804d5520ec74c63d082c20a13efe52d37f86 Mon Sep 17 00:00:00 2001 From: Miroslav Rezanina Date: Wed, 4 Jan 2023 04:47:00 -0500 Subject: [PATCH] * Wed Jan 04 2023 Miroslav Rezanina - 7.2.0-3 - kvm-hw-arm-virt-Introduce-virt_set_high_memmap-helper.patch [bz#2113840] - kvm-hw-arm-virt-Rename-variable-size-to-region_size-in-v.patch [bz#2113840] - kvm-hw-arm-virt-Introduce-variable-region_base-in-virt_s.patch [bz#2113840] - kvm-hw-arm-virt-Introduce-virt_get_high_memmap_enabled-h.patch [bz#2113840] - kvm-hw-arm-virt-Improve-high-memory-region-address-assig.patch [bz#2113840] - kvm-hw-arm-virt-Add-compact-highmem-property.patch [bz#2113840] - kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch [bz#2113840] - kvm-hw-arm-virt-Enable-compat-high-memory-region-address.patch [bz#2113840] - Resolves: bz#2113840 ([RHEL9.2] Memory mapping optimization for virt machine) --- ...rm-virt-Add-compact-highmem-property.patch | 169 +++++++++++++++++ ...properties-to-disable-high-memory-re.patch | 179 ++++++++++++++++++ ...le-compat-high-memory-region-address.patch | 51 +++++ ...ove-high-memory-region-address-assig.patch | 112 +++++++++++ ...oduce-variable-region_base-in-virt_s.patch | 82 ++++++++ ...oduce-virt_get_high_memmap_enabled-h.patch | 95 ++++++++++ ...ntroduce-virt_set_high_memmap-helper.patch | 130 +++++++++++++ ...me-variable-size-to-region_size-in-v.patch | 83 ++++++++ qemu-kvm.spec | 30 ++- 9 files changed, 930 insertions(+), 1 deletion(-) create mode 100644 kvm-hw-arm-virt-Add-compact-highmem-property.patch create mode 100644 kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch create mode 100644 kvm-hw-arm-virt-Enable-compat-high-memory-region-address.patch create mode 100644 kvm-hw-arm-virt-Improve-high-memory-region-address-assig.patch create mode 100644 kvm-hw-arm-virt-Introduce-variable-region_base-in-virt_s.patch create mode 100644 kvm-hw-arm-virt-Introduce-virt_get_high_memmap_enabled-h.patch create mode 100644 kvm-hw-arm-virt-Introduce-virt_set_high_memmap-helper.patch create mode 100644 kvm-hw-arm-virt-Rename-variable-size-to-region_size-in-v.patch diff --git a/kvm-hw-arm-virt-Add-compact-highmem-property.patch b/kvm-hw-arm-virt-Add-compact-highmem-property.patch new file mode 100644 index 0000000..bc65e2f --- /dev/null +++ b/kvm-hw-arm-virt-Add-compact-highmem-property.patch @@ -0,0 +1,169 @@ +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 + diff --git a/kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch b/kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch new file mode 100644 index 0000000..df691a7 --- /dev/null +++ b/kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch @@ -0,0 +1,179 @@ +From 30e86a7c4fbcdc95b74bcb2a15745cb221783091 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 21 Dec 2022 08:48:45 +0800 +Subject: [PATCH 7/8] hw/arm/virt: Add properties to disable high memory + regions + +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: [7/8] 16f8762393b447a590b31c9e4d8d3c58c6bc9fa8 + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 + +The 3 high memory regions are usually enabled by default, but they may +be not used. For example, VIRT_HIGH_GIC_REDIST2 isn't needed by GICv2. +This leads to waste in the PA space. + +Add properties ("highmem-redists", "highmem-ecam", "highmem-mmio") to +allow users selectively disable them if needed. After that, the high +memory region for GICv3 or GICv4 redistributor can be disabled by user, +the number of maximal supported CPUs needs to be calculated based on +'vms->highmem_redists'. The follow-up error message is also improved +to indicate if the high memory region for GICv3 and GICv4 has been +enabled or not. + +Suggested-by: Marc Zyngier +Signed-off-by: Gavin Shan +Reviewed-by: Marc Zyngier +Reviewed-by: Cornelia Huck +Reviewed-by: Eric Auger +Message-id: 20221029224307.138822-8-gshan@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit 6a48c64eec355ab1aff694eb4522d07a8e461368) +Signed-off-by: Gavin Shan +Conflicts: + hw/arm/virt.c + Comment out the handlers of the property 'highmem-redists', + 'highmem-ecam' and 'highmem-mmio' since they aren't exposed. +--- + docs/system/arm/virt.rst | 13 +++++++ + hw/arm/virt.c | 75 ++++++++++++++++++++++++++++++++++++++-- + 2 files changed, 86 insertions(+), 2 deletions(-) + +diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst +index 4454706392..188a4f211f 100644 +--- a/docs/system/arm/virt.rst ++++ b/docs/system/arm/virt.rst +@@ -98,6 +98,19 @@ 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``. + ++highmem-redists ++ Set ``on``/``off`` to enable/disable the high memory region for GICv3 or ++ GICv4 redistributor. The default is ``on``. Setting this to ``off`` will ++ limit the maximum number of CPUs when GICv3 or GICv4 is used. ++ ++highmem-ecam ++ Set ``on``/``off`` to enable/disable the high memory region for PCI ECAM. ++ The default is ``on`` for machine types later than ``virt-3.0``. ++ ++highmem-mmio ++ Set ``on``/``off`` to enable/disable the high memory region for PCI MMIO. ++ The default is ``on``. ++ + 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 6087511ae9..304fa0d6e7 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -2142,14 +2142,20 @@ static void machvirt_init(MachineState *machine) + if (vms->gic_version == VIRT_GIC_VERSION_2) { + virt_max_cpus = GIC_NCPU; + } else { +- virt_max_cpus = virt_redist_capacity(vms, VIRT_GIC_REDIST) + +- virt_redist_capacity(vms, VIRT_HIGH_GIC_REDIST2); ++ virt_max_cpus = virt_redist_capacity(vms, VIRT_GIC_REDIST); ++ if (vms->highmem_redists) { ++ virt_max_cpus += virt_redist_capacity(vms, VIRT_HIGH_GIC_REDIST2); ++ } + } + + if (max_cpus > virt_max_cpus) { + error_report("Number of SMP CPUs requested (%d) exceeds max CPUs " + "supported by machine 'mach-virt' (%d)", + max_cpus, virt_max_cpus); ++ if (vms->gic_version != VIRT_GIC_VERSION_2 && !vms->highmem_redists) { ++ error_printf("Try 'highmem-redists=on' for more CPUs\n"); ++ } ++ + exit(1); + } + +@@ -2420,6 +2426,49 @@ static void virt_set_compact_highmem(Object *obj, bool value, Error **errp) + + vms->highmem_compact = value; + } ++ ++static bool virt_get_highmem_redists(Object *obj, Error **errp) ++{ ++ VirtMachineState *vms = VIRT_MACHINE(obj); ++ ++ return vms->highmem_redists; ++} ++ ++static void virt_set_highmem_redists(Object *obj, bool value, Error **errp) ++{ ++ VirtMachineState *vms = VIRT_MACHINE(obj); ++ ++ vms->highmem_redists = value; ++} ++ ++static bool virt_get_highmem_ecam(Object *obj, Error **errp) ++{ ++ VirtMachineState *vms = VIRT_MACHINE(obj); ++ ++ return vms->highmem_ecam; ++} ++ ++static void virt_set_highmem_ecam(Object *obj, bool value, Error **errp) ++{ ++ VirtMachineState *vms = VIRT_MACHINE(obj); ++ ++ vms->highmem_ecam = value; ++} ++ ++static bool virt_get_highmem_mmio(Object *obj, Error **errp) ++{ ++ VirtMachineState *vms = VIRT_MACHINE(obj); ++ ++ return vms->highmem_mmio; ++} ++ ++static void virt_set_highmem_mmio(Object *obj, bool value, Error **errp) ++{ ++ VirtMachineState *vms = VIRT_MACHINE(obj); ++ ++ vms->highmem_mmio = value; ++} ++ + #endif /* disabled for RHEL */ + + static bool virt_get_its(Object *obj, Error **errp) +@@ -3052,6 +3101,28 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) + "Set on/off to enable/disable compact " + "layout for high memory regions"); + ++ object_class_property_add_bool(oc, "highmem-redists", ++ virt_get_highmem_redists, ++ virt_set_highmem_redists); ++ object_class_property_set_description(oc, "highmem-redists", ++ "Set on/off to enable/disable high " ++ "memory region for GICv3 or GICv4 " ++ "redistributor"); ++ ++ object_class_property_add_bool(oc, "highmem-ecam", ++ virt_get_highmem_ecam, ++ virt_set_highmem_ecam); ++ object_class_property_set_description(oc, "highmem-ecam", ++ "Set on/off to enable/disable high " ++ "memory region for PCI ECAM"); ++ ++ object_class_property_add_bool(oc, "highmem-mmio", ++ virt_get_highmem_mmio, ++ virt_set_highmem_mmio); ++ object_class_property_set_description(oc, "highmem-mmio", ++ "Set on/off to enable/disable high " ++ "memory region for PCI MMIO"); ++ + object_class_property_add_str(oc, "gic-version", virt_get_gic_version, + virt_set_gic_version); + object_class_property_set_description(oc, "gic-version", +-- +2.31.1 + diff --git a/kvm-hw-arm-virt-Enable-compat-high-memory-region-address.patch b/kvm-hw-arm-virt-Enable-compat-high-memory-region-address.patch new file mode 100644 index 0000000..6b20bb8 --- /dev/null +++ b/kvm-hw-arm-virt-Enable-compat-high-memory-region-address.patch @@ -0,0 +1,51 @@ +From 969ea1ff46b52c5fe6d87f2eeb1625871a2dfb2a Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 21 Dec 2022 08:48:45 +0800 +Subject: [PATCH 8/8] hw/arm/virt: Enable compat high memory region address + assignment for 9.2.0 machine + +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: [8/8] beda1791c0c35dce5c669efd47685302b8468032 + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 +Upstream: RHEL only + +The compact high memory region address assignment is enabled for 9.2.0, +but it's kept as disabled for 9.0.0, to keep the backwards compatibility +on 9.0.0. Note that these newly added properties ('compact-highmem', +'highmem-redists', 'highmem-ecam', and 'highmem-mmio') in the upstream +aren't exposed for the downstream. + +Signed-off-by: Gavin Shan +--- + hw/arm/virt.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 304fa0d6e7..e41c0b462c 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -3581,6 +3581,7 @@ static void rhel_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; +@@ -3659,5 +3660,7 @@ static void rhel900_virt_options(MachineClass *mc) + + /* Disable FEAT_LPA2 since old kernels (<= v5.12) don't boot with that feature */ + vmc->no_tcg_lpa2 = true; ++ /* Compact layout for high memory regions was introduced with 9.2.0 */ ++ vmc->no_highmem_compact = true; + } + DEFINE_RHEL_MACHINE(9, 0, 0) +-- +2.31.1 + diff --git a/kvm-hw-arm-virt-Improve-high-memory-region-address-assig.patch b/kvm-hw-arm-virt-Improve-high-memory-region-address-assig.patch new file mode 100644 index 0000000..9dcdf61 --- /dev/null +++ b/kvm-hw-arm-virt-Improve-high-memory-region-address-assig.patch @@ -0,0 +1,112 @@ +From 1c7fad3776a14ca35b24dc2fdb262d4ddf40d6eb Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 21 Dec 2022 08:48:45 +0800 +Subject: [PATCH 5/8] hw/arm/virt: Improve high memory region address + assignment + +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: [5/8] 4d77fa78b5258a1bd8d30405cec5ba3311d42f92 + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 + +There are three high memory regions, which are VIRT_HIGH_REDIST2, +VIRT_HIGH_PCIE_ECAM and VIRT_HIGH_PCIE_MMIO. Their base addresses +are floating on highest RAM address. However, they can be disabled +in several cases. + +(1) One specific high memory region is likely to be disabled by + code by toggling vms->highmem_{redists, ecam, mmio}. + +(2) VIRT_HIGH_PCIE_ECAM region is disabled on machine, which is + 'virt-2.12' or ealier than it. + +(3) VIRT_HIGH_PCIE_ECAM region is disabled when firmware is loaded + on 32-bits system. + +(4) One specific high memory region is disabled when it breaks the + PA space limit. + +The current implementation of virt_set_{memmap, high_memmap}() isn't +optimized because the high memory region's PA space is always reserved, +regardless of whatever the actual state in the corresponding +vms->highmem_{redists, ecam, mmio} flag. In the code, 'base' and +'vms->highest_gpa' are always increased for case (1), (2) and (3). +It's unnecessary since the assigned PA space for the disabled high +memory region won't be used afterwards. + +Improve the address assignment for those three high memory region by +skipping the address assignment for one specific high memory region if +it has been disabled in case (1), (2) and (3). The memory layout may +be changed after the improvement is applied, which leads to potential +migration breakage. So 'vms->highmem_compact' is added to control if +the improvement should be applied. For now, 'vms->highmem_compact' is +set to false, meaning that we don't have memory layout change until it +becomes configurable through property 'compact-highmem' in next patch. + +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-6-gshan@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit 4a4ff9edc6a8fdc76082af5b41b059217138c09b) +Signed-off-by: Gavin Shan +--- + hw/arm/virt.c | 15 ++++++++++----- + include/hw/arm/virt.h | 1 + + 2 files changed, 11 insertions(+), 5 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index 6e3b9fc060..6896e0ca0f 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1768,18 +1768,23 @@ static void virt_set_high_memmap(VirtMachineState *vms, + vms->memmap[i].size = region_size; + + /* +- * Check each device to see if they fit in the PA space, +- * moving highest_gpa as we go. ++ * Check each device to see if it fits in the PA space, ++ * moving highest_gpa as we go. For compatibility, move ++ * highest_gpa for disabled fitting devices as well, if ++ * the compact layout has been disabled. + * + * For each device that doesn't fit, disable it. + */ + fits = (region_base + region_size) <= BIT_ULL(pa_bits); +- if (fits) { +- vms->highest_gpa = region_base + region_size - 1; ++ *region_enabled &= fits; ++ if (vms->highmem_compact && !*region_enabled) { ++ continue; + } + +- *region_enabled &= fits; + base = region_base + region_size; ++ if (fits) { ++ vms->highest_gpa = base - 1; ++ } + } + } + +diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h +index 22b54ec510..15bd291311 100644 +--- a/include/hw/arm/virt.h ++++ b/include/hw/arm/virt.h +@@ -144,6 +144,7 @@ struct VirtMachineState { + PFlashCFI01 *flash[2]; + bool secure; + bool highmem; ++ bool highmem_compact; + bool highmem_ecam; + bool highmem_mmio; + bool highmem_redists; +-- +2.31.1 + diff --git a/kvm-hw-arm-virt-Introduce-variable-region_base-in-virt_s.patch b/kvm-hw-arm-virt-Introduce-variable-region_base-in-virt_s.patch new file mode 100644 index 0000000..ea9cb1f --- /dev/null +++ b/kvm-hw-arm-virt-Introduce-variable-region_base-in-virt_s.patch @@ -0,0 +1,82 @@ +From 305a369fd18f29914bf96cc181add532d435d8ed Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 21 Dec 2022 08:48:45 +0800 +Subject: [PATCH 3/8] hw/arm/virt: Introduce variable region_base in + virt_set_high_memmap() + +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: [3/8] 15de90df217d680ccc858b679898b3993e1c050a + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 + +This introduces variable 'region_base' for the base address of the +specific high memory region. It's the preparatory work to optimize +high memory region address assignment. + +No functional change intended. + +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-4-gshan@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit fa245799b9407fc7b561da185b3d889df5e16a88) +Signed-off-by: Gavin Shan +--- + hw/arm/virt.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index ca098d40b8..ddcf7ee2f8 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1739,15 +1739,15 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) + static void virt_set_high_memmap(VirtMachineState *vms, + hwaddr base, int pa_bits) + { +- hwaddr region_size; ++ hwaddr region_base, region_size; + bool fits; + int i; + + for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { ++ region_base = ROUND_UP(base, extended_memmap[i].size); + region_size = extended_memmap[i].size; + +- base = ROUND_UP(base, region_size); +- vms->memmap[i].base = base; ++ vms->memmap[i].base = region_base; + vms->memmap[i].size = region_size; + + /* +@@ -1756,9 +1756,9 @@ static void virt_set_high_memmap(VirtMachineState *vms, + * + * For each device that doesn't fit, disable it. + */ +- fits = (base + region_size) <= BIT_ULL(pa_bits); ++ fits = (region_base + region_size) <= BIT_ULL(pa_bits); + if (fits) { +- vms->highest_gpa = base + region_size - 1; ++ vms->highest_gpa = region_base + region_size - 1; + } + + switch (i) { +@@ -1773,7 +1773,7 @@ static void virt_set_high_memmap(VirtMachineState *vms, + break; + } + +- base += region_size; ++ base = region_base + region_size; + } + } + +-- +2.31.1 + diff --git a/kvm-hw-arm-virt-Introduce-virt_get_high_memmap_enabled-h.patch b/kvm-hw-arm-virt-Introduce-virt_get_high_memmap_enabled-h.patch new file mode 100644 index 0000000..659faeb --- /dev/null +++ b/kvm-hw-arm-virt-Introduce-virt_get_high_memmap_enabled-h.patch @@ -0,0 +1,95 @@ +From a2ddd68c8365ec602db6b2a9cf83bb441ca701cc Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 21 Dec 2022 08:48:45 +0800 +Subject: [PATCH 4/8] hw/arm/virt: Introduce virt_get_high_memmap_enabled() + helper + +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: [4/8] 65524de2fc106600bbaff641caa8c4f2f8027114 + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 + +This introduces virt_get_high_memmap_enabled() helper, which returns +the pointer to vms->highmem_{redists, ecam, mmio}. The pointer will +be used in the subsequent patches. + +No functional change intended. + +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-5-gshan@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit a5cb1350b19a5c2a58ab4edddf609ed429c13085) +Signed-off-by: Gavin Shan +--- + hw/arm/virt.c | 32 +++++++++++++++++++------------- + 1 file changed, 19 insertions(+), 13 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index ddcf7ee2f8..6e3b9fc060 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1736,14 +1736,31 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) + return arm_cpu_mp_affinity(idx, clustersz); + } + ++static inline bool *virt_get_high_memmap_enabled(VirtMachineState *vms, ++ int index) ++{ ++ bool *enabled_array[] = { ++ &vms->highmem_redists, ++ &vms->highmem_ecam, ++ &vms->highmem_mmio, ++ }; ++ ++ assert(ARRAY_SIZE(extended_memmap) - VIRT_LOWMEMMAP_LAST == ++ ARRAY_SIZE(enabled_array)); ++ assert(index - VIRT_LOWMEMMAP_LAST < ARRAY_SIZE(enabled_array)); ++ ++ return enabled_array[index - VIRT_LOWMEMMAP_LAST]; ++} ++ + static void virt_set_high_memmap(VirtMachineState *vms, + hwaddr base, int pa_bits) + { + hwaddr region_base, region_size; +- bool fits; ++ bool *region_enabled, fits; + int i; + + for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { ++ region_enabled = virt_get_high_memmap_enabled(vms, i); + region_base = ROUND_UP(base, extended_memmap[i].size); + region_size = extended_memmap[i].size; + +@@ -1761,18 +1778,7 @@ static void virt_set_high_memmap(VirtMachineState *vms, + vms->highest_gpa = region_base + region_size - 1; + } + +- switch (i) { +- case VIRT_HIGH_GIC_REDIST2: +- vms->highmem_redists &= fits; +- break; +- case VIRT_HIGH_PCIE_ECAM: +- vms->highmem_ecam &= fits; +- break; +- case VIRT_HIGH_PCIE_MMIO: +- vms->highmem_mmio &= fits; +- break; +- } +- ++ *region_enabled &= fits; + base = region_base + region_size; + } + } +-- +2.31.1 + diff --git a/kvm-hw-arm-virt-Introduce-virt_set_high_memmap-helper.patch b/kvm-hw-arm-virt-Introduce-virt_set_high_memmap-helper.patch new file mode 100644 index 0000000..f55c06a --- /dev/null +++ b/kvm-hw-arm-virt-Introduce-virt_set_high_memmap-helper.patch @@ -0,0 +1,130 @@ +From 5dff87c5ea60054709021025c9513ec259433ce2 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 21 Dec 2022 08:48:45 +0800 +Subject: [PATCH 1/8] hw/arm/virt: Introduce virt_set_high_memmap() helper + +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: [1/8] 5f6ba5af7a2c21d8473c58e088ee99b11336c673 + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 + +This introduces virt_set_high_memmap() helper. The logic of high +memory region address assignment is moved to the helper. The intention +is to make the subsequent optimization for high memory region address +assignment easier. + +No functional change intended. + +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-2-gshan@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit 4af6b6edece5ef273d29972d53547f823d2bc1c0) +Signed-off-by: Gavin Shan +--- + hw/arm/virt.c | 74 ++++++++++++++++++++++++++++----------------------- + 1 file changed, 41 insertions(+), 33 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index bf18838b87..bea5f54720 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1736,6 +1736,46 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) + return arm_cpu_mp_affinity(idx, clustersz); + } + ++static void virt_set_high_memmap(VirtMachineState *vms, ++ hwaddr base, int pa_bits) ++{ ++ int i; ++ ++ for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { ++ hwaddr size = extended_memmap[i].size; ++ bool fits; ++ ++ base = ROUND_UP(base, size); ++ vms->memmap[i].base = base; ++ vms->memmap[i].size = size; ++ ++ /* ++ * Check each device to see if they fit in the PA space, ++ * moving highest_gpa as we go. ++ * ++ * For each device that doesn't fit, disable it. ++ */ ++ fits = (base + size) <= BIT_ULL(pa_bits); ++ if (fits) { ++ vms->highest_gpa = base + size - 1; ++ } ++ ++ switch (i) { ++ case VIRT_HIGH_GIC_REDIST2: ++ vms->highmem_redists &= fits; ++ break; ++ case VIRT_HIGH_PCIE_ECAM: ++ vms->highmem_ecam &= fits; ++ break; ++ case VIRT_HIGH_PCIE_MMIO: ++ vms->highmem_mmio &= fits; ++ break; ++ } ++ ++ base += size; ++ } ++} ++ + static void virt_set_memmap(VirtMachineState *vms, int pa_bits) + { + MachineState *ms = MACHINE(vms); +@@ -1791,39 +1831,7 @@ static void virt_set_memmap(VirtMachineState *vms, int pa_bits) + /* We know for sure that at least the memory fits in the PA space */ + vms->highest_gpa = memtop - 1; + +- for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { +- hwaddr size = extended_memmap[i].size; +- bool fits; +- +- base = ROUND_UP(base, size); +- vms->memmap[i].base = base; +- vms->memmap[i].size = size; +- +- /* +- * Check each device to see if they fit in the PA space, +- * moving highest_gpa as we go. +- * +- * For each device that doesn't fit, disable it. +- */ +- fits = (base + size) <= BIT_ULL(pa_bits); +- if (fits) { +- vms->highest_gpa = base + size - 1; +- } +- +- switch (i) { +- case VIRT_HIGH_GIC_REDIST2: +- vms->highmem_redists &= fits; +- break; +- case VIRT_HIGH_PCIE_ECAM: +- vms->highmem_ecam &= fits; +- break; +- case VIRT_HIGH_PCIE_MMIO: +- vms->highmem_mmio &= fits; +- break; +- } +- +- base += size; +- } ++ virt_set_high_memmap(vms, base, pa_bits); + + if (device_memory_size > 0) { + ms->device_memory = g_malloc0(sizeof(*ms->device_memory)); +-- +2.31.1 + diff --git a/kvm-hw-arm-virt-Rename-variable-size-to-region_size-in-v.patch b/kvm-hw-arm-virt-Rename-variable-size-to-region_size-in-v.patch new file mode 100644 index 0000000..27bc6bb --- /dev/null +++ b/kvm-hw-arm-virt-Rename-variable-size-to-region_size-in-v.patch @@ -0,0 +1,83 @@ +From bd5b7edbf8f4425f4b4e0d49a00cbdd48d9c6f48 Mon Sep 17 00:00:00 2001 +From: Gavin Shan +Date: Wed, 21 Dec 2022 08:48:45 +0800 +Subject: [PATCH 2/8] hw/arm/virt: Rename variable size to region_size in + virt_set_high_memmap() + +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: [2/8] 1cadf1b00686cceb45821a58fdcb509bc5da335d + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2113840 + +This renames variable 'size' to 'region_size' in virt_set_high_memmap(). +Its counterpart ('region_base') will be introduced in next patch. + +No functional change intended. + +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-3-gshan@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit 370bea9d1c78796eec235ed6cb4310f489931a62) +Signed-off-by: Gavin Shan +--- + hw/arm/virt.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/hw/arm/virt.c b/hw/arm/virt.c +index bea5f54720..ca098d40b8 100644 +--- a/hw/arm/virt.c ++++ b/hw/arm/virt.c +@@ -1739,15 +1739,16 @@ static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) + static void virt_set_high_memmap(VirtMachineState *vms, + hwaddr base, int pa_bits) + { ++ hwaddr region_size; ++ bool fits; + int i; + + for (i = VIRT_LOWMEMMAP_LAST; i < ARRAY_SIZE(extended_memmap); i++) { +- hwaddr size = extended_memmap[i].size; +- bool fits; ++ region_size = extended_memmap[i].size; + +- base = ROUND_UP(base, size); ++ base = ROUND_UP(base, region_size); + vms->memmap[i].base = base; +- vms->memmap[i].size = size; ++ vms->memmap[i].size = region_size; + + /* + * Check each device to see if they fit in the PA space, +@@ -1755,9 +1756,9 @@ static void virt_set_high_memmap(VirtMachineState *vms, + * + * For each device that doesn't fit, disable it. + */ +- fits = (base + size) <= BIT_ULL(pa_bits); ++ fits = (base + region_size) <= BIT_ULL(pa_bits); + if (fits) { +- vms->highest_gpa = base + size - 1; ++ vms->highest_gpa = base + region_size - 1; + } + + switch (i) { +@@ -1772,7 +1773,7 @@ static void virt_set_high_memmap(VirtMachineState *vms, + break; + } + +- base += size; ++ base += region_size; + } + } + +-- +2.31.1 + diff --git a/qemu-kvm.spec b/qemu-kvm.spec index 1e052fb..49a09a7 100644 --- a/qemu-kvm.spec +++ b/qemu-kvm.spec @@ -148,7 +148,7 @@ Obsoletes: %{name}-block-ssh <= %{epoch}:%{version} \ Summary: QEMU is a machine emulator and virtualizer Name: qemu-kvm Version: 7.2.0 -Release: 2%{?rcrel}%{?dist}%{?cc_suffix} +Release: 3%{?rcrel}%{?dist}%{?cc_suffix} # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped # Epoch 15 used for RHEL 8 # Epoch 17 used for RHEL 9 (due to release versioning offset in RHEL 8.5) @@ -192,6 +192,22 @@ Patch0020: 0020-redhat-aarch64-add-rhel9.2.0-virt-machine-type.patch Patch0021: 0021-redhat-Add-new-rhel-9.2.0-s390x-machine-type.patch Patch0022: 0022-x86-rhel-9.2.0-machine-type.patch Patch23: kvm-redhat-fix-virt-rhel9.2.0-compat-props.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch24: kvm-hw-arm-virt-Introduce-virt_set_high_memmap-helper.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch25: kvm-hw-arm-virt-Rename-variable-size-to-region_size-in-v.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch26: kvm-hw-arm-virt-Introduce-variable-region_base-in-virt_s.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch27: kvm-hw-arm-virt-Introduce-virt_get_high_memmap_enabled-h.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch28: kvm-hw-arm-virt-Improve-high-memory-region-address-assig.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch29: kvm-hw-arm-virt-Add-compact-highmem-property.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch30: kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch +# For bz#2113840 - [RHEL9.2] Memory mapping optimization for virt machine +Patch31: kvm-hw-arm-virt-Enable-compat-high-memory-region-address.patch %if %{have_clang} BuildRequires: clang @@ -1220,6 +1236,18 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Wed Jan 04 2023 Miroslav Rezanina - 7.2.0-3 +- kvm-hw-arm-virt-Introduce-virt_set_high_memmap-helper.patch [bz#2113840] +- kvm-hw-arm-virt-Rename-variable-size-to-region_size-in-v.patch [bz#2113840] +- kvm-hw-arm-virt-Introduce-variable-region_base-in-virt_s.patch [bz#2113840] +- kvm-hw-arm-virt-Introduce-virt_get_high_memmap_enabled-h.patch [bz#2113840] +- kvm-hw-arm-virt-Improve-high-memory-region-address-assig.patch [bz#2113840] +- kvm-hw-arm-virt-Add-compact-highmem-property.patch [bz#2113840] +- kvm-hw-arm-virt-Add-properties-to-disable-high-memory-re.patch [bz#2113840] +- kvm-hw-arm-virt-Enable-compat-high-memory-region-address.patch [bz#2113840] +- Resolves: bz#2113840 + ([RHEL9.2] Memory mapping optimization for virt machine) + * Tue Dec 20 2022 Miroslav Rezanina - 7.2.0-2 - Fix updating from 7.1.0 - kvm-redhat-fix-virt-rhel9.2.0-compat-props.patch[bz#2154640]