On 07/10/2013 08:54:39 AM, JiveTalkin wrote:
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).
I don't understand this... What specifically do you mean by "interrupt
context"? Do you mean syscall context? Syscall parameters are passed
in registers, not in the stack frame.
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?
Linux doesn't use EABI -- and in any case, I don't see "SPRG" anywhere
in the EABI document, and no relevant mention in the SVR4 ABI. It's up
to the OS how SPRGs are used.
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)?
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
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.
r10 was loaded from SPRG3, and thus points to the thread struct. The
thread struct (a.k.a. SPRG3, a.k.a. THREAD) and a pointer to the stack
are both contained within the task_struct (a.k.a. current). At the
bottom of the stack is the thread_info struct, which is why
current->stack is called THREAD_INFO in asm-offsets.c. Since THREAD
and THREAD_INFO are both in the same struct, we can get THREAD_INFO by
adding the difference in offsets to the THREAD pointer that we got from
SPRG3.
That gets us to the bottom of the stack; ALLOC_STACK_FRAME() adds the
size of the stack so that we point to the top and are ready to create a
frame. It's a confusing name since it doesn't actually allocate a
frame; that happens in the "subi" instruction that follows.
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:
What are we doing with what?
The previous value of r1 is still in r1. At this point r11 holds the
new stack pointer. Did you misread the "stw r1, GPR1(r11)" as a load?
-Scott
_______________________________________________
Linuxppc-dev mailing list
[email protected]
https://lists.ozlabs.org/listinfo/linuxppc-dev