Skip to content

Commit 765b055

Browse files
HarithGeorge-AlifSemimehmetb0
authored andcommitted
ARM: 9419/1: mm: Fix kernel memory mapping for xip kernels
BugLink: https://bugs.launchpad.net/bugs/2095283 [ Upstream commit ed6cbe6e5563452f305e89c15846820f2874e431 ] The patchset introducing kernel_sec_start/end variables to separate the kernel/lowmem memory mappings, broke the mapping of the kernel memory for xipkernels. kernel_sec_start/end variables are in RO area before the MMU is switched on for xipkernels. So these cannot be set early in boot in head.S. Fix this by setting these after MMU is switched on. xipkernels need two different mappings for kernel text (starting at CONFIG_XIP_PHYS_ADDR) and data (starting at CONFIG_PHYS_OFFSET). Also, move the kernel code mapping from devicemaps_init() to map_kernel(). Fixes: a91da54 ("ARM: 9089/1: Define kernel physical section start and end") Signed-off-by: Harith George <harith.g@alifsemi.com> Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Koichiro Den <koichiro.den@canonical.com>
1 parent 62add8f commit 765b055

File tree

2 files changed

+27
-15
lines changed

2 files changed

+27
-15
lines changed

arch/arm/kernel/head.S

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,27 +252,31 @@ __create_page_tables:
252252
*/
253253
add r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ORDER)
254254
ldr r6, =(_end - 1)
255+
256+
/* For XIP, kernel_sec_start/kernel_sec_end are currently in RO memory */
257+
#ifndef CONFIG_XIP_KERNEL
255258
adr_l r5, kernel_sec_start @ _pa(kernel_sec_start)
256259
#if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
257260
str r8, [r5, #4] @ Save physical start of kernel (BE)
258261
#else
259262
str r8, [r5] @ Save physical start of kernel (LE)
263+
#endif
260264
#endif
261265
orr r3, r8, r7 @ Add the MMU flags
262266
add r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ORDER)
263267
1: str r3, [r0], #1 << PMD_ORDER
264268
add r3, r3, #1 << SECTION_SHIFT
265269
cmp r0, r6
266270
bls 1b
271+
#ifndef CONFIG_XIP_KERNEL
267272
eor r3, r3, r7 @ Remove the MMU flags
268273
adr_l r5, kernel_sec_end @ _pa(kernel_sec_end)
269274
#if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
270275
str r3, [r5, #4] @ Save physical end of kernel (BE)
271276
#else
272277
str r3, [r5] @ Save physical end of kernel (LE)
273278
#endif
274-
275-
#ifdef CONFIG_XIP_KERNEL
279+
#else
276280
/*
277281
* Map the kernel image separately as it is not located in RAM.
278282
*/

arch/arm/mm/mmu.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,18 +1381,6 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
13811381
create_mapping(&map);
13821382
}
13831383

1384-
/*
1385-
* Map the kernel if it is XIP.
1386-
* It is always first in the modulearea.
1387-
*/
1388-
#ifdef CONFIG_XIP_KERNEL
1389-
map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
1390-
map.virtual = MODULES_VADDR;
1391-
map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
1392-
map.type = MT_ROM;
1393-
create_mapping(&map);
1394-
#endif
1395-
13961384
/*
13971385
* Map the cache flushing regions.
13981386
*/
@@ -1582,12 +1570,27 @@ static void __init map_kernel(void)
15821570
* This will only persist until we turn on proper memory management later on
15831571
* and we remap the whole kernel with page granularity.
15841572
*/
1573+
#ifdef CONFIG_XIP_KERNEL
1574+
phys_addr_t kernel_nx_start = kernel_sec_start;
1575+
#else
15851576
phys_addr_t kernel_x_start = kernel_sec_start;
15861577
phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
15871578
phys_addr_t kernel_nx_start = kernel_x_end;
1579+
#endif
15881580
phys_addr_t kernel_nx_end = kernel_sec_end;
15891581
struct map_desc map;
15901582

1583+
/*
1584+
* Map the kernel if it is XIP.
1585+
* It is always first in the modulearea.
1586+
*/
1587+
#ifdef CONFIG_XIP_KERNEL
1588+
map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
1589+
map.virtual = MODULES_VADDR;
1590+
map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
1591+
map.type = MT_ROM;
1592+
create_mapping(&map);
1593+
#else
15911594
map.pfn = __phys_to_pfn(kernel_x_start);
15921595
map.virtual = __phys_to_virt(kernel_x_start);
15931596
map.length = kernel_x_end - kernel_x_start;
@@ -1597,7 +1600,7 @@ static void __init map_kernel(void)
15971600
/* If the nx part is small it may end up covered by the tail of the RWX section */
15981601
if (kernel_x_end == kernel_nx_end)
15991602
return;
1600-
1603+
#endif
16011604
map.pfn = __phys_to_pfn(kernel_nx_start);
16021605
map.virtual = __phys_to_virt(kernel_nx_start);
16031606
map.length = kernel_nx_end - kernel_nx_start;
@@ -1742,6 +1745,11 @@ void __init paging_init(const struct machine_desc *mdesc)
17421745
{
17431746
void *zero_page;
17441747

1748+
#ifdef CONFIG_XIP_KERNEL
1749+
/* Store the kernel RW RAM region start/end in these variables */
1750+
kernel_sec_start = CONFIG_PHYS_OFFSET & SECTION_MASK;
1751+
kernel_sec_end = round_up(__pa(_end), SECTION_SIZE);
1752+
#endif
17451753
pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
17461754
kernel_sec_start, kernel_sec_end);
17471755

0 commit comments

Comments
 (0)