[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v3 38/52] xen/mpu: map domain page in MPU system



In MPU system, we implement map_domain_page()/unmap_domain_page()
through mapping the domain page with a transient MPU region on demand.

Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
---
v3:
- new patch
---
 xen/arch/arm/Makefile             |  4 ++
 xen/arch/arm/include/asm/mpu/mm.h |  1 +
 xen/arch/arm/mpu/domain_page.c    | 68 +++++++++++++++++++++++++++++++
 xen/arch/arm/mpu/mm.c             | 17 ++++++++
 4 files changed, 90 insertions(+)
 create mode 100644 xen/arch/arm/mpu/domain_page.c

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 5f6ee817ad..feb49640a0 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -17,7 +17,11 @@ obj-y += device.o
 obj-$(CONFIG_IOREQ_SERVER) += dm.o
 obj-y += domain.o
 obj-y += domain_build.init.o
+ifneq ($(CONFIG_HAS_MPU),y)
 obj-$(CONFIG_ARCH_MAP_DOMAIN_PAGE) += domain_page.o
+else
+obj-$(CONFIG_ARCH_MAP_DOMAIN_PAGE) += mpu/domain_page.o
+endif
 obj-y += domctl.o
 obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
 obj-y += efi/
diff --git a/xen/arch/arm/include/asm/mpu/mm.h 
b/xen/arch/arm/include/asm/mpu/mm.h
index 452fe20c5f..a83519ad13 100644
--- a/xen/arch/arm/include/asm/mpu/mm.h
+++ b/xen/arch/arm/include/asm/mpu/mm.h
@@ -10,6 +10,7 @@ extern void setup_staticheap_mappings(void);
 extern uint8_t is_mm_range_mapped(paddr_t pa, paddr_t len);
 extern void *map_mm_range(paddr_t pa, size_t len, unsigned int attributes);
 extern void unmap_mm_range(paddr_t pa);
+extern bool is_mm_range_mapped_transient(paddr_t pa, paddr_t len);
 
 #endif /* __ARCH_ARM_MM_MPU__ */
 
diff --git a/xen/arch/arm/mpu/domain_page.c b/xen/arch/arm/mpu/domain_page.c
new file mode 100644
index 0000000000..da408bb9e0
--- /dev/null
+++ b/xen/arch/arm/mpu/domain_page.c
@@ -0,0 +1,68 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <xen/mm.h>
+#include <asm/arm64/mpu.h>
+
+/* Override macros from asm/mm.h to make them work with mfn_t */
+#undef mfn_to_virt
+#define mfn_to_virt(mfn) __mfn_to_virt(mfn_x(mfn))
+
+void *map_domain_page_global(mfn_t mfn)
+{
+    /* TODO: map shared domain page globally */
+    printk(XENLOG_ERR
+           "mpu: mapping shared domain page not SUPPORTED right now!\n");
+    return NULL;
+}
+
+void unmap_domain_page_global(const void *va)
+{
+    /* TODO: map shared domain page globally */
+    printk(XENLOG_ERR
+           "mpu: mapping shared domain page not SUPPORTED right now!\n");
+    return;
+}
+
+/* Map a page of domain memory */
+void *map_domain_page(mfn_t mfn)
+{
+    uint8_t idx;
+    paddr_t pa = mfn_to_maddr(mfn);
+
+    idx = is_mm_range_mapped(pa, PAGE_SIZE);
+    if ( idx != INVALID_REGION_IDX )
+        /* Already mapped */
+        return mfn_to_virt(mfn);
+    else
+        /*
+         * Map it temporarily with a transient MPU region.
+         * And it is caller's responsibity to unmap it
+         * through unmap_domain_page.
+         */
+        return map_mm_range(pa, PAGE_SIZE, PAGE_HYPERVISOR_RW);
+}
+
+/* Release a mapping taken with map_domain_page() */
+void unmap_domain_page(const void *va)
+{
+    paddr_t pa = (paddr_t)(unsigned long)(va);
+
+    /* Only unmap transient page */
+    if ( is_mm_range_mapped_transient(pa, PAGE_SIZE) )
+        unmap_mm_range(pa);
+}
+
+mfn_t domain_page_map_to_mfn(const void *ptr)
+{
+    printk(XENLOG_ERR
+           "mpu: domain_page_map_to_mfn() not SUPPORTED right now!\n");
+    return INVALID_MFN;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
index 21276d6de9..b2419f0603 100644
--- a/xen/arch/arm/mpu/mm.c
+++ b/xen/arch/arm/mpu/mm.c
@@ -809,6 +809,23 @@ void iounmap(void __iomem *va)
     unmap_mm_range(virt_to_maddr(va));
 }
 
+bool is_mm_range_mapped_transient(paddr_t pa, paddr_t len)
+{
+    uint8_t idx;
+
+    idx = is_mm_range_mapped(pa, len);
+    if ( idx != INVALID_REGION_IDX )
+    {
+        pr_t *region;
+
+        region = &xen_mpumap[idx];
+        if ( region_is_transient(region) )
+            return true;
+    }
+
+    return false;
+}
+
 /*
  * Local variables:
  * mode: C
-- 
2.25.1




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.