Skip to content

Commit a4c9c32

Browse files
authored
Merge pull request #267 from tavip/fix-setjmp
lkl: host ops: fix jump buffer API and implementation
2 parents 379f265 + 79131f2 commit a4c9c32

8 files changed

Lines changed: 51 additions & 43 deletions

File tree

arch/lkl/include/asm/sched.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#ifndef _ASM_LKL_SCHED_H
2+
#define _ASM_LKL_SCHED_H
3+
4+
#include <linux/sched.h>
5+
6+
static inline void thread_sched_jb(void)
7+
{
8+
set_ti_thread_flag(current_thread_info(), TIF_SCHED_JB);
9+
10+
if (test_ti_thread_flag(current_thread_info(), TIF_HOST_THREAD)) {
11+
set_current_state(TASK_UNINTERRUPTIBLE);
12+
lkl_ops->jmp_buf_set(&current_thread_info()->sched_jb,
13+
schedule);
14+
} else {
15+
lkl_ops->jmp_buf_set(&current_thread_info()->sched_jb,
16+
lkl_idle_tail_schedule);
17+
}
18+
}
19+
20+
static inline void thread_set_sched_exit(void)
21+
{
22+
set_ti_thread_flag(current_thread_info(), TIF_SCHED_EXIT);
23+
}
24+
25+
void switch_to_host_task(struct task_struct *);
26+
27+
#endif /* _ASM_LKL_SCHED_H */

arch/lkl/include/asm/thread_info.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,6 @@ void threads_cnt_dec(void);
6363
#define TIF_HOST_THREAD 9
6464
#define TIF_IDLE 10
6565

66-
static inline void set_ti_thread_flag(struct thread_info *ti, int flag);
67-
68-
static inline int thread_set_sched_jmp(void)
69-
{
70-
set_ti_thread_flag(current_thread_info(), TIF_SCHED_JB);
71-
return lkl_ops->jmp_buf_set(&current_thread_info()->sched_jb);
72-
}
73-
74-
static inline void thread_set_sched_exit(void)
75-
{
76-
set_ti_thread_flag(current_thread_info(), TIF_SCHED_EXIT);
77-
}
78-
79-
void switch_to_host_task(struct task_struct *);
80-
8166
#define __HAVE_THREAD_FUNCTIONS
8267

8368
#define task_thread_info(task) ((struct thread_info *)(task)->stack)

arch/lkl/include/uapi/asm/host_ops.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,17 @@ struct lkl_jmp_buf {
7070
*
7171
* @gettid - returns the host thread id of the caller, which need not
7272
* be the same as the handle returned by thread_create
73+
*
74+
* @jmp_buf_set - runs the give function and setups a jump back point by saving
75+
* the context in the jump buffer; jmp_buf_longjmp can be called from the give
76+
* function or any callee in that function to return back to the jump back
77+
* point
78+
*
79+
* NOTE: we can't return from jmp_buf_set before calling jmp_buf_longjmp or
80+
* otherwise the saved context (stack) is not going to be valid, so we must pass
81+
* the function that will eventually call longjmp here
82+
*
83+
* @jmp_buf_longjmp - perform a jump back to the saved jump buffer
7384
*/
7485
struct lkl_host_operations {
7586
const char *virtio_devices;
@@ -114,7 +125,7 @@ struct lkl_host_operations {
114125

115126
long (*gettid)(void);
116127

117-
int (*jmp_buf_set)(struct lkl_jmp_buf *jmpb);
128+
void (*jmp_buf_set)(struct lkl_jmp_buf *jmpb, void (*f)(void));
118129
void (*jmp_buf_longjmp)(struct lkl_jmp_buf *jmpb, int val);
119130
};
120131

arch/lkl/kernel/cpu.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <asm/cpu.h>
88
#include <asm/thread_info.h>
99
#include <asm/unistd.h>
10+
#include <asm/sched.h>
1011
#include <asm/syscalls.h>
1112

1213

@@ -137,14 +138,7 @@ void lkl_cpu_put(void)
137138
if (in_interrupt())
138139
lkl_bug("%s: in interrupt\n", __func__);
139140
lkl_ops->mutex_unlock(cpu.lock);
140-
if (test_thread_flag(TIF_HOST_THREAD)) {
141-
set_current_state(TASK_UNINTERRUPTIBLE);
142-
if (!thread_set_sched_jmp())
143-
schedule();
144-
} else {
145-
if (!thread_set_sched_jmp())
146-
lkl_idle_tail_schedule();
147-
}
141+
thread_sched_jb();
148142
return;
149143
}
150144

@@ -242,10 +236,8 @@ void arch_cpu_idle_prepare(void)
242236
* We hijack the idle loop here so that we can let the idle thread
243237
* jump back to the beginning.
244238
*/
245-
while (1) {
246-
if (!lkl_ops->jmp_buf_set(&cpu.idle_jb))
247-
cpu_idle_loop();
248-
}
239+
while (1)
240+
lkl_ops->jmp_buf_set(&cpu.idle_jb, cpu_idle_loop);
249241
}
250242

251243
void lkl_cpu_wakeup_idle(void)

arch/lkl/kernel/syscalls.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <asm/syscalls.h>
1515
#include <asm/syscalls_32.h>
1616
#include <asm/cpu.h>
17+
#include <asm/sched.h>
1718

1819
static asmlinkage long sys_virtio_mmio_device_add(long base, long size,
1920
unsigned int irq);
@@ -114,9 +115,7 @@ long lkl_syscall(long no, long *params)
114115
ret = run_syscall(no, params);
115116

116117
if (no == __NR_reboot) {
117-
set_current_state(TASK_UNINTERRUPTIBLE);
118-
if (!thread_set_sched_jmp())
119-
schedule();
118+
thread_sched_jb();
120119
return ret;
121120
}
122121

arch/lkl/kernel/threads.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <linux/sched.h>
44
#include <asm/host_ops.h>
55
#include <asm/cpu.h>
6+
#include <asm/sched.h>
67

78
static volatile int threads_counter;
89

@@ -140,15 +141,7 @@ void switch_to_host_task(struct task_struct *task)
140141
task_thread_info(task)->tid = lkl_ops->thread_self();
141142

142143
wake_up_process(task);
143-
if (test_thread_flag(TIF_HOST_THREAD)) {
144-
set_current_state(TASK_UNINTERRUPTIBLE);
145-
if (!thread_set_sched_jmp())
146-
schedule();
147-
} else {
148-
if (!thread_set_sched_jmp())
149-
lkl_idle_tail_schedule();
150-
}
151-
144+
thread_sched_jb();
152145
lkl_ops->sem_down(task_thread_info(task)->sched_sem);
153146
schedule_tail(abs_prev);
154147
}

tools/lkl/lib/jmp_buf.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#include <setjmp.h>
22
#include <lkl_host.h>
33

4-
int jmp_buf_set(struct lkl_jmp_buf *jmpb)
4+
void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void))
55
{
6-
return setjmp(*((jmp_buf *)jmpb->buf));
6+
if (!setjmp(*((jmp_buf *)jmpb->buf)))
7+
f();
78
}
89

910
void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val)

tools/lkl/lib/jmp_buf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef _LKL_LIB_JMP_BUF_H
22
#define _LKL_LIB_JMP_BUF_H
33

4-
int jmp_buf_set(struct lkl_jmp_buf *jmpb);
4+
void jmp_buf_set(struct lkl_jmp_buf *jmpb, void (*f)(void));
55
void jmp_buf_longjmp(struct lkl_jmp_buf *jmpb, int val);
66

77
#endif

0 commit comments

Comments
 (0)