In MPU system, we could not afford mapping a new MPU memory region
with each new device, it will exhaust limited MPU memory regions
very quickly.

So we introduce `mpu,device-memory-section` for users to statically
configure the whole system device memory with the least number of
memory regions in Device Tree. This section shall cover all devices
that will be used in Xen, like `UART`, `GIC`, etc.

Before we map `mpu,device-memory-section` with device memory attributes and
permissions(REGION_HYPRVISOR_NOCACHE), we shall destroy the mapping for early
UART which got set up in assembly boot-time, to avoid MPU memory
region overlapping.

Signed-off-by: Penny Zheng <penny.zh...@arm.com>
Signed-off-by: Wei Chen <wei.c...@arm.com>
---
 xen/arch/arm/include/asm/arm64/mpu.h |  6 ++++--
 xen/arch/arm/include/asm/setup.h     |  1 +
 xen/arch/arm/mm_mpu.c                | 14 +++++++++++++-
 xen/arch/arm/setup_mpu.c             |  5 +++++
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/include/asm/arm64/mpu.h 
b/xen/arch/arm/include/asm/arm64/mpu.h
index c1dea1c8e9..8e8679bc82 100644
--- a/xen/arch/arm/include/asm/arm64/mpu.h
+++ b/xen/arch/arm/include/asm/arm64/mpu.h
@@ -69,10 +69,11 @@
 #define REGION_TRANSIENT_MASK(x)  (((x) >> _REGION_TRANSIENT_BIT) & 0x3U)
 
 /*
- * _REGION_NORMAL is convenience define. It is not meant to be used
- * outside of this header.
+ * _REGION_NORMAL and _REGION_DEVICE are convenience defines. They are not
+ * meant to be used outside of this header.
  */
 #define _REGION_NORMAL            (MT_NORMAL|_REGION_PRESENT)
+#define _REGION_DEVICE            (_REGION_XN|_REGION_PRESENT)
 
 #define REGION_HYPERVISOR_RW      (_REGION_NORMAL|_REGION_XN)
 #define REGION_HYPERVISOR_RO      (_REGION_NORMAL|_REGION_XN|_REGION_RO)
@@ -80,6 +81,7 @@
 #define REGION_HYPERVISOR         REGION_HYPERVISOR_RW
 #define REGION_HYPERVISOR_BOOT    (REGION_HYPERVISOR_RW|_REGION_BOOTONLY)
 #define REGION_HYPERVISOR_SWITCH  (REGION_HYPERVISOR_RW|_REGION_SWITCH)
+#define REGION_HYPERVISOR_NOCACHE 
(_REGION_DEVICE|MT_DEVICE_nGnRE|_REGION_SWITCH)
 
 #define INVALID_REGION            (~0UL)
 
diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index 3581f8f990..b7a2225c25 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -194,6 +194,7 @@ struct init_info
 /* Index of MPU memory section */
 enum mpu_section_info {
     MSINFO_GUEST,
+    MSINFO_DEVICE,
     MSINFO_MAX
 };
 
diff --git a/xen/arch/arm/mm_mpu.c b/xen/arch/arm/mm_mpu.c
index 3a0d110b13..1566ba60af 100644
--- a/xen/arch/arm/mm_mpu.c
+++ b/xen/arch/arm/mm_mpu.c
@@ -73,6 +73,7 @@ struct page_info *frame_table;
 
 static const unsigned int mpu_section_mattr[MSINFO_MAX] = {
     REGION_HYPERVISOR_SWITCH,
+    REGION_HYPERVISOR_NOCACHE,
 };
 
 /* Write a MPU protection region */
@@ -673,8 +674,19 @@ void __init setup_static_mappings(void)
     setup_staticheap_mappings();
 
     for ( uint8_t i = MSINFO_GUEST; i < MSINFO_MAX; i++ )
+    {
+#ifdef CONFIG_EARLY_PRINTK
+        if ( i == MSINFO_DEVICE )
+            /*
+             * Destroy early UART mapping before mapping device memory section.
+             * WARNING:console will be inaccessible temporarily.
+             */
+            destroy_xen_mappings(CONFIG_EARLY_UART_BASE_ADDRESS,
+                                 CONFIG_EARLY_UART_BASE_ADDRESS + 
EARLY_UART_SIZE);
+#endif
         map_mpu_memory_section_on_boot(i, mpu_section_mattr[i]);
-    /* TODO: device memory section, boot-module section, etc */
+    }
+    /* TODO: boot-module section, etc */
 }
 
 /* Map a frame table to cover physical addresses ps through pe */
diff --git a/xen/arch/arm/setup_mpu.c b/xen/arch/arm/setup_mpu.c
index 09a38a34a4..ec05542f68 100644
--- a/xen/arch/arm/setup_mpu.c
+++ b/xen/arch/arm/setup_mpu.c
@@ -29,6 +29,7 @@
 
 const char *mpu_section_info_str[MSINFO_MAX] = {
     "mpu,guest-memory-section",
+    "mpu,device-memory-section",
 };
 
 /*
@@ -47,6 +48,10 @@ struct mpuinfo __initdata mpuinfo;
  * through "xen,static-mem" property in MPU system. "mpu,guest-memory-section"
  * limits the scattering of "xen,static-mem", as users could not define
  * a "xen,static-mem" outside "mpu,guest-memory-section".
+ *
+ * "mpu,device-memory-section": this section draws the device memory layout
+ * with the least number of memory regions for all devices in system that will
+ * be used in Xen, like `UART`, `GIC`, etc.
  */
 static int __init process_mpu_memory_section(const void *fdt, int node,
                                              const char *name, void *data,
-- 
2.25.1


Reply via email to