From: Scott Wood <scottwood@freescale•com>
To: JiveTalkin <aijazbaig1@gmail•com>
Cc: linuxppc-dev@ozlabs•org
Subject: Re: ABI defined register usage within function calls
Date: Fri, 19 Jul 2013 18:49:13 -0500 [thread overview]
Message-ID: <1374277753.5357.36@snotra> (raw)
In-Reply-To: <1373464479578-73565.post@n7.nabble.com> (from aijazbaig1@gmail.com on Wed Jul 10 08:54:39 2013)
On 07/10/2013 08:54:39 AM, JiveTalkin wrote:
> Hello.
>=20
> I would like to monitor the value of one of the parameters (within =20
> the stack
> frame) that have been passed as part of a context switch (from process
> context to interrupt context).
I don't understand this... What specifically do you mean by "interrupt =20
context"? Do you mean syscall context? Syscall parameters are passed =20
in registers, not in the stack frame.
> START_EXCEPTION does nothing more than align us to a word (32bit) =20
> boundary
> (obviously for performance reasons). What I need to understand is the
> NORMAL_EXCEPTION_PROLOG. I reproduce it here:
>=20
>=20
> First thing it does it saves r10, r11 and r1(containing the Stack =20
> pointer)
> into the scratch registers 0,1 and 2 respectively. Correct me if I am =20
> wrong,
> but as per the older EABI, isn't it recommended for the OS to load =20
> SPRG0
> with the start address of an area of memory (the stack top) to be =20
> used by
> the 1st level interrupt handler? Or can these registers be used =20
> anyway we
> see fit?
Linux doesn't use EABI -- and in any case, I don't see "SPRG" anywhere =20
in the EABI document, and no relevant mention in the SVR4 ABI. It's up =20
to the OS how SPRGs are used.
> Moving on, it seems the kernel folks have decided to use SPRNG3 to =20
> point to
> the currently running process's thread_struct structure. Is there a =20
> document
> which recommends so or was it an unanimous decision taken during early
> development? Just curios.
>=20
> Then we go on to check the value of the PR bit from the MSR which has =20
> been
> copied by the hardware to SRR1. So here we are actually checking =20
> whether the
> exception occurred when the machine was in user space or kernel space =20
> right?
>=20
> So once we determine that we've originated in the userspace, as is =20
> the case
> for SystemCall, we are apparently updating r1 (stack pointer) with =20
> (r1 +
> THREAD) - THREAD_INFO. Or is it actually r1 + (THREAD_INFO-THREAD)?
Neither; it's the address stored at r10 + (THREAD_INFO-THREAD).
> In
> either case, how does this take us to the top of the kernel stack, is
> something I am unable to get my head around. May be I do not know =20
> some basic
> concepts here, which is why this is looking strange to me. Could =20
> someone
> please elaborate? Some ASCII art would be really nice here.
r10 was loaded from SPRG3, and thus points to the thread struct. The =20
thread struct (a.k.a. SPRG3, a.k.a. THREAD) and a pointer to the stack =20
are both contained within the task_struct (a.k.a. current). At the =20
bottom of the stack is the thread_info struct, which is why =20
current->stack is called THREAD_INFO in asm-offsets.c. Since THREAD =20
and THREAD_INFO are both in the same struct, we can get THREAD_INFO by =20
adding the difference in offsets to the THREAD pointer that we got from =20
SPRG3.
That gets us to the bottom of the stack; ALLOC_STACK_FRAME() adds the =20
size of the stack so that we point to the top and are ready to create a =20
frame. It's a confusing name since it doesn't actually allocate a =20
frame; that happens in the "subi" instruction that follows.
> We then allocate an exception frame to hold the activation record =20
> (stack
> frame) for the caller. Into this frame, we save the CR. We also save =20
> R12 and
> R9 (as they are volatile registers and the caller must save them =20
> before
> calling a function). We then retrieve the earlier stored values of =20
> r10 and
> r11 and store them into the frame (using r11 as an anchor as it now =20
> points
> to the top of the stack frame). Then we store the link register.
>=20
> We retrieve previously stored r1 (previous frame's stack pointer =20
> isn't it?),
> retrieve SRR0 (which includes the return address and in this case, the
> address of the next instruction in case of a syscall from userspace,
> correct?). If we have already stored the previous value of R1 then =20
> what are
> we doing with this:
>=20
>=20
>=20
What are we doing with what?
The previous value of r1 is still in r1. At this point r11 holds the =20
new stack pointer. Did you misread the "stw r1, GPR1(r11)" as a load?
-Scott=
prev parent reply other threads:[~2013-07-19 23:49 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-07-10 13:54 ABI defined register usage within function calls JiveTalkin
2013-07-12 11:38 ` JiveTalkin
2013-07-14 22:19 ` Benjamin Herrenschmidt
2013-07-16 0:37 ` JiveTalkin
2013-07-19 23:49 ` Scott Wood [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=1374277753.5357.36@snotra \
--to=scottwood@freescale$(echo .)com \
--cc=aijazbaig1@gmail$(echo .)com \
--cc=linuxppc-dev@ozlabs$(echo .)org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
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