* [RFC 0/2] Selective MMU identity mapping for kexec
@ 2010-11-01 18:32 Per Fransson
2010-11-01 18:32 ` [RFC 1/2] " Per Fransson
2010-11-01 18:32 ` [RFC 2/2] " Per Fransson
0 siblings, 2 replies; 6+ messages in thread
From: Per Fransson @ 2010-11-01 18:32 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
I would appreciate your input on some kexec related changes.
When restarting using the kernel kexec functionality the MMU needs to be turned off.
Any code which does this needs to use identity mapped addresses to get
reliable results. In the ARM kexec case this identity mapping is done:
- using the page table of the current task
- for all addresses normally used by user space, i.e. 0x00000000-PAGE_OFFSET
If kexec is used at a kernel crash to collect a core dump this means that we lose important information.
This is what these patches do:
* Actually turn off the MMU, which has been omitted by mistake, see this post:
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-July/019631.html
* Set up a more selective identity mapping
* Restore the old mapping once the MMU is off
The patch was generated from a linux-next 20101028 with these additional related patches which are in the pipeline:
http://dev.omapzoom.org/?p=santosh/kernel-omap4-base.git;a=commit;h=ae360a78f41164e7f9c4cf846696b5b6d8dae5c8
http://dev.omapzoom.org/?p=santosh/kernel-omap4-base.git;a=commit;h=2fd8658931193599c867fd6974fa184ec34af16c
http://dev.omapzoom.org/?p=santosh/kernel-omap4-base.git;a=commit;h=ae6948048c417d429b8a0f85fad13e483f7cc1a3
Regards,
Per
Per Fransson (2):
Turn off MMU in cpu_v7_reset
Selective MMU identity mapping for kexec
arch/arm/kernel/machine_kexec.c | 27 +++++++++++++++++++++-
arch/arm/kernel/relocate_kernel.S | 23 +++++++++++++++++++
arch/arm/mm/mmu.c | 44 +++++++++++++++++++++++++++++++++++++
arch/arm/mm/proc-v7.S | 4 +++
4 files changed, 97 insertions(+), 1 deletions(-)
--
1.7.2.2
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC 1/2] Selective MMU identity mapping for kexec
2010-11-01 18:32 [RFC 0/2] Selective MMU identity mapping for kexec Per Fransson
@ 2010-11-01 18:32 ` Per Fransson
2010-11-01 18:32 ` [RFC 2/2] " Per Fransson
1 sibling, 0 replies; 6+ messages in thread
From: Per Fransson @ 2010-11-01 18:32 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
---
arch/arm/mm/proc-v7.S | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 2b5b20b..b249143 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -61,6 +61,9 @@ ENDPROC(cpu_v7_proc_fin)
*/
.align 5
ENTRY(cpu_v7_reset)
+ mrc p15, 0, ip, c1, c0, 0 @ ctrl register
+ bic ip, ip, #0x0001 @ ...............m
+ mcr p15, 0, ip, c1, c0, 0 @ ctrl register
mov pc, r0
ENDPROC(cpu_v7_reset)
--
1.7.2.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC 2/2] Selective MMU identity mapping for kexec
2010-11-01 18:32 [RFC 0/2] Selective MMU identity mapping for kexec Per Fransson
2010-11-01 18:32 ` [RFC 1/2] " Per Fransson
@ 2010-11-01 18:32 ` Per Fransson
2010-12-15 17:39 ` Will Deacon
1 sibling, 1 reply; 6+ messages in thread
From: Per Fransson @ 2010-11-01 18:32 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
---
arch/arm/kernel/machine_kexec.c | 27 +++++++++++++++++++++-
arch/arm/kernel/relocate_kernel.S | 23 +++++++++++++++++++
arch/arm/mm/mmu.c | 44 +++++++++++++++++++++++++++++++++++++
arch/arm/mm/proc-v7.S | 1 +
4 files changed, 94 insertions(+), 1 deletions(-)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 3a8fd51..d5bb12f 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -17,12 +17,20 @@ extern const unsigned char relocate_new_kernel[];
extern const unsigned int relocate_new_kernel_size;
extern void setup_mm_for_reboot(char mode);
+extern void identity_map(unsigned long, pgd_t*, pgd_t**);
extern unsigned long kexec_start_address;
extern unsigned long kexec_indirection_page;
extern unsigned long kexec_mach_type;
extern unsigned long kexec_boot_atags;
+typedef struct {
+ pgd_t *ptr;
+ pgd_t store;
+} kexec_mmu_ent_t;
+
+extern kexec_mmu_ent_t kexec_mmu_ents[4];
+
/*
* Provide a dummy crash_notes definition while crash dump arrives to arm.
* This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
@@ -51,6 +59,7 @@ void machine_kexec(struct kimage *image)
unsigned long reboot_code_buffer_phys;
void *reboot_code_buffer;
+ unsigned long cpu_reset_phys;
page_list = image->head & PAGE_MASK;
@@ -65,18 +74,34 @@ void machine_kexec(struct kimage *image)
kexec_mach_type = machine_arch_type;
kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+ /* Identity map the code which turns off the mmu (cpu_reset) and
+ the code which will be executed immediately afterwards
+ (relocate_new_kernel).
+ Store the old entries so they can be restored. */
+ /* cpu_reset cannot be used directly when MULTI_CPU is true, see
+ cpu-multi32.h, instead processor.reset will have to be used */
+ cpu_reset_phys = virt_to_phys(cpu_reset);
+ identity_map(cpu_reset_phys, &kexec_mmu_ents[0].store,
+ &kexec_mmu_ents[0].ptr);
+ identity_map(((char *)cpu_reset_phys)+PGDIR_SIZE,
+ &kexec_mmu_ents[1].store, &kexec_mmu_ents[1].ptr);
+ identity_map(reboot_code_buffer_phys,
+ &kexec_mmu_ents[2].store, &kexec_mmu_ents[2].ptr);
+ identity_map(((char *)reboot_code_buffer_phys)+PGDIR_SIZE,
+ &kexec_mmu_ents[3].store, &kexec_mmu_ents[3].ptr);
+
/* copy our kernel relocation code to the control code page */
memcpy(reboot_code_buffer,
relocate_new_kernel, relocate_new_kernel_size);
+
flush_icache_range((unsigned long) reboot_code_buffer,
(unsigned long) reboot_code_buffer + KEXEC_CONTROL_PAGE_SIZE);
printk(KERN_INFO "Bye!\n");
local_irq_disable();
local_fiq_disable();
- setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
flush_cache_all();
outer_flush_all();
outer_disable();
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
index fd26f8d..36b1268 100644
--- a/arch/arm/kernel/relocate_kernel.S
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -7,6 +7,23 @@
.globl relocate_new_kernel
relocate_new_kernel:
+ /* We get here when the MMU is in a transitional state.
+ Wait for the virtual address mapping to wear off before
+ overwriting the identity mappings (set up for the sake
+ of MMU disabling) with the previous mappings. */
+ ldr r0, =100
+0: subs r0, r0, #1
+ beq 0b
+
+ adr r0, kexec_mmu_ents
+ .rept 4
+ ldr r1, [r0], #4
+ ldr r2, [r0], #4
+ str r2, [r1], #4
+ ldr r2, [r0], #4
+ str r2, [r1], #4
+ .endr
+
ldr r0,kexec_indirection_page
ldr r1,kexec_start_address
@@ -67,6 +84,12 @@ kexec_start_address:
kexec_indirection_page:
.long 0x0
+
+ .globl kexec_mmu_ents
+kexec_mmu_ents:
+ .space 4*12, 0
+
+
.globl kexec_mach_type
kexec_mach_type:
.long 0x0
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index de3afc7..64f3f05 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1080,3 +1080,47 @@ void setup_mm_for_reboot(char mode)
local_flush_tlb_all();
}
+
+
+/*
+ * 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
+ */
+void identity_map(unsigned long phys_addr, pmd_t *pmd_store, pmd_t **pmd_ptr)
+{
+ unsigned long base_pmdval;
+ pgd_t *pgd;
+ pmd_t *pmd;
+ int i;
+ unsigned long pmdval;
+
+ /*
+ * 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".
+ */
+ pgd = current->active_mm->pgd;
+
+ base_pmdval = PMD_SECT_AP_WRITE | PMD_SECT_AP_READ | PMD_TYPE_SECT;
+ if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+ base_pmdval |= PMD_BIT4;
+
+ /* Where to modify */
+ pmd = pgd + (phys_addr >> PGDIR_SHIFT);
+
+ /* Save old value */
+ pmd_store[0] = pmd[0];
+ pmd_store[1] = pmd[1];
+
+ *pmd_ptr = virt_to_phys(pmd);
+
+ /* Set new value */
+ pmdval = ((phys_addr >> PGDIR_SHIFT) << PGDIR_SHIFT) | base_pmdval;
+ pmd[0] = __pmd(pmdval);
+ pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1)));
+
+ flush_pmd_entry(pmd);
+ local_flush_tlb_all();
+}
+
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index b249143..37ee55b 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -61,6 +61,7 @@ ENDPROC(cpu_v7_proc_fin)
*/
.align 5
ENTRY(cpu_v7_reset)
+ sub pc, pc, #PAGE_OFFSET+4 @ go to physical addresses
mrc p15, 0, ip, c1, c0, 0 @ ctrl register
bic ip, ip, #0x0001 @ ...............m
mcr p15, 0, ip, c1, c0, 0 @ ctrl register
--
1.7.2.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [RFC 2/2] Selective MMU identity mapping for kexec
2010-11-01 18:32 ` [RFC 2/2] " Per Fransson
@ 2010-12-15 17:39 ` Will Deacon
2010-12-15 23:35 ` Russell King - ARM Linux
0 siblings, 1 reply; 6+ messages in thread
From: Will Deacon @ 2010-12-15 17:39 UTC (permalink / raw)
To: linux-arm-kernel
Hi Per,
It's nice to see somebody looking at this!
On Mon, 2010-11-01 at 19:32 +0100, Per Fransson wrote:
> Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
> ---
> arch/arm/kernel/machine_kexec.c | 27 +++++++++++++++++++++-
> arch/arm/kernel/relocate_kernel.S | 23 +++++++++++++++++++
> arch/arm/mm/mmu.c | 44 +++++++++++++++++++++++++++++++++++++
> arch/arm/mm/proc-v7.S | 1 +
> 4 files changed, 94 insertions(+), 1 deletions(-)
Some parts of this patchset will be useful for implementing CPU hotplug
on the ARM RealView boards. The idea is to throw cores back to the
bootloader when they are offlined, so we need to be able to disable the
MMU safely before we jump.
> diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
> index 3a8fd51..d5bb12f 100644
> --- a/arch/arm/kernel/machine_kexec.c
> +++ b/arch/arm/kernel/machine_kexec.c
> @@ -17,12 +17,20 @@ extern const unsigned char relocate_new_kernel[];
> extern const unsigned int relocate_new_kernel_size;
>
> extern void setup_mm_for_reboot(char mode);
> +extern void identity_map(unsigned long, pgd_t*, pgd_t**);
[...]
> + cpu_reset_phys = virt_to_phys(cpu_reset);
> + identity_map(cpu_reset_phys, &kexec_mmu_ents[0].store,
> + &kexec_mmu_ents[0].ptr);
> + identity_map(((char *)cpu_reset_phys)+PGDIR_SIZE,
> + &kexec_mmu_ents[1].store, &kexec_mmu_ents[1].ptr);
I think this could become common code as calling cpu_reset will require
the identity map to be in place now that you have added MMU disable code
there.
> diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
> index b249143..37ee55b 100644
> --- a/arch/arm/mm/proc-v7.S
> +++ b/arch/arm/mm/proc-v7.S
> @@ -61,6 +61,7 @@ ENDPROC(cpu_v7_proc_fin)
> */
> .align 5
> ENTRY(cpu_v7_reset)
> + sub pc, pc, #PAGE_OFFSET+4 @ go to physical addresses
> mrc p15, 0, ip, c1, c0, 0 @ ctrl register
> bic ip, ip, #0x0001 @ ...............m
> mcr p15, 0, ip, c1, c0, 0 @ ctrl register
I'm not too keen on modifying the PC directly here. It also won't
compile for Thumb2. How about invoking the function using the 1:1
mapping instead? I think casting its physical address to a function
pointer will cause the compiler to generate any trampolines that are
needed.
Cheers,
Will
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC 2/2] Selective MMU identity mapping for kexec
2010-12-15 17:39 ` Will Deacon
@ 2010-12-15 23:35 ` Russell King - ARM Linux
0 siblings, 0 replies; 6+ messages in thread
From: Russell King - ARM Linux @ 2010-12-15 23:35 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 15, 2010 at 05:39:22PM +0000, Will Deacon wrote:
> Hi Per,
>
> It's nice to see somebody looking at this!
>
> On Mon, 2010-11-01 at 19:32 +0100, Per Fransson wrote:
> > Signed-off-by: Per Fransson <per.xx.fransson@stericsson.com>
> > ---
> > arch/arm/kernel/machine_kexec.c | 27 +++++++++++++++++++++-
> > arch/arm/kernel/relocate_kernel.S | 23 +++++++++++++++++++
> > arch/arm/mm/mmu.c | 44 +++++++++++++++++++++++++++++++++++++
> > arch/arm/mm/proc-v7.S | 1 +
> > 4 files changed, 94 insertions(+), 1 deletions(-)
>
> Some parts of this patchset will be useful for implementing CPU hotplug
> on the ARM RealView boards. The idea is to throw cores back to the
> bootloader when they are offlined, so we need to be able to disable the
> MMU safely before we jump.
Beware - you can't replace random pre-existing table entries on a running
SMP system without creating hazards.
> > + cpu_reset_phys = virt_to_phys(cpu_reset);
> > + identity_map(cpu_reset_phys, &kexec_mmu_ents[0].store,
> > + &kexec_mmu_ents[0].ptr);
> > + identity_map(((char *)cpu_reset_phys)+PGDIR_SIZE,
> > + &kexec_mmu_ents[1].store, &kexec_mmu_ents[1].ptr);
>
> I think this could become common code as calling cpu_reset will require
> the identity map to be in place now that you have added MMU disable code
> there.
We have an identity mapping function set in the kernel (which has been
recently moved into its own file in my devel branch.) It would need to
be extended to return the old pmd and pmd pointer to undo.
^ permalink raw reply [flat|nested] 6+ messages in thread
* [RFC 0/2] Selective MMU identity mapping for kexec
@ 2010-11-08 8:42 Per Fransson
0 siblings, 0 replies; 6+ messages in thread
From: Per Fransson @ 2010-11-08 8:42 UTC (permalink / raw)
To: kexec; +Cc: Per Fransson
Hi,
I would appreciate your input on some kexec related changes.
When restarting using the kernel kexec functionality the MMU needs to be turned off.
Any code which does this needs to use identity mapped addresses to get
reliable results. In the ARM kexec case this identity mapping is done:
- using the page table of the current task
- for all addresses normally used by user space, i.e. 0x00000000-PAGE_OFFSET
If kexec is used at a kernel crash to collect a core dump this means that we lose important information.
This is what these patches do:
* Actually turn off the MMU, which has been omitted by mistake, see this post:
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-July/019631.html
* Set up a more selective identity mapping
* Restore the old mapping once the MMU is off
The patch was generated from a linux-next 20101028 with these additional related patches which are in the pipeline:
http://dev.omapzoom.org/?p=santosh/kernel-omap4-base.git;a=commit;h=ae360a78f41164e7f9c4cf846696b5b6d8dae5c8
http://dev.omapzoom.org/?p=santosh/kernel-omap4-base.git;a=commit;h=2fd8658931193599c867fd6974fa184ec34af16c
http://dev.omapzoom.org/?p=santosh/kernel-omap4-base.git;a=commit;h=ae6948048c417d429b8a0f85fad13e483f7cc1a3
Regards,
Per
Per Fransson (2):
Turn off MMU in cpu_v7_reset
Selective MMU identity mapping for kexec
arch/arm/kernel/machine_kexec.c | 27 +++++++++++++++++++++-
arch/arm/kernel/relocate_kernel.S | 23 +++++++++++++++++++
arch/arm/mm/mmu.c | 44 +++++++++++++++++++++++++++++++++++++
arch/arm/mm/proc-v7.S | 4 +++
4 files changed, 97 insertions(+), 1 deletions(-)
--
1.7.2.2
_______________________________________________
kexec mailing list
kexec@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/kexec
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2010-12-15 23:35 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-01 18:32 [RFC 0/2] Selective MMU identity mapping for kexec Per Fransson
2010-11-01 18:32 ` [RFC 1/2] " Per Fransson
2010-11-01 18:32 ` [RFC 2/2] " Per Fransson
2010-12-15 17:39 ` Will Deacon
2010-12-15 23:35 ` Russell King - ARM Linux
2010-11-08 8:42 [RFC 0/2] " Per Fransson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.