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

[PATCH v3 37/52] xen/mpu: implement MPU version of copy_from_paddr



When implementing MPU version of copy_from_paddr, if source physical address
is not accessible, we shall map it temporarily with a transient MPU
memory region for copying and pasting.

Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
---
v3:
- new patch
---
 xen/arch/arm/include/asm/mpu/mm.h |  3 +++
 xen/arch/arm/mpu/mm.c             |  6 +++---
 xen/arch/arm/mpu/setup.c          | 32 +++++++++++++++++++++++++++++++
 3 files changed, 38 insertions(+), 3 deletions(-)

diff --git a/xen/arch/arm/include/asm/mpu/mm.h 
b/xen/arch/arm/include/asm/mpu/mm.h
index 98f6df65b8..452fe20c5f 100644
--- a/xen/arch/arm/include/asm/mpu/mm.h
+++ b/xen/arch/arm/include/asm/mpu/mm.h
@@ -7,6 +7,9 @@ extern unsigned long frametable_pdx_end;
 
 extern int xen_mpumap_update(paddr_t base, paddr_t limit, unsigned int flags);
 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);
 
 #endif /* __ARCH_ARM_MM_MPU__ */
 
diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
index 3bb1a5c7c4..21276d6de9 100644
--- a/xen/arch/arm/mpu/mm.c
+++ b/xen/arch/arm/mpu/mm.c
@@ -631,7 +631,7 @@ int __init unmap_staticmem_pages_to_xen(paddr_t start, 
paddr_t end)
  * If it is mapped, the associated index will be returned.
  * If it is not mapped, INVALID_REGION_IDX will be returned.
  */
-static uint8_t is_mm_range_mapped(paddr_t pa, paddr_t len)
+uint8_t is_mm_range_mapped(paddr_t pa, paddr_t len)
 {
     int rc;
     uint8_t idx;
@@ -705,7 +705,7 @@ static int is_mm_range_mapped_with_attr(paddr_t pa, paddr_t 
len,
  * map_mm_range shall work with unmap_mm_range to map a chunk
  * of memory with a transient MPU memory region for a period of short time.
  */
-static void *map_mm_range(paddr_t pa, size_t len, unsigned int attributes)
+void *map_mm_range(paddr_t pa, size_t len, unsigned int attributes)
 {
     if ( xen_mpumap_update(pa, pa + len, attributes | _PAGE_TRANSIENT) )
         printk(XENLOG_ERR "Failed to map_mm_range 
0x%"PRIpaddr"-0x%"PRIpaddr"\n",
@@ -714,7 +714,7 @@ static void *map_mm_range(paddr_t pa, size_t len, unsigned 
int attributes)
     return maddr_to_virt(pa);
 }
 
-static void unmap_mm_range(paddr_t pa)
+void unmap_mm_range(paddr_t pa)
 {
     uint8_t idx;
 
diff --git a/xen/arch/arm/mpu/setup.c b/xen/arch/arm/mpu/setup.c
index 31f412957c..9963975b4e 100644
--- a/xen/arch/arm/mpu/setup.c
+++ b/xen/arch/arm/mpu/setup.c
@@ -22,6 +22,7 @@
 #include <xen/init.h>
 #include <xen/mm.h>
 #include <xen/pfn.h>
+#include <asm/arm64/mpu.h>
 #include <asm/mpu/mm.h>
 #include <asm/page.h>
 #include <asm/setup.h>
@@ -60,6 +61,37 @@ void __init setup_mm(void)
     init_staticmem_pages();
 }
 
+/*
+ * copy_from_paddr - copy data from a physical address
+ * @dst: destination virtual address
+ * @paddr: source physical address
+ * @len: length to copy
+ */
+void __init copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
+{
+    void *src, *rc = NULL;
+    uint8_t idx;
+
+    idx = is_mm_range_mapped(round_pgdown(paddr), round_pgup(len));
+    if ( idx == INVALID_REGION_IDX )
+    {
+        /*
+         * If source physical address is not accessible, we shall map it
+         * temporarily for copying and pasting
+         */
+        rc = map_mm_range(round_pgdown(paddr), round_pgup(len),
+                          PAGE_HYPERVISOR_WC);
+        if ( !rc )
+            return;
+    }
+
+    src = maddr_to_virt(paddr);
+    memcpy(dst, src, len);
+
+    if ( rc )
+        unmap_mm_range(round_pgdown(paddr));
+}
+
 /*
  * 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®.