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