Skip to content

Commit e5a2736

Browse files
committed
Fix syscall handling in the kernel loop
1 parent cd9fdfa commit e5a2736

File tree

4 files changed

+30
-37
lines changed

4 files changed

+30
-37
lines changed

arch/v7m_entry.S

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ ENTRY(PendSV_Handler)
4242
/* Disable interrupts */
4343
irq_disable
4444

45-
neg r7, r7 /* Negate _r7 to indicate that the returning is triggered by SysTick */
46-
4745
/* Save user state */
4846
mrs r0, psp /* Load psp into the r0 */
4947

@@ -87,11 +85,16 @@ ENTRY(SVC_Handler)
8785
msr control, r4
8886

8987
/* Load kernel state */
90-
pop {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
91-
msr psr_nzcvq, ip /* Load psr from the ip */
88+
pop {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
89+
msr psr_nzcvq, ip /* Load psr from the ip */
90+
91+
/* Set syscall request flag */
92+
push {r0-r3, lr}
93+
bl set_syscall_flag
94+
pop {r0-r3, lr}
9295

9396
/* Exception return (back to the kernel) */
94-
bx lr
97+
bx lr
9598
ENDPROC(SVC_Handler)
9699

97100
ENTRY(__preempt_disable)

arch/v7m_port.c

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -148,29 +148,6 @@ void __platform_init(void)
148148
os_env_init(&stack_empty[31]);
149149
}
150150

151-
bool check_systick_event(void *sp)
152-
{
153-
uint32_t lr = ((uint32_t *) sp)[8];
154-
long *syscall_num = NULL;
155-
156-
/* EXC_RETURN[4]: 0 = FPU used / 1 = FPU unused */
157-
if (lr & 0x10) {
158-
syscall_num = (long *) &((struct context *) sp)->_r7;
159-
} else {
160-
syscall_num = (long *) &((struct context_fpu *) sp)->_r7;
161-
}
162-
163-
/* If r7 is negative, then the kernel is returned from the SysTick
164-
* interrupt. Otherwise the kernel is returned via supervisor call.
165-
*/
166-
if (*syscall_num < 0) {
167-
*syscall_num *= -1; /* Restore the syscall number */
168-
return true;
169-
}
170-
171-
return false;
172-
}
173-
174151
unsigned long get_syscall_num(void *sp)
175152
{
176153
uint32_t lr = ((uint32_t *) sp)[8];

include/arch/port.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,6 @@ void __stack_init(uint32_t **stack_top,
7676
uint32_t return_handler,
7777
uint32_t args[4]);
7878

79-
/**
80-
* @brief Check if the kernel is returned from user space via systick
81-
* @param sp: The stack pointer points to the top of the thread stack.
82-
* @retval bool: true if it is returned via systick; otherwise false.
83-
*/
84-
bool check_systick_event(void *sp);
85-
8679
/**
8780
* @brief Get syscall number
8881
* @param sp: The stack pointer points to the top of the thread stack.

kernel/kernel.c

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ struct list_head ready_list[KTHREAD_PRI_MAX + 1];
7070
static bool need_resched_flag;
7171
static uint32_t preempt_cnt;
7272

73+
/* System call */
74+
static bool syscall_flag;
75+
7376
/* Tasks and threads */
7477
static struct task_struct tasks[TASK_MAX];
7578

@@ -3066,6 +3069,21 @@ static void setup_syscall(struct thread_info *thread,
30663069
/* Syscall table */
30673070
static struct syscall_info syscall_table[] = {SYSCALL_TABLE_INIT};
30683071

3072+
void set_syscall_flag(void)
3073+
{
3074+
syscall_flag = true;
3075+
}
3076+
3077+
void reset_syscall_flag(void)
3078+
{
3079+
syscall_flag = false;
3080+
}
3081+
3082+
bool get_syscall_flag(void)
3083+
{
3084+
return syscall_flag;
3085+
}
3086+
30693087
static void syscall_handler(void)
30703088
{
30713089
unsigned long syscall_num = get_syscall_num(running_thread->stack_top);
@@ -3303,11 +3321,13 @@ void sched_start(void)
33033321
list_del(&threads[0].list);
33043322

33053323
while (1) {
3306-
if (!check_systick_event(running_thread->stack_top)) {
3324+
/* Syscall request */
3325+
if (get_syscall_flag()) {
3326+
reset_syscall_flag();
33073327
syscall_handler();
33083328
}
33093329

3310-
/* Rescheduling */
3330+
/* Rescheduling request */
33113331
if (need_resched()) {
33123332
reset_need_resched();
33133333
__schedule();

0 commit comments

Comments
 (0)