From: geoff@infradead.org (Geoff Levand)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] Arm64: convert soft_restart() to assembly code
Date: Fri, 15 Aug 2014 10:20:21 -0700 [thread overview]
Message-ID: <1408123221.22761.38.camel@smoke> (raw)
In-Reply-To: <1407847365-10873-1-git-send-email-achandran@mvista.com>
Hi Arun,
On Tue, 2014-08-12 at 18:12 +0530, Arun Chandran wrote:
> soft_restart() will fail on arm64 systems that does not
> quarantee the flushing of cache to PoC with flush_cache_all().
>
> soft_restart(addr)
> {
> push_to_stack(addr);
>
> Do mm setup for restart;
> Flush&turnoff D-cache;
>
> pop_from_stack(addr); --> fails here as addr is not at PoC
> cpu_reset(addr) --> Jumps to invalid address
> }
For the cpu-ops shutdown I'm working on I need a call to move the
secondary processors to an identity mapped spin loop after the identity
map is enabled. I want to do this in C code, so it needs to happen
after the identity map is enabled, and before the dcache is disabled.
I think to do this we can keep the existing soft_restart(addr) routine
with something like this:
void soft_restart(unsigned long addr)
{
setup_mm_for_reboot();
#if defined(CONFIG_SMP)
smp_secondary_shutdown();
#endif
cpu_soft_restart(addr);
/* Should never get here */
BUG();
}
>
> So convert the whole code to assembly to make sure that addr
> is not pushed to stack.
>
> Signed-off-by: Arun Chandran <achandran@mvista.com>
> ---
> arch/arm64/include/asm/proc-fns.h | 1 +
> arch/arm64/include/asm/system_misc.h | 1 -
> arch/arm64/kernel/process.c | 38 ++--------------------------------
> arch/arm64/mm/proc.S | 34 ++++++++++++++++++++++++++++++
> 4 files changed, 37 insertions(+), 37 deletions(-)
>
> diff --git a/arch/arm64/include/asm/proc-fns.h b/arch/arm64/include/asm/proc-fns.h
> index 0c657bb..e18d5d0 100644
> --- a/arch/arm64/include/asm/proc-fns.h
> +++ b/arch/arm64/include/asm/proc-fns.h
> @@ -32,6 +32,7 @@ extern void cpu_cache_off(void);
> extern void cpu_do_idle(void);
> extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
> extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
> +extern void cpu_soft_restart(unsigned long addr) __attribute__((noreturn));
Function prototypes are never definitions, so remove this 'extern'
keyword. checkpatch should have warned about this. If it did not,
report it to the checkpatch maintainers.
> extern void cpu_do_suspend(struct cpu_suspend_ctx *ptr);
> extern u64 cpu_do_resume(phys_addr_t ptr, u64 idmap_ttbr);
>
> diff --git a/arch/arm64/include/asm/system_misc.h b/arch/arm64/include/asm/system_misc.h
> index 7a18fab..659fbf5 100644
> --- a/arch/arm64/include/asm/system_misc.h
> +++ b/arch/arm64/include/asm/system_misc.h
> @@ -41,7 +41,6 @@ struct mm_struct;
> extern void show_pte(struct mm_struct *mm, unsigned long addr);
> extern void __show_regs(struct pt_regs *);
>
> -void soft_restart(unsigned long);
> extern void (*arm_pm_restart)(enum reboot_mode reboot_mode, const char *cmd);
>
> #define UDBG_UNDEFINED (1 << 0)
> diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
> index 1309d64..3ca1ade 100644
> --- a/arch/arm64/kernel/process.c
> +++ b/arch/arm64/kernel/process.c
> @@ -57,40 +57,6 @@ unsigned long __stack_chk_guard __read_mostly;
> EXPORT_SYMBOL(__stack_chk_guard);
> #endif
>
> -static void setup_restart(void)
> -{
> - /*
> - * 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.
> - */
> - setup_mm_for_reboot();
> -
> - /* Clean and invalidate caches */
> - flush_cache_all();
> -
> - /* Turn D-cache off */
> - cpu_cache_off();
> -
> - /* Push out any further dirty data, and ensure cache is empty */
> - flush_cache_all();
> -}
> -
> -void soft_restart(unsigned long addr)
> -{
> - typedef void (*phys_reset_t)(unsigned long);
> - phys_reset_t phys_reset;
> -
> - setup_restart();
> -
> - /* Switch to the identity mapping */
> - phys_reset = (phys_reset_t)virt_to_phys(cpu_reset);
> - phys_reset(addr);
> -
> - /* Should never get here */
> - BUG();
> -}
> -
> /*
> * Function pointers to optional machine specific functions
> */
> @@ -162,8 +128,8 @@ void machine_power_off(void)
>
> /*
> * Restart requires that the secondary CPUs stop performing any activity
> - * while the primary CPU resets the system. Systems with a single CPU can
> - * use soft_restart() as their machine descriptor's .restart hook, since that
> + * while the primary CPU resets the system. Systems with a single CPU can use
> + * cpu_soft_restart() as their machine descriptor's .restart hook, since that
> * will cause the only available CPU to reset. Systems with multiple CPUs must
> * provide a HW restart implementation, to ensure that all CPUs reset at once.
> * This is required so that any code running after reset on the primary CPU
> diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S
> index 7736779..a7c3fce 100644
> --- a/arch/arm64/mm/proc.S
> +++ b/arch/arm64/mm/proc.S
> @@ -76,6 +76,40 @@ ENTRY(cpu_reset)
> ret x0
> ENDPROC(cpu_reset)
>
> + .align 3
> +1: .quad memstart_addr
> +
> +ENTRY(cpu_soft_restart)
> + adr x1, cpu_reset
> + adr x2, 1b
> +
> + /* virt_to_phys(cpu_reset) */
> + ldr x3, [x2]
> + ldr x3, [x3]
> + mov x4, #1
> + lsl x4, x4, #(VA_BITS - 1)
> + add x1, x1, x4
> + add x1, x1, x3
> +
> + /* Save it; We can't use stack as it is going to run with caches OFF */
> + mov x19, x0
> + mov x20, x1
> +
> + bl setup_mm_for_reboot
> +
> + bl flush_cache_all
> + /* Turn D-cache off */
> + bl cpu_cache_off
> + /* Push out any further dirty data, and ensure cache is empty */
> + bl flush_cache_all
It would be nice to have some blank lines above the comments. Same
below.
> + mov x0, x19
> +
> + br x20
> + /* It should never come back */
> + bl panic
> +ENDPROC(cpu_soft_restart)
> +
> /*
> * cpu_do_idle()
> *
next prev parent reply other threads:[~2014-08-15 17:20 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-08-12 12:42 [PATCH] Arm64: convert soft_restart() to assembly code Arun Chandran
2014-08-12 14:05 ` Mark Rutland
2014-08-13 4:57 ` Arun Chandran
2014-08-13 7:43 ` [PATCH] Arm64: convert part of soft_restart() to assembly Arun Chandran
2014-08-13 10:58 ` Mark Rutland
2014-08-13 11:17 ` Arun Chandran
2014-08-13 11:21 ` Mark Rutland
2014-08-15 17:20 ` Geoff Levand [this message]
2014-08-15 18:21 ` [PATCH] Arm64: convert soft_restart() to assembly code Mark Rutland
2014-08-15 18:53 ` Geoff Levand
2014-08-18 16:02 ` Mark Rutland
2014-08-18 17:33 ` Christoffer Dall
2014-08-19 1:10 ` Geoff Levand
2014-08-20 10:48 ` Mark Rutland
2014-08-20 10:54 ` Christoffer Dall
2014-08-20 11:21 ` Mark Rutland
2014-08-25 11:04 ` Arun Chandran
2014-08-25 14:14 ` Arun Chandran
2014-08-26 15:22 ` Mark Rutland
2014-08-26 16:14 ` Arun Chandran
2014-08-18 6:43 ` Arun Chandran
2014-08-19 9:04 ` Arun Chandran
2014-08-20 10:28 ` Arun Chandran
2014-08-20 10:54 ` Mark Rutland
2014-08-20 13:57 ` Arun Chandran
2014-08-20 14:16 ` Mark Rutland
2014-08-21 13:34 ` Arun Chandran
2014-08-21 14:31 ` Mark Rutland
2014-08-22 11:11 ` Arun Chandran
2014-08-22 13:15 ` Mark Rutland
2014-08-23 19:50 ` Arun Chandran
2014-08-26 13:00 ` Arun Chandran
2014-08-26 14:08 ` Mark Rutland
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1408123221.22761.38.camel@smoke \
--to=geoff@infradead.org \
--cc=linux-arm-kernel@lists.infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox