public inbox for linux-arm-kernel@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Consolidate identity mapping code in idmap.c
@ 2011-11-16 16:48 Will Deacon
  2011-11-16 16:48 ` [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text Will Deacon
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Will Deacon @ 2011-11-16 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hello,

This patch series consolidates the identity mapping code into idmap.c,
where a single set of page tables (idmap_pgd) are allocated and populated
at init time for use by subsystems such as soft reboot, kexec and CPU
suspend.

A new linker section (.idmap.text) is introduced so that code which
needs to be identity mapped can be annotated with __idmap or, if written
in assembly, placed there explicitly.

CPU suspend, cpu_*_reset and setup_mm_for_reboot are all updated to work
with the new mapping code.

This is currently based on 3.2-rc2, but will be based on Russell's reset
branch when it comes to merging (where the prototype of
setup_mm_for_reboot has changed slightly). Furthermore, I have rebased
my kexec series against this which I will post separately.

Comments welcome.

Cheers,

Will


Will Deacon (4):
  ARM: idmap: populate identity map pgd at init time using .init.text
  ARM: suspend: use idmap_pgd instead of suspend_pgd
  ARM: proc-*.S: place cpu_reset functions into .idmap.text section
  ARM: idmap: use idmap_pgd when setting up mm for reboot

 arch/arm/include/asm/idmap.h      |   11 ++++++++
 arch/arm/kernel/sleep.S           |    2 +
 arch/arm/kernel/suspend.c         |   17 ++----------
 arch/arm/kernel/vmlinux.lds.S     |    1 +
 arch/arm/mm/idmap.c               |   49 ++++++++++++++++++++++++++++++-------
 arch/arm/mm/proc-arm1020.S        |    3 ++
 arch/arm/mm/proc-arm1020e.S       |    3 ++
 arch/arm/mm/proc-arm1022.S        |    3 ++
 arch/arm/mm/proc-arm1026.S        |    3 ++
 arch/arm/mm/proc-arm6_7.S         |    4 +++
 arch/arm/mm/proc-arm720.S         |    3 ++
 arch/arm/mm/proc-arm740.S         |    3 ++
 arch/arm/mm/proc-arm7tdmi.S       |    3 ++
 arch/arm/mm/proc-arm920.S         |    3 ++
 arch/arm/mm/proc-arm922.S         |    3 ++
 arch/arm/mm/proc-arm925.S         |    3 ++
 arch/arm/mm/proc-arm926.S         |    3 ++
 arch/arm/mm/proc-arm940.S         |    3 ++
 arch/arm/mm/proc-arm946.S         |    3 ++
 arch/arm/mm/proc-arm9tdmi.S       |    3 ++
 arch/arm/mm/proc-fa526.S          |    3 ++
 arch/arm/mm/proc-feroceon.S       |    3 ++
 arch/arm/mm/proc-mohawk.S         |    3 ++
 arch/arm/mm/proc-sa110.S          |    3 ++
 arch/arm/mm/proc-sa1100.S         |    3 ++
 arch/arm/mm/proc-v6.S             |    3 ++
 arch/arm/mm/proc-v7.S             |    2 +
 arch/arm/mm/proc-xsc3.S           |    3 ++
 arch/arm/mm/proc-xscale.S         |    3 ++
 include/asm-generic/vmlinux.lds.h |    6 ++++
 30 files changed, 135 insertions(+), 23 deletions(-)
 create mode 100644 arch/arm/include/asm/idmap.h

-- 
1.7.4.1

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

* [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text
  2011-11-16 16:48 [PATCH 0/4] Consolidate identity mapping code in idmap.c Will Deacon
@ 2011-11-16 16:48 ` Will Deacon
  2011-11-18 12:02   ` Catalin Marinas
  2011-11-16 16:48 ` [PATCH 2/4] ARM: suspend: use idmap_pgd instead of suspend_pgd Will Deacon
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2011-11-16 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

When disabling and re-enabling the MMU, it is necessary to take out an
identity mapping for the code that manipulates the SCTLR in order to
avoid it disappearing from under our feet. This is useful when soft
rebooting and returning from CPU suspend.

This patch allocates a set of page tables during boot and populates them
with an identity mapping for the .idmap.text section. This means that
users of the identity map do not need to manage their own pgd and can
instead annotate their functions with __idmap or, in the case of assembly
code, place them in the correct section.

Tested-by: Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm/include/asm/idmap.h      |   11 +++++++++++
 arch/arm/kernel/vmlinux.lds.S     |    1 +
 arch/arm/mm/idmap.c               |   30 ++++++++++++++++++++++++++++++
 include/asm-generic/vmlinux.lds.h |    6 ++++++
 4 files changed, 48 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/idmap.h

diff --git a/arch/arm/include/asm/idmap.h b/arch/arm/include/asm/idmap.h
new file mode 100644
index 0000000..95a09d7
--- /dev/null
+++ b/arch/arm/include/asm/idmap.h
@@ -0,0 +1,11 @@
+#ifndef __ASM_IDMAP_H
+#define __ASM_IDMAP_H
+
+#include <linux/compiler.h>
+
+/* Tag a function as requiring to be executed via an identity mapping. */
+#define __idmap __section(.idmap.text) noinline notrace
+
+void setup_mm_for_reboot(char mode);
+
+#endif	/* __ASM_IDMAP_H */
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 20b3041..a0205ad 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -92,6 +92,7 @@ SECTIONS
 			SCHED_TEXT
 			LOCK_TEXT
 			KPROBES_TEXT
+			IDMAP_TEXT
 #ifdef CONFIG_MMU
 			*(.fixup)
 #endif
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 2be9139..8c1230a 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -1,8 +1,12 @@
 #include <linux/kernel.h>
 
 #include <asm/cputype.h>
+#include <asm/idmap.h>
 #include <asm/pgalloc.h>
 #include <asm/pgtable.h>
+#include <asm/sections.h>
+
+pgd_t *idmap_pgd;
 
 static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
 	unsigned long prot)
@@ -73,6 +77,32 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
 }
 #endif
 
+extern char  __idmap_text_start[], __idmap_text_end[];
+
+static int __init init_static_idmap(void)
+{
+	phys_addr_t idmap_start, idmap_end;
+
+	idmap_pgd = pgd_alloc(&init_mm);
+	if (!idmap_pgd)
+		return -ENOMEM;
+
+	/* Align the idmap.text section pointers to PMD_SIZE. */
+	idmap_start = (phys_addr_t)__idmap_text_start & PMD_MASK;
+	idmap_end = PTR_ALIGN((phys_addr_t)__idmap_text_end, PMD_SIZE);
+
+	/* Add an identity mapping for the physical address of the section. */
+	idmap_start = virt_to_phys((void *)idmap_start);
+	idmap_end = virt_to_phys((void *)idmap_end);
+
+	pr_info("Setting up static identity map for 0x%llx - 0x%llx\n",
+		(long long)idmap_start, (long long)idmap_end);
+	identity_mapping_add(idmap_pgd, idmap_start, idmap_end);
+
+	return 0;
+}
+arch_initcall(init_static_idmap);
+
 /*
  * In order to soft-boot, we need to insert a 1:1 mapping in place of
  * the user-mode pages.  This will then ensure that we have predictable
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index b5e2e4c..d555a24 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -425,6 +425,12 @@
 		*(.kprobes.text)					\
 		VMLINUX_SYMBOL(__kprobes_text_end) = .;
 
+#define IDMAP_TEXT							\
+		ALIGN_FUNCTION();					\
+		VMLINUX_SYMBOL(__idmap_text_start) = .;			\
+		*(.idmap.text)						\
+		VMLINUX_SYMBOL(__idmap_text_end) = .;
+
 #define ENTRY_TEXT							\
 		ALIGN_FUNCTION();					\
 		VMLINUX_SYMBOL(__entry_text_start) = .;			\
-- 
1.7.4.1

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

* [PATCH 2/4] ARM: suspend: use idmap_pgd instead of suspend_pgd
  2011-11-16 16:48 [PATCH 0/4] Consolidate identity mapping code in idmap.c Will Deacon
  2011-11-16 16:48 ` [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text Will Deacon
@ 2011-11-16 16:48 ` Will Deacon
  2011-11-18 16:43   ` Catalin Marinas
  2011-11-16 16:48 ` [PATCH 3/4] ARM: proc-*.S: place cpu_reset functions into .idmap.text section Will Deacon
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2011-11-16 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

The ARM CPU suspend code requires cpu_resume_mmu to be identity mapped
in order to re-enable the MMU when coming out of suspend. Currently,
this is accomplished by maintaining a suspend_pgd with the relevant
mapping put in place at init time.

This patch replaces the use of suspend_pgd with the new idmap_pgd.
cpu_resume_mmu is placed in the .idmap.text section so that it is
included in the identity map.

Tested-by: Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm/kernel/sleep.S   |    2 ++
 arch/arm/kernel/suspend.c |   17 +++--------------
 2 files changed, 5 insertions(+), 14 deletions(-)

diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S
index 020e99c..9e64231 100644
--- a/arch/arm/kernel/sleep.S
+++ b/arch/arm/kernel/sleep.S
@@ -54,6 +54,7 @@ ENDPROC(cpu_suspend_abort)
  * r0 = control register value
  */
 	.align	5
+	.pushsection	.idmap.text,"ax"
 ENTRY(cpu_resume_mmu)
 	ldr	r3, =cpu_resume_after_mmu
 	mcr	p15, 0, r0, c1, c0, 0	@ turn on MMU, I-cache, etc
@@ -62,6 +63,7 @@ ENTRY(cpu_resume_mmu)
 	mov	r0, r0
 	mov	pc, r3			@ jump to virtual address
 ENDPROC(cpu_resume_mmu)
+	.popsection
 cpu_resume_after_mmu:
 	bl	cpu_init		@ restore the und/abt/irq banked regs
 	mov	r0, #0			@ return zero on success
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 93a22d2..8880f94 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -6,7 +6,7 @@
 #include <asm/suspend.h>
 #include <asm/tlbflush.h>
 
-static pgd_t *suspend_pgd;
+extern pgd_t *idmap_pgd;
 
 extern int __cpu_suspend(unsigned long, int (*)(unsigned long));
 extern void cpu_resume_mmu(void);
@@ -21,7 +21,7 @@ void __cpu_suspend_save(u32 *ptr, u32 ptrsz, u32 sp, u32 *save_ptr)
 	*save_ptr = virt_to_phys(ptr);
 
 	/* This must correspond to the LDM in cpu_resume() assembly */
-	*ptr++ = virt_to_phys(suspend_pgd);
+	*ptr++ = virt_to_phys(idmap_pgd);
 	*ptr++ = sp;
 	*ptr++ = virt_to_phys(cpu_do_resume);
 
@@ -42,7 +42,7 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
 	struct mm_struct *mm = current->active_mm;
 	int ret;
 
-	if (!suspend_pgd)
+	if (!idmap_pgd)
 		return -EINVAL;
 
 	/*
@@ -59,14 +59,3 @@ int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
 
 	return ret;
 }
-
-static int __init cpu_suspend_init(void)
-{
-	suspend_pgd = pgd_alloc(&init_mm);
-	if (suspend_pgd) {
-		unsigned long addr = virt_to_phys(cpu_resume_mmu);
-		identity_mapping_add(suspend_pgd, addr, addr + SECTION_SIZE);
-	}
-	return suspend_pgd ? 0 : -ENOMEM;
-}
-core_initcall(cpu_suspend_init);
-- 
1.7.4.1

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

* [PATCH 3/4] ARM: proc-*.S: place cpu_reset functions into .idmap.text section
  2011-11-16 16:48 [PATCH 0/4] Consolidate identity mapping code in idmap.c Will Deacon
  2011-11-16 16:48 ` [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text Will Deacon
  2011-11-16 16:48 ` [PATCH 2/4] ARM: suspend: use idmap_pgd instead of suspend_pgd Will Deacon
@ 2011-11-16 16:48 ` Will Deacon
  2011-11-16 16:48 ` [PATCH 4/4] ARM: idmap: use idmap_pgd when setting up mm for reboot Will Deacon
  2011-11-17 13:47 ` [PATCH 0/4] Consolidate identity mapping code in idmap.c Dave Martin
  4 siblings, 0 replies; 12+ messages in thread
From: Will Deacon @ 2011-11-16 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

The CPU reset functions disable the MMU and therefore must be executed
with an identity mapping in place.

This patch places the CPU reset functions into the .idmap.text section,
causing the idmap code to include them as part of the identity mapping.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm/mm/proc-arm1020.S  |    3 +++
 arch/arm/mm/proc-arm1020e.S |    3 +++
 arch/arm/mm/proc-arm1022.S  |    3 +++
 arch/arm/mm/proc-arm1026.S  |    3 +++
 arch/arm/mm/proc-arm6_7.S   |    4 ++++
 arch/arm/mm/proc-arm720.S   |    3 +++
 arch/arm/mm/proc-arm740.S   |    3 +++
 arch/arm/mm/proc-arm7tdmi.S |    3 +++
 arch/arm/mm/proc-arm920.S   |    3 +++
 arch/arm/mm/proc-arm922.S   |    3 +++
 arch/arm/mm/proc-arm925.S   |    3 +++
 arch/arm/mm/proc-arm926.S   |    3 +++
 arch/arm/mm/proc-arm940.S   |    3 +++
 arch/arm/mm/proc-arm946.S   |    3 +++
 arch/arm/mm/proc-arm9tdmi.S |    3 +++
 arch/arm/mm/proc-fa526.S    |    3 +++
 arch/arm/mm/proc-feroceon.S |    3 +++
 arch/arm/mm/proc-mohawk.S   |    3 +++
 arch/arm/mm/proc-sa110.S    |    3 +++
 arch/arm/mm/proc-sa1100.S   |    3 +++
 arch/arm/mm/proc-v6.S       |    3 +++
 arch/arm/mm/proc-v7.S       |    2 ++
 arch/arm/mm/proc-xsc3.S     |    3 +++
 arch/arm/mm/proc-xscale.S   |    3 +++
 24 files changed, 72 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mm/proc-arm1020.S b/arch/arm/mm/proc-arm1020.S
index 6746966..2349513 100644
--- a/arch/arm/mm/proc-arm1020.S
+++ b/arch/arm/mm/proc-arm1020.S
@@ -95,6 +95,7 @@ ENTRY(cpu_arm1020_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm1020_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -107,6 +108,8 @@ ENTRY(cpu_arm1020_reset)
 	bic	ip, ip, #0x1100 		@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm1020_reset)
+	.popsection
 
 /*
  * cpu_arm1020_do_idle()
diff --git a/arch/arm/mm/proc-arm1020e.S b/arch/arm/mm/proc-arm1020e.S
index 4251421..c244b06 100644
--- a/arch/arm/mm/proc-arm1020e.S
+++ b/arch/arm/mm/proc-arm1020e.S
@@ -95,6 +95,7 @@ ENTRY(cpu_arm1020e_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm1020e_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -107,6 +108,8 @@ ENTRY(cpu_arm1020e_reset)
 	bic	ip, ip, #0x1100 		@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm1020e_reset)
+	.popsection
 
 /*
  * cpu_arm1020e_do_idle()
diff --git a/arch/arm/mm/proc-arm1022.S b/arch/arm/mm/proc-arm1022.S
index d283cf3..38fe22e 100644
--- a/arch/arm/mm/proc-arm1022.S
+++ b/arch/arm/mm/proc-arm1022.S
@@ -84,6 +84,7 @@ ENTRY(cpu_arm1022_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm1022_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -96,6 +97,8 @@ ENTRY(cpu_arm1022_reset)
 	bic	ip, ip, #0x1100 		@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm1022_reset)
+	.popsection
 
 /*
  * cpu_arm1022_do_idle()
diff --git a/arch/arm/mm/proc-arm1026.S b/arch/arm/mm/proc-arm1026.S
index 678a1ce..3eb9c3c 100644
--- a/arch/arm/mm/proc-arm1026.S
+++ b/arch/arm/mm/proc-arm1026.S
@@ -84,6 +84,7 @@ ENTRY(cpu_arm1026_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm1026_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -96,6 +97,8 @@ ENTRY(cpu_arm1026_reset)
 	bic	ip, ip, #0x1100 		@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm1026_reset)
+	.popsection
 
 /*
  * cpu_arm1026_do_idle()
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S
index e5b974c..4fbeb5b 100644
--- a/arch/arm/mm/proc-arm6_7.S
+++ b/arch/arm/mm/proc-arm6_7.S
@@ -225,6 +225,7 @@ ENTRY(cpu_arm7_set_pte_ext)
  * Params  : r0 = address to jump to
  * Notes   : This sets up everything for a reset
  */
+		.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm6_reset)
 ENTRY(cpu_arm7_reset)
 		mov	r1, #0
@@ -235,6 +236,9 @@ ENTRY(cpu_arm7_reset)
 		mov	r1, #0x30
 		mcr	p15, 0, r1, c1, c0, 0		@ turn off MMU etc
 		mov	pc, r0
+ENDPROC(cpu_arm6_reset)
+ENDPROC(cpu_arm7_reset)
+		.popsection
 
 		__CPUINIT
 
diff --git a/arch/arm/mm/proc-arm720.S b/arch/arm/mm/proc-arm720.S
index 55f4e29..0ac908c 100644
--- a/arch/arm/mm/proc-arm720.S
+++ b/arch/arm/mm/proc-arm720.S
@@ -101,6 +101,7 @@ ENTRY(cpu_arm720_set_pte_ext)
  * Params  : r0 = address to jump to
  * Notes   : This sets up everything for a reset
  */
+		.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm720_reset)
 		mov	ip, #0
 		mcr	p15, 0, ip, c7, c7, 0		@ invalidate cache
@@ -112,6 +113,8 @@ ENTRY(cpu_arm720_reset)
 		bic	ip, ip, #0x2100			@ ..v....s........
 		mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 		mov	pc, r0
+ENDPROC(cpu_arm720_reset)
+		.popsection
 
 	__CPUINIT
 
diff --git a/arch/arm/mm/proc-arm740.S b/arch/arm/mm/proc-arm740.S
index 4506be3..dc5de5d 100644
--- a/arch/arm/mm/proc-arm740.S
+++ b/arch/arm/mm/proc-arm740.S
@@ -49,6 +49,7 @@ ENTRY(cpu_arm740_proc_fin)
  * Params  : r0 = address to jump to
  * Notes   : This sets up everything for a reset
  */
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm740_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c0, 0		@ invalidate cache
@@ -56,6 +57,8 @@ ENTRY(cpu_arm740_reset)
 	bic	ip, ip, #0x0000000c		@ ............wc..
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm740_reset)
+	.popsection
 
 	__CPUINIT
 
diff --git a/arch/arm/mm/proc-arm7tdmi.S b/arch/arm/mm/proc-arm7tdmi.S
index 7e0e1fe..6ddea3e 100644
--- a/arch/arm/mm/proc-arm7tdmi.S
+++ b/arch/arm/mm/proc-arm7tdmi.S
@@ -45,8 +45,11 @@ ENTRY(cpu_arm7tdmi_proc_fin)
  * Params  : loc(r0)	address to jump to
  * Purpose : Sets up everything for a reset and jump to the location for soft reset.
  */
+		.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm7tdmi_reset)
 		mov	pc, r0
+ENDPROC(cpu_arm7tdmi_reset)
+		.popsection
 
 		__CPUINIT
 
diff --git a/arch/arm/mm/proc-arm920.S b/arch/arm/mm/proc-arm920.S
index 88fb3d9..cb941ae 100644
--- a/arch/arm/mm/proc-arm920.S
+++ b/arch/arm/mm/proc-arm920.S
@@ -85,6 +85,7 @@ ENTRY(cpu_arm920_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm920_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -97,6 +98,8 @@ ENTRY(cpu_arm920_reset)
 	bic	ip, ip, #0x1100			@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm920_reset)
+	.popsection
 
 /*
  * cpu_arm920_do_idle()
diff --git a/arch/arm/mm/proc-arm922.S b/arch/arm/mm/proc-arm922.S
index 490e188..4ec0e07 100644
--- a/arch/arm/mm/proc-arm922.S
+++ b/arch/arm/mm/proc-arm922.S
@@ -87,6 +87,7 @@ ENTRY(cpu_arm922_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm922_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -99,6 +100,8 @@ ENTRY(cpu_arm922_reset)
 	bic	ip, ip, #0x1100			@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm922_reset)
+	.popsection
 
 /*
  * cpu_arm922_do_idle()
diff --git a/arch/arm/mm/proc-arm925.S b/arch/arm/mm/proc-arm925.S
index 51d494b..9dccd9a 100644
--- a/arch/arm/mm/proc-arm925.S
+++ b/arch/arm/mm/proc-arm925.S
@@ -108,6 +108,7 @@ ENTRY(cpu_arm925_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm925_reset)
 	/* Send software reset to MPU and DSP */
 	mov	ip, #0xff000000
@@ -115,6 +116,8 @@ ENTRY(cpu_arm925_reset)
 	orr	ip, ip, #0x0000ce00
 	mov	r4, #1
 	strh	r4, [ip, #0x10]
+ENDPROC(cpu_arm925_reset)
+	.popsection
 
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
diff --git a/arch/arm/mm/proc-arm926.S b/arch/arm/mm/proc-arm926.S
index 9f8fd91..820259b 100644
--- a/arch/arm/mm/proc-arm926.S
+++ b/arch/arm/mm/proc-arm926.S
@@ -77,6 +77,7 @@ ENTRY(cpu_arm926_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm926_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -89,6 +90,8 @@ ENTRY(cpu_arm926_reset)
 	bic	ip, ip, #0x1100			@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm926_reset)
+	.popsection
 
 /*
  * cpu_arm926_do_idle()
diff --git a/arch/arm/mm/proc-arm940.S b/arch/arm/mm/proc-arm940.S
index ac750d5..9fdc0a1 100644
--- a/arch/arm/mm/proc-arm940.S
+++ b/arch/arm/mm/proc-arm940.S
@@ -48,6 +48,7 @@ ENTRY(cpu_arm940_proc_fin)
  * Params  : r0 = address to jump to
  * Notes   : This sets up everything for a reset
  */
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm940_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c5, 0		@ flush I cache
@@ -58,6 +59,8 @@ ENTRY(cpu_arm940_reset)
 	bic	ip, ip, #0x00001000		@ i-cache
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm940_reset)
+	.popsection
 
 /*
  * cpu_arm940_do_idle()
diff --git a/arch/arm/mm/proc-arm946.S b/arch/arm/mm/proc-arm946.S
index 683af3a..f684cfe 100644
--- a/arch/arm/mm/proc-arm946.S
+++ b/arch/arm/mm/proc-arm946.S
@@ -55,6 +55,7 @@ ENTRY(cpu_arm946_proc_fin)
  * Params  : r0 = address to jump to
  * Notes   : This sets up everything for a reset
  */
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm946_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c5, 0		@ flush I cache
@@ -65,6 +66,8 @@ ENTRY(cpu_arm946_reset)
 	bic	ip, ip, #0x00001000		@ i-cache
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_arm946_reset)
+	.popsection
 
 /*
  * cpu_arm946_do_idle()
diff --git a/arch/arm/mm/proc-arm9tdmi.S b/arch/arm/mm/proc-arm9tdmi.S
index 2120f9e..8881391 100644
--- a/arch/arm/mm/proc-arm9tdmi.S
+++ b/arch/arm/mm/proc-arm9tdmi.S
@@ -45,8 +45,11 @@ ENTRY(cpu_arm9tdmi_proc_fin)
  * Params  : loc(r0)	address to jump to
  * Purpose : Sets up everything for a reset and jump to the location for soft reset.
  */
+		.pushsection	.idmap.text, "ax"
 ENTRY(cpu_arm9tdmi_reset)
 		mov	pc, r0
+ENDPROC(cpu_arm9tdmi_reset)
+		.popsection
 
 		__CPUINIT
 
diff --git a/arch/arm/mm/proc-fa526.S b/arch/arm/mm/proc-fa526.S
index 4c7a571..272558a 100644
--- a/arch/arm/mm/proc-fa526.S
+++ b/arch/arm/mm/proc-fa526.S
@@ -57,6 +57,7 @@ ENTRY(cpu_fa526_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	4
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_fa526_reset)
 /* TODO: Use CP8 if possible... */
 	mov	ip, #0
@@ -73,6 +74,8 @@ ENTRY(cpu_fa526_reset)
 	nop
 	nop
 	mov	pc, r0
+ENDPROC(cpu_fa526_reset)
+	.popsection
 
 /*
  * cpu_fa526_do_idle()
diff --git a/arch/arm/mm/proc-feroceon.S b/arch/arm/mm/proc-feroceon.S
index 8a6c2f7..ba3c500 100644
--- a/arch/arm/mm/proc-feroceon.S
+++ b/arch/arm/mm/proc-feroceon.S
@@ -98,6 +98,7 @@ ENTRY(cpu_feroceon_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_feroceon_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -110,6 +111,8 @@ ENTRY(cpu_feroceon_reset)
 	bic	ip, ip, #0x1100			@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_feroceon_reset)
+	.popsection
 
 /*
  * cpu_feroceon_do_idle()
diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S
index db52b0f..cdfedc5 100644
--- a/arch/arm/mm/proc-mohawk.S
+++ b/arch/arm/mm/proc-mohawk.S
@@ -69,6 +69,7 @@ ENTRY(cpu_mohawk_proc_fin)
  * (same as arm926)
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_mohawk_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -79,6 +80,8 @@ ENTRY(cpu_mohawk_reset)
 	bic	ip, ip, #0x1100			@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_mohawk_reset)
+	.popsection
 
 /*
  * cpu_mohawk_do_idle()
diff --git a/arch/arm/mm/proc-sa110.S b/arch/arm/mm/proc-sa110.S
index d50ada2..775d70f 100644
--- a/arch/arm/mm/proc-sa110.S
+++ b/arch/arm/mm/proc-sa110.S
@@ -62,6 +62,7 @@ ENTRY(cpu_sa110_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_sa110_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -74,6 +75,8 @@ ENTRY(cpu_sa110_reset)
 	bic	ip, ip, #0x1100			@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_sa110_reset)
+	.popsection
 
 /*
  * cpu_sa110_do_idle(type)
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S
index 7d91545..3aa0da1 100644
--- a/arch/arm/mm/proc-sa1100.S
+++ b/arch/arm/mm/proc-sa1100.S
@@ -70,6 +70,7 @@ ENTRY(cpu_sa1100_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_sa1100_reset)
 	mov	ip, #0
 	mcr	p15, 0, ip, c7, c7, 0		@ invalidate I,D caches
@@ -82,6 +83,8 @@ ENTRY(cpu_sa1100_reset)
 	bic	ip, ip, #0x1100			@ ...i...s........
 	mcr	p15, 0, ip, c1, c0, 0		@ ctrl register
 	mov	pc, r0
+ENDPROC(cpu_sa1100_reset)
+	.popsection
 
 /*
  * cpu_sa1100_do_idle(type)
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index d061d2f..5900cd5 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -55,6 +55,7 @@ ENTRY(cpu_v6_proc_fin)
  *	- loc   - location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_v6_reset)
 	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
 	bic	r1, r1, #0x1			@ ...............m
@@ -62,6 +63,8 @@ ENTRY(cpu_v6_reset)
 	mov	r1, #0
 	mcr	p15, 0, r1, c7, c5, 4		@ ISB
 	mov	pc, r0
+ENDPROC(cpu_v6_reset)
+	.popsection
 
 /*
  *	cpu_v6_do_idle()
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 2c559ac..66a185f 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -63,6 +63,7 @@ ENDPROC(cpu_v7_proc_fin)
  *      caches disabled.
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_v7_reset)
 	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
 	bic	r1, r1, #0x1			@ ...............m
@@ -71,6 +72,7 @@ ENTRY(cpu_v7_reset)
 	isb
 	mov	pc, r0
 ENDPROC(cpu_v7_reset)
+	.popsection
 
 /*
  *	cpu_v7_do_idle()
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index abf0507..b0d5786 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -105,6 +105,7 @@ ENTRY(cpu_xsc3_proc_fin)
  * loc: location to jump to for soft reset
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_xsc3_reset)
 	mov	r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
 	msr	cpsr_c, r1			@ reset CPSR
@@ -119,6 +120,8 @@ ENTRY(cpu_xsc3_reset)
 	@ already containing those two last instructions to survive.
 	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I and D TLBs
 	mov	pc, r0
+ENDPROC(cpu_xsc3_reset)
+	.popsection
 
 /*
  * cpu_xsc3_do_idle()
diff --git a/arch/arm/mm/proc-xscale.S b/arch/arm/mm/proc-xscale.S
index 3277904..4ffebaa 100644
--- a/arch/arm/mm/proc-xscale.S
+++ b/arch/arm/mm/proc-xscale.S
@@ -142,6 +142,7 @@ ENTRY(cpu_xscale_proc_fin)
  * Beware PXA270 erratum E7.
  */
 	.align	5
+	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_xscale_reset)
 	mov	r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
 	msr	cpsr_c, r1			@ reset CPSR
@@ -160,6 +161,8 @@ ENTRY(cpu_xscale_reset)
 	@ already containing those two last instructions to survive.
 	mcr	p15, 0, ip, c8, c7, 0		@ invalidate I & D TLBs
 	mov	pc, r0
+ENDPROC(cpu_xscale_reset)
+	.popsection
 
 /*
  * cpu_xscale_do_idle()
-- 
1.7.4.1

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

* [PATCH 4/4] ARM: idmap: use idmap_pgd when setting up mm for reboot
  2011-11-16 16:48 [PATCH 0/4] Consolidate identity mapping code in idmap.c Will Deacon
                   ` (2 preceding siblings ...)
  2011-11-16 16:48 ` [PATCH 3/4] ARM: proc-*.S: place cpu_reset functions into .idmap.text section Will Deacon
@ 2011-11-16 16:48 ` Will Deacon
  2011-11-18 16:56   ` Catalin Marinas
  2011-11-17 13:47 ` [PATCH 0/4] Consolidate identity mapping code in idmap.c Dave Martin
  4 siblings, 1 reply; 12+ messages in thread
From: Will Deacon @ 2011-11-16 16:48 UTC (permalink / raw)
  To: linux-arm-kernel

For soft-rebooting a system, it is necessary to map the MMU-off code
with an identity mapping so that execution can continue safely once the
MMU has been switched off.

Currently, switch_mm_for_reboot takes out a 1:1 mapping from 0x0 to
TASK_SIZE during reboot in the hope that the reset code lives at a
physical address corresponding to a userspace virtual address.

This patch modifies the code so that we switch to the idmap_pgd tables,
which contain a 1:1 mapping of the cpu_reset code. This has the
advantage of only remapping the code that we need and also means we
don't need to worry about allocating a pgd from an atomic context in the
case that the physical address of the cpu_reset code aliases with the
virtual space used by the kernel.

Signed-off-by: Will Deacon <will.deacon@arm.com>
---
 arch/arm/mm/idmap.c |   19 ++++++++++---------
 1 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 8c1230a..0f96fb2 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -104,17 +104,18 @@ static int __init init_static_idmap(void)
 arch_initcall(init_static_idmap);
 
 /*
- * In order to soft-boot, we need to insert a 1:1 mapping in place of
- * the user-mode pages.  This will then ensure that we have predictable
- * results when turning the mmu off
+ * In order to soft-boot, we need to switch to a 1:1 mapping for the
+ * cpu_reset functions. This will then ensure that we have predictable
+ * results when turning off the mmu.
  */
 void setup_mm_for_reboot(char mode)
 {
-	/*
-	 * We need to access to user-mode page tables here. For kernel threads
-	 * we don't have any user-mode mappings so we use the context that we
-	 * "borrowed".
-	 */
-	identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
+	/* Clean and invalidate L1. */
+	flush_cache_all();
+
+	/* Switch exclusively to kernel mappings. */
+	cpu_switch_mm(idmap_pgd, &init_mm);
+
+	/* Flush the TLB. */
 	local_flush_tlb_all();
 }
-- 
1.7.4.1

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

* [PATCH 0/4] Consolidate identity mapping code in idmap.c
  2011-11-16 16:48 [PATCH 0/4] Consolidate identity mapping code in idmap.c Will Deacon
                   ` (3 preceding siblings ...)
  2011-11-16 16:48 ` [PATCH 4/4] ARM: idmap: use idmap_pgd when setting up mm for reboot Will Deacon
@ 2011-11-17 13:47 ` Dave Martin
  4 siblings, 0 replies; 12+ messages in thread
From: Dave Martin @ 2011-11-17 13:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 16, 2011 at 04:48:10PM +0000, Will Deacon wrote:
> Hello,
> 
> This patch series consolidates the identity mapping code into idmap.c,
> where a single set of page tables (idmap_pgd) are allocated and populated
> at init time for use by subsystems such as soft reboot, kexec and CPU
> suspend.
> 
> A new linker section (.idmap.text) is introduced so that code which
> needs to be identity mapped can be annotated with __idmap or, if written
> in assembly, placed there explicitly.
> 
> CPU suspend, cpu_*_reset and setup_mm_for_reboot are all updated to work
> with the new mapping code.
> 
> This is currently based on 3.2-rc2, but will be based on Russell's reset
> branch when it comes to merging (where the prototype of
> setup_mm_for_reboot has changed slightly). Furthermore, I have rebased
> my kexec series against this which I will post separately.
> 
> Comments welcome.

I haven't exhaustively checked every detail, but this looks like a
cleaner, more scalabale and more robust way to handle code which needs
to be identity-mapped compared with what we had previously; so I'm in
favour of it.

FWIW

Acked-by: Dave Martin <dave.martin@linaro.org>

> 
> Cheers,
> 
> Will
> 
> 
> Will Deacon (4):
>   ARM: idmap: populate identity map pgd at init time using .init.text
>   ARM: suspend: use idmap_pgd instead of suspend_pgd
>   ARM: proc-*.S: place cpu_reset functions into .idmap.text section
>   ARM: idmap: use idmap_pgd when setting up mm for reboot
> 
>  arch/arm/include/asm/idmap.h      |   11 ++++++++
>  arch/arm/kernel/sleep.S           |    2 +
>  arch/arm/kernel/suspend.c         |   17 ++----------
>  arch/arm/kernel/vmlinux.lds.S     |    1 +
>  arch/arm/mm/idmap.c               |   49 ++++++++++++++++++++++++++++++-------
>  arch/arm/mm/proc-arm1020.S        |    3 ++
>  arch/arm/mm/proc-arm1020e.S       |    3 ++
>  arch/arm/mm/proc-arm1022.S        |    3 ++
>  arch/arm/mm/proc-arm1026.S        |    3 ++
>  arch/arm/mm/proc-arm6_7.S         |    4 +++
>  arch/arm/mm/proc-arm720.S         |    3 ++
>  arch/arm/mm/proc-arm740.S         |    3 ++
>  arch/arm/mm/proc-arm7tdmi.S       |    3 ++
>  arch/arm/mm/proc-arm920.S         |    3 ++
>  arch/arm/mm/proc-arm922.S         |    3 ++
>  arch/arm/mm/proc-arm925.S         |    3 ++
>  arch/arm/mm/proc-arm926.S         |    3 ++
>  arch/arm/mm/proc-arm940.S         |    3 ++
>  arch/arm/mm/proc-arm946.S         |    3 ++
>  arch/arm/mm/proc-arm9tdmi.S       |    3 ++
>  arch/arm/mm/proc-fa526.S          |    3 ++
>  arch/arm/mm/proc-feroceon.S       |    3 ++
>  arch/arm/mm/proc-mohawk.S         |    3 ++
>  arch/arm/mm/proc-sa110.S          |    3 ++
>  arch/arm/mm/proc-sa1100.S         |    3 ++
>  arch/arm/mm/proc-v6.S             |    3 ++
>  arch/arm/mm/proc-v7.S             |    2 +
>  arch/arm/mm/proc-xsc3.S           |    3 ++
>  arch/arm/mm/proc-xscale.S         |    3 ++
>  include/asm-generic/vmlinux.lds.h |    6 ++++
>  30 files changed, 135 insertions(+), 23 deletions(-)
>  create mode 100644 arch/arm/include/asm/idmap.h
> 
> -- 
> 1.7.4.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text
  2011-11-16 16:48 ` [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text Will Deacon
@ 2011-11-18 12:02   ` Catalin Marinas
  2011-11-18 12:08     ` Will Deacon
  0 siblings, 1 reply; 12+ messages in thread
From: Catalin Marinas @ 2011-11-18 12:02 UTC (permalink / raw)
  To: linux-arm-kernel

On 16 November 2011 16:48, Will Deacon <will.deacon@arm.com> wrote:
> When disabling and re-enabling the MMU, it is necessary to take out an
> identity mapping for the code that manipulates the SCTLR in order to
> avoid it disappearing from under our feet. This is useful when soft
> rebooting and returning from CPU suspend.
>
> This patch allocates a set of page tables during boot and populates them
> with an identity mapping for the .idmap.text section. This means that
> users of the identity map do not need to manage their own pgd and can
> instead annotate their functions with __idmap or, in the case of assembly
> code, place them in the correct section.
>
> Tested-by: Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
...
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -425,6 +425,12 @@
> ? ? ? ? ? ? ? ?*(.kprobes.text) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> ? ? ? ? ? ? ? ?VMLINUX_SYMBOL(__kprobes_text_end) = .;
>
> +#define IDMAP_TEXT ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? ALIGN_FUNCTION(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? VMLINUX_SYMBOL(__idmap_text_start) = .; ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? *(.idmap.text) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? VMLINUX_SYMBOL(__idmap_text_end) = .;
> +
> ?#define ENTRY_TEXT ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> ? ? ? ? ? ? ? ?ALIGN_FUNCTION(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> ? ? ? ? ? ? ? ?VMLINUX_SYMBOL(__entry_text_start) = .; ? ? ? ? ? ? ? ? \

Since IDMAP is specific to ARM, we should just add the IDMAP_TEXT
macro to vmlinux.lds.S.

-- 
Catalin

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

* [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text
  2011-11-18 12:02   ` Catalin Marinas
@ 2011-11-18 12:08     ` Will Deacon
  0 siblings, 0 replies; 12+ messages in thread
From: Will Deacon @ 2011-11-18 12:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 18, 2011 at 12:02:03PM +0000, Catalin Marinas wrote:
> On 16 November 2011 16:48, Will Deacon <will.deacon@arm.com> wrote:
> > --- a/include/asm-generic/vmlinux.lds.h
> > +++ b/include/asm-generic/vmlinux.lds.h
> > @@ -425,6 +425,12 @@
> > ? ? ? ? ? ? ? ?*(.kprobes.text) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> > ? ? ? ? ? ? ? ?VMLINUX_SYMBOL(__kprobes_text_end) = .;
> >
> > +#define IDMAP_TEXT ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> > + ? ? ? ? ? ? ? ALIGN_FUNCTION(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> > + ? ? ? ? ? ? ? VMLINUX_SYMBOL(__idmap_text_start) = .; ? ? ? ? ? ? ? ? \
> > + ? ? ? ? ? ? ? *(.idmap.text) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
> > + ? ? ? ? ? ? ? VMLINUX_SYMBOL(__idmap_text_end) = .;
> > +
> > ?#define ENTRY_TEXT ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> > ? ? ? ? ? ? ? ?ALIGN_FUNCTION(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
> > ? ? ? ? ? ? ? ?VMLINUX_SYMBOL(__entry_text_start) = .; ? ? ? ? ? ? ? ? \
> 
> Since IDMAP is specific to ARM, we should just add the IDMAP_TEXT
> macro to vmlinux.lds.S.

Argh, well spotted! ctags launched me there and I didn't realise I was outside
of my usual stomping ground.

I'll fix this.

Will

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

* [PATCH 2/4] ARM: suspend: use idmap_pgd instead of suspend_pgd
  2011-11-16 16:48 ` [PATCH 2/4] ARM: suspend: use idmap_pgd instead of suspend_pgd Will Deacon
@ 2011-11-18 16:43   ` Catalin Marinas
  2011-11-18 17:26     ` Will Deacon
  0 siblings, 1 reply; 12+ messages in thread
From: Catalin Marinas @ 2011-11-18 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

On 16 November 2011 16:48, Will Deacon <will.deacon@arm.com> wrote:
> The ARM CPU suspend code requires cpu_resume_mmu to be identity mapped
> in order to re-enable the MMU when coming out of suspend. Currently,
> this is accomplished by maintaining a suspend_pgd with the relevant
> mapping put in place at init time.
>
> This patch replaces the use of suspend_pgd with the new idmap_pgd.
> cpu_resume_mmu is placed in the .idmap.text section so that it is
> included in the identity map.
>
> Tested-by: Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
...
> diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
> index 93a22d2..8880f94 100644
> --- a/arch/arm/kernel/suspend.c
> +++ b/arch/arm/kernel/suspend.c
> @@ -6,7 +6,7 @@
> ?#include <asm/suspend.h>
> ?#include <asm/tlbflush.h>
>
> -static pgd_t *suspend_pgd;
> +extern pgd_t *idmap_pgd;

We should move the extern declaration to pgtable.h where we have the
identity_mapping_*() function prototypes (we may need this in the
future for other things).

Otherwise,

Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

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

* [PATCH 4/4] ARM: idmap: use idmap_pgd when setting up mm for reboot
  2011-11-16 16:48 ` [PATCH 4/4] ARM: idmap: use idmap_pgd when setting up mm for reboot Will Deacon
@ 2011-11-18 16:56   ` Catalin Marinas
  2011-11-18 17:21     ` Will Deacon
  0 siblings, 1 reply; 12+ messages in thread
From: Catalin Marinas @ 2011-11-18 16:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 16 November 2011 16:48, Will Deacon <will.deacon@arm.com> wrote:
> For soft-rebooting a system, it is necessary to map the MMU-off code
> with an identity mapping so that execution can continue safely once the
> MMU has been switched off.
>
> Currently, switch_mm_for_reboot takes out a 1:1 mapping from 0x0 to
> TASK_SIZE during reboot in the hope that the reset code lives at a
> physical address corresponding to a userspace virtual address.
>
> This patch modifies the code so that we switch to the idmap_pgd tables,
> which contain a 1:1 mapping of the cpu_reset code. This has the
> advantage of only remapping the code that we need and also means we
> don't need to worry about allocating a pgd from an atomic context in the
> case that the physical address of the cpu_reset code aliases with the
> virtual space used by the kernel.
>
> Signed-off-by: Will Deacon <will.deacon@arm.com>
> ---
> ?arch/arm/mm/idmap.c | ? 19 ++++++++++---------
> ?1 files changed, 10 insertions(+), 9 deletions(-)
>
> diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
> index 8c1230a..0f96fb2 100644
> --- a/arch/arm/mm/idmap.c
> +++ b/arch/arm/mm/idmap.c
> @@ -104,17 +104,18 @@ static int __init init_static_idmap(void)
> ?arch_initcall(init_static_idmap);
>
> ?/*
> - * In order to soft-boot, we need to insert a 1:1 mapping in place of
> - * the user-mode pages. ?This will then ensure that we have predictable
> - * results when turning the mmu off
> + * In order to soft-boot, we need to switch to a 1:1 mapping for the
> + * cpu_reset functions. This will then ensure that we have predictable
> + * results when turning off the mmu.
> ?*/
> ?void setup_mm_for_reboot(char mode)
> ?{
> - ? ? ? /*
> - ? ? ? ?* We need to access to user-mode page tables here. For kernel threads
> - ? ? ? ?* we don't have any user-mode mappings so we use the context that we
> - ? ? ? ?* "borrowed".
> - ? ? ? ?*/
> - ? ? ? identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
> + ? ? ? /* Clean and invalidate L1. */
> + ? ? ? flush_cache_all();

Is the cache flushing needed here? The setup_mm_for_reboot callers do
it after this function anyway (unless this is needed for VIVT
caches?).

-- 
Catalin

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

* [PATCH 4/4] ARM: idmap: use idmap_pgd when setting up mm for reboot
  2011-11-18 16:56   ` Catalin Marinas
@ 2011-11-18 17:21     ` Will Deacon
  0 siblings, 0 replies; 12+ messages in thread
From: Will Deacon @ 2011-11-18 17:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 18, 2011 at 04:56:24PM +0000, Catalin Marinas wrote:
> On 16 November 2011 16:48, Will Deacon <will.deacon@arm.com> wrote:
> > ?void setup_mm_for_reboot(char mode)
> > ?{
> > - ? ? ? /*
> > - ? ? ? ?* We need to access to user-mode page tables here. For kernel threads
> > - ? ? ? ?* we don't have any user-mode mappings so we use the context that we
> > - ? ? ? ?* "borrowed".
> > - ? ? ? ?*/
> > - ? ? ? identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
> > + ? ? ? /* Clean and invalidate L1. */
> > + ? ? ? flush_cache_all();
> 
> Is the cache flushing needed here? The setup_mm_for_reboot callers do
> it after this function anyway (unless this is needed for VIVT
> caches?).

I initially added the cache flushing because we used to manipulate the page
tables at this point. We don't do that anymore, but as you say, if we have
a VIVT D-side then we do need that flush before switching to the new pgd.

One thing I will change is the following comment (/* Switch exclusively to kernel
mappings. */) because that's a bit confusing now.

Will

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

* [PATCH 2/4] ARM: suspend: use idmap_pgd instead of suspend_pgd
  2011-11-18 16:43   ` Catalin Marinas
@ 2011-11-18 17:26     ` Will Deacon
  0 siblings, 0 replies; 12+ messages in thread
From: Will Deacon @ 2011-11-18 17:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Nov 18, 2011 at 04:43:55PM +0000, Catalin Marinas wrote:
> On 16 November 2011 16:48, Will Deacon <will.deacon@arm.com> wrote:
> > The ARM CPU suspend code requires cpu_resume_mmu to be identity mapped
> > in order to re-enable the MMU when coming out of suspend. Currently,
> > this is accomplished by maintaining a suspend_pgd with the relevant
> > mapping put in place at init time.
> >
> > This patch replaces the use of suspend_pgd with the new idmap_pgd.
> > cpu_resume_mmu is placed in the .idmap.text section so that it is
> > included in the identity map.
> >
> > Tested-by: Lorenzo Pieralisi <Lorenzo.Pieralisi@arm.com>
> > Signed-off-by: Will Deacon <will.deacon@arm.com>
> ...
> > diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
> > index 93a22d2..8880f94 100644
> > --- a/arch/arm/kernel/suspend.c
> > +++ b/arch/arm/kernel/suspend.c
> > @@ -6,7 +6,7 @@
> > ?#include <asm/suspend.h>
> > ?#include <asm/tlbflush.h>
> >
> > -static pgd_t *suspend_pgd;
> > +extern pgd_t *idmap_pgd;
> 
> We should move the extern declaration to pgtable.h where we have the
> identity_mapping_*() function prototypes (we may need this in the
> future for other things).

Actually, I've added asm/idmap.h now so maybe I'd be better off putting
everything in there? I missed the declarations in pgtable.h, although in the
future I may be able to make the identity_mapping_{add,del} functions static
and include _stext & co in the idmap_pgd.

> Otherwise,
> 
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>

Cheers,

Will

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

end of thread, other threads:[~2011-11-18 17:26 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-16 16:48 [PATCH 0/4] Consolidate identity mapping code in idmap.c Will Deacon
2011-11-16 16:48 ` [PATCH 1/4] ARM: idmap: populate identity map pgd at init time using .init.text Will Deacon
2011-11-18 12:02   ` Catalin Marinas
2011-11-18 12:08     ` Will Deacon
2011-11-16 16:48 ` [PATCH 2/4] ARM: suspend: use idmap_pgd instead of suspend_pgd Will Deacon
2011-11-18 16:43   ` Catalin Marinas
2011-11-18 17:26     ` Will Deacon
2011-11-16 16:48 ` [PATCH 3/4] ARM: proc-*.S: place cpu_reset functions into .idmap.text section Will Deacon
2011-11-16 16:48 ` [PATCH 4/4] ARM: idmap: use idmap_pgd when setting up mm for reboot Will Deacon
2011-11-18 16:56   ` Catalin Marinas
2011-11-18 17:21     ` Will Deacon
2011-11-17 13:47 ` [PATCH 0/4] Consolidate identity mapping code in idmap.c Dave Martin

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