diff mbox series

[v2,29/40] xen/mpu: introduce mpu_memory_section_contains for address range check

Message ID 20230113052914.3845596-30-Penny.Zheng@arm.com (mailing list archive)
State New, archived
Headers show
Series xen/arm: Add Armv8-R64 MPU support to Xen - Part#1 | expand

Commit Message

Penny Zheng Jan. 13, 2023, 5:29 a.m. UTC
We have already introduced "mpu,xxx-memory-section" to limit system/domain
configuration, so we shall add check to verfify user's configuration.

We shall check if any guest boot module is within the boot module section,
including kernel module(BOOTMOD_KERNEL), device tree
passthrough module(BOOTMOD_GUEST_DTB), and ramdisk module(BOOTMOD_RAMDISK).

We also shall check if any guest RAM through "xen,static-mem" is within
the guest memory section.

Function mpu_memory_section_contains is introduced to do above check.

Signed-off-by: Penny Zheng <penny.zheng@arm.com>
Signed-off-by: Wei Chen <wei.chen@arm.com>
---
 xen/arch/arm/domain_build.c      |  4 ++++
 xen/arch/arm/include/asm/setup.h |  2 ++
 xen/arch/arm/kernel.c            | 18 ++++++++++++++++++
 xen/arch/arm/setup_mpu.c         | 22 ++++++++++++++++++++++
 4 files changed, 46 insertions(+)
diff mbox series

Patch

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 829cea8de8..f48a3f679f 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -546,6 +546,10 @@  static mfn_t __init acquire_static_memory_bank(struct domain *d,
                d, *psize);
         return INVALID_MFN;
     }
+#ifdef CONFIG_HAS_MPU
+    if ( !mpu_memory_section_contains(*pbase, *pbase + *psize, MSINFO_GUEST) )
+        return INVALID_MFN;
+#endif
 
     smfn = maddr_to_mfn(*pbase);
     res = acquire_domstatic_pages(d, smfn, PFN_DOWN(*psize), 0);
diff --git a/xen/arch/arm/include/asm/setup.h b/xen/arch/arm/include/asm/setup.h
index 61f24b5848..d4c1336597 100644
--- a/xen/arch/arm/include/asm/setup.h
+++ b/xen/arch/arm/include/asm/setup.h
@@ -209,6 +209,8 @@  extern struct mpuinfo mpuinfo;
 
 extern int process_mpuinfo(const void *fdt, int node, uint32_t address_cells,
                            uint32_t size_cells);
+extern bool mpu_memory_section_contains(paddr_t s, paddr_t e,
+                                        enum mpu_section_info type);
 #endif /* CONFIG_HAS_MPU */
 
 #endif
diff --git a/xen/arch/arm/kernel.c b/xen/arch/arm/kernel.c
index 0475d8fae7..ee7144ec13 100644
--- a/xen/arch/arm/kernel.c
+++ b/xen/arch/arm/kernel.c
@@ -467,6 +467,12 @@  int __init kernel_probe(struct kernel_info *info,
                 mod = boot_module_find_by_addr_and_kind(
                         BOOTMOD_KERNEL, kernel_addr);
                 info->kernel_bootmodule = mod;
+#ifdef CONFIG_HAS_MPU
+                if ( !mpu_memory_section_contains(mod->start,
+                                                  mod->start + mod->size,
+                                                  MSINFO_BOOTMODULE) )
+                    return -EINVAL;
+#endif
             }
             else if ( dt_device_is_compatible(node, "multiboot,ramdisk") )
             {
@@ -477,6 +483,12 @@  int __init kernel_probe(struct kernel_info *info,
                 dt_get_range(&val, node, &initrd_addr, &size);
                 info->initrd_bootmodule = boot_module_find_by_addr_and_kind(
                         BOOTMOD_RAMDISK, initrd_addr);
+#ifdef CONFIG_HAS_MPU
+                if ( !mpu_memory_section_contains(mod->start,
+                                                  mod->start + mod->size,
+                                                  MSINFO_BOOTMODULE) )
+                    return -EINVAL;
+#endif
             }
             else if ( dt_device_is_compatible(node, "multiboot,device-tree") )
             {
@@ -489,6 +501,12 @@  int __init kernel_probe(struct kernel_info *info,
                 dt_get_range(&val, node, &dtb_addr, &size);
                 info->dtb_bootmodule = boot_module_find_by_addr_and_kind(
                         BOOTMOD_GUEST_DTB, dtb_addr);
+#ifdef CONFIG_HAS_MPU
+                if ( !mpu_memory_section_contains(mod->start,
+                                                  mod->start + mod->size,
+                                                  MSINFO_BOOTMODULE) )
+                    return -EINVAL;
+#endif
             }
             else
                 continue;
diff --git a/xen/arch/arm/setup_mpu.c b/xen/arch/arm/setup_mpu.c
index 160934bf86..f7d74ea604 100644
--- a/xen/arch/arm/setup_mpu.c
+++ b/xen/arch/arm/setup_mpu.c
@@ -130,6 +130,28 @@  void __init setup_mm(void)
     init_staticmem_pages();
 }
 
+bool __init mpu_memory_section_contains(paddr_t s, paddr_t e,
+                                        enum mpu_section_info type)
+{
+    unsigned int i = 0;
+
+    for ( ; i < mpuinfo.sections[type].nr_banks; i++ )
+    {
+        paddr_t section_start = mpuinfo.sections[type].bank[i].start;
+        paddr_t section_size = mpuinfo.sections[type].bank[i].size;
+        paddr_t section_end = section_start + section_size;
+
+        /* range inclusive */
+        if ( s >= section_start && e <= section_end )
+            return true;
+    }
+
+    printk(XENLOG_ERR
+           "mpu: invalid range configuration 0x%"PRIpaddr" - 0x%"PRIpaddr", and it shall be within %s\n",
+           s, e, mpu_section_info_str[i]);
+    return false;
+}
+
 /*
  * Local variables:
  * mode: C