Skip to content

Commit

Permalink
fork: return value in child
Browse files Browse the repository at this point in the history
Due to exiting on different stack than current's thread in fork in child
the return value was not set by threads_setupUserReturn.

JIRA: RTOS-979
  • Loading branch information
badochov committed Nov 28, 2024
1 parent c47c66d commit 5035acc
Show file tree
Hide file tree
Showing 17 changed files with 43 additions and 19 deletions.
2 changes: 2 additions & 0 deletions hal/armv7a/_interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ _syscalls_dispatch:
cpsie if

blx syscalls_dispatch
ldr r1, [sp]
blx threads_setupUserReturn

cpsid if

Expand Down
4 changes: 2 additions & 2 deletions hal/armv7a/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ static void exceptions_defaultHandler(unsigned int n, exc_context_t *ctx)
}


extern void threads_setupUserReturn(void *retval);
extern void *threads_setupUserReturn(void *retval, cpu_context_t *ctx);


void exceptions_dispatch(unsigned int n, exc_context_t *ctx)
Expand All @@ -130,7 +130,7 @@ void exceptions_dispatch(unsigned int n, exc_context_t *ctx)

/* Handle signals if necessary */
if (hal_cpuSupervisorMode(&ctx->cpuCtx) == 0) {
threads_setupUserReturn((void *)ctx->cpuCtx.r0);
threads_setupUserReturn((void *)ctx->cpuCtx.r0, &ctx->cpuCtx);
}
}

Expand Down
3 changes: 3 additions & 0 deletions hal/armv7m/imxrt/_init.S
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,9 @@ _syscall_dispatch:

_syscallend:
/* return value in r0 */
mov r1, sp
blx threads_setupUserReturn

ldr lr, [sp, #8] /* psp */
add lr, lr, #(26 * 4)
msr psp, lr
Expand Down
3 changes: 3 additions & 0 deletions hal/armv7m/stm32/_init.S
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ _syscall_dispatch:

_syscallend:
/* return value in r0 */
mov r1, sp
blx threads_setupUserReturn

ldr lr, [sp, #8] /* psp */
add lr, lr, #(8 * 4)
msr psp, lr
Expand Down
3 changes: 3 additions & 0 deletions hal/armv8m/mcx/_init.S
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ _syscall_dispatch:

_syscallend:
/* return value in r0 */
mov r1, sp
blx threads_setupUserReturn

ldr lr, [sp, #8] /* psp */
add lr, lr, #(8 * 4)
msr psp, lr
Expand Down
3 changes: 3 additions & 0 deletions hal/armv8m/nrf/_init.S
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,9 @@ _syscall_dispatch:

_syscallend:
/* return value in r0 */
mov r1, sp
blx threads_setupUserReturn

ldr lr, [sp, #8] /* psp */
add lr, lr, #(8 * 4)
msr psp, lr
Expand Down
2 changes: 2 additions & 0 deletions hal/armv8r/_interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,8 @@ _syscalls_dispatch:
cpsie if

blx syscalls_dispatch
ldr r1, [sp]
blx threads_setupUserReturn

cpsid if

Expand Down
4 changes: 2 additions & 2 deletions hal/armv8r/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static void exceptions_defaultHandler(unsigned int n, exc_context_t *ctx)
}


extern void threads_setupUserReturn(void *retval);
extern void *threads_setupUserReturn(void *retval, cpu_context_t *ctx);


void exceptions_dispatch(unsigned int n, exc_context_t *ctx)
Expand All @@ -135,7 +135,7 @@ void exceptions_dispatch(unsigned int n, exc_context_t *ctx)

/* Handle signals if necessary */
if (hal_cpuSupervisorMode(&ctx->cpuCtx) == 0) {
threads_setupUserReturn((void *)ctx->cpuCtx.r0);
threads_setupUserReturn((void *)ctx->cpuCtx.r0, &ctx->cpuCtx);
}
}

Expand Down
7 changes: 5 additions & 2 deletions hal/ia32/_exceptions.S
Original file line number Diff line number Diff line change
Expand Up @@ -169,11 +169,14 @@ sym:
addl $4, %esp;\
testl %eax, %eax;\
jnz exception_popContext;\
/* cpu_context_t */;\
leal 28(%esp), %eax;\
/* return value */ ;\
movl 56(%esp), %eax;\
movl 56(%esp), %ebx;\
pushl %eax;\
pushl %ebx;\
call threads_setupUserReturn;\
addl $4, %esp;\
addl $8, %esp;\
;\
jmp exception_popContext

Expand Down
7 changes: 5 additions & 2 deletions hal/ia32/_interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,12 @@ _interrupts_syscall:
pushl %eax
sti
call syscalls_dispatch
cli
addl $8, %esp
movl %eax, (4 * CTXPUSHL - EAX_OFFSET)(%esp) /* Save return value to eax in context */
pushl %esp
pushl %eax
call threads_setupUserReturn
addl $8, %esp
cli
jmp interrupts_popContextUnlocked
.size _interrupts_syscall, .-_interrupts_syscall

Expand Down
3 changes: 2 additions & 1 deletion hal/riscv64/_interrupts.S
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,8 @@ _interrupts_notIrq:

csrs sstatus, SSTATUS_SIE
call syscalls_dispatch
sd a0, 56(sp)
mv a1, sp
call threads_setupUserReturn
csrc sstatus, SSTATUS_SIE

tail _interrupts_returnUnlocked
Expand Down
4 changes: 2 additions & 2 deletions hal/riscv64/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ inline ptr_t hal_exceptionsPC(exc_context_t *ctx)
}


extern void threads_setupUserReturn(void *retval);
extern void *threads_setupUserReturn(void *retval, cpu_context_t *ctx);


void exceptions_dispatch(unsigned int n, cpu_context_t *ctx)
Expand All @@ -195,7 +195,7 @@ void exceptions_dispatch(unsigned int n, cpu_context_t *ctx)

/* Handle signals if necessary */
if (hal_cpuSupervisorMode(ctx) == 0) {
threads_setupUserReturn((void *)ctx->a0);
threads_setupUserReturn((void *)ctx->a0, ctx);
}
}

Expand Down
2 changes: 2 additions & 0 deletions hal/sparcv8leon/_traps.S
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,8 @@ s_fpu_done:
/* void *syscalls_dispatch(int n, char *ustack) */
call syscalls_dispatch
nop
call threads_setupUserReturn
add %sp, 0x60, %o1

/* disable traps */
#ifdef LEON3_USE_PWR
Expand Down
4 changes: 2 additions & 2 deletions hal/sparcv8leon/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ __attribute__((noreturn)) static void exceptions_defaultHandler(unsigned int n,
}


extern void threads_setupUserReturn(void *retval);
extern void *threads_setupUserReturn(void *retval, cpu_context_t *ctx);


void exceptions_dispatch(unsigned int n, exc_context_t *ctx)
Expand All @@ -167,7 +167,7 @@ void exceptions_dispatch(unsigned int n, exc_context_t *ctx)

/* Handle signals if necessary */
if (hal_cpuSupervisorMode(&ctx->cpuCtx) == 0) {
threads_setupUserReturn((void *)ctx->cpuCtx.o0);
threads_setupUserReturn((void *)ctx->cpuCtx.o0, &ctx->cpuCtx);
}
}

Expand Down
7 changes: 4 additions & 3 deletions proc/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -1482,10 +1482,10 @@ static int _threads_checkSignal(thread_t *selected, process_t *proc, cpu_context
}


void threads_setupUserReturn(void *retval)
void *threads_setupUserReturn(void *retval, cpu_context_t *ctx)
{
spinlock_ctx_t sc;
cpu_context_t *ctx, *signalCtx;
cpu_context_t *signalCtx;
void *f;
void *kstackTop;
thread_t *thread;
Expand All @@ -1494,7 +1494,6 @@ void threads_setupUserReturn(void *retval)
thread = _proc_current();

kstackTop = thread->kstack + thread->kstacksz;
ctx = kstackTop - sizeof(*ctx);
signalCtx = (void *)((char *)hal_cpuGetUserSP(ctx) - sizeof(*signalCtx));
hal_cpuSetReturnValue(ctx, retval);

Expand All @@ -1506,6 +1505,8 @@ void threads_setupUserReturn(void *retval)
}

hal_spinlockClear(&threads_common.spinlock, &sc);

return retval;
}


Expand Down
2 changes: 1 addition & 1 deletion proc/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ extern int _threads_init(vm_map_t *kmap, vm_object_t *kernel);
extern int threads_sigpost(process_t *process, thread_t *thread, int sig);


extern void threads_setupUserReturn(void *retval);
extern void *threads_setupUserReturn(void *retval, cpu_context_t *ctx);


#endif
2 changes: 0 additions & 2 deletions syscalls.c
Original file line number Diff line number Diff line change
Expand Up @@ -1868,8 +1868,6 @@ void *syscalls_dispatch(int n, char *ustack)
proc_threadEnd();
}

threads_setupUserReturn(retval);

return retval;
}

Expand Down

0 comments on commit 5035acc

Please sign in to comment.