From: Zhu, Yaozong (zyz@chinadigipro.com)
Date: Fri Jan 26 2001 - 07:31:02 EST
Yes, system calls can be nested, but keep in mind that when in SVC mode, after making a system call, lr_SVC and spsr_SVC will not be the same as before the call. In this sense, I say the context is not fully saved and restored.
=====================
@Code executed in SVC mode
@Now spsr_SVC and lr_SVC can have any values
... ...
400100:
mv r0, #syscall_foo_param
400104:
swi #syscall_foo_id
400108: mv r4, r0
... ...
@ When the swi returns, pc = 400108, cpsr is SVC mode, AND
@ spsr_SVC = cpsr, lr_SVC = pc; Surely this is a side-effect of the system call.
----- Original Message -----
From: "Joe deBlaquiere" <jadb@redhat.com>
To: <uclinux-dev@uClinux.org>
Sent: Wednesday, January 24, 2001 12:25 AM
Subject: Re: [uClinux-dev] About system call code in arm-uclinux, Aplio version
> I think I see what you're getting at...
>
> Suppose we have a USR thread which executes a swi to make a syscall
> (foo) and then that syscall uses swi to invove another syscall (bar).
> You are concerned that the original return address is lost.
>
> Here's how it works... FYI, you can follow the register magic for swi
> from the ARM ARM (Architecture Reference Manual) section 2.5.3
>
> user code
>
> 400100:
> mv r0, #syscall_foo_param
> 400104:
> swi #syscall_foo_id
> 400108: mv r4, r0
>
> so when the swi is hit, the following operations take place
>
> lr_svc = &swi + 4 = 400108
> spsr_svc = cpsr(usr)
> cpsr = svc, irq disabled, fiq enabled
> pc = 0x08
>
> the instruction at 0x08 branches us to vector_swi...
>
> 00>>> vector_swi: sub sp, sp, #S_FRAME_SIZE
> 04>>> stmia sp, {r0 - r12} @ Calling r0 - r12
> 08>>> add r8, sp, #S_PC
> 0C>>> stmdb r8, {sp, lr}^ @ Calling sp, lr
> 10>>> mov r7, r0
> 14>>> mrs r6, spsr
> 18>>> mov r5, lr
> 1C>>> stmia r8, {r5, r6, r7} @ Save calling
>
> @(vector_swi+0x0C) we stuff the current lr ( 400108 ) into the context
> save struct (CSS_a) on the stack. @(vector_swi+1C) we stuff the spsr (
> previous usr cpsr ) into CSS_a. All of this is done with interrupts
> disabled. Once the CSS_a is in place, interrupts are reenabled.
>
> Then the code looks at the address of the SWI and does a table lookup to
> realize that we wanted to call sys_foo. sys_foo is called and when it
> returns, we proceed (eventually) to Lret_no_check which disables
> interrupts and then replaces the spsr, lr, sp from CSS_a.
>
> if sys_foo performs a swi to call sys_bar, the result is basically the same.
>
> 10200: mv r0, #syscall_bar_param0
> 10204: mv r1, #syscall_bar_param1
> 10208: swi #syscall_bar_id
> 1020C: mv r4, r0
>
> lr_svc = &swi + 4 = 1020C
> spsr_svc = cpsr(svc)
> cpsr = svc, irq disabled, fiq enabled
> pc = 0x08
>
> At this point in time, the lr (somewhere in sys_foo) and spsr are again
> stored to CSS_b (in a new stack frame, so the old one isn't clobbered)
> and the call to sys_bar is made. at the exit from the call, the lr (in
> sys_foo), spsr are restored from CSS_b and sys_foo resumes. when sys_foo
> exits, CSS_a still holds the original user space lr, spsr, etc. so you
> can return to the original user process.
>
> I'm pretty sure this can nest until the stack eats up all the available
> memory... (you could write a recursive syscall to test that... )
>
> Am I making sense now? I think I understand this better now that I've
> looked at it a little deeper.
>
> Joe
>
> Zhu, Yaozong wrote:
>
> > I am sorry Joe but I have to say you are not reasoning here:-}
> > Once SWI is executed in SVC mode, the value of spsr_SVC and lr_SVC are lost instantly. Spsr_SVC and lr_SVC may be saved after SWI is executed, but the values are not those before
> > SWI is executed.
> > BTW, aren't sp and lr in "stmdb r8, {sp, lr}^" USER-bank ones?
> > -----Original Message-----
> > From: owner-uclinux-dev@uClinux.org
> > [mailto:owner-uclinux-dev@uClinux.org]On Behalf Of Joe deBlaquiere
> > Sent: Monday, January 22, 2001 11:04 PM
> > To: uclinux-dev@uClinux.org
> > Subject: Re: [uClinux-dev] About system call code in arm-uclinux, Aplio
> > version
> >
> >
> > actually, if this is entered via swi from SVC context, the sp,lr are for
> > the SVC context (I know the comment says differently, but it lies ;o).
> >
> > Zhu, Yaozong wrote:
> >
> >
> >> I do know the context is to be pushed and poped from SVC stack. But it seems to me that SVC context is not fully saved and restored during software interrupt processing. Yes, the kernel runs quite well so the code works just fine. But convince me that this is not by a fluke.
> >>
> >>
> >>
> >>> vector_swi: sub sp, sp, #S_FRAME_SIZE
> >>> stmia sp, {r0 - r12} @ Calling r0 - r12
> >>> add r8, sp, #S_PC
> >>> stmdb r8, {sp, lr}^ @ Calling sp, lr <<<<<<>>>>>>> Look HERE, Joe. sp and lr here are sp_USR and lr_USR
> >>> mov r7, r0
> >>> mrs r6, spsr <<<<<<< saves whichever PSR called
> >>> mov r5, lr
> >>> stmia r8, {r5, r6, r7} @ Save calling
> >>> PC, CPSR, OLD_R0
> >>>
> >>
> >> ======================
> >>
> >>
> >>> Lret_no_check: mrs r0, cpsr @ disable IRQs
> >>> orr r0, r0, #I_BIT
> >>> msr cpsr, r0
> >>> ldr r0, [sp, #S_PSR] @ Get calling cpsr
> >>> msr spsr, r0
> >>> ldmia sp, {r0 - lr}^ @ Get calling r0 <<<<<>>>>> Look here. USER bank sp and lr are restored from stack context
> >>> - lr
> >>> mov r0, r0
> >>> add sp, sp, #S_PC
> >>> ldr lr, [sp], #S_FRAME_SIZE - S_PC @ Get PC and <<<<<>>>>> Look here. sp_SVC is restored anyway, but how about lr_SVC?
> >>> jump over PC, PSR, OLD_R0
> >>> movs pc, lr <<<<<>>>>> Look here. cpsr_SVC is restored anyway, but how about spsr_SVC?
> >>>
> >>>
> >>
> >>
> >>
> >> -----Original Message-----
> >> From: owner-uclinux-dev@uClinux.org
> >> [mailto:owner-uclinux-dev@uClinux.org]On Behalf Of Joe deBlaquiere
> >> Sent: Monday, January 22, 2001 1:49 PM
> >> To: uclinux-dev@uClinux.org
> >> Subject: Re: [uClinux-dev] About system call code in arm-uclinux, Aplio
> >> version
> >>
> >>
> >> The values are pushed to the stack before interrupts are turned on and
> >> restored with ints turned off in ret_from_syscall...
> >>
> >> Zhu, Yaozong wrote:
> >>
> >>
> >>
> >>> Actually if SWI is executed in SVC mode, the previous lr_SVC and spsr_SVC are lost, right?
> >>> Quoted from ARM7TDMI data sheet:
> >>> "
> >>> Note that the link mechanism is not re-entrant, so if the supervisor code
> >>> wishes to use software interrupts within itself it must first save a copy of the
> >>> return address and SPSR.
> >>> "
> >>> -----Original Message-----
> >>> From: owner-uclinux-dev@uClinux.org
> >>> [mailto:owner-uclinux-dev@uClinux.org]On Behalf Of Joe deBlaquiere
> >>> Sent: Monday, January 22, 2001 11:30 AM
> >>> To: uclinux-dev@uClinux.org
> >>> Subject: Re: [uClinux-dev] About system call code in arm-uclinux, Aplio
> >>> version
> >>>
> >>>
> >>> Sure, you can make syscalls in a system thread, you just have to make
> >>> sure you have timers, interrupts and all configured (i.e. not at the .
> >>> It would probably be more appropriate to put the code into the init
> >>> thread or even better to run it as /bin/init.
> >>>
> >>> Now that I look at it a little deeper, I doesn't matter what context you
> >>> came from. If you look at the SWI entry point (below), it saves off
> >>> whatever CPSR was stuffed into the SPSR at interrupt. So if you do a SWI
> >>> from SVC mode, it saves off the SVC mode PSR.
> >>>
> >>> vector_swi: sub sp, sp, #S_FRAME_SIZE
> >>> stmia sp, {r0 - r12} @ Calling r0 - r12
> >>> add r8, sp, #S_PC
> >>> stmdb r8, {sp, lr}^ @ Calling sp, lr <<<<<< Look HERE, Joe. sp and lr here are sp_USR and lr_USR
> >>> mov r7, r0
> >>> mrs r6, spsr <<<<<<< saves whichever PSR called
> >>> mov r5, lr
> >>> stmia r8, {r5, r6, r7} @ Save calling
> >>> PC, CPSR, OLD_R0
> >>>
> >>> Looking a little father in, the ret_from_syscall routines (below) which
> >>> perform a context restore really doesn't care either.
> >>>
> >>> Lret_no_check: mrs r0, cpsr @ disable IRQs
> >>> orr r0, r0, #I_BIT
> >>> msr cpsr, r0
> >>> ldr r0, [sp, #S_PSR] @ Get calling cpsr
> >>> msr spsr, r0
> >>> ldmia sp, {r0 - lr}^ @ Get calling r0
> >>> - lr
> >>> mov r0, r0
> >>> add sp, sp, #S_PC
> >>> ldr lr, [sp], #S_FRAME_SIZE - S_PC @ Get PC and
> >>> jump over PC, PSR, OLD_R0
> >>> movs pc, lr
> >>>
> >>>
> >>>
> >>> Zhu, Yaozong wrote:
> >>>
> >>>
> >>>
> >>>
> >>>> Hi Joe,
> >>>> To put my question in another way: can system calls( swi intructions indeed ) be called by kernel code? It seems that SWI handling code are written to service USER mode calls. The init may run in USER mode. But clone system calls must be called from kernel mode code(in start_kernel) to make init run.
> >>>>
> >>>> -----Original Message-----
> >>>> From: owner-uclinux-dev@uClinux.org
> >>>> [mailto:owner-uclinux-dev@uClinux.org]On Behalf Of Joe deBlaquiere
> >>>> Sent: Sunday, January 21, 2001 11:30 PM
> >>>> To: uclinux-dev@uClinux.org
> >>>> Subject: Re: [uClinux-dev] About system call code in arm-uclinux, Aplio
> >>>> version
> >>>>
> >>>>
> >>>> I'm not entirely sure about this, but I think the answer to this is that
> >>>> the kernel_thread() call creates a thread which runs as a user mode
> >>>> process (using the clone call). Therefore init() is not being run in SVC
> >>>> mode.
> >>>>
> >>>> Zhu, Yaozong wrote:
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>> Hi all,
> >>>>> It seems that start_kernel(init/main.c) runs in SVC mode. And in start_kernel, kernel_thread(init, NULL, 0) is called which does two swi's . My humble question is , when doing system calls from SVC mode, vector_swi(arch/armnommu/kernel/entry-armv.S) saves and restores USER mode registers, and _ret_from_sys_call does restore sp_SVC and spsr_SVC, but lr_SVC is lost, isn't this a problem, or I am wrong?
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> This message resent by the uclinux-dev@uclinux.org list server http://www.uClinux.org/
> >>>>
>
>
> --
> Joe deBlaquiere
> Red Hat, Inc.
> 307 Wynn Drive
> Huntsville AL, 35805
> voice : (256)-704-9200
> fax : (256)-837-3839
>
> This message resent by the uclinux-dev@uclinux.org list server http://www.uClinux.org/
This message resent by the uclinux-dev@uclinux.org list server http://www.uClinux.org/
This archive was generated by hypermail 2.1.4 : Thu Sep 19 2002 - 13:19:28 EDT