Skip to content

Commit

Permalink
symmetric multi processing (it doesnt work)
Browse files Browse the repository at this point in the history
  • Loading branch information
tombl committed Feb 15, 2024
1 parent db82da5 commit 8ae8223
Show file tree
Hide file tree
Showing 31 changed files with 525 additions and 190 deletions.
12 changes: 7 additions & 5 deletions arch/wasm/Kconfig
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
config WASM
def_bool y
depends on !BINFMT_ELF && !SMP && !MMU && !MODULES && !COREDUMP && !SECCOMP && !UPROBES && !COMPAT
depends on !BINFMT_ELF && !MMU && !MODULES && !COREDUMP && !SECCOMP && !UPROBES && !COMPAT
select ARCH_HAS_BINFMT_WASM
select ARCH_HAS_CURRENT_STACK_POINTER
select ARCH_HAS_SYSCALL_WRAPPER
select ARCH_NO_SWAP
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
select BUG
select FLATMEM
select FORCE_NR_CPUS
select GENERIC_ATOMIC64
select GENERIC_CSUM
select GENERIC_HWEIGHT
select OF
select OF_EARLY_FLATTREE
select PAGE_SIZE_64KB
select UACCESS_MEMCPY if !MMU
select SMP
select THREAD_INFO_IN_TASK
select UACCESS_MEMCPY if !MMU
select USE_PER_CPU_TLS

config ARCH_HAS_BINFMT_WASM
bool
Expand All @@ -38,12 +40,12 @@ config EARLY_PRINTK
def_bool y

config SMP
def_bool n
def_bool y

config NR_CPUS
int
default 1 if !SMP
default 64 if SMP
default 8 if SMP

config HZ
int
Expand Down
18 changes: 18 additions & 0 deletions arch/wasm/include/asm/bug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#ifndef _WASM_BUG_H
#define _WASM_BUG_H

#include <asm/wasm_imports.h>

#define HAVE_ARCH_BUG
#define BUG() \
do { \
pr_crit("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, \
__func__); \
barrier_before_unreachable(); \
wasm_breakpoint(); \
__builtin_trap(); \
} while (0)

#include <asm-generic/bug.h>

#endif
5 changes: 3 additions & 2 deletions arch/wasm/include/asm/cmpxchg.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _WASM_CMPXCHG_H
#define _WASM_CMPXCHG_H

#include <asm/bug.h>
#include <linux/types.h>

static inline unsigned long __arch_xchg(unsigned long x, volatile void *ptr,
Expand All @@ -21,7 +22,7 @@ static inline unsigned long __arch_xchg(unsigned long x, volatile void *ptr,
return __atomic_exchange_n((volatile u64 *)ptr, x, order);
#endif
default:
__builtin_trap();
BUG();
}
}

Expand Down Expand Up @@ -68,7 +69,7 @@ static inline unsigned long __arch_cmpxchg(volatile void *ptr,
(u64 *)&old, new, 0, order,
__ATOMIC_SEQ_CST)
#endif
default : __builtin_trap();
default : BUG();
}
}

Expand Down
4 changes: 0 additions & 4 deletions arch/wasm/include/asm/percpu.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#ifndef _WASM_PERCPU_H
#define _WASM_PERCPU_H

#ifdef CONFIG_SMP
#define PER_CPU_ATTRIBUTES _Thread_local
#endif

#include <asm-generic/percpu.h>

#endif
8 changes: 7 additions & 1 deletion arch/wasm/include/asm/processor.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,38 @@
#ifndef _WASM_PROCESSOR_H
#define _WASM_PROCESSOR_H

#include <asm/bug.h>
#include <asm/wasm_imports.h>

struct task_struct;

static inline void cpu_relax(void) {
static inline void cpu_relax(void)
{
wasm_relax();
}

#define current_text_addr() wasm_return_address(-1)

static inline unsigned long thread_saved_pc(struct task_struct *tsk)
{
BUG();
return 0;
}

static inline void prepare_to_copy(struct task_struct *tsk)
{
BUG();
}

static inline unsigned long __get_wchan(struct task_struct *p)
{
BUG();
return 0;
}

static inline void flush_thread(void)
{
BUG();
}

struct thread_struct {};
Expand Down
4 changes: 1 addition & 3 deletions arch/wasm/include/asm/sigcontext.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#ifndef _WASM_SIGCONTEXT_H
#define _WASM_SIGCONTEXT_H

struct pt_regs {
void* stack_pointer;
};
struct pt_regs {};

struct sigcontext {
struct pt_regs regs;
Expand Down
6 changes: 4 additions & 2 deletions arch/wasm/include/asm/syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,18 @@
#define _WASM_SYSCALL_H

#include <asm-generic/syscalls.h>
#include <asm/bug.h>
#include <asm/ptrace.h>

static inline long syscall_get_nr(struct task_struct *task,
struct pt_regs *regs)
{
__builtin_trap();
BUG();
}

static inline int syscall_get_arch(struct task_struct *task)
{
return 0;
BUG();
}

#endif
4 changes: 3 additions & 1 deletion arch/wasm/include/asm/sysmem.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define _WASM_SYSMEM_H

void zones_init(void);
void tls_init(void);
void early_tls_init(void);
void smp_tls_prepare(void);
void smp_tls_init(int cpu);

#endif
14 changes: 6 additions & 8 deletions arch/wasm/include/asm/thread_info.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
#ifndef _WASM_THREAD_INFO_H
#define _WASM_THREAD_INFO_H

// THREAD_SIZE is the size of the task_struct+kernel stack
// wasm stores stacks outside of addressable memory, plus its page size is 64KiB
// so that'll be big enough
#define THREAD_SIZE PAGE_SIZE
#define THREAD_SIZE_ORDER 0
/* THREAD_SIZE is the size of the task_struct + kernel stack
* This is asserted in setup, but the stack should be 1 page,
* and a task_struct should be *way* less than a page big. */
#define THREAD_SIZE_ORDER 1
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
#define THREAD_SHIFT (PAGE_SHIFT << THREAD_SIZE_ORDER)

struct thread_info {
struct task_struct *task;
Expand All @@ -22,9 +23,6 @@ struct thread_info {
.task = &tsk, .flags = 0, .preempt_count = INIT_PREEMPT_COUNT, \
}

extern unsigned long *__stack_pointer;
#define current_stack_pointer __stack_pointer

#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
#define TIF_SIGPENDING 2 /* signal pending */
Expand Down
9 changes: 4 additions & 5 deletions arch/wasm/include/asm/wasm_imports.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
#define import(name) __attribute__((import_module("kernel"), import_name(name)))

import("breakpoint") void wasm_breakpoint(void);
import("relax") void wasm_relax(void);
import("idle") void wasm_idle(void);
import("halt") void wasm_halt(void);
import("restart") void wasm_restart(void);

import("boot_console_write") void wasm_boot_console_write(const char *msg,
size_t len);
Expand All @@ -17,11 +21,6 @@ import("get_irq_enabled") int wasm_get_irq_enabled(void);

import("return_address") void *wasm_return_address(int level);

import("relax") void wasm_relax(void);
import("idle") void wasm_idle(void);

import("restart") void wasm_restart(void);

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

import("get_now_nsec") unsigned long long wasm_get_now_nsec(void);
Expand Down
4 changes: 3 additions & 1 deletion arch/wasm/include/uapi/asm/ptrace.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _WASM_PTRACE_H
#define _WASM_PTRACE_H

#include <asm/bug.h>
#include <linux/errno.h>

struct task_struct;
Expand All @@ -14,12 +15,13 @@ struct task_struct;
static inline long arch_ptrace(struct task_struct *child, long request,
unsigned long addr, unsigned long data)
{
BUG();
return -EINVAL;
}

static inline void ptrace_disable(struct task_struct *child)
{
__builtin_trap();
BUG();
}

#endif
3 changes: 1 addition & 2 deletions arch/wasm/kernel/irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@
#include <linux/irqchip.h>
#include <linux/seq_file.h>

void init_IRQ(void)
void __init init_IRQ(void)
{
pr_info("init irq\n");
irqchip_init();
}

Expand Down
58 changes: 44 additions & 14 deletions arch/wasm/kernel/process.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "linux/thread_info.h"
#include <asm/sysmem.h>
#include <asm/wasm_imports.h>
#include <linux/printk.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/task.h>
Expand All @@ -11,23 +11,43 @@ void arch_cpu_idle(void)
wasm_idle();
}

__asm__(".globaltype __stack_pointer, i32\n");

static void *get_stack_pointer(void)
{
void *ptr;
__asm("global.get __stack_pointer\n"
"local.set %0"
: "=r"(ptr));
return ptr;
}

static void __always_inline set_stack_pointer(void *ptr)
{
__asm("local.get %0\n"
"global.set __stack_pointer" ::"r"(ptr));
}

struct task_struct *__switch_to(struct task_struct *from,
struct task_struct *to)
{
struct thread_info *from_info = task_thread_info(from);
// struct thread_info *from_info = task_thread_info(from);
struct thread_info *to_info = task_thread_info(to);

to_info->from_sched = from;

pr_info("context switch: %u -> %u\n", from->pid, to->pid);
pr_info("context switch CPU: %i PID: %u -> %u STACK: %p -> %p\n",
smp_processor_id(), from->pid, to->pid, get_stack_pointer(),
to->stack);

set_stack_pointer(to->stack);
current = to;
current_stack_pointer = task_pt_regs(to)->stack_pointer;

return from;
}

struct entry_arg {
int cpu;
struct thread_info *thread_info;
int (*fn)(void *);
void *fn_arg;
Expand All @@ -39,37 +59,47 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
struct entry_arg *entry;

if (!args->fn) {
panic("can't copy userspace thread");
}
if (!args->fn) panic("can't copy userspace thread"); // yet

entry = kmalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) return -ENOMEM;
if (!entry)
return -ENOMEM;

entry->fn = args->fn;
entry->fn_arg = args->fn_arg;
entry->thread_info = task_thread_info(p);

pr_info("spawning: %p %p\n", entry, entry->fn);
wasm_new_worker(entry, p->comm);

return 0;
}

__attribute__((export_name("task_entry"))) void __init task_entry(struct entry_arg *entry)
static atomic_t next_cpu_nr = ATOMIC_INIT(1);
void noinline_for_stack task_entry_inner(struct entry_arg *entry)
{
int (*fn)(void *) = entry->fn;
void *fn_arg = entry->fn_arg;
struct thread_info *thread_info = entry->thread_info;
int cpu;
kfree(entry);

tls_init();
cpu = atomic_inc_return(&next_cpu_nr);
smp_tls_init(cpu);
current = thread_info->from_sched;

kfree(entry);
current_thread_info()->cpu = cpu;
pr_info("== THREAD ENTRY! CPU: %i ==", cpu);

if (thread_info->from_sched)
schedule_tail(thread_info->from_sched);

fn(fn_arg);

do_exit(0);
}

__attribute__((export_name("task_entry"))) void
task_entry(struct entry_arg *entry)
{
set_stack_pointer(entry->thread_info->task->stack);
task_entry_inner(entry);
}
2 changes: 1 addition & 1 deletion arch/wasm/kernel/ptrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
void show_regs(struct pt_regs *fp)
{
pr_info("show_regs");
__builtin_trap();
BUG();
}
Loading

0 comments on commit 8ae8223

Please sign in to comment.