public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] arm: mm: Fix kernel memory mapping for xip kernels
@ 2024-07-31 11:39 Harith George
  2024-07-31 11:39 ` [PATCH 2/2] arm: smp: Fix SMP " Harith George
  2024-08-23 15:36 ` [PATCH 1/2] arm: mm: Fix kernel memory mapping " Linus Walleij
  0 siblings, 2 replies; 4+ messages in thread
From: Harith George @ 2024-07-31 11:39 UTC (permalink / raw)
  To: linus.walleij, linux, linux-arm-kernel, linux-kernel
  Cc: harith.g, akpm, rppt, rmk+kernel, m.szyprowski, vishal.moola,
	david, willy, nico, ardb

From: Harith George <harith.g@alifsemi.com>

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: a91da5457085 ("ARM: 9089/1: Define kernel physical section start and end")
Signed-off-by: Harith George <harith.g@alifsemi.com>
---
 arch/arm/kernel/head.S |  8 ++++++--
 arch/arm/mm/mmu.c      | 34 +++++++++++++++++++++-------------
 2 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 1ec35f065617..28873cda464f 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -252,11 +252,15 @@ __create_page_tables:
 	 */
 	add	r0, r4, #KERNEL_OFFSET >> (SECTION_SHIFT - PMD_ENTRY_ORDER)
 	ldr	r6, =(_end - 1)
+
+	/* For XIP, kernel_sec_start/kernel_sec_end are currently in RO memory */
+#ifndef CONFIG_XIP_KERNEL
 	adr_l	r5, kernel_sec_start		@ _pa(kernel_sec_start)
 #if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
 	str	r8, [r5, #4]			@ Save physical start of kernel (BE)
 #else
 	str	r8, [r5]			@ Save physical start of kernel (LE)
+#endif
 #endif
 	orr	r3, r8, r7			@ Add the MMU flags
 	add	r6, r4, r6, lsr #(SECTION_SHIFT - PMD_ENTRY_ORDER)
@@ -264,6 +268,7 @@ __create_page_tables:
 	add	r3, r3, #1 << SECTION_SHIFT
 	cmp	r0, r6
 	bls	1b
+#ifndef CONFIG_XIP_KERNEL
 	eor	r3, r3, r7			@ Remove the MMU flags
 	adr_l	r5, kernel_sec_end		@ _pa(kernel_sec_end)
 #if defined CONFIG_CPU_ENDIAN_BE8 || defined CONFIG_CPU_ENDIAN_BE32
@@ -271,8 +276,7 @@ __create_page_tables:
 #else
 	str	r3, [r5]			@ Save physical end of kernel (LE)
 #endif
-
-#ifdef CONFIG_XIP_KERNEL
+#else
 	/*
 	 * Map the kernel image separately as it is not located in RAM.
 	 */
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index f11bf84aa3a2..537f94cd6012 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1402,18 +1402,6 @@ static void __init devicemaps_init(const struct machine_desc *mdesc)
 		create_mapping(&map);
 	}
 
-	/*
-	 * Map the kernel if it is XIP.
-	 * It is always first in the modulearea.
-	 */
-#ifdef CONFIG_XIP_KERNEL
-	map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
-	map.virtual = MODULES_VADDR;
-	map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
-	map.type = MT_ROM;
-	create_mapping(&map);
-#endif
-
 	/*
 	 * Map the cache flushing regions.
 	 */
@@ -1603,12 +1591,27 @@ static void __init map_kernel(void)
 	 * This will only persist until we turn on proper memory management later on
 	 * and we remap the whole kernel with page granularity.
 	 */
+#ifdef CONFIG_XIP_KERNEL
+	phys_addr_t kernel_nx_start = kernel_sec_start;
+#else
 	phys_addr_t kernel_x_start = kernel_sec_start;
 	phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
 	phys_addr_t kernel_nx_start = kernel_x_end;
+#endif
 	phys_addr_t kernel_nx_end = kernel_sec_end;
 	struct map_desc map;
 
+	/*
+	 * Map the kernel if it is XIP.
+	 * It is always first in the modulearea.
+	 */
+#ifdef CONFIG_XIP_KERNEL
+	map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
+	map.virtual = MODULES_VADDR;
+	map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
+	map.type = MT_ROM;
+	create_mapping(&map);
+#else
 	map.pfn = __phys_to_pfn(kernel_x_start);
 	map.virtual = __phys_to_virt(kernel_x_start);
 	map.length = kernel_x_end - kernel_x_start;
@@ -1618,7 +1621,7 @@ static void __init map_kernel(void)
 	/* If the nx part is small it may end up covered by the tail of the RWX section */
 	if (kernel_x_end == kernel_nx_end)
 		return;
-
+#endif
 	map.pfn = __phys_to_pfn(kernel_nx_start);
 	map.virtual = __phys_to_virt(kernel_nx_start);
 	map.length = kernel_nx_end - kernel_nx_start;
@@ -1762,6 +1765,11 @@ void __init paging_init(const struct machine_desc *mdesc)
 {
 	void *zero_page;
 
+#ifdef CONFIG_XIP_KERNEL
+	/* Store the kernel RW RAM region start/end in these variables */
+	kernel_sec_start = CONFIG_PHYS_OFFSET & SECTION_MASK;
+	kernel_sec_end = round_up(__pa(_end), SECTION_SIZE);
+#endif
 	pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
 		 kernel_sec_start, kernel_sec_end);
 
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] arm: smp: Fix SMP for xip kernels
  2024-07-31 11:39 [PATCH 1/2] arm: mm: Fix kernel memory mapping for xip kernels Harith George
@ 2024-07-31 11:39 ` Harith George
  2024-08-23 15:36 ` [PATCH 1/2] arm: mm: Fix kernel memory mapping " Linus Walleij
  1 sibling, 0 replies; 4+ messages in thread
From: Harith George @ 2024-07-31 11:39 UTC (permalink / raw)
  To: linus.walleij, linux, linux-arm-kernel, linux-kernel
  Cc: harith.g, akpm, rppt, rmk+kernel, m.szyprowski, vishal.moola,
	david, willy, nico, ardb

From: Harith George <harith.g@alifsemi.com>

Fix the physical address calculation of the following to get smp working
on xip kernels.
- secondary_data needed for secondary cpu bootup.
- secondary_startup address passed through psci.
- identity mapped code region needed for enabling mmu for secondary cpus.

Signed-off-by: Harith George <harith.g@alifsemi.com>
---
 arch/arm/kernel/head.S     | 4 ++++
 arch/arm/kernel/psci_smp.c | 7 +++++++
 arch/arm/mm/idmap.c        | 7 +++++++
 3 files changed, 18 insertions(+)

diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 28873cda464f..f22c50d4bd41 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -411,7 +411,11 @@ ENTRY(secondary_startup)
 	/*
 	 * Use the page tables supplied from  __cpu_up.
 	 */
+#ifdef CONFIG_XIP_KERNEL
+	ldr	r3, =(secondary_data + PLAT_PHYS_OFFSET - PAGE_OFFSET)
+#else
 	adr_l	r3, secondary_data
+#endif
 	mov_l	r12, __secondary_switched
 	ldrd	r4, r5, [r3, #0]		@ get secondary_data.pgdir
 ARM_BE8(eor	r4, r4, r5)			@ Swap r5 and r4 in BE:
diff --git a/arch/arm/kernel/psci_smp.c b/arch/arm/kernel/psci_smp.c
index d4392e177484..3bb0c4dcfc5c 100644
--- a/arch/arm/kernel/psci_smp.c
+++ b/arch/arm/kernel/psci_smp.c
@@ -45,8 +45,15 @@ extern void secondary_startup(void);
 static int psci_boot_secondary(unsigned int cpu, struct task_struct *idle)
 {
 	if (psci_ops.cpu_on)
+#ifdef CONFIG_XIP_KERNEL
+		return psci_ops.cpu_on(cpu_logical_map(cpu),
+			((phys_addr_t)(&secondary_startup)
+			- XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+			+ CONFIG_XIP_PHYS_ADDR));
+#else
 		return psci_ops.cpu_on(cpu_logical_map(cpu),
 					virt_to_idmap(&secondary_startup));
+#endif
 	return -ENODEV;
 }
 
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 448e57c6f653..4a833e89782a 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -84,8 +84,15 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
 	unsigned long addr, end;
 	unsigned long next;
 
+#ifdef CONFIG_XIP_KERNEL
+	addr = (phys_addr_t)(text_start) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+		+ CONFIG_XIP_PHYS_ADDR;
+	end = (phys_addr_t)(text_end) - XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR)
+		+ CONFIG_XIP_PHYS_ADDR;
+#else
 	addr = virt_to_idmap(text_start);
 	end = virt_to_idmap(text_end);
+#endif
 	pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);
 
 	prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] arm: mm: Fix kernel memory mapping for xip kernels
  2024-07-31 11:39 [PATCH 1/2] arm: mm: Fix kernel memory mapping for xip kernels Harith George
  2024-07-31 11:39 ` [PATCH 2/2] arm: smp: Fix SMP " Harith George
@ 2024-08-23 15:36 ` Linus Walleij
  2024-09-18  8:51   ` Harith George
  1 sibling, 1 reply; 4+ messages in thread
From: Linus Walleij @ 2024-08-23 15:36 UTC (permalink / raw)
  To: Harith George
  Cc: linux, linux-arm-kernel, linux-kernel, harith.g, akpm, rppt,
	rmk+kernel, m.szyprowski, vishal.moola, david, willy, nico, ardb

On Wed, Jul 31, 2024 at 1:39 PM Harith George <mail2hgg@gmail.com> wrote:

> From: Harith George <harith.g@alifsemi.com>
>
> 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: a91da5457085 ("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>
(also for patch 2/2)

Sorry for breaking XIP :(

Can you put these patches into Russell's patch tracker so he
can track it?
https://www.armlinux.org.uk/developer/patches/

Yours,
Linus Walleij

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] arm: mm: Fix kernel memory mapping for xip kernels
  2024-08-23 15:36 ` [PATCH 1/2] arm: mm: Fix kernel memory mapping " Linus Walleij
@ 2024-09-18  8:51   ` Harith George
  0 siblings, 0 replies; 4+ messages in thread
From: Harith George @ 2024-09-18  8:51 UTC (permalink / raw)
  To: Linus Walleij
  Cc: linux, linux-arm-kernel, linux-kernel, harith.g, akpm, rppt,
	rmk+kernel, m.szyprowski, vishal.moola, david, willy, nico, ardb

Hi Linus,

>>
>> Fixes: a91da5457085 ("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>
> (also for patch 2/2)
Thanks a lot for the review. I somehow missed this mail and saw it only 
today. I have uploaded to Russell's patch tracker today.

Warm Regards,
Harith

> 
> Sorry for breaking XIP :(
> 
> Can you put these patches into Russell's patch tracker so he
> can track it?
> https://www.armlinux.org.uk/developer/patches/
> 
> Yours,
> Linus Walleij


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2024-09-18  8:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-07-31 11:39 [PATCH 1/2] arm: mm: Fix kernel memory mapping for xip kernels Harith George
2024-07-31 11:39 ` [PATCH 2/2] arm: smp: Fix SMP " Harith George
2024-08-23 15:36 ` [PATCH 1/2] arm: mm: Fix kernel memory mapping " Linus Walleij
2024-09-18  8:51   ` Harith George

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox