* [PATCH v6 1/5] ARM: lib: add call_with_stack function for safely changing stack
2011-11-16 17:54 [PATCH v6 0/5] kexec fixes and soft restart code Will Deacon
@ 2011-11-16 17:54 ` Will Deacon
2011-11-22 13:42 ` Catalin Marinas
2011-11-16 17:54 ` [PATCH v6 2/5] ARM: reset: implement soft_restart for jumping to a physical address Will Deacon
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Will Deacon @ 2011-11-16 17:54 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] 13+ messages in thread
* [PATCH v6 1/5] ARM: lib: add call_with_stack function for safely changing stack
2011-11-16 17:54 ` [PATCH v6 1/5] ARM: lib: add call_with_stack function for safely changing stack Will Deacon
@ 2011-11-22 13:42 ` Catalin Marinas
0 siblings, 0 replies; 13+ messages in thread
From: Catalin Marinas @ 2011-11-22 13:42 UTC (permalink / raw)
To: linux-arm-kernel
On 16 November 2011 17:54, Will Deacon <will.deacon@arm.com> wrote:
> 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>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 2/5] ARM: reset: implement soft_restart for jumping to a physical address
2011-11-16 17:54 [PATCH v6 0/5] kexec fixes and soft restart code Will Deacon
2011-11-16 17:54 ` [PATCH v6 1/5] ARM: lib: add call_with_stack function for safely changing stack Will Deacon
@ 2011-11-16 17:54 ` Will Deacon
2011-11-22 13:41 ` Catalin Marinas
2011-11-16 17:54 ` [PATCH v6 3/5] ARM: soft_restart: disable the outer L2 when the last CPU is going down Will Deacon
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Will Deacon @ 2011-11-16 17:54 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] 13+ messages in thread
* [PATCH v6 2/5] ARM: reset: implement soft_restart for jumping to a physical address
2011-11-16 17:54 ` [PATCH v6 2/5] ARM: reset: implement soft_restart for jumping to a physical address Will Deacon
@ 2011-11-22 13:41 ` Catalin Marinas
2011-11-22 13:54 ` Dave Martin
2011-11-22 14:15 ` Will Deacon
0 siblings, 2 replies; 13+ messages in thread
From: Catalin Marinas @ 2011-11-22 13:41 UTC (permalink / raw)
To: linux-arm-kernel
On 16 November 2011 17:54, Will Deacon <will.deacon@arm.com> wrote:
> 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];
Just for ABI stack alignment requirements, do we get the right
alignment of this array in memory?
> +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();
A few unnecessary comment changes :) (it's not clear in the Linux
coding style but many single-line comments don't have a full-stop.
> ? ? ? ?/* 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;
We could use ARRAY_SIZE() here and just avoid defining SOFT_RESTART_STACK_WORDS.
--
Catalin
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 2/5] ARM: reset: implement soft_restart for jumping to a physical address
2011-11-22 13:41 ` Catalin Marinas
@ 2011-11-22 13:54 ` Dave Martin
2011-11-22 14:15 ` Will Deacon
1 sibling, 0 replies; 13+ messages in thread
From: Dave Martin @ 2011-11-22 13:54 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 22, 2011 at 01:41:24PM +0000, Catalin Marinas wrote:
> On 16 November 2011 17:54, Will Deacon <will.deacon@arm.com> wrote:
> > 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];
>
> Just for ABI stack alignment requirements, do we get the right
> alignment of this array in memory?
Could we fix that by making it a u64 array?
In architecture versions where it matters, the compiler should also 64-
bit align such an array.
Of we're paranoid, we could align the initial stack pointer explicitly.
Cheers
---Dave
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 2/5] ARM: reset: implement soft_restart for jumping to a physical address
2011-11-22 13:41 ` Catalin Marinas
2011-11-22 13:54 ` Dave Martin
@ 2011-11-22 14:15 ` Will Deacon
1 sibling, 0 replies; 13+ messages in thread
From: Will Deacon @ 2011-11-22 14:15 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 22, 2011 at 01:41:24PM +0000, Catalin Marinas wrote:
> On 16 November 2011 17:54, Will Deacon <will.deacon@arm.com> wrote:
> > 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];
>
> Just for ABI stack alignment requirements, do we get the right
> alignment of this array in memory?
I'll make it u64[16] instead then (as per Dave's suggestion).
> > +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();
>
> A few unnecessary comment changes :) (it's not clear in the Linux
> coding style but many single-line comments don't have a full-stop.
I think the change to the setup_mm_for_reboot comment is valid, but I'll
leave the other guys without full stops, even if it annoys me unjustifiably
:)
> > +void soft_restart(unsigned long addr)
> > +{
> > + ? ? ? u32 *stack = soft_restart_stack + SOFT_RESTART_STACK_WORDS;
>
> We could use ARRAY_SIZE() here and just avoid defining SOFT_RESTART_STACK_WORDS.
Sure.
Thanks for the review, I'll post a v2 of this after Russell has stablised the
reset patches.
Will
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 3/5] ARM: soft_restart: disable the outer L2 when the last CPU is going down
2011-11-16 17:54 [PATCH v6 0/5] kexec fixes and soft restart code Will Deacon
2011-11-16 17:54 ` [PATCH v6 1/5] ARM: lib: add call_with_stack function for safely changing stack Will Deacon
2011-11-16 17:54 ` [PATCH v6 2/5] ARM: reset: implement soft_restart for jumping to a physical address Will Deacon
@ 2011-11-16 17:54 ` Will Deacon
2011-11-16 18:20 ` Stephen Boyd
2011-11-16 17:54 ` [PATCH v6 4/5] ARM: stop: execute platform callback from cpu_stop code Will Deacon
2011-11-16 17:54 ` [PATCH v6 5/5] ARM: kexec: use soft_restart for branching to the reboot buffer Will Deacon
4 siblings, 1 reply; 13+ messages in thread
From: Will Deacon @ 2011-11-16 17:54 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] 13+ messages in thread
* [PATCH v6 3/5] ARM: soft_restart: disable the outer L2 when the last CPU is going down
2011-11-16 17:54 ` [PATCH v6 3/5] ARM: soft_restart: disable the outer L2 when the last CPU is going down Will Deacon
@ 2011-11-16 18:20 ` Stephen Boyd
2011-11-16 18:30 ` Will Deacon
0 siblings, 1 reply; 13+ messages in thread
From: Stephen Boyd @ 2011-11-16 18:20 UTC (permalink / raw)
To: linux-arm-kernel
On 11/16/11 09:54, Will Deacon wrote:
> 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();
> +
When does this code execute on another cpu? My understanding is that
soft_restart() is only called on one CPU so I would think checking the
number of online cpus isn't necessary.
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 3/5] ARM: soft_restart: disable the outer L2 when the last CPU is going down
2011-11-16 18:20 ` Stephen Boyd
@ 2011-11-16 18:30 ` Will Deacon
2011-11-16 21:59 ` Stephen Boyd
0 siblings, 1 reply; 13+ messages in thread
From: Will Deacon @ 2011-11-16 18:30 UTC (permalink / raw)
To: linux-arm-kernel
Hi Stephen,
On Wed, Nov 16, 2011 at 06:20:08PM +0000, Stephen Boyd wrote:
> On 11/16/11 09:54, Will Deacon wrote:
> > 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();
> > +
>
> When does this code execute on another cpu? My understanding is that
> soft_restart() is only called on one CPU so I would think checking the
> number of online cpus isn't necessary.
Currently, yes, this only executes on one CPU. The code is there in case
we want to implement a SMP kexec solution that doesn't require CPU hotplug
at some point.
I suppose you could end up in a situation where the reset path leads to a
soft reboot and you haven't dealt with the secondaries at this point, but
then you have bigger problems to worry about (namely that whatever you jump
to after turning the MMU off needs to deal with the secondaries somehow).
Are you seeing problems with this?
Cheers,
Will
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 3/5] ARM: soft_restart: disable the outer L2 when the last CPU is going down
2011-11-16 18:30 ` Will Deacon
@ 2011-11-16 21:59 ` Stephen Boyd
0 siblings, 0 replies; 13+ messages in thread
From: Stephen Boyd @ 2011-11-16 21:59 UTC (permalink / raw)
To: linux-arm-kernel
On 11/16/11 10:30, Will Deacon wrote:
> Hi Stephen,
>
> On Wed, Nov 16, 2011 at 06:20:08PM +0000, Stephen Boyd wrote:
>> When does this code execute on another cpu? My understanding is that
>> soft_restart() is only called on one CPU so I would think checking the
>> number of online cpus isn't necessary.
> Currently, yes, this only executes on one CPU. The code is there in case
> we want to implement a SMP kexec solution that doesn't require CPU hotplug
> at some point.
>
> I suppose you could end up in a situation where the reset path leads to a
> soft reboot and you haven't dealt with the secondaries at this point, but
> then you have bigger problems to worry about (namely that whatever you jump
> to after turning the MMU off needs to deal with the secondaries somehow).
Fair enough. I was just curious.
--
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v6 4/5] ARM: stop: execute platform callback from cpu_stop code
2011-11-16 17:54 [PATCH v6 0/5] kexec fixes and soft restart code Will Deacon
` (2 preceding siblings ...)
2011-11-16 17:54 ` [PATCH v6 3/5] ARM: soft_restart: disable the outer L2 when the last CPU is going down Will Deacon
@ 2011-11-16 17:54 ` Will Deacon
2011-11-16 17:54 ` [PATCH v6 5/5] ARM: kexec: use soft_restart for branching to the reboot buffer Will Deacon
4 siblings, 0 replies; 13+ messages in thread
From: Will Deacon @ 2011-11-16 17:54 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] 13+ messages in thread
* [PATCH v6 5/5] ARM: kexec: use soft_restart for branching to the reboot buffer
2011-11-16 17:54 [PATCH v6 0/5] kexec fixes and soft restart code Will Deacon
` (3 preceding siblings ...)
2011-11-16 17:54 ` [PATCH v6 4/5] ARM: stop: execute platform callback from cpu_stop code Will Deacon
@ 2011-11-16 17:54 ` Will Deacon
4 siblings, 0 replies; 13+ messages in thread
From: Will Deacon @ 2011-11-16 17:54 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] 13+ messages in thread