Skip to content

Commit 7b707b1

Browse files
committed
use a distinct memory for each process
currently no support for sharing memory across threads, no clue how/if mmap works now, will fix later.
1 parent dd7ee60 commit 7b707b1

File tree

10 files changed

+83
-40
lines changed

10 files changed

+83
-40
lines changed

arch/wasm/Kconfig

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ config WASM
2121
select PAGE_SIZE_64KB
2222
select SMP
2323
select THREAD_INFO_IN_TASK
24-
select UACCESS_MEMCPY if !MMU
2524

2625
config CMDLINE
2726
string "Kernel command string to append"

arch/wasm/drivers/virtio_wasm.c

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,6 @@
1212
#include <linux/virtio_ring.h>
1313
#include <linux/virtio.h>
1414

15-
void wasm_import(virtio, set_features)(u32 id, u64 features);
16-
17-
void wasm_import(virtio, setup)(u32 id, u32 irq, bool *is_config,
18-
bool *is_vring, u8 *config, u32 config_len);
19-
20-
void wasm_import(virtio, enable_vring)(u32 id, u32 index, u32 size,
21-
dma_addr_t desc);
22-
void wasm_import(virtio, disable_vring)(u32 id, u32 index);
23-
24-
void wasm_import(virtio, notify)(u32 id, u32 index);
25-
2615
#define to_virtio_wasm_device(_plat_dev) \
2716
container_of(_plat_dev, struct virtio_wasm_device, vdev)
2817

arch/wasm/include/asm/uaccess.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,23 @@
11
#ifndef _WASM_UACCESS_H
22
#define _WASM_UACCESS_H
33

4-
// TODO(wasm): when implementing mmu, swap generic/CONFIG_UACCESS_MEMCPY for custom impl
4+
#include <asm/wasm_imports.h>
5+
6+
#define __access_ok __access_ok
7+
static inline int __access_ok(const void __user *ptr, unsigned long size)
8+
{
9+
unsigned long limit = TASK_SIZE;
10+
unsigned long addr = (unsigned long)ptr;
11+
12+
return (size <= limit) && (addr <= (limit - size));
13+
}
14+
15+
#define raw_copy_from_user wasm_user_read
16+
#define raw_copy_to_user wasm_user_write
17+
#define __clear_user wasm_user_write_zeroes
18+
19+
#define INLINE_COPY_FROM_USER
20+
#define INLINE_COPY_TO_USER
521

622
#include <asm-generic/uaccess.h>
723

arch/wasm/include/asm/wasm_imports.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
__attribute__((import_module(#ns), import_name(#name))) \
88
wasm_##ns##_##name
99

10+
void wasm_import(boot, get_devicetree)(char *buf, size_t size);
11+
int wasm_import(boot, get_initramfs)(char *buf, size_t size);
12+
1013
void wasm_import(kernel, breakpoint)(void);
1114
void wasm_import(kernel, halt)(void);
1215
void wasm_import(kernel, restart)(void);
@@ -25,4 +28,26 @@ void wasm_import(kernel, spawn_worker)(void (*fn)(void *), void *arg,
2528

2629
void wasm_import(kernel, run_on_main)(void (*fn)(void *), void *arg);
2730

31+
int wasm_import(user, compile)(u8 *bytes, u32 len);
32+
void wasm_import(user, instantiate)(u32 stack, u32 memory, u32 table_size);
33+
34+
int wasm_import(user, read)(void *to, const void __user *from, unsigned long n);
35+
int wasm_import(user, write)(void __user *to, const void *from, unsigned long n);
36+
int wasm_import(user, write_zeroes)(void __user *to, unsigned long n);
37+
38+
#ifdef CONFIG_VIRTIO_WASM
39+
void wasm_import(virtio, set_features)(u32 id, u64 features);
40+
41+
void wasm_import(virtio, setup)(u32 id, u32 irq, bool *is_config,
42+
bool *is_vring, u8 *config, u32 config_len);
43+
44+
void wasm_import(virtio, enable_vring)(u32 id, u32 index, u32 size,
45+
dma_addr_t desc);
46+
void wasm_import(virtio, disable_vring)(u32 id, u32 index);
47+
48+
void wasm_import(virtio, notify)(u32 id, u32 index);
49+
#endif
50+
51+
#undef wasm_import
52+
2853
#endif

arch/wasm/kernel/binfmt_wasm.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,6 @@ static int get_wasm_dylink_mem_info(u8 *code, loff_t size,
161161
return ret;
162162
}
163163

164-
int wasm_import(user, compile)(u8 *bytes, u32 len);
165-
void wasm_import(user, instantiate)(u32 stack, u32 memory, u32 table_size);
166-
167164
static int load_wasm_binary(struct linux_binprm *bprm)
168165
{
169166
int ret;

arch/wasm/kernel/setup.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ void __wasm_call_ctors(void);
1515
int __init setup_early_printk(char *buf);
1616
void __init smp_init_cpus(unsigned int ncpus);
1717
void __init init_sections(unsigned long node);
18-
void wasm_import(boot, get_devicetree)(char *buf, size_t size);
19-
int wasm_import(boot, get_initramfs)(char *buf, size_t size);
2018

2119
char *__initramfs_start;
2220
unsigned long __initramfs_size;

tools/wasm/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,9 @@ export class Machine extends EventEmitter<{
167167
user: {
168168
compile: unavailable,
169169
instantiate: unavailable,
170+
read: unavailable,
171+
write: unavailable,
172+
write_zeroes: unavailable,
170173
},
171174
virtio: virtio_imports({
172175
memory: this.#memory,

tools/wasm/src/init2.cpio

3.15 KB
Binary file not shown.

tools/wasm/src/wasm.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ export interface Imports {
3737
user: {
3838
compile(buf: number, size: number): number;
3939
instantiate(stack: number, memory: number, table_size: number): void;
40+
read(to: number, from: number, n: number): number;
41+
write(to: number, from: number, n: number): number;
42+
write_zeroes(to: number, n: number): number;
4043
};
4144
virtio: {
4245
set_features(dev: number, features: bigint): void;

tools/wasm/src/worker.ts

Lines changed: 35 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ const postMessage = self.postMessage as (message: WorkerMessage) => void;
2121

2222
let user_module: WebAssembly.Module | null = null;
2323
let user_instance: WebAssembly.Instance | null = null;
24+
let user_memory: WebAssembly.Memory | null = null;
25+
let user_memory_buffer: Uint8Array | null = null;
2426

2527
self.onmessage = (event: MessageEvent<InitMessage>) => {
2628
const { fn, arg, vmlinux, memory } = event.data;
27-
const mem = new Uint8Array(memory.buffer);
29+
const memory_buffer = new Uint8Array(memory.buffer);
2830

2931
const imports = {
3032
env: { memory },
@@ -34,46 +36,57 @@ self.onmessage = (event: MessageEvent<InitMessage>) => {
3436
},
3537
user: {
3638
compile(buf, size) {
37-
const bytes = new Uint8Array(mem.slice(buf, buf + size));
39+
const bytes = new Uint8Array(memory_buffer.slice(buf, buf + size));
3840
try {
3941
user_module = new WebAssembly.Module(bytes);
4042
return 0;
4143
} catch {
4244
return -8; // exec format error
4345
}
4446
},
45-
instantiate(stack, memory_base, table_size) {
47+
instantiate() {
4648
assert(user_module);
4749

50+
// TODO: shared memory support by postMessage-ing the buffer back to the main thread
51+
// and having it pass all known memories back to newly spawned workers.
52+
// TODO: read the real initial size from the module.
53+
// TOOD: enforce rlimit via maximum.
54+
user_memory = new WebAssembly.Memory({
55+
initial: 10,
56+
maximum: 100,
57+
});
58+
user_memory_buffer = new Uint8Array(user_memory.buffer);
59+
4860
try {
4961
user_instance = new WebAssembly.Instance(user_module, {
50-
env: {
51-
memory,
52-
__stack_pointer: new WebAssembly.Global({
53-
value: "i32",
54-
mutable: true,
55-
}, stack),
56-
__memory_base: memory_base,
57-
__indirect_function_table: new WebAssembly.Table({
58-
element: "anyfunc",
59-
initial: table_size,
60-
}),
61-
__table_base: 0,
62-
},
62+
env: { memory: user_memory },
6363
linux: {
6464
syscall: instance.exports.syscall,
6565
get_thread_area: instance.exports.get_thread_area,
6666
},
6767
});
68-
69-
const { __wasm_apply_data_relocs } = user_instance.exports;
70-
if (typeof __wasm_apply_data_relocs === "function") {
71-
__wasm_apply_data_relocs();
72-
}
7368
} catch (error) {
7469
console.warn("error instantiating user module:", error);
7570
}
76-
},
71+
},
72+
read(to, from, n) {
73+
assert(user_memory_buffer);
74+
const slice = user_memory_buffer.subarray(from, from + n);
75+
memory_buffer.set(slice, to);
76+
return n - slice.length;
77+
},
78+
write(to, from, n) {
79+
assert(user_memory_buffer);
80+
const slice = memory_buffer.subarray(from, from + n);
81+
user_memory_buffer.set(slice, to);
82+
return n - slice.length;
83+
},
84+
write_zeroes(to, n) {
85+
assert(user_memory_buffer);
86+
const slice = user_memory_buffer.subarray(to, to + n);
87+
slice.fill(0);
88+
return n - slice.length;
89+
},
7790
},
7891
kernel: kernel_imports({
7992
is_worker: true,

0 commit comments

Comments
 (0)