* [PATCH v5 0/8] kexec fixes and soft restart code
@ 2011-11-08 15:52 Will Deacon
2011-11-08 15:52 ` [PATCH v5 1/8] Revert "ARM: 7098/1: kdump: copy kernel relocation code at the kexec prepare stage" Will Deacon
` (7 more replies)
0 siblings, 8 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:52 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
This is version 5 of the patches originally posted here:
v1: http://lists.infradead.org/pipermail/linux-arm-kernel/2011-June/052157.html
v2: http://lists.infradead.org/pipermail/linux-arm-kernel/2011-June/052559.html
v3: http://lists.infradead.org/pipermail/linux-arm-kernel/2011-June/053252.html
v4: http://lists.infradead.org/pipermail/linux-arm-kernel/2011-August/062305.html
This time around, the patches are based on top of Russell's reset branch,
where soft restart on ARMv6 onwards is starting to look like a reality.
Notable changes from previous versions of this code are:
- The identity map pgd is now populated at init time and is
static to idmap.c
- The reserved stack page is no more
- The temporary restart stack is simply a static array
The reserved stack page disappeared after feedback from Nicolas suggesting
that using a known physical location for the secondary CPU pen is ripe for
bootloader abuse. Although I can think of ways around this, having to maintain
this in future kernels could become tricky so I got rid of the idea.
Furthermore, talks at the ARM workshop in Prague revealed that most SMP SoCs
have hardware for controlling SMP boot anyway, so a purely software solution
is not usually needed (the exception being boards from ARM Ltd.).
The removal of the stack page means that we need to use a static array for
the stack prior to turning off the MMU. It looks to me like we currently only
need 6 stack slots [__soft_restart (-4), setup_mm_for_reboot (-2)] so I've
allocated 32 to be safe. Is there a way GCC can help us here?
The first patch (revert) is present in Russell's fixes branch but I'm
including it here for completeness. The fourth and fifth patches may
also need to be combined as it doesn't make sense to apply one without
the other.
As per usual, all feedback is welcome.
Cheers,
Will
Will Deacon (8):
Revert "ARM: 7098/1: kdump: copy kernel relocation code at the kexec
prepare stage"
ARM: lib: add call_with_stack function for safely changing stack
ARM: idmap: populate identity map pgd at init time
ARM: reset: allow kernelspace mappings to be flat mapped during reset
ARM: reset: implement soft_restart for jumping to a physical address
ARM: soft_restart: disable the outer L2 when the last CPU is going
down
ARM: stop: execute platform callback from cpu_stop code
ARM: kexec: use soft_restart for branching to the reboot buffer
arch/arm/Kconfig | 2 +-
arch/arm/kernel/machine_kexec.c | 50 ++++++++++++++---------------------
arch/arm/kernel/process.c | 55 ++++++++++++++++++++++++++++++--------
arch/arm/kernel/smp.c | 4 +++
arch/arm/lib/Makefile | 3 +-
arch/arm/lib/call_with_stack.S | 44 +++++++++++++++++++++++++++++++
arch/arm/mm/idmap.c | 37 ++++++++++++++++++++------
7 files changed, 142 insertions(+), 53 deletions(-)
create mode 100644 arch/arm/lib/call_with_stack.S
--
1.7.4.1
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v5 1/8] Revert "ARM: 7098/1: kdump: copy kernel relocation code at the kexec prepare stage"
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
@ 2011-11-08 15:52 ` Will Deacon
2011-11-08 15:52 ` [PATCH v5 2/8] ARM: lib: add call_with_stack function for safely changing stack Will Deacon
` (6 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:52 UTC (permalink / raw)
To: linux-arm-kernel
This reverts commit 2b034922af2caa19df86f0c502e76cb6f6e910f9.
---
arch/arm/kernel/machine_kexec.c | 35 +++++++++++++++++------------------
1 files changed, 17 insertions(+), 18 deletions(-)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index cc40b96..29620b6 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -32,24 +32,6 @@ static atomic_t waiting_for_crash_ipi;
int machine_kexec_prepare(struct kimage *image)
{
- unsigned long page_list;
- void *reboot_code_buffer;
- page_list = image->head & PAGE_MASK;
-
- reboot_code_buffer = page_address(image->control_code_page);
-
- /* Prepare parameters for reboot_code_buffer*/
- kexec_start_address = image->start;
- kexec_indirection_page = page_list;
- kexec_mach_type = machine_arch_type;
- kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
-
- /* 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);
return 0;
}
@@ -100,14 +82,31 @@ void (*kexec_reinit)(void);
void machine_kexec(struct kimage *image)
{
+ unsigned long page_list;
unsigned long reboot_code_buffer_phys;
void *reboot_code_buffer;
+
+ page_list = image->head & PAGE_MASK;
+
/* we need both effective and real address here */
reboot_code_buffer_phys =
page_to_pfn(image->control_code_page) << PAGE_SHIFT;
reboot_code_buffer = page_address(image->control_code_page);
+ /* Prepare parameters for reboot_code_buffer*/
+ kexec_start_address = image->start;
+ kexec_indirection_page = page_list;
+ kexec_mach_type = machine_arch_type;
+ kexec_boot_atags = image->start - KEXEC_ARM_ZIMAGE_OFFSET + KEXEC_ARM_ATAGS_OFFSET;
+
+ /* 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");
if (kexec_reinit)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 2/8] ARM: lib: add call_with_stack function for safely changing stack
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
2011-11-08 15:52 ` [PATCH v5 1/8] Revert "ARM: 7098/1: kdump: copy kernel relocation code at the kexec prepare stage" Will Deacon
@ 2011-11-08 15:52 ` Will Deacon
2011-11-08 15:52 ` [PATCH v5 3/8] ARM: idmap: populate identity map pgd at init time Will Deacon
` (5 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:52 UTC (permalink / raw)
To: linux-arm-kernel
When disabling the MMU, it is necessary to take out a 1:1 identity map
of the reset code so that it can safely be executed with and without
the MMU active. To avoid the situation where the physical address of the
reset code aliases with the virtual address of the active stack (which
cannot be included in the 1:1 mapping), it is desirable to change to a
new stack at a location which is less likely to alias.
This code adds a new lib function, call_with_stack:
void call_with_stack(void (*fn)(void *), void *arg, void *sp);
which changes the stack to point at the sp parameter, before invoking
fn(arg) with the new stack selected.
Reviewed-by: Nicolas Pitre <nicolas.pitre@linaro.org>
Signed-off-by: Dave Martin <dave.martin@linaro.org>
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/lib/Makefile | 3 +-
arch/arm/lib/call_with_stack.S | 44 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/lib/call_with_stack.S
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index cf73a7f..0ade0ac 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -13,7 +13,8 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
testchangebit.o testclearbit.o testsetbit.o \
ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
ucmpdi2.o lib1funcs.o div64.o \
- io-readsb.o io-writesb.o io-readsl.o io-writesl.o
+ io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
+ call_with_stack.o
mmu-y := clear_user.o copy_page.o getuser.o putuser.o
diff --git a/arch/arm/lib/call_with_stack.S b/arch/arm/lib/call_with_stack.S
new file mode 100644
index 0000000..916c80f
--- /dev/null
+++ b/arch/arm/lib/call_with_stack.S
@@ -0,0 +1,44 @@
+/*
+ * arch/arm/lib/call_with_stack.S
+ *
+ * Copyright (C) 2011 ARM Ltd.
+ * Written by Will Deacon <will.deacon@arm.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+
+/*
+ * void call_with_stack(void (*fn)(void *), void *arg, void *sp)
+ *
+ * Change the stack to that pointed at by sp, then invoke fn(arg) with
+ * the new stack.
+ */
+ENTRY(call_with_stack)
+ str sp, [r2, #-4]!
+ str lr, [r2, #-4]!
+
+ mov sp, r2
+ mov r2, r0
+ mov r0, r1
+
+ adr lr, BSYM(1f)
+ mov pc, r2
+
+1: ldr lr, [sp]
+ ldr sp, [sp, #4]
+ mov pc, lr
+ENDPROC(call_with_stack)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 3/8] ARM: idmap: populate identity map pgd at init time
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
2011-11-08 15:52 ` [PATCH v5 1/8] Revert "ARM: 7098/1: kdump: copy kernel relocation code at the kexec prepare stage" Will Deacon
2011-11-08 15:52 ` [PATCH v5 2/8] ARM: lib: add call_with_stack function for safely changing stack Will Deacon
@ 2011-11-08 15:52 ` Will Deacon
2011-11-12 11:14 ` Russell King - ARM Linux
2011-11-08 15:52 ` [PATCH v5 4/8] ARM: reset: allow kernelspace mappings to be flat mapped during reset Will Deacon
` (4 subsequent siblings)
7 siblings, 1 reply; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:52 UTC (permalink / raw)
To: linux-arm-kernel
When disabling the MMU, it is necessary to take out an identity mapping
for as much of the address space as possible so that the reset path can
be executed using its physical address. This is useful for softbooting
and entering low power states.
This patch allocates a set of pagetables during boot and populates them
with an identity mapping for all of memory apart from a small window
containing the kernel image.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/mm/idmap.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 296ad2e..24f6cf3 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -3,6 +3,9 @@
#include <asm/cputype.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>
+#include <asm/sections.h>
+
+static pgd_t *idmap_pgd;
static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
unsigned long prot)
@@ -73,6 +76,21 @@ void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
}
#endif
+static int __init init_static_idmap(void)
+{
+ unsigned long kernel_end = ALIGN((unsigned long)_end, PMD_SIZE);
+
+ idmap_pgd = pgd_alloc(&init_mm);
+ if (!idmap_pgd)
+ return -ENOMEM;
+
+ identity_mapping_add(idmap_pgd, 0, TASK_SIZE);
+ identity_mapping_add(idmap_pgd, kernel_end, 0);
+
+ 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
--
1.7.4.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 4/8] ARM: reset: allow kernelspace mappings to be flat mapped during reset
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
` (2 preceding siblings ...)
2011-11-08 15:52 ` [PATCH v5 3/8] ARM: idmap: populate identity map pgd at init time Will Deacon
@ 2011-11-08 15:52 ` Will Deacon
2011-11-08 15:53 ` [PATCH v5 5/8] ARM: reset: implement soft_restart for jumping to a physical address Will Deacon
` (3 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:52 UTC (permalink / raw)
To: linux-arm-kernel
Currently, switch_mm_for_reboot only takes out a 1:1 mapping from 0x0
to TASK_SIZE during reboot. For situations where we actually want to
turn off the MMU (e.g. kexec, hibernate, CPU hotplug) we want to map
as much memory as possible using the identity mapping so that we
increase the chance of mapping our reset code.
This patch modifies setup_mm_for_reboot to change to the static identity
map page tables that are setup during booting, therefore remapping all
of memory apart from a small window containing the kernel image.
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 24f6cf3..cdd4d08 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -92,17 +92,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 insert a 1:1 mapping of memory.
+ * This will then ensure that we have predictable results when turning
+ * the mmu off
*/
void setup_mm_for_reboot(void)
{
- /*
- * 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] 11+ messages in thread
* [PATCH v5 5/8] ARM: reset: implement soft_restart for jumping to a physical address
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
` (3 preceding siblings ...)
2011-11-08 15:52 ` [PATCH v5 4/8] ARM: reset: allow kernelspace mappings to be flat mapped during reset Will Deacon
@ 2011-11-08 15:53 ` Will Deacon
2011-11-08 15:53 ` [PATCH v5 6/8] ARM: soft_restart: disable the outer L2 when the last CPU is going down Will Deacon
` (2 subsequent siblings)
7 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:53 UTC (permalink / raw)
To: linux-arm-kernel
Tools such as kexec and CPU hotplug require a way to reset the processor
and branch to some code in physical space. This requires various bits of
jiggery pokery with the caches and MMU which, when it goes wrong, tends
to lock up the system.
This patch fleshes out the soft_restart implementation so that it
branches to the reset code using the identity mapping. This requires us
to change to a temporary stack, held within the kernel image as a static
array, to avoid conflicting with the new view of memory.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/kernel/process.c | 51 ++++++++++++++++++++++++++++++++++----------
1 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index a92ca50..577d092 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -92,29 +92,56 @@ static int __init hlt_setup(char *__unused)
__setup("nohlt", nohlt_setup);
__setup("hlt", hlt_setup);
-void soft_restart(unsigned long addr)
+extern void call_with_stack(void (*fn)(void *), void *arg, void *sp);
+typedef void (*phys_reset_t)(unsigned long);
+
+/*
+ * A temporary stack to use for CPU reset. This is static so that we
+ * don't clobber it with the identity mapping. When running with this
+ * stack, any references to the current task *will not work* so you
+ * should really do as little as possible before jumping to your reset
+ * code.
+ */
+#define SOFT_RESTART_STACK_WORDS 32
+static u32 soft_restart_stack[SOFT_RESTART_STACK_WORDS];
+
+static void __soft_restart(void *addr)
{
- /* Disable interrupts first */
- local_irq_disable();
- local_fiq_disable();
+ phys_reset_t phys_reset;
- /*
- * Tell the mm system that we are going to reboot -
- * we may need it to insert some 1:1 mappings so that
- * soft boot works.
- */
+ /* Take out a flat memory mapping. */
setup_mm_for_reboot();
- /* Clean and invalidate caches */
+ /* Clean and invalidate caches. */
flush_cache_all();
- /* Turn off caching */
+ /* Turn off caching. */
cpu_proc_fin();
/* Push out any further dirty data, and ensure cache is empty */
flush_cache_all();
- cpu_reset(addr);
+ /* Switch to the identity mapping. */
+ phys_reset = (phys_reset_t)(unsigned long)virt_to_phys(cpu_reset);
+ phys_reset((unsigned long)addr);
+
+ /* Should never get here. */
+ BUG();
+}
+
+void soft_restart(unsigned long addr)
+{
+ u32 *stack = soft_restart_stack + SOFT_RESTART_STACK_WORDS;
+
+ /* Disable interrupts first */
+ local_irq_disable();
+ local_fiq_disable();
+
+ /* Change to the new stack and continue with the reset. */
+ call_with_stack(__soft_restart, (void *)addr, (void *)stack);
+
+ /* Should never get here. */
+ BUG();
}
static void null_restart(char mode, const char *cmd)
--
1.7.4.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 6/8] ARM: soft_restart: disable the outer L2 when the last CPU is going down
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
` (4 preceding siblings ...)
2011-11-08 15:53 ` [PATCH v5 5/8] ARM: reset: implement soft_restart for jumping to a physical address Will Deacon
@ 2011-11-08 15:53 ` Will Deacon
2011-11-08 15:53 ` [PATCH v5 7/8] ARM: stop: execute platform callback from cpu_stop code Will Deacon
2011-11-08 15:53 ` [PATCH v5 8/8] ARM: kexec: use soft_restart for branching to the reboot buffer Will Deacon
7 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:53 UTC (permalink / raw)
To: linux-arm-kernel
Soft-restarting a system with an outer, shared L2 requires us to disable
it when no other CPUs are running.
This patch adds an outer_disable call to soft_restart so that the last
CPU going down will disable the L2 cache.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/kernel/process.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 577d092..664d351 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -137,6 +137,10 @@ void soft_restart(unsigned long addr)
local_irq_disable();
local_fiq_disable();
+ /* Disable the L2 if we're the last man standing. */
+ if (num_online_cpus() == 1)
+ outer_disable();
+
/* Change to the new stack and continue with the reset. */
call_with_stack(__soft_restart, (void *)addr, (void *)stack);
--
1.7.4.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 7/8] ARM: stop: execute platform callback from cpu_stop code
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
` (5 preceding siblings ...)
2011-11-08 15:53 ` [PATCH v5 6/8] ARM: soft_restart: disable the outer L2 when the last CPU is going down Will Deacon
@ 2011-11-08 15:53 ` Will Deacon
2011-11-08 15:53 ` [PATCH v5 8/8] ARM: kexec: use soft_restart for branching to the reboot buffer Will Deacon
7 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:53 UTC (permalink / raw)
To: linux-arm-kernel
Sending IPI_CPU_STOP to a CPU causes it to execute a busy cpu_relax
loop forever. This makes it impossible to kexec successfully on an SMP
system since the secondary CPUs do not reset.
This patch adds a callback to platform_cpu_kill, defined when
CONFIG_HOTPLUG_CPU=y, from the ipi_cpu_stop handling code. This function
currently just returns 1 on all platforms that define it but allows them
to do something more sophisticated in the future.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/Kconfig | 2 +-
arch/arm/kernel/smp.c | 4 ++++
2 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 44789ef..796d8cc 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1989,7 +1989,7 @@ config XIP_PHYS_ADDR
config KEXEC
bool "Kexec system call (EXPERIMENTAL)"
- depends on EXPERIMENTAL
+ depends on EXPERIMENTAL && (!SMP || HOTPLUG_CPU)
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index ef5640b..9c71665 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -550,6 +550,10 @@ static void ipi_cpu_stop(unsigned int cpu)
local_fiq_disable();
local_irq_disable();
+#ifdef CONFIG_HOTPLUG_CPU
+ platform_cpu_kill(cpu);
+#endif
+
while (1)
cpu_relax();
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 8/8] ARM: kexec: use soft_restart for branching to the reboot buffer
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
` (6 preceding siblings ...)
2011-11-08 15:53 ` [PATCH v5 7/8] ARM: stop: execute platform callback from cpu_stop code Will Deacon
@ 2011-11-08 15:53 ` Will Deacon
7 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-08 15:53 UTC (permalink / raw)
To: linux-arm-kernel
Now that there is a common way to reset the machine, let's use it
instead of reinventing the wheel in the kexec backend.
Signed-off-by: Will Deacon <will.deacon@arm.com>
---
arch/arm/kernel/machine_kexec.c | 15 +++------------
1 files changed, 3 insertions(+), 12 deletions(-)
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
index 29620b6..764bd45 100644
--- a/arch/arm/kernel/machine_kexec.c
+++ b/arch/arm/kernel/machine_kexec.c
@@ -12,12 +12,11 @@
#include <asm/mmu_context.h>
#include <asm/cacheflush.h>
#include <asm/mach-types.h>
+#include <asm/system.h>
extern const unsigned char relocate_new_kernel[];
extern const unsigned int relocate_new_kernel_size;
-extern void setup_mm_for_reboot(void);
-
extern unsigned long kexec_start_address;
extern unsigned long kexec_indirection_page;
extern unsigned long kexec_mach_type;
@@ -111,14 +110,6 @@ void machine_kexec(struct kimage *image)
if (kexec_reinit)
kexec_reinit();
- local_irq_disable();
- local_fiq_disable();
- setup_mm_for_reboot();
- flush_cache_all();
- outer_flush_all();
- outer_disable();
- cpu_proc_fin();
- outer_inv_all();
- flush_cache_all();
- cpu_reset(reboot_code_buffer_phys);
+
+ soft_restart(reboot_code_buffer_phys);
}
--
1.7.4.1
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v5 3/8] ARM: idmap: populate identity map pgd at init time
2011-11-08 15:52 ` [PATCH v5 3/8] ARM: idmap: populate identity map pgd at init time Will Deacon
@ 2011-11-12 11:14 ` Russell King - ARM Linux
2011-11-13 12:20 ` Will Deacon
0 siblings, 1 reply; 11+ messages in thread
From: Russell King - ARM Linux @ 2011-11-12 11:14 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 08, 2011 at 03:52:58PM +0000, Will Deacon wrote:
> When disabling the MMU, it is necessary to take out an identity mapping
> for as much of the address space as possible so that the reset path can
> be executed using its physical address. This is useful for softbooting
> and entering low power states.
>
> This patch allocates a set of pagetables during boot and populates them
> with an identity mapping for all of memory apart from a small window
> containing the kernel image.
I'd like to suggest a slightly different approach, now that we have the
'soft_restart()' thing which is guaranteed to be handling all of the
soft-restart stuff.
First, what does the soft-restart code need to do? It needs to:
1. Perform an orderly shutdown of caches.
2. Perform an orderly shutdown of the MMU.
3. Jump to the supplied physical address with the caches and MMU off,
IRQs disabled, etc.
And for (3) to work across the range of processors with ease, we need
the code to run in a 1:1 mapping so turning off the MMU doesn't leads
to unpredictable results.
We can achieve most of this in the way that we're already doing, so:
1. calling local_irq_disable() and local_fiq_disable() to disable interrupts
2. cpu_proc_fin() to disable caches
3. flush_cache_all() (and outer_flush_all()).
So far, that's very much what the new soft_restart() function already
does. But - can we be smarter about the 1:1 mapping like we are with
the CPU suspend code? Or, to put it another way, can we use the CPU
suspend code's page table which it allocated, and setup a mapping to
cover just the cpu_reset() code itself.
We'd need to reorganize the cpu_reset() code to ensure that the MMU
is actually turned off before we do the final jump, but that shouldn't
be too hard to achieve.
In other words, what I'm saying is that we don't need a 1:1 mapping
setup for the entire userland _if_ we're careful enough with how we
deal with the MMU-off -> jump transition.
This should fix the concerns people have had with kexec and kdump, as
well as fixing up the (broken) v6 and v7 cpu_reset() code.
^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v5 3/8] ARM: idmap: populate identity map pgd at init time
2011-11-12 11:14 ` Russell King - ARM Linux
@ 2011-11-13 12:20 ` Will Deacon
0 siblings, 0 replies; 11+ messages in thread
From: Will Deacon @ 2011-11-13 12:20 UTC (permalink / raw)
To: linux-arm-kernel
Hi Russell,
On Sat, Nov 12, 2011 at 11:14:14AM +0000, Russell King - ARM Linux wrote:
> On Tue, Nov 08, 2011 at 03:52:58PM +0000, Will Deacon wrote:
> > When disabling the MMU, it is necessary to take out an identity mapping
> > for as much of the address space as possible so that the reset path can
> > be executed using its physical address. This is useful for softbooting
> > and entering low power states.
> >
> > This patch allocates a set of pagetables during boot and populates them
> > with an identity mapping for all of memory apart from a small window
> > containing the kernel image.
>
> I'd like to suggest a slightly different approach, now that we have the
> 'soft_restart()' thing which is guaranteed to be handling all of the
> soft-restart stuff.
Sure, it's nice to have some feedback for the kexec stuff.
> First, what does the soft-restart code need to do? It needs to:
> 1. Perform an orderly shutdown of caches.
> 2. Perform an orderly shutdown of the MMU.
> 3. Jump to the supplied physical address with the caches and MMU off,
> IRQs disabled, etc.
>
> And for (3) to work across the range of processors with ease, we need
> the code to run in a 1:1 mapping so turning off the MMU doesn't leads
> to unpredictable results.
>
> We can achieve most of this in the way that we're already doing, so:
> 1. calling local_irq_disable() and local_fiq_disable() to disable interrupts
> 2. cpu_proc_fin() to disable caches
> 3. flush_cache_all() (and outer_flush_all()).
Agreed. This is what I currently do and it works nicely.
> So far, that's very much what the new soft_restart() function already
> does. But - can we be smarter about the 1:1 mapping like we are with
> the CPU suspend code? Or, to put it another way, can we use the CPU
> suspend code's page table which it allocated, and setup a mapping to
> cover just the cpu_reset() code itself.
Hmm, interesting idea, although we'll still need the code for changing stack
so that the C code between changing page tables and calling cpu_reset can
execute properly (to protect against the case where the physical address
of cpu_reset aliases with the virtual address of the stack). If we're going
to use the same page table for suspend and reset, should we move that into
idmap.c?
One possible advantage of only remapping cpu_reset would be that if we
could place all functions that require an identity mapping into a separate
linker section then the idmap code could simply remap that area.
> We'd need to reorganize the cpu_reset() code to ensure that the MMU
> is actually turned off before we do the final jump, but that shouldn't
> be too hard to achieve.
This is already taken care of by the isbs for v6 and v7. For older platforms,
I think we should be ok (Ye Olde ARM ARM second edition doesn't mention any
synchronisation requirements) but it would be worth testing it if possible.
> This should fix the concerns people have had with kexec and kdump, as
> well as fixing up the (broken) v6 and v7 cpu_reset() code.
Yes, we just have to make sure it doesn't break any older platforms.
Will
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2011-11-13 12:20 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-08 15:52 [PATCH v5 0/8] kexec fixes and soft restart code Will Deacon
2011-11-08 15:52 ` [PATCH v5 1/8] Revert "ARM: 7098/1: kdump: copy kernel relocation code at the kexec prepare stage" Will Deacon
2011-11-08 15:52 ` [PATCH v5 2/8] ARM: lib: add call_with_stack function for safely changing stack Will Deacon
2011-11-08 15:52 ` [PATCH v5 3/8] ARM: idmap: populate identity map pgd at init time Will Deacon
2011-11-12 11:14 ` Russell King - ARM Linux
2011-11-13 12:20 ` Will Deacon
2011-11-08 15:52 ` [PATCH v5 4/8] ARM: reset: allow kernelspace mappings to be flat mapped during reset Will Deacon
2011-11-08 15:53 ` [PATCH v5 5/8] ARM: reset: implement soft_restart for jumping to a physical address Will Deacon
2011-11-08 15:53 ` [PATCH v5 6/8] ARM: soft_restart: disable the outer L2 when the last CPU is going down Will Deacon
2011-11-08 15:53 ` [PATCH v5 7/8] ARM: stop: execute platform callback from cpu_stop code Will Deacon
2011-11-08 15:53 ` [PATCH v5 8/8] ARM: kexec: use soft_restart for branching to the reboot buffer Will Deacon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).