diff options
author | Vladimir Murzin <vladimir.murzin@arm.com> | 2017-10-16 14:00:45 +0200 |
---|---|---|
committer | Russell King <rmk+kernel@armlinux.org.uk> | 2017-10-23 17:59:31 +0200 |
commit | 216218308cfb0939aeecb246b34faf6e179c8d57 (patch) | |
tree | ac012bba6a2ab6728d7747b57cbf7fdc4a892912 /arch/arm/kernel | |
parent | ARM: 8712/1: NOMMU: Use more MPU regions to cover memory (diff) | |
download | linux-216218308cfb0939aeecb246b34faf6e179c8d57.tar.xz linux-216218308cfb0939aeecb246b34faf6e179c8d57.zip |
ARM: 8713/1: NOMMU: Support MPU in XIP configuration
Currently, there is assumption in early MPU setup code that kernel
image is located in RAM, which is obviously not true for XIP. To run
code from ROM we need to make sure that it is covered by MPU. However,
due to we allocate regions (semi-)dynamically we can run into issue of
trimming region we are running from in case ROM spawns several MPU
regions. To help deal with that we enforce minimum alignments for start
end end of XIP address space as 1MB and 128Kb correspondingly.
Tested-by: Alexandre TORGUE <alexandre.torgue@st.com>
Tested-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/head-nommu.S | 20 | ||||
-rw-r--r-- | arch/arm/kernel/vmlinux-xip.lds.S | 23 |
2 files changed, 43 insertions, 0 deletions
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 0d64b8ba7e9c..2e38f85b757a 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S @@ -258,6 +258,26 @@ M_CLASS(ldr r0, [r12, #MPU_TYPE]) setup_region r0, r5, r6, MPU_INSTR_SIDE r12 @ 0x0, BG region, enabled 2: isb +#ifdef CONFIG_XIP_KERNEL + set_region_nr r0, #MPU_ROM_REGION, r12 + isb + + ldr r5,=(MPU_AP_PL1RO_PL0NA | MPU_RGN_NORMAL) + + ldr r0, =CONFIG_XIP_PHYS_ADDR @ ROM start + ldr r6, =(_exiprom) @ ROM end + sub r6, r6, r0 @ Minimum size of region to map + clz r6, r6 @ Region size must be 2^N... + rsb r6, r6, #31 @ ...so round up region size + lsl r6, r6, #MPU_RSR_SZ @ Put size in right field + orr r6, r6, #(1 << MPU_RSR_EN) @ Set region enabled bit + + setup_region r0, r5, r6, MPU_DATA_SIDE, r12 @ XIP_PHYS_ADDR, shared, enabled + beq 3f @ Memory-map not unified + setup_region r0, r5, r6, MPU_INSTR_SIDE, r12 @ XIP_PHYS_ADDR, shared, enabled +3: isb +#endif + /* Enable the MPU */ AR_CLASS(mrc p15, 0, r0, c1, c0, 0) @ Read SCTLR AR_CLASS(bic r0, r0, #CR_BR) @ Disable the 'default mem-map' diff --git a/arch/arm/kernel/vmlinux-xip.lds.S b/arch/arm/kernel/vmlinux-xip.lds.S index 7a844310085e..74c93879532a 100644 --- a/arch/arm/kernel/vmlinux-xip.lds.S +++ b/arch/arm/kernel/vmlinux-xip.lds.S @@ -6,6 +6,8 @@ /* No __ro_after_init data in the .rodata section - which will always be ro */ #define RO_AFTER_INIT_DATA +#include <linux/sizes.h> + #include <asm-generic/vmlinux.lds.h> #include <asm/cache.h> #include <asm/thread_info.h> @@ -187,6 +189,9 @@ SECTIONS INIT_RAM_FS } +#ifdef CONFIG_ARM_MPU + . = ALIGN(SZ_128K); +#endif _exiprom = .; /* End of XIP ROM area */ /* @@ -314,3 +319,21 @@ ASSERT(__hyp_idmap_text_end - (__hyp_idmap_text_start & PAGE_MASK) <= PAGE_SIZE, */ ASSERT((_end - __bss_start) >= 12288, ".bss too small for CONFIG_XIP_DEFLATED_DATA") #endif + +#ifdef CONFIG_ARM_MPU +/* + * Due to PMSAv7 restriction on base address and size we have to + * enforce minimal alignment restrictions. It was seen that weaker + * alignment restriction on _xiprom will likely force XIP address + * space spawns multiple MPU regions thus it is likely we run in + * situation when we are reprogramming MPU region we run on with + * something which doesn't cover reprogramming code itself, so as soon + * as we update MPU settings we'd immediately try to execute straight + * from background region which is XN. + * It seem that alignment in 1M should suit most users. + * _exiprom is aligned as 1/8 of 1M so can be covered by subregion + * disable + */ +ASSERT(!(_xiprom & (SZ_1M - 1)), "XIP start address may cause MPU programming issues") +ASSERT(!(_exiprom & (SZ_128K - 1)), "XIP end address may cause MPU programming issues") +#endif |