|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 31/52] xen/mpu: make early_fdt_map support in MPU systems
In MPU system, MPU memory region is always mapped PAGE_ALIGN, so in order to
not access unexpected memory area, dtb section in xen.lds.S should be made
page-aligned too.
We add . = ALIGN(PAGE_SIZE); in the head of dtb section to make it happen.
In this commit, we map early FDT with a transient MPU memory region, as
it will be relocated into heap and unmapped at the end of boot.
Signed-off-by: Penny Zheng <penny.zheng@xxxxxxx>
Signed-off-by: Wei Chen <wei.chen@xxxxxxx>
---
v3:
- map the first 2MB. Check the size and then re-map with an extra 2MB if needed
---
xen/arch/arm/include/asm/arm64/mpu.h | 3 ++-
xen/arch/arm/include/asm/page.h | 5 +++++
xen/arch/arm/mm.c | 26 ++++++++++++++++++++------
xen/arch/arm/mpu/mm.c | 1 +
xen/arch/arm/xen.lds.S | 5 ++++-
5 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/xen/arch/arm/include/asm/arm64/mpu.h
b/xen/arch/arm/include/asm/arm64/mpu.h
index a6b07bab02..715ea69884 100644
--- a/xen/arch/arm/include/asm/arm64/mpu.h
+++ b/xen/arch/arm/include/asm/arm64/mpu.h
@@ -72,7 +72,8 @@ typedef union {
unsigned long ns:1; /* Not-Secure */
unsigned long res:1; /* Reserved 0 by hardware */
unsigned long limit:42; /* Limit Address */
- unsigned long pad:16;
+ unsigned long pad:15;
+ unsigned long tran:1; /* Transient region */
} reg;
uint64_t bits;
} prlar_t;
diff --git a/xen/arch/arm/include/asm/page.h b/xen/arch/arm/include/asm/page.h
index 85ecd5e4de..a434e2205a 100644
--- a/xen/arch/arm/include/asm/page.h
+++ b/xen/arch/arm/include/asm/page.h
@@ -97,19 +97,24 @@
* [3:4] Execute Never
* [5:6] Access Permission
* [7] Region Present
+ * [8] Transient Region, e.g. MPU memory region is temproraily
+ * mapped for a short time
*/
#define _PAGE_AI_BIT 0
#define _PAGE_XN_BIT 3
#define _PAGE_AP_BIT 5
#define _PAGE_PRESENT_BIT 7
+#define _PAGE_TRANSIENT_BIT 8
#define _PAGE_AI (7U << _PAGE_AI_BIT)
#define _PAGE_XN (2U << _PAGE_XN_BIT)
#define _PAGE_RO (2U << _PAGE_AP_BIT)
#define _PAGE_PRESENT (1U << _PAGE_PRESENT_BIT)
+#define _PAGE_TRANSIENT (1U << _PAGE_TRANSIENT_BIT)
#define PAGE_AI_MASK(x) (((x) >> _PAGE_AI_BIT) & 0x7U)
#define PAGE_XN_MASK(x) (((x) >> _PAGE_XN_BIT) & 0x3U)
#define PAGE_AP_MASK(x) (((x) >> _PAGE_AP_BIT) & 0x3U)
#define PAGE_RO_MASK(x) (((x) >> _PAGE_AP_BIT) & 0x2U)
+#define PAGE_TRANSIENT_MASK(x) (((x) >> _PAGE_TRANSIENT_BIT) & 0x1U)
#endif /* CONFIG_HAS_MPU */
/*
diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index d35e7e280f..8625066256 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -61,8 +61,17 @@ void flush_page_to_ram(unsigned long mfn, bool sync_icache)
void * __init early_fdt_map(paddr_t fdt_paddr)
{
+#ifndef CONFIG_HAS_MPU
/* We are using 2MB superpage for mapping the FDT */
paddr_t base_paddr = fdt_paddr & SECOND_MASK;
+ unsigned int flags = PAGE_HYPERVISOR_RO | _PAGE_BLOCK;
+ unsigned long base_virt = BOOT_FDT_VIRT_START;
+#else
+ /* MPU region must be PAGE aligned */
+ paddr_t base_paddr = fdt_paddr & PAGE_MASK;
+ unsigned int flags = PAGE_HYPERVISOR_RO | _PAGE_TRANSIENT;
+ unsigned long base_virt = ~0UL;
+#endif
paddr_t offset;
void *fdt_virt;
uint32_t size;
@@ -79,18 +88,24 @@ void * __init early_fdt_map(paddr_t fdt_paddr)
if ( !fdt_paddr || fdt_paddr % MIN_FDT_ALIGN )
return NULL;
+#ifndef CONFIG_HAS_MPU
/* The FDT is mapped using 2MB superpage */
BUILD_BUG_ON(BOOT_FDT_VIRT_START % SZ_2M);
+#endif
- rc = map_pages_to_xen(BOOT_FDT_VIRT_START, maddr_to_mfn(base_paddr),
- SZ_2M >> PAGE_SHIFT,
- PAGE_HYPERVISOR_RO | _PAGE_BLOCK);
+ rc = map_pages_to_xen(base_virt, maddr_to_mfn(base_paddr),
+ SZ_2M >> PAGE_SHIFT, flags);
if ( rc )
panic("Unable to map the device-tree.\n");
+#ifndef CONFIG_HAS_MPU
offset = fdt_paddr % SECOND_SIZE;
fdt_virt = (void *)BOOT_FDT_VIRT_START + offset;
+#else
+ offset = fdt_paddr % PAGE_SIZE;
+ fdt_virt = (void *)fdt_paddr;
+#endif
if ( fdt_magic(fdt_virt) != FDT_MAGIC )
return NULL;
@@ -101,10 +116,9 @@ void * __init early_fdt_map(paddr_t fdt_paddr)
if ( (offset + size) > SZ_2M )
{
- rc = map_pages_to_xen(BOOT_FDT_VIRT_START + SZ_2M,
+ rc = map_pages_to_xen(base_virt + SZ_2M,
maddr_to_mfn(base_paddr + SZ_2M),
- SZ_2M >> PAGE_SHIFT,
- PAGE_HYPERVISOR_RO | _PAGE_BLOCK);
+ SZ_2M >> PAGE_SHIFT, flags);
if ( rc )
panic("Unable to map the device-tree\n");
}
diff --git a/xen/arch/arm/mpu/mm.c b/xen/arch/arm/mpu/mm.c
index 14a1309ca1..f4ce19d36a 100644
--- a/xen/arch/arm/mpu/mm.c
+++ b/xen/arch/arm/mpu/mm.c
@@ -448,6 +448,7 @@ static int xen_mpumap_update_entry(paddr_t base, paddr_t
limit,
/* Set permission */
xen_mpumap[idx].prbar.reg.ap = PAGE_AP_MASK(flags);
xen_mpumap[idx].prbar.reg.xn = PAGE_XN_MASK(flags);
+ xen_mpumap[idx].prlar.reg.tran = PAGE_TRANSIENT_MASK(flags);
write_protection_region((const pr_t*)(&xen_mpumap[idx]), idx);
}
diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S
index 4f7daa7dca..f2715d7cb7 100644
--- a/xen/arch/arm/xen.lds.S
+++ b/xen/arch/arm/xen.lds.S
@@ -216,7 +216,10 @@ SECTIONS
_end = . ;
/* Section for the device tree blob (if any). */
- .dtb : { *(.dtb) } :text
+ .dtb : {
+ . = ALIGN(PAGE_SIZE);
+ *(.dtb)
+ } :text
DWARF2_DEBUG_SECTIONS
--
2.25.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |