[PATCH v12 05/16] arm64: Add back cpu_reset routines
Marc Zyngier
marc.zyngier at arm.com
Mon Nov 30 02:40:27 PST 2015
On Mon, 30 Nov 2015 10:58:43 +0530
Pratyush Anand <panand at redhat.com> wrote:
> On 27/11/2015:02:19:37 PM, Marc Zyngier wrote:
> > On 24/11/15 22:25, Geoff Levand wrote:
> > > +ENTRY(cpu_soft_restart)
> > > + mov x18, x0 // cpu_reset
> > > + mov x0, x1 // el2_switch
> > > + mov x1, x2 // entry
> > > + mov x2, x3 // arg0
> > > + mov x3, x4 // arg1
> > > + ret x18
> > > +ENDPROC(cpu_soft_restart)
> >
> > Grepping through the tree, I can only find a single use of
> > cpu_soft_restart, with cpu_reset as its first parameter.
> >
> > Why do we need this indirection? Having
>
> It is needed because we need to execute cpu_reset() in physical address space.
>
> >
> > void cpu_soft_restart(el2_switch, entry, arg0, arg1);
> >
> > should be enough...
>
> We can do with only cpu_soft_restart(), but then a function pointer to __pa() of
> it need to be called. May be current approach is more cleaner.
All that can be solved in C, and mostly at compile time. Using an
assembler trampoline is complicating things for no good reason:
diff --git a/arch/arm64/kernel/cpu-reset.S b/arch/arm64/kernel/cpu-reset.S
index 0423f27..099f6f2 100644
--- a/arch/arm64/kernel/cpu-reset.S
+++ b/arch/arm64/kernel/cpu-reset.S
@@ -28,27 +28,7 @@
.align 5
/*
- * cpu_soft_restart(cpu_reset, el2_switch, entry, arg0, arg1) - Perform a cpu
- * soft reset.
- *
- * @cpu_reset: Physical address of the cpu_reset routine.
- * @el2_switch: Flag to indicate a swich to EL2 is needed, passed to cpu_reset.
- * @entry: Location to jump to for soft reset, passed to cpu_reset.
- * arg0: First argument passed to @entry.
- * arg1: Second argument passed to @entry.
- */
-
-ENTRY(cpu_soft_restart)
- mov x18, x0 // cpu_reset
- mov x0, x1 // el2_switch
- mov x1, x2 // entry
- mov x2, x3 // arg0
- mov x3, x4 // arg1
- ret x18
-ENDPROC(cpu_soft_restart)
-
-/*
- * cpu_reset(el2_switch, entry, arg0, arg1) - Helper for cpu_soft_restart.
+ * __cpu_soft_restart(el2_switch, entry, arg0, arg1) - Helper for cpu_soft_restart.
*
* @el2_switch: Flag to indicate a swich to EL2 is needed.
* @entry: Location to jump to for soft reset.
@@ -60,7 +40,7 @@ ENDPROC(cpu_soft_restart)
* flat identity mapping.
*/
-ENTRY(cpu_reset)
+ENTRY(__cpu_soft_restart)
/* Clear sctlr_el1 flags. */
mrs x12, sctlr_el1
ldr x13, =SCTLR_ELx_FLAGS
@@ -79,6 +59,6 @@ ENTRY(cpu_reset)
mov x0, x2 // arg0
mov x1, x3 // arg1
ret x18
-ENDPROC(cpu_reset)
+ENDPROC(__cpu_soft_restart)
.popsection
diff --git a/arch/arm64/kernel/cpu-reset.h b/arch/arm64/kernel/cpu-reset.h
index 79816b6..df88892 100644
--- a/arch/arm64/kernel/cpu-reset.h
+++ b/arch/arm64/kernel/cpu-reset.h
@@ -13,10 +13,17 @@
#include <asm/virt.h>
-void __attribute__((noreturn)) cpu_reset(unsigned long el2_switch,
- unsigned long entry, unsigned long arg0, unsigned long arg1);
-void __attribute__((noreturn)) cpu_soft_restart(phys_addr_t cpu_reset,
- unsigned long el2_switch, unsigned long entry, unsigned long arg0,
- unsigned long arg1);
+void __cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
+ unsigned long arg0, unsigned long arg1);
+
+static inline
+void __noreturn cpu_soft_restart(unsigned long el2_switch, unsigned long entry,
+ unsigned long arg0, unsigned long arg1)
+{
+ typeof(__cpu_soft_restart) *restart;
+ restart = (void *)virt_to_phys(__cpu_soft_restart);
+ restart(el2_switch, entry, arg0, arg1);
+ unreachable();
+}
#endif
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index 482aae7..ecdf822 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -210,8 +210,7 @@ void machine_kexec(struct kimage *kimage)
* relocation is complete.
*/
- cpu_soft_restart(virt_to_phys(cpu_reset),
- in_crash_kexec ? 0 : is_hyp_mode_available(),
+ cpu_soft_restart(in_crash_kexec ? 0 : is_hyp_mode_available(),
reboot_code_buffer_phys, kimage->head, kimage_start);
BUG(); /* Should never get here. */
Simpler, more readable, no pointless register shifting, smaller idmap
footprint.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
More information about the linux-arm-kernel
mailing list