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
prev 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).