Skip to content

Commit db82da5

Browse files
committed
we spawn threads (they don't work)
1 parent fa4deb7 commit db82da5

38 files changed

+459
-367
lines changed

arch/wasm/Kconfig

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@ config WASM
22
def_bool y
33
depends on !BINFMT_ELF && !SMP && !MMU && !MODULES && !COREDUMP && !SECCOMP && !UPROBES && !COMPAT
44
select ARCH_HAS_BINFMT_WASM
5+
select ARCH_HAS_CURRENT_STACK_POINTER
56
select ARCH_HAS_SYSCALL_WRAPPER
67
select ARCH_NO_SWAP
78
select ARCH_USE_QUEUED_RWLOCKS
89
select ARCH_USE_QUEUED_SPINLOCKS
9-
# select ARCH_SUPPORTS_LTO_CLANG
10-
# select ARCH_SUPPORTS_LTO_CLANG_THIN
1110
select BUG
1211
select FLATMEM
1312
select GENERIC_ATOMIC64
1413
select GENERIC_CSUM
1514
select GENERIC_HWEIGHT
16-
select HAS_CURRENT_STACK_POINTER
1715
select OF
1816
select OF_EARLY_FLATTREE
1917
select PAGE_SIZE_64KB
@@ -44,7 +42,8 @@ config SMP
4442

4543
config NR_CPUS
4644
int
47-
default 1
45+
default 1 if !SMP
46+
default 64 if SMP
4847

4948
config HZ
5049
int

arch/wasm/include/asm/current.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
#ifndef _WASM_CURRENT_H
22
#define _WASM_CURRENT_H
33

4-
#include <asm/wasm_imports.h>
4+
struct task_struct;
55

6-
extern _Thread_local struct task_struct *current;
6+
extern _Thread_local struct task_struct * current;
77

88
#endif

arch/wasm/include/asm/irqflags.h

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,12 @@
33

44
#include <asm/wasm_imports.h>
55

6-
#define arch_local_irq_save arch_local_irq_save
7-
static inline unsigned long arch_local_irq_save(void)
8-
{
9-
return wasm_get_irq_enabled();
10-
}
11-
126
#define arch_local_irq_restore arch_local_irq_restore
137
static inline void arch_local_irq_restore(unsigned long flags)
148
{
159
wasm_set_irq_enabled(flags);
1610
}
1711

18-
#define arch_local_irq_enable arch_local_irq_enable
19-
static inline void arch_local_irq_enable(void)
20-
{
21-
wasm_set_irq_enabled(1);
22-
}
23-
24-
#define arch_local_irq_disable arch_local_irq_disable
25-
static inline void arch_local_irq_disable(void)
26-
{
27-
wasm_set_irq_enabled(0);
28-
}
29-
3012
#define arch_local_save_flags arch_local_save_flags
3113
static inline unsigned long arch_local_save_flags(void)
3214
{

arch/wasm/include/asm/page.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ typedef struct page *pgtable_t;
6060

6161
#define pfn_valid(pfn) ((pfn) < max_mapnr)
6262

63+
struct page;
64+
void arch_alloc_page(struct page *page, int order);
65+
#define HAVE_ARCH_ALLOC_PAGE
66+
6367
#include <asm-generic/getorder.h>
6468

6569
#endif

arch/wasm/include/asm/percpu.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef _WASM_PERCPU_H
2+
#define _WASM_PERCPU_H
3+
4+
#ifdef CONFIG_SMP
5+
#define PER_CPU_ATTRIBUTES _Thread_local
6+
#endif
7+
8+
#include <asm-generic/percpu.h>
9+
10+
#endif

arch/wasm/include/asm/processor.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
struct task_struct;
77

8-
static inline void cpu_relax(void)
9-
{
8+
static inline void cpu_relax(void) {
109
wasm_relax();
1110
}
1211

@@ -36,9 +35,12 @@ struct thread_struct {};
3635
{ \
3736
}
3837

39-
#define task_pt_regs(tsk) (struct pt_regs *)(NULL)
38+
#define task_pt_regs(task) \
39+
((struct pt_regs *)(task->stack + THREAD_SIZE) - 1)
40+
41+
// I believe this is unreferenced in nommu:
42+
#define TASK_SIZE (__builtin_trap(),U32_MAX)
4043

41-
#define TASK_SIZE U32_MAX
4244
#define TASK_UNMAPPED_BASE 0
4345

4446
#define KSTK_EIP(tsk) (0)

arch/wasm/include/asm/sigcontext.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#ifndef _WASM_SIGCONTEXT_H
22
#define _WASM_SIGCONTEXT_H
33

4-
struct pt_regs {};
4+
struct pt_regs {
5+
void* stack_pointer;
6+
};
57

68
struct sigcontext {
79
struct pt_regs regs;

arch/wasm/include/asm/smp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#define raw_smp_processor_id() (current_thread_info()->cpu)
55

6+
struct cpumask;
67
void arch_send_call_function_ipi_mask(const struct cpumask *mask);
78
void arch_send_call_function_single_ipi(int cpu);
89

arch/wasm/include/asm/thread_info.h

Lines changed: 10 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -11,63 +11,31 @@ struct thread_info {
1111
struct task_struct *task;
1212
unsigned long flags;
1313
int preempt_count;
14-
unsigned int worker;
14+
struct task_struct *from_sched;
15+
#ifdef CONFIG_SMP
16+
unsigned int cpu;
17+
#endif
1518
};
1619

17-
#define INIT_THREAD_INFO(tsk) \
18-
{ \
19-
.task = &tsk, .flags = 0, .preempt_count = 1, \
20+
#define INIT_THREAD_INFO(tsk) \
21+
{ \
22+
.task = &tsk, .flags = 0, .preempt_count = INIT_PREEMPT_COUNT, \
2023
}
2124

2225
extern unsigned long *__stack_pointer;
2326
#define current_stack_pointer __stack_pointer
2427

2528
#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
26-
#define TIF_NOTIFY_RESUME 1 /* callback before returning to user */
29+
#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
2730
#define TIF_SIGPENDING 2 /* signal pending */
2831
#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
29-
#define TIF_SINGLESTEP 4 /* reenable singlestep on user return*/
30-
#define TIF_SSBD 5 /* Speculative store bypass disable */
31-
#define TIF_SPEC_IB 9 /* Indirect branch speculation mitigation */
32-
#define TIF_SPEC_L1D_FLUSH 10 /* Flush L1D on mm switches (processes) */
33-
#define TIF_USER_RETURN_NOTIFY 11 /* notify kernel of userspace return */
34-
#define TIF_UPROBE 12 /* breakpointed or singlestepping */
35-
#define TIF_PATCH_PENDING 13 /* pending live patching update */
36-
#define TIF_NEED_FPU_LOAD 14 /* load FPU on return to userspace */
37-
#define TIF_NOCPUID 15 /* CPUID is not accessible in userland */
38-
#define TIF_NOTSC 16 /* TSC is not accessible in userland */
39-
#define TIF_NOTIFY_SIGNAL 17 /* signal notifications exist */
40-
#define TIF_MEMDIE 20 /* is terminating due to OOM killer */
41-
#define TIF_POLLING_NRFLAG 21 /* idle is polling for TIF_NEED_RESCHED */
42-
#define TIF_IO_BITMAP 22 /* uses I/O bitmap */
43-
#define TIF_SPEC_FORCE_UPDATE \
44-
23 /* Force speculation MSR update in context switch */
45-
#define TIF_FORCED_TF 24 /* true if TF in eflags artificially */
46-
#define TIF_BLOCKSTEP 25 /* set when we want DEBUGCTLMSR_BTF */
47-
#define TIF_LAZY_MMU_UPDATES 27 /* task is updating the mmu lazily */
48-
#define TIF_ADDR32 29 /* 32-bit address space on 64 bits */
32+
#define TIF_NOTIFY_SIGNAL 7 /* signal notifications exist */
33+
#define TIF_MEMDIE 17 /* OOM killer killed process */
4934

5035
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
5136
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
5237
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
5338
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
54-
#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP)
55-
#define _TIF_SSBD (1 << TIF_SSBD)
56-
#define _TIF_SPEC_IB (1 << TIF_SPEC_IB)
57-
#define _TIF_SPEC_L1D_FLUSH (1 << TIF_SPEC_L1D_FLUSH)
58-
#define _TIF_USER_RETURN_NOTIFY (1 << TIF_USER_RETURN_NOTIFY)
59-
#define _TIF_UPROBE (1 << TIF_UPROBE)
60-
#define _TIF_PATCH_PENDING (1 << TIF_PATCH_PENDING)
61-
#define _TIF_NEED_FPU_LOAD (1 << TIF_NEED_FPU_LOAD)
62-
#define _TIF_NOCPUID (1 << TIF_NOCPUID)
63-
#define _TIF_NOTSC (1 << TIF_NOTSC)
6439
#define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL)
65-
#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG)
66-
#define _TIF_IO_BITMAP (1 << TIF_IO_BITMAP)
67-
#define _TIF_SPEC_FORCE_UPDATE (1 << TIF_SPEC_FORCE_UPDATE)
68-
#define _TIF_FORCED_TF (1 << TIF_FORCED_TF)
69-
#define _TIF_BLOCKSTEP (1 << TIF_BLOCKSTEP)
70-
#define _TIF_LAZY_MMU_UPDATES (1 << TIF_LAZY_MMU_UPDATES)
71-
#define _TIF_ADDR32 (1 << TIF_ADDR32)
7240

7341
#endif

arch/wasm/include/asm/timex.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,4 @@ static inline cycles_t get_cycles(void)
99
return wasm_get_now_nsec();
1010
}
1111

12-
#define ARCH_HAS_READ_CURRENT_TIMER
13-
static inline int read_current_timer(unsigned long *timer_val)
14-
{
15-
__builtin_trap();
16-
*timer_val = wasm_get_now_nsec();
17-
return 0;
18-
}
19-
2012
#endif

arch/wasm/include/asm/wasm_imports.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@ import("get_irq_enabled") int wasm_get_irq_enabled(void);
1818
import("return_address") void *wasm_return_address(int level);
1919

2020
import("relax") void wasm_relax(void);
21+
import("idle") void wasm_idle(void);
22+
2123
import("restart") void wasm_restart(void);
2224

2325
import("get_dt") void wasm_get_dt(char *buf, size_t size);
2426

2527
import("get_now_nsec") unsigned long long wasm_get_now_nsec(void);
2628

27-
import("spawn_worker") unsigned int wasm_spawn_worker(unsigned int worker);
28-
import("start_worker") void wasm_start_worker(unsigned int worker);
29+
import("get_stacktrace") void wasm_get_stacktrace(char *buf, size_t size);
30+
31+
import("new_worker") void wasm_new_worker(void* arg, char name[16]);
2932

3033
#undef import
3134

arch/wasm/kernel/process.c

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,75 @@
1+
#include <asm/sysmem.h>
2+
#include <asm/wasm_imports.h>
3+
#include <linux/printk.h>
4+
#include <linux/ptrace.h>
15
#include <linux/sched.h>
6+
#include <linux/sched/task_stack.h>
27
#include <linux/sched/task.h>
38

4-
void *__switch_to(struct task_struct *from, struct task_struct *to)
9+
void arch_cpu_idle(void)
510
{
6-
__builtin_trap();
11+
wasm_idle();
712
}
813

14+
struct task_struct *__switch_to(struct task_struct *from,
15+
struct task_struct *to)
16+
{
17+
struct thread_info *from_info = task_thread_info(from);
18+
struct thread_info *to_info = task_thread_info(to);
19+
20+
to_info->from_sched = from;
21+
22+
pr_info("context switch: %u -> %u\n", from->pid, to->pid);
23+
24+
current = to;
25+
current_stack_pointer = task_pt_regs(to)->stack_pointer;
26+
27+
return from;
28+
}
29+
30+
struct entry_arg {
31+
struct thread_info *thread_info;
32+
int (*fn)(void *);
33+
void *fn_arg;
34+
};
35+
void show_stack(struct task_struct *task, unsigned long *sp,
36+
const char *loglvl);
37+
938
int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
1039
{
11-
__builtin_trap();
12-
}
40+
struct entry_arg *entry;
41+
42+
if (!args->fn) {
43+
panic("can't copy userspace thread");
44+
}
45+
46+
entry = kmalloc(sizeof(*entry), GFP_KERNEL);
47+
if (!entry) return -ENOMEM;
48+
49+
entry->fn = args->fn;
50+
entry->fn_arg = args->fn_arg;
51+
entry->thread_info = task_thread_info(p);
52+
53+
pr_info("spawning: %p %p\n", entry, entry->fn);
54+
wasm_new_worker(entry, p->comm);
55+
56+
return 0;
57+
}
58+
59+
__attribute__((export_name("task_entry"))) void __init task_entry(struct entry_arg *entry)
60+
{
61+
int (*fn)(void *) = entry->fn;
62+
void *fn_arg = entry->fn_arg;
63+
struct thread_info *thread_info = entry->thread_info;
64+
65+
tls_init();
66+
current = thread_info->from_sched;
67+
68+
kfree(entry);
69+
70+
if (thread_info->from_sched)
71+
schedule_tail(thread_info->from_sched);
72+
73+
fn(fn_arg);
74+
do_exit(0);
75+
}

arch/wasm/kernel/setup.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,7 @@ unsigned long volatile jiffies = INITIAL_JIFFIES;
1717

1818
char __init_begin[0], __init_end[0];
1919

20-
#undef current
21-
_Thread_local struct task_struct *current = { 0 };
20+
_Thread_local struct task_struct *current = &init_task;
2221

2322
unsigned long init_stack[THREAD_SIZE / sizeof(unsigned long)];
2423
unsigned long empty_zero_page[PAGE_SIZE / sizeof(unsigned long)] = { 0 };
@@ -40,16 +39,18 @@ extern void __heap_base;
4039
extern void __heap_end;
4140

4241
int __init setup_early_printk(char *buf);
43-
44-
static char wasm_dt[1024];
42+
void __init smp_init_cpus(void);
4543

4644
__attribute__((export_name("start"))) void __init _start(void)
4745
{
46+
static char wasm_dt[1024];
4847
__wasm_call_ctors();
4948

5049
setup_early_printk(NULL);
50+
5151
wasm_get_dt(wasm_dt, ARRAY_SIZE(wasm_dt));
5252
early_init_dt_scan(wasm_dt);
53+
early_init_fdt_scan_reserved_mem();
5354

5455
memblock_reserve(0, (phys_addr_t)&__heap_base);
5556

@@ -95,12 +96,3 @@ void machine_power_off(void)
9596
pr_info("poweroff\n");
9697
__builtin_trap();
9798
}
98-
99-
__attribute__((export_name("thread_entry"))) void __init
100-
_thread_entry(unsigned int worker)
101-
{
102-
early_printk("thread entry = %u\n", current_thread_info()->worker);
103-
current_thread_info()->worker = worker;
104-
early_printk(" = %u\n", current_thread_info()->worker);
105-
pr_info("entered new thread!\n");
106-
}

0 commit comments

Comments
 (0)