linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: cov@codeaurora.org (Christopher Covington)
To: linux-arm-kernel@lists.infradead.org
Subject: where/how arm start first jump from svc to user in kernel
Date: Tue, 21 Oct 2014 18:00:06 -0400	[thread overview]
Message-ID: <5446D766.4010004@codeaurora.org> (raw)
In-Reply-To: <CAOVJa8Fa25W=oNHridmq+zZCRWRgKZtH+Ykt=w_YSwcaqpaNhA@mail.gmail.com>

On 10/21/2014 07:37 AM, vichy wrote:
> hi Catalin:
>> As a quick answer, it's ret_to_user (or ret_slow_syscall to be more
>> precise) in arch/arm/kernel/entry-common.S.
>>
>> How it gets there is a bit more complicated. The initial kernel call
>> path:
>>
>> start_kernel()
>>   rest_init()
>>     kernel_thread(kernel_init)
>>
>> kernel_thread() creates a new thread which executes the kernel_init()
>> function. After the multitude of calls that kernel_thread() -> do_fork()
>> does, it eventually calls copy_thread() which sets the
>> thread->cpu_context.pc to ret_from_fork and the actual address of
>> kernel_init in thread->cpu_context.r5. When the kernel eventually
>> switches to the new kernel thread, it will jump to
>> thread->cpu_context.pc which is ret_from_fork (see __switch_to in
>> arch/arm/kernel/entry-armv.S). ret_from_fork() branches to kernel_init()
>> but sets the return address (LR) to label 1 in ret_from_fork.
>>
>> After kernel_init() does its work, it eventually calls
>> run_init_process() which invokes do_execve() and eventually
>> load_elf_binary(). If the ELF binary was successfully loaded, this
>> function calls start_thread() with the ELF entry point. The
>> start_thread() function populates the pt_regs structure on the stack so
>> that regs->ARM_pc points to the ELF entry point and regs->ARM_cpsr has
>> the user mode bits set.
> Many thanks for your kind and detail explanation.
> 
>>
>> Going back to kernel_init(), if run_init_process() was successful, it
>> returns to label 1 in ret_from_fork which branches to ret_slow_syscall
>> which eventually returns to user space via the restore_user_regs macro
>> (in arch/arm/kernel/entry-header.S).
> 
> Below is excerpted from arch/arm/kernel/entry-header.S
> 
>         .macro  restore_user_regs, fast = 0, offset = 0
>         ldr     r1, [sp, #\offset + S_PSR]      @ get calling cpsr
>         ldr     lr, [sp, #\offset + S_PC]!      @ get pc
>         msr     spsr_cxsf, r1                   @ save in spsr_svc
>         ..........
>         add     sp, sp, #S_FRAME_SIZE - S_PC
>         movs    pc, lr                          @ return & move
> spsr_svc into cpsr
>         .endm
> 
> so before armv8 architecture and kernel switch to user mode (arm svn-> user),
> we first put the cpsr, the mode we want to jump to, in current spsr.
> Then update pc counter to where the ELF entry, right?
> 
> BTW, in armv8, aarch64, arch/arm64/entry.S, kernel_exit,
> (if I look at the right place.)
> 
> .macro  kernel_exit, el, ret = 0
>         ..............................
>         msr     elr_el1, x21                    // set up the return data
>         msr     spsr_el1, x22
>         .if     \el == 0
>         msr     sp_el0, x23
>         .endif
>         pop     x10, x11
>         ............................
>         ldr     lr, [sp], #S_FRAME_SIZE - S_LR  // load LR and restore SP
>         eret                                    // return to kernel
> .endm
> 
> Is there any special reason we use eret in v8 instead of modify pc in v7?
> I have looked arm v8 architecture reference menu but get no explanation so far.

"In AArch64 state, the PC is not a general purpose register and you cannot
access it explicitly."

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0801a/BABGHBJC.html

Chris

-- 
Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

      parent reply	other threads:[~2014-10-21 22:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-15  3:37 where/how arm start first jump from svc to user in kernel vichy
2014-10-15 16:20 ` Catalin Marinas
2014-10-21 11:37   ` vichy
2014-10-21 12:41     ` Mark Rutland
2014-10-21 13:49       ` vichy
2014-10-21 16:15         ` Mark Rutland
2014-10-27 13:32           ` vichy
2014-10-27 14:25             ` Mark Rutland
2014-10-27 17:41               ` vichy
2014-10-29 10:43                 ` Mark Rutland
2014-10-21 22:00     ` Christopher Covington [this message]

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=5446D766.4010004@codeaurora.org \
    --to=cov@codeaurora.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;
as well as URLs for NNTP newsgroup(s).