All of lore.kernel.org
 help / color / mirror / Atom feed
* ABI defined register usage within function calls
@ 2013-07-10 13:54 JiveTalkin
  2013-07-12 11:38 ` JiveTalkin
  2013-07-19 23:49 ` Scott Wood
  0 siblings, 2 replies; 5+ messages in thread
From: JiveTalkin @ 2013-07-10 13:54 UTC (permalink / raw)
  To: linuxppc-dev

Hello.

I would like to monitor the value of one of the parameters (within the stack
frame) that have been passed as part of a context switch (from process
context to interrupt context). Hence I have been looking at the call flow of
a typical exception (which can be thought of as a synchronous exception
isn't it?).

Since e500 is a 32bit processor, I have been looking at entry_32.S which
contains the context switching code which is the entry point for the
exception handling. As an example, I am looking at how system calls are
handled in the PowerPC architecture in general and e500 in particular. Since
in case of BookE, the MMU is always ON, we are never in real mode and the
interrupt vector can be at arbitrary virtual address.

This defines how a Syscall is going to handled, as per head_fsl_booke.S:
/* System Call Interrupt */
START_EXCEPTION(SystemCall)
NORMAL_EXCEPTION_PROLOG
EXC_XFER_EE_LITE(0x0c00, DoSyscall)

START_EXCEPTION does nothing more than align us to a word (32bit) boundary
(obviously for performance reasons). What I need to understand is the
NORMAL_EXCEPTION_PROLOG. I reproduce it here:


First thing it does it saves r10, r11 and r1(containing the Stack pointer)
into the scratch registers 0,1 and 2 respectively. Correct me if I am wrong,
but as per the older EABI, isn't it recommended for the OS to load SPRG0
with the start address of an area of memory (the stack top) to be used by
the 1st level interrupt handler? Or can these registers be used anyway we
see fit?

Moving on, it seems the kernel folks have decided to use SPRNG3 to point to
the currently running process's thread_struct structure. Is there a document
which recommends so or was it an unanimous decision taken during early
development? Just curios.

Then we go on to check the value of the PR bit from the MSR which has been
copied by the hardware to SRR1. So here we are actually checking whether the
exception occurred when the machine was in user space or kernel space right? 

So once we determine that we've originated in the userspace, as is the case
for SystemCall, we are apparently updating r1 (stack pointer) with (r1 +
THREAD) - THREAD_INFO. Or is it actually r1 + (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 some basic
concepts here, which is why this is looking strange to me. Could someone
please elaborate? Some ASCII art would be really nice here.

We then allocate an exception frame to hold the activation record (stack
frame) for the caller. Into this frame, we save the CR. We also save R12 and
R9 (as they are volatile registers and the caller must save them before
calling a function). We then retrieve the earlier stored values of r10 and
r11 and store them into the frame (using r11 as an anchor as it now points
to the top of the stack frame). Then we store the link register.

We retrieve previously stored r1 (previous frame's stack pointer 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 what are
we doing with this:



Please correct me if my understanding is incorrect somewhere in addition to
some of the doubts I have raised with this. I appreciate your help.




--
View this message in context: http://linuxppc.10917.n7.nabble.com/ABI-defined-register-usage-within-function-calls-tp73565.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ABI defined register usage within function calls
  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-19 23:49 ` Scott Wood
  1 sibling, 1 reply; 5+ messages in thread
From: JiveTalkin @ 2013-07-12 11:38 UTC (permalink / raw)
  To: linuxppc-dev

Moderator..can you change the subject of this to "Understanding register
usage as per ABI rules for functions" ??

Additionally, doesn't anyone have anything to say about this?



--
View this message in context: http://linuxppc.10917.n7.nabble.com/ABI-defined-register-usage-within-function-calls-tp73565p73669.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ABI defined register usage within function calls
  2013-07-12 11:38 ` JiveTalkin
@ 2013-07-14 22:19   ` Benjamin Herrenschmidt
  2013-07-16  0:37     ` JiveTalkin
  0 siblings, 1 reply; 5+ messages in thread
From: Benjamin Herrenschmidt @ 2013-07-14 22:19 UTC (permalink / raw)
  To: JiveTalkin; +Cc: linuxppc-dev

On Fri, 2013-07-12 at 04:38 -0700, JiveTalkin wrote:
> Moderator..can you change the subject of this to "Understanding register
> usage as per ABI rules for functions" ??
> 
> Additionally, doesn't anyone have anything to say about this?

We don't modify subjects after the fact. As to why nobody replied, well,
I suppose the 2 or 3 people who actually understand that stuff were
all too busy or didn't notice :-)

I'll try to reply later today if I get a chance or you can try to catch
me on IRC (freenode/#mklinux)

Cheers,
Ben.

> --
> View this message in context: http://linuxppc.10917.n7.nabble.com/ABI-defined-register-usage-within-function-calls-tp73565p73669.html
> Sent from the linuxppc-dev mailing list archive at Nabble.com.
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ABI defined register usage within function calls
  2013-07-14 22:19   ` Benjamin Herrenschmidt
@ 2013-07-16  0:37     ` JiveTalkin
  0 siblings, 0 replies; 5+ messages in thread
From: JiveTalkin @ 2013-07-16  0:37 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 2432 bytes --]

Hi Ben.

Thanks for the information. Your reply is eagerly awaited.

Regards.
On Jul 15, 2013 3:50 AM, "Benjamin Herrenschmidt [via linuxppc]" <
ml-node+s10917n73731h5@n7.nabble.com> wrote:

> On Fri, 2013-07-12 at 04:38 -0700, JiveTalkin wrote:
> > Moderator..can you change the subject of this to "Understanding register
> > usage as per ABI rules for functions" ??
> >
> > Additionally, doesn't anyone have anything to say about this?
>
> We don't modify subjects after the fact. As to why nobody replied, well,
> I suppose the 2 or 3 people who actually understand that stuff were
> all too busy or didn't notice :-)
>
> I'll try to reply later today if I get a chance or you can try to catch
> me on IRC (freenode/#mklinux)
>
> Cheers,
> Ben.
>
> > --
> > View this message in context:
> http://linuxppc.10917.n7.nabble.com/ABI-defined-register-usage-within-function-calls-tp73565p73669.html
> > Sent from the linuxppc-dev mailing list archive at Nabble.com.
> > _______________________________________________
> > Linuxppc-dev mailing list
> > [hidden email] <http://user/SendEmail.jtp?type=node&node=73731&i=0>
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
> _______________________________________________
> Linuxppc-dev mailing list
> [hidden email] <http://user/SendEmail.jtp?type=node&node=73731&i=1>
> https://lists.ozlabs.org/listinfo/linuxppc-dev
>
>
> ------------------------------
>  If you reply to this email, your message will be added to the discussion
> below:
>
> http://linuxppc.10917.n7.nabble.com/ABI-defined-register-usage-within-function-calls-tp73565p73731.html
>  To unsubscribe from ABI defined register usage within function calls, click
> here<http://linuxppc.10917.n7.nabble.com/template/NamlServlet.jtp?macro=unsubscribe_by_code&node=73565&code=YWlqYXpiYWlnMUBnbWFpbC5jb218NzM1NjV8MTg5MDM1OTIxOA==>
> .
> NAML<http://linuxppc.10917.n7.nabble.com/template/NamlServlet.jtp?macro=macro_viewer&id=instant_html%21nabble%3Aemail.naml&base=nabble.naml.namespaces.BasicNamespace-nabble.view.web.template.NabbleNamespace-nabble.view.web.template.NodeNamespace&breadcrumbs=notify_subscribers%21nabble%3Aemail.naml-instant_emails%21nabble%3Aemail.naml-send_instant_email%21nabble%3Aemail.naml>
>




--
View this message in context: http://linuxppc.10917.n7.nabble.com/ABI-defined-register-usage-within-function-calls-tp73565p73803.html
Sent from the linuxppc-dev mailing list archive at Nabble.com.

[-- Attachment #2: Type: text/html, Size: 4008 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: ABI defined register usage within function calls
  2013-07-10 13:54 ABI defined register usage within function calls JiveTalkin
  2013-07-12 11:38 ` JiveTalkin
@ 2013-07-19 23:49 ` Scott Wood
  1 sibling, 0 replies; 5+ messages in thread
From: Scott Wood @ 2013-07-19 23:49 UTC (permalink / raw)
  To: JiveTalkin; +Cc: linuxppc-dev

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=

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-07-19 23:49 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.