* [RFC 0/2] Selective identity mapping for kexec
@ 2010-11-01 16:36 Per Fransson
2010-11-01 16:36 ` [RFC 2/2] Selective MMU " Per Fransson
2010-11-02 12:59 ` [RFC 0/2] Selective " Simon Horman
0 siblings, 2 replies; 4+ messages in thread
From: Per Fransson @ 2010-11-01 16:36 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] 4+ messages in thread
* [RFC 2/2] Selective MMU identity mapping for kexec
2010-11-01 16:36 [RFC 0/2] Selective identity mapping for kexec Per Fransson
@ 2010-11-01 16:36 ` Per Fransson
2010-11-02 12:59 ` [RFC 0/2] Selective " Simon Horman
1 sibling, 0 replies; 4+ messages in thread
From: Per Fransson @ 2010-11-01 16:36 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] 4+ messages in thread
* [RFC 0/2] Selective identity mapping for kexec
2010-11-01 16:36 [RFC 0/2] Selective identity mapping for kexec Per Fransson
2010-11-01 16:36 ` [RFC 2/2] Selective MMU " Per Fransson
@ 2010-11-02 12:59 ` Simon Horman
2010-11-02 13:05 ` Simon Horman
1 sibling, 1 reply; 4+ messages in thread
From: Simon Horman @ 2010-11-02 12:59 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Nov 01, 2010 at 05:36:52PM +0100, Per Fransson wrote:
> Hi,
>
> I would appreciate your input on some kexec related changes.
Hi,
It would be useful to CC kexec at lists.infradead.org on kexec patches.
Also, I seem to be missing patch 1/2. Did it have a different CC list?
^ permalink raw reply [flat|nested] 4+ messages in thread
* [RFC 0/2] Selective identity mapping for kexec
2010-11-02 12:59 ` [RFC 0/2] Selective " Simon Horman
@ 2010-11-02 13:05 ` Simon Horman
0 siblings, 0 replies; 4+ messages in thread
From: Simon Horman @ 2010-11-02 13:05 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 02, 2010 at 09:59:10PM +0900, Simon Horman wrote:
> On Mon, Nov 01, 2010 at 05:36:52PM +0100, Per Fransson wrote:
> > Hi,
> >
> > I would appreciate your input on some kexec related changes.
>
> Hi,
>
> It would be useful to CC kexec at lists.infradead.org on kexec patches.
> Also, I seem to be missing patch 1/2. Did it have a different CC list?
Scratch the second comment, I see 1/2 in your second posting of the patches.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-11-02 13:05 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-11-01 16:36 [RFC 0/2] Selective identity mapping for kexec Per Fransson
2010-11-01 16:36 ` [RFC 2/2] Selective MMU " Per Fransson
2010-11-02 12:59 ` [RFC 0/2] Selective " Simon Horman
2010-11-02 13:05 ` Simon Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox