[PATCH 05/17] arm64: entry: add a call_on_stack helper

Mark Rutland mark.rutland at arm.com
Tue Jan 14 10:24:22 PST 2020


On Thu, Jan 09, 2020 at 01:30:02PM +0530, Anshuman Khandual wrote:
> 
> 
> On 01/09/2020 12:26 AM, Mark Rutland wrote:
> > In some cases, we want to call a function from C code, using an
> > alternative stack. Add a helper that we can use in such cases.
> > 
> > Signed-off-by: Mark Rutland <mark.rutland at arm.com>
> > Cc: Catalin Marinas <catalin.marinas at arm.com>
> > Cc: James Morse <james.morse at arm.com>
> > Cc: Will Deacon <will at kernel.org>
> > ---
> >  arch/arm64/include/asm/exception.h |  2 ++
> >  arch/arm64/kernel/entry.S          | 21 +++++++++++++++++++++
> >  2 files changed, 23 insertions(+)
> > 
> > diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h
> > index b87c6e276ab1..a49038fa4faf 100644
> > --- a/arch/arm64/include/asm/exception.h
> > +++ b/arch/arm64/include/asm/exception.h
> > @@ -31,6 +31,8 @@ static inline u32 disr_to_esr(u64 disr)
> >  	return esr;
> >  }
> >  
> > +asmlinkage void call_on_stack(struct pt_regs *, void (*)(struct pt_regs *),
> > +			      unsigned long);
> >  asmlinkage void enter_from_user_mode(void);
> >  void do_mem_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
> >  void do_sp_pc_abort(unsigned long addr, unsigned int esr, struct pt_regs *regs);
> > diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
> > index 53ce1877a4aa..184313c773ea 100644
> > --- a/arch/arm64/kernel/entry.S
> > +++ b/arch/arm64/kernel/entry.S
> > @@ -901,6 +901,27 @@ ENTRY(ret_from_fork)
> >  ENDPROC(ret_from_fork)
> >  NOKPROBE(ret_from_fork)
> >  
> > +/*
> > + * x0 = argument to function
> 
> A small nit. Though the definition here itself does not limit the
> argument type, it might worth to mention that to be struct pt_regs
> per the previous declaration.
> 

True.

To make this clearer, I've given the C prototype instead, as we do for the
SMCCC wrappers:

/*
 * void call_on_stack(struct pt_regs *regs,
 *                    void (*func)(struct pt_regs *),
 *                    unsigned long new_sp)
 *
 * Calls func(regs) using new_sp as the initial stack pointer.
 */

> > +ENTRY(call_on_stack)
> > +	/* Create a frame record to save our LR and SP (implicit in FP) */
> > +	stp	x29, x30, [sp, #-16]!
> > +	mov	x29, sp
> > +
> > +	/* Move to the new stack and call the function there */
> > +	mov	sp, x2
> > +	blr	x1
> > +
> > +	/* Restore SP from the FP, FP and LR from the record, and return */
> > +	mov	sp, x29
> > +	ldp	x29, x30, [sp], #16
> > +	ret
> > +ENDPROC(call_on_stack)
> > +NOKPROBE(call_on_stack)
> > +
> >  #ifdef CONFIG_ARM_SDE_INTERFACE
> >  
> >  #include <asm/sdei.h>
> > 
> 
> Reviewed-by: Anshuman Khandual <anshuman.khandual at arm.com>

Thanks!

Mark.



More information about the linux-arm-kernel mailing list