Add initial release patches
This commit is contained in:
parent
6fa54d5671
commit
de0118ef2a
8
patches/busybox-kernel-headers/README.md
Normal file
8
patches/busybox-kernel-headers/README.md
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
# Busybox Kernel Headers
|
||||||
|
Read repo root README.md for an explanation of what this is.
|
||||||
|
|
||||||
|
## Origin
|
||||||
|
This patch comes from the patch set at https://github.com/sabotage-linux/kernel-headers/tree/4.4.2/patches but is slightly modified to fit a 6.4 kernel. Note that patch 2 in that set fails but can be ignored, patch 4, 6 and 8 partially works and partially needs some merge conflict resolving. All of this is combined into one patch in this repo. It would probably be better to offer a complete new patch set, oh well...
|
||||||
|
|
||||||
|
## License
|
||||||
|
The same license as for the original source files apply, i.e. "GPL-2.0 WITH Linux-syscall-note".
|
||||||
1851
patches/busybox-kernel-headers/busybox-kernel-headers-for-musl.patch
Normal file
1851
patches/busybox-kernel-headers/busybox-kernel-headers-for-musl.patch
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
14
patches/initramfs/init
Executable file
14
patches/initramfs/init
Executable file
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
mount -t proc none /proc
|
||||||
|
mount -t sysfs none /sys
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "Welcome to Linux running on Wasm!"
|
||||||
|
echo "Known bugs:"
|
||||||
|
echo " * Terminal input freezes after a while (timer issue)."
|
||||||
|
echo " * dup_fd, wq_worker_comm, rcu_os crash (memory corruption (fixed?))."
|
||||||
|
echo " * longjmp() does not work (not implemented yet)."
|
||||||
|
echo
|
||||||
|
|
||||||
|
exec /sbin/init -s
|
||||||
BIN
patches/initramfs/initramfs-base.cpio
Normal file
BIN
patches/initramfs/initramfs-base.cpio
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,68 @@
|
||||||
|
From 99fe993477b73fab9aeffb8ed96c79319f2abfff Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 14 Sep 2025 17:03:25 +0200
|
||||||
|
Subject: [PATCH] Allow architecture-specific panic handling
|
||||||
|
|
||||||
|
Debugging panics can be made much easier in hosted architectures (like
|
||||||
|
Wasm) if they can intercept panic() calls right when they happen.
|
||||||
|
---
|
||||||
|
include/asm-generic/Kbuild | 1 +
|
||||||
|
include/asm-generic/panic.h | 12 ++++++++++++
|
||||||
|
kernel/panic.c | 3 +++
|
||||||
|
3 files changed, 16 insertions(+)
|
||||||
|
create mode 100644 include/asm-generic/panic.h
|
||||||
|
|
||||||
|
diff --git a/include/asm-generic/Kbuild b/include/asm-generic/Kbuild
|
||||||
|
index 941be574b..f1feb32a4 100644
|
||||||
|
--- a/include/asm-generic/Kbuild
|
||||||
|
+++ b/include/asm-generic/Kbuild
|
||||||
|
@@ -42,6 +42,7 @@ mandatory-y += mmu_context.h
|
||||||
|
mandatory-y += module.h
|
||||||
|
mandatory-y += module.lds.h
|
||||||
|
mandatory-y += msi.h
|
||||||
|
+mandatory-y += panic.h
|
||||||
|
mandatory-y += pci.h
|
||||||
|
mandatory-y += percpu.h
|
||||||
|
mandatory-y += pgalloc.h
|
||||||
|
diff --git a/include/asm-generic/panic.h b/include/asm-generic/panic.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..5f1a0ac69
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/include/asm-generic/panic.h
|
||||||
|
@@ -0,0 +1,12 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||||
|
+
|
||||||
|
+#ifndef _ASM_GENERIC_PANIC_H
|
||||||
|
+#define _ASM_GENERIC_PANIC_H
|
||||||
|
+
|
||||||
|
+#ifndef CONFIG_ARCH_HAVE_PANIC_NOTIFY
|
||||||
|
+static inline void arch_panic_notify(const char *msg)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#endif /* _ASM_GENERIC_PANIC_H */
|
||||||
|
diff --git a/kernel/panic.c b/kernel/panic.c
|
||||||
|
index c990ada85..c2343cfc9 100644
|
||||||
|
--- a/kernel/panic.c
|
||||||
|
+++ b/kernel/panic.c
|
||||||
|
@@ -36,6 +36,7 @@
|
||||||
|
#include <linux/sysfs.h>
|
||||||
|
#include <linux/context_tracking.h>
|
||||||
|
#include <trace/events/error_report.h>
|
||||||
|
+#include <asm/panic.h>
|
||||||
|
#include <asm/sections.h>
|
||||||
|
|
||||||
|
#define PANIC_TIMER_STEP 100
|
||||||
|
@@ -397,6 +398,8 @@ void panic(const char *fmt, ...)
|
||||||
|
|
||||||
|
panic_print_sys_info(true);
|
||||||
|
|
||||||
|
+ arch_panic_notify(buf);
|
||||||
|
+
|
||||||
|
if (!panic_blink)
|
||||||
|
panic_blink = no_blink;
|
||||||
|
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
From 8d9649b899cd680ad4f5f57069eeceed72acc162 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 14 Sep 2025 17:29:37 +0200
|
||||||
|
Subject: [PATCH] Add missing processor.h include for asm-generic/barrier.h
|
||||||
|
|
||||||
|
The default implementation of smp_cond_load_relaxed() uses cpu_relax(),
|
||||||
|
which is defined in the arch-specific processor.h header.
|
||||||
|
---
|
||||||
|
include/asm-generic/barrier.h | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
diff --git a/include/asm-generic/barrier.h b/include/asm-generic/barrier.h
|
||||||
|
index 961f4d88f..2fd9233f0 100644
|
||||||
|
--- a/include/asm-generic/barrier.h
|
||||||
|
+++ b/include/asm-generic/barrier.h
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/kcsan-checks.h>
|
||||||
|
+#include <asm/processor.h>
|
||||||
|
#include <asm/rwonce.h>
|
||||||
|
|
||||||
|
#ifndef nop
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
From 29413574b48c2f12120b65573d28324d74129ee5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 14 Sep 2025 18:21:14 +0200
|
||||||
|
Subject: [PATCH] Align dot instead of section in vmlinux.lds.h
|
||||||
|
|
||||||
|
The rudimentary linker script support in wasm-ld does not permit a section
|
||||||
|
to be aligned directly. This workaround overcomes that limitation by
|
||||||
|
immediately aligning the dot at the start of each section instead.
|
||||||
|
---
|
||||||
|
include/asm-generic/vmlinux.lds.h | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
|
||||||
|
index da9e5629e..b331a3947 100644
|
||||||
|
--- a/include/asm-generic/vmlinux.lds.h
|
||||||
|
+++ b/include/asm-generic/vmlinux.lds.h
|
||||||
|
@@ -865,7 +865,8 @@
|
||||||
|
/* Built-in firmware blobs */
|
||||||
|
#ifdef CONFIG_FW_LOADER
|
||||||
|
#define FW_LOADER_BUILT_IN_DATA \
|
||||||
|
- .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) ALIGN(8) { \
|
||||||
|
+ . = ALIGN(8); \
|
||||||
|
+ .builtin_fw : AT(ADDR(.builtin_fw) - LOAD_OFFSET) { \
|
||||||
|
BOUNDED_SECTION_PRE_LABEL(.builtin_fw, _builtin_fw, __start, __end) \
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
3758
patches/kernel/0005-Add-Wasm-architecture.patch
Normal file
3758
patches/kernel/0005-Add-Wasm-architecture.patch
Normal file
File diff suppressed because it is too large
Load Diff
517
patches/kernel/0006-Add-Wasm-binfmt.patch
Normal file
517
patches/kernel/0006-Add-Wasm-binfmt.patch
Normal file
|
|
@ -0,0 +1,517 @@
|
||||||
|
From 66c917eaad32544aaf992bffa61f1dac0ad37746 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 12 May 2024 17:15:17 +0200
|
||||||
|
Subject: [PATCH] Add Wasm binfmt
|
||||||
|
|
||||||
|
While ELF is used for basically every other Linux-supported
|
||||||
|
architecture, current Wasm toolchains produce binaries in the .wasm
|
||||||
|
format. The .wasm file format is also the format all major Wasm
|
||||||
|
runtimes/VMs (e.g. browsers) consumes.
|
||||||
|
---
|
||||||
|
arch/wasm/Kconfig | 2 +
|
||||||
|
fs/Kconfig.binfmt | 9 +
|
||||||
|
fs/Makefile | 1 +
|
||||||
|
fs/binfmt_wasm.c | 446 ++++++++++++++++++++++++++++++++++++++++++++++
|
||||||
|
4 files changed, 458 insertions(+)
|
||||||
|
create mode 100644 fs/binfmt_wasm.c
|
||||||
|
|
||||||
|
diff --git a/arch/wasm/Kconfig b/arch/wasm/Kconfig
|
||||||
|
index f6e566f50..744e8c676 100644
|
||||||
|
--- a/arch/wasm/Kconfig
|
||||||
|
+++ b/arch/wasm/Kconfig
|
||||||
|
@@ -40,6 +40,8 @@ config WASM
|
||||||
|
select ARCH_SUPPORTS_LTO_CLANG
|
||||||
|
select ARCH_SUPPORTS_LTO_CLANG_THIN
|
||||||
|
|
||||||
|
+ select ARCH_HAS_BINFMT_WASM
|
||||||
|
+
|
||||||
|
# TODO: Very inefficient, replace with native stuff. Our atomic impl.
|
||||||
|
# of xchg and cmpxchg already supports 64-bit integers, we could use it.
|
||||||
|
select GENERIC_ATOMIC64
|
||||||
|
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
|
||||||
|
index 93539aac0..cbddea6a0 100644
|
||||||
|
--- a/fs/Kconfig.binfmt
|
||||||
|
+++ b/fs/Kconfig.binfmt
|
||||||
|
@@ -142,6 +142,15 @@ config BINFMT_ZFLAT
|
||||||
|
help
|
||||||
|
Support FLAT format compressed binaries
|
||||||
|
|
||||||
|
+config ARCH_HAS_BINFMT_WASM
|
||||||
|
+ bool
|
||||||
|
+
|
||||||
|
+config BINFMT_WASM
|
||||||
|
+ bool "Kernel support for Wasm binaries"
|
||||||
|
+ depends on ARCH_HAS_BINFMT_WASM
|
||||||
|
+ help
|
||||||
|
+ Support WebAssembly format binaries.
|
||||||
|
+
|
||||||
|
config BINFMT_MISC
|
||||||
|
tristate "Kernel support for MISC binaries"
|
||||||
|
help
|
||||||
|
diff --git a/fs/Makefile b/fs/Makefile
|
||||||
|
index 5bfdbf0d7..ab4581f7d 100644
|
||||||
|
--- a/fs/Makefile
|
||||||
|
+++ b/fs/Makefile
|
||||||
|
@@ -44,6 +44,7 @@ obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
|
||||||
|
obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
|
||||||
|
obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
|
||||||
|
obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
|
||||||
|
+obj-$(CONFIG_BINFMT_WASM) += binfmt_wasm.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_FS_MBCACHE) += mbcache.o
|
||||||
|
obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
|
||||||
|
diff --git a/fs/binfmt_wasm.c b/fs/binfmt_wasm.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..51f268246
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/fs/binfmt_wasm.c
|
||||||
|
@@ -0,0 +1,446 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
+/* Somewhat based on binfmt_flat.c and binfmt_elf_fdpic.c */
|
||||||
|
+
|
||||||
|
+#include <linux/kernel.h>
|
||||||
|
+#include <linux/sched.h>
|
||||||
|
+#include <linux/sched/task_stack.h>
|
||||||
|
+#include <linux/mm.h>
|
||||||
|
+#include <linux/mman.h>
|
||||||
|
+#include <linux/errno.h>
|
||||||
|
+#include <linux/signal.h>
|
||||||
|
+#include <linux/string.h>
|
||||||
|
+#include <linux/fs.h>
|
||||||
|
+#include <linux/file.h>
|
||||||
|
+#include <linux/ptrace.h>
|
||||||
|
+#include <linux/user.h>
|
||||||
|
+#include <linux/slab.h>
|
||||||
|
+#include <linux/binfmts.h>
|
||||||
|
+#include <linux/personality.h>
|
||||||
|
+#include <linux/init.h>
|
||||||
|
+#include <linux/uaccess.h>
|
||||||
|
+#include <linux/vmalloc.h>
|
||||||
|
+
|
||||||
|
+#define WASM_STACK_SIZE (2UL * PAGE_SIZE)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Userland expects the stack to be page aligned as of now, which allows it to
|
||||||
|
+ * find the initial stack pointer by rounding up the current stack pointer to
|
||||||
|
+ * the next page in the _start function. This allows _start to be written in C.
|
||||||
|
+ * If this restriction can be lifted we could instead use something like this:
|
||||||
|
+ * max_t(unsigned long, sizeof(void *), ARCH_SLAB_MINALIGN)
|
||||||
|
+ */
|
||||||
|
+#define WASM_STACK_ALIGN PAGE_SIZE
|
||||||
|
+
|
||||||
|
+#define WASM_DYLINK_MEMINFO (0x01)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Parse the env- and arg-strings in new user memory and create the pointer
|
||||||
|
+ * tables from them, and put their addresses on the "stack", recording the new
|
||||||
|
+ * stack pointer value.
|
||||||
|
+ */
|
||||||
|
+static int create_wasm_tables(struct linux_binprm *bprm, unsigned long arg_start)
|
||||||
|
+{
|
||||||
|
+ char __user *p;
|
||||||
|
+ unsigned long __user *sp;
|
||||||
|
+ long i, len;
|
||||||
|
+ const struct cred *cred = current_cred();
|
||||||
|
+
|
||||||
|
+ // We emulate common ELF auxillary vectors to help userland out a bit.
|
||||||
|
+ const u32 wasm_auxv[] = {
|
||||||
|
+ AT_NOTELF, 1U,
|
||||||
|
+ AT_PAGESZ, PAGE_SIZE,
|
||||||
|
+ AT_UID, from_kuid_munged(cred->user_ns, cred->uid),
|
||||||
|
+ AT_EUID, from_kuid_munged(cred->user_ns, cred->euid),
|
||||||
|
+ AT_GID, from_kgid_munged(cred->user_ns, cred->gid),
|
||||||
|
+ AT_EGID, from_kgid_munged(cred->user_ns, cred->gid),
|
||||||
|
+ AT_SECURE, bprm->secureexec,
|
||||||
|
+ AT_NULL, 0U /* end */
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ p = (char __user *)arg_start;
|
||||||
|
+ sp = (unsigned long __user *)current->mm->start_stack;
|
||||||
|
+
|
||||||
|
+ sp -= (sizeof(wasm_auxv) + (sizeof(unsigned long) - 1U)) /
|
||||||
|
+ sizeof(unsigned long);
|
||||||
|
+ sp -= bprm->envc + 1;
|
||||||
|
+ sp -= bprm->argc + 1;
|
||||||
|
+ sp -= 1; /* &argc */
|
||||||
|
+
|
||||||
|
+ current->mm->start_stack = (unsigned long)sp & -WASM_STACK_ALIGN;
|
||||||
|
+ sp = (unsigned long __user *)current->mm->start_stack;
|
||||||
|
+
|
||||||
|
+ if (put_user(bprm->argc, sp++))
|
||||||
|
+ return -EFAULT;
|
||||||
|
+
|
||||||
|
+ current->mm->arg_start = (unsigned long)p;
|
||||||
|
+ for (i = bprm->argc; i > 0; i--) {
|
||||||
|
+ if (put_user((unsigned long)p, sp++))
|
||||||
|
+ return -EFAULT;
|
||||||
|
+ len = strnlen_user(p, MAX_ARG_STRLEN);
|
||||||
|
+ if (!len || len > MAX_ARG_STRLEN)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ p += len;
|
||||||
|
+ }
|
||||||
|
+ if (put_user(0, sp++))
|
||||||
|
+ return -EFAULT;
|
||||||
|
+ current->mm->arg_end = (unsigned long)p;
|
||||||
|
+
|
||||||
|
+ current->mm->env_start = (unsigned long)p;
|
||||||
|
+ for (i = bprm->envc; i > 0; i--) {
|
||||||
|
+ if (put_user((unsigned long)p, sp++))
|
||||||
|
+ return -EFAULT;
|
||||||
|
+ len = strnlen_user(p, MAX_ARG_STRLEN);
|
||||||
|
+ if (!len || len > MAX_ARG_STRLEN)
|
||||||
|
+ return -EINVAL;
|
||||||
|
+ p += len;
|
||||||
|
+ }
|
||||||
|
+ if (put_user(0, sp++))
|
||||||
|
+ return -EFAULT;
|
||||||
|
+ current->mm->env_end = (unsigned long)p;
|
||||||
|
+
|
||||||
|
+ memcpy(sp, wasm_auxv, sizeof(wasm_auxv));
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Read unsigned LEB128 encoded value, encoding a maximum of 32 bits, limited to
|
||||||
|
+ * a certain length. The input can be anywhere from 0 to 5 bytes in length,
|
||||||
|
+ * unless limited by the count artgument. A count of 5 should normally be used.
|
||||||
|
+ */
|
||||||
|
+static bool
|
||||||
|
+wasm_consume_varU32(char **bufp, unsigned int *output, unsigned long count)
|
||||||
|
+{
|
||||||
|
+ unsigned int result = 0;
|
||||||
|
+ char* buf = *bufp;
|
||||||
|
+ char* end = buf + count;
|
||||||
|
+ unsigned char chunk;
|
||||||
|
+ int shift = 0;
|
||||||
|
+
|
||||||
|
+ while (buf != end) {
|
||||||
|
+ chunk = *(buf++);
|
||||||
|
+
|
||||||
|
+ result |= (chunk & 0x7F) << shift;
|
||||||
|
+ shift += 7;
|
||||||
|
+
|
||||||
|
+ if (!(chunk & 0x80))
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *output = result;
|
||||||
|
+ *bufp = buf;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Return false to signal if the "continue bit" was set on the last
|
||||||
|
+ * byte, indicating faulty input data, or premature exit if count < 5.
|
||||||
|
+ */
|
||||||
|
+ return !(chunk & 0x80);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * User data version of wasm_consume_varU32.
|
||||||
|
+ */
|
||||||
|
+static bool wasm_consume_varU32_user(
|
||||||
|
+ unsigned long *bufp, unsigned int *output, unsigned long count)
|
||||||
|
+{
|
||||||
|
+ unsigned int result = 0;
|
||||||
|
+ unsigned long buf = *bufp;
|
||||||
|
+ unsigned long end = buf + count;
|
||||||
|
+ unsigned char chunk;
|
||||||
|
+ int shift = 0;
|
||||||
|
+
|
||||||
|
+ while (buf != end) {
|
||||||
|
+ if (get_user(chunk, (unsigned char __user *)(buf++)))
|
||||||
|
+ return false;
|
||||||
|
+
|
||||||
|
+ result |= (chunk & 0x7F) << shift;
|
||||||
|
+ shift += 7;
|
||||||
|
+
|
||||||
|
+ if (!(chunk & 0x80))
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *output = result;
|
||||||
|
+ *bufp = buf;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Return false to signal if the "continue bit" was set on the last
|
||||||
|
+ * byte, indicating faulty input data, or premature exit if count < 5.
|
||||||
|
+ */
|
||||||
|
+ return !(chunk & 0x80);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int load_wasm_file(struct linux_binprm *bprm, unsigned long extra_stack)
|
||||||
|
+{
|
||||||
|
+ unsigned long data_start = 0; /* Will contain data and bss */
|
||||||
|
+ unsigned long stack_size;
|
||||||
|
+ unsigned long whole_start, whole_p, whole_size, whole_end;
|
||||||
|
+ loff_t whole_size_ll;
|
||||||
|
+ char *parsed = bprm->buf;
|
||||||
|
+ int ret;
|
||||||
|
+
|
||||||
|
+ /* Related to Wasm dylink.0 parsing: */
|
||||||
|
+ unsigned int dylink_0_length;
|
||||||
|
+ unsigned long count;
|
||||||
|
+ u8 subsection_id;
|
||||||
|
+ unsigned int subsection_length;
|
||||||
|
+ unsigned long subsection_end;
|
||||||
|
+
|
||||||
|
+ /* Related to WASM_DYLINK_MEMINFO parsing: */
|
||||||
|
+ bool has_meminfo = false;
|
||||||
|
+ unsigned int data_size; /* memorysize */
|
||||||
|
+ unsigned int data_align; /* memoryalignment unpacked */
|
||||||
|
+ unsigned int table_size; /* tablesize */
|
||||||
|
+ unsigned int table_align; /* tablealign unpacked */
|
||||||
|
+
|
||||||
|
+ if (memcmp(parsed, "\x00" "asm", 4UL)) { /* Wasm binary magic header */
|
||||||
|
+ return -ENOEXEC;
|
||||||
|
+ }
|
||||||
|
+ parsed += 4UL;
|
||||||
|
+
|
||||||
|
+ /* We only know version 1 of the format. */
|
||||||
|
+ if (memcmp(parsed, "\x01\x00\x00\x00", 4UL)) { /* Version 0x1 (MVP) */
|
||||||
|
+ return -ENOEXEC;
|
||||||
|
+ }
|
||||||
|
+ parsed += 4UL;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We can only allow position independent code since Wasm has no MMU.
|
||||||
|
+ * This is currently flagged by a "dylink.0" custom section (first type
|
||||||
|
+ * byte 0), and should come as the first section in the file. If not, we
|
||||||
|
+ * can't run this file. However, we could allow some other magic binfmt
|
||||||
|
+ * to handle this (e.g. emulate support), so don't hard fail.
|
||||||
|
+ */
|
||||||
|
+ if (*(parsed++) != 0x00
|
||||||
|
+ || !wasm_consume_varU32(&parsed, &dylink_0_length, 5UL)
|
||||||
|
+ || dylink_0_length < 9U
|
||||||
|
+ || memcmp(parsed, "\x08" "dylink.0", 9UL)) {
|
||||||
|
+ return -ENOEXEC;
|
||||||
|
+ }
|
||||||
|
+ parsed += 9UL;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Map the whole file into memory so we can read it and hand it off to
|
||||||
|
+ * the host. We will unmap this as soon as the host has made its copy
|
||||||
|
+ * (the host would not be able to use a shared buffer as source anyway).
|
||||||
|
+ */
|
||||||
|
+ whole_size_ll = i_size_read(file_inode(bprm->file));
|
||||||
|
+ if (whole_size_ll > (loff_t)ULONG_MAX)
|
||||||
|
+ return -ENOMEM;
|
||||||
|
+
|
||||||
|
+ whole_size = (unsigned long)whole_size_ll;
|
||||||
|
+ if (whole_size < (unsigned long)(parsed - bprm->buf))
|
||||||
|
+ return -ENOEXEC;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * This would be a placed to check RLIMITs, but since Wasm can allocate
|
||||||
|
+ * as much memory it wants on its own stack that makes little sense.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+ ret = begin_new_exec(bprm);
|
||||||
|
+ if (ret)
|
||||||
|
+ return ret;
|
||||||
|
+
|
||||||
|
+ set_personality(PER_LINUX_32BIT);
|
||||||
|
+ setup_new_exec(bprm);
|
||||||
|
+
|
||||||
|
+ whole_start = vm_mmap(bprm->file, 0, whole_size,
|
||||||
|
+ PROT_READ | PROT_EXEC, MAP_PRIVATE, 0);
|
||||||
|
+ if (!whole_start || IS_ERR_VALUE(whole_start)) {
|
||||||
|
+ ret = whole_start ? (int)whole_start : -ENOMEM;
|
||||||
|
+ pr_err("Unable to mmap process binary, errno: %d\n", ret);
|
||||||
|
+ return ret;
|
||||||
|
+ }
|
||||||
|
+ whole_end = whole_start + whole_size;
|
||||||
|
+
|
||||||
|
+ /* Move parsed to the whole file, since bprm->buf is cut off. */
|
||||||
|
+ whole_p = whole_start +
|
||||||
|
+ ((unsigned long)parsed - (unsigned long)bprm->buf);
|
||||||
|
+
|
||||||
|
+ /* Time to read some subsections of the dylink.0 section! */
|
||||||
|
+ while (!has_meminfo) {
|
||||||
|
+ if (whole_p == whole_end) {
|
||||||
|
+ pr_err("No dylink.0 subsection id");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ } else if (get_user(subsection_id, (u8 __user *)(whole_p++))) {
|
||||||
|
+ pr_err("Failed to read dylink.0 subsection id");
|
||||||
|
+ ret = -EFAULT;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ count = min_t(unsigned long, 5UL, whole_end - whole_p);
|
||||||
|
+ if (!wasm_consume_varU32_user(&whole_p, &subsection_length, count)) {
|
||||||
|
+ pr_err("Failed to read dylink.0 subsection length");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ subsection_end = whole_p + subsection_length;
|
||||||
|
+ if (subsection_end < whole_p /* overflow */
|
||||||
|
+ || subsection_end > whole_end) {
|
||||||
|
+ pr_err("dylink.0 subsection length overflow");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (subsection_id == WASM_DYLINK_MEMINFO) {
|
||||||
|
+ count = min_t(unsigned long, 5UL, subsection_end - whole_p);
|
||||||
|
+ if (!wasm_consume_varU32_user(&whole_p, &data_size, count)) {
|
||||||
|
+ pr_err("Failed to read dylink.0 meminfo memory size");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+ data_size = PAGE_ALIGN(data_size);
|
||||||
|
+
|
||||||
|
+ count = min_t(unsigned long, 5UL, subsection_end - whole_p);
|
||||||
|
+ if (!wasm_consume_varU32_user(&whole_p, &data_align, count)) {
|
||||||
|
+ pr_err("Failed to read dylink.0 meminfo memory alignment");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ } else if (data_align > 31U) {
|
||||||
|
+ pr_err("dylink.0 meminfo memory alignment too large");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+ data_align = 1UL << (int)data_align;
|
||||||
|
+
|
||||||
|
+ count = min_t(unsigned long, 5UL, subsection_end - whole_p);
|
||||||
|
+ if (!wasm_consume_varU32_user(&whole_p, &table_size, count)) {
|
||||||
|
+ pr_err("Failed to read dylink.0 meminfo table size");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+ table_size = PAGE_ALIGN(table_size);
|
||||||
|
+
|
||||||
|
+ count = min_t(unsigned long, 5UL, subsection_end - whole_p);
|
||||||
|
+ if (!wasm_consume_varU32_user(&whole_p, &table_align, count)) {
|
||||||
|
+ pr_err("Failed to read dylink.0 meminfo table alignment");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ } else if (table_align > 31U) {
|
||||||
|
+ pr_err("dylink.0 meminfo table alignment too large");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+ table_align = 1UL << (int)table_align;
|
||||||
|
+
|
||||||
|
+ has_meminfo = true;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ whole_p = subsection_end;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (!has_meminfo) {
|
||||||
|
+ pr_err("No dylink.0 meminfo found");
|
||||||
|
+ ret = -ENOEXEC;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * MAP_ANMONYMOUS clears the data (and bss). In Wasm, the runtime
|
||||||
|
+ * manages bss inside the data area. The runtime may rely on the data
|
||||||
|
+ * being zeroed as it is placing bss inside (or rather not touchhing bss
|
||||||
|
+ * pages at all). Thus data and bss are the same and zeroed.
|
||||||
|
+ */
|
||||||
|
+ data_start = vm_mmap(NULL, 0, data_size,
|
||||||
|
+ PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0);
|
||||||
|
+ if (!data_start || IS_ERR_VALUE(data_start)) {
|
||||||
|
+ ret = data_start ? (int)data_start : -ENOMEM;
|
||||||
|
+ pr_err("Unable to allocate RAM for process data, errno: %d\n",
|
||||||
|
+ ret);
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * Create a stack, and put the brk at the start of this area.
|
||||||
|
+ */
|
||||||
|
+ stack_size = PAGE_ALIGN(WASM_STACK_SIZE + extra_stack);
|
||||||
|
+ current->mm->start_brk = vm_mmap(NULL, 0, stack_size,
|
||||||
|
+ PROT_READ|PROT_WRITE,
|
||||||
|
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_GROWSDOWN, 0);
|
||||||
|
+ if (!current->mm->start_brk || IS_ERR_VALUE(current->mm->start_brk)) {
|
||||||
|
+ ret = current->mm->start_brk ?
|
||||||
|
+ (int)current->mm->start_brk : -ENOMEM;
|
||||||
|
+ pr_err("Unable to allocate RAM for stack, errno: %d\n", ret);
|
||||||
|
+ current->mm->start_brk = 0;
|
||||||
|
+ goto out_unmap;
|
||||||
|
+ }
|
||||||
|
+ current->mm->brk = current->mm->start_brk; /* Already page aligned... */
|
||||||
|
+#ifndef CONFIG_MMU
|
||||||
|
+ current->mm->context.end_brk = current->mm->start_brk + stack_size;
|
||||||
|
+#endif
|
||||||
|
+ current->mm->start_stack = current->mm->start_brk + stack_size;
|
||||||
|
+
|
||||||
|
+ /* Only set these if the above succeeds. */
|
||||||
|
+ current->mm->start_code = whole_start;
|
||||||
|
+ current->mm->end_code = whole_end;
|
||||||
|
+ current->mm->start_data = data_start;
|
||||||
|
+ current->mm->end_data = data_start + data_size;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+
|
||||||
|
+out_unmap:
|
||||||
|
+ vm_munmap(whole_start, whole_size);
|
||||||
|
+ if (data_start)
|
||||||
|
+ vm_munmap(data_start, data_size);
|
||||||
|
+ return ret;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int load_wasm_binary(struct linux_binprm *bprm);
|
||||||
|
+
|
||||||
|
+static struct linux_binfmt wasm_format = {
|
||||||
|
+ .module = THIS_MODULE,
|
||||||
|
+ .load_binary = load_wasm_binary,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int load_wasm_binary(struct linux_binprm *bprm)
|
||||||
|
+{
|
||||||
|
+ struct pt_regs *regs = current_pt_regs();
|
||||||
|
+ unsigned long extra_stack = 0;
|
||||||
|
+ int res;
|
||||||
|
+
|
||||||
|
+ /*
|
||||||
|
+ * We have to add the size of our arguments to our stack size
|
||||||
|
+ * otherwise it's too easy for users to create stack overflows
|
||||||
|
+ * by passing in a huge argument list. And yes, we have to be
|
||||||
|
+ * pedantic and include space for the argv/envp array as it may have
|
||||||
|
+ * a lot of entries.
|
||||||
|
+ */
|
||||||
|
+#ifndef CONFIG_MMU
|
||||||
|
+ extra_stack += PAGE_SIZE * MAX_ARG_PAGES - bprm->p; /* the strings */
|
||||||
|
+#endif
|
||||||
|
+ extra_stack += (bprm->argc + 1) * sizeof(char *); /* the argv array */
|
||||||
|
+ extra_stack += (bprm->envc + 1) * sizeof(char *); /* the envp array */
|
||||||
|
+ extra_stack = ALIGN(extra_stack, WASM_STACK_ALIGN);
|
||||||
|
+
|
||||||
|
+ res = load_wasm_file(bprm, extra_stack);
|
||||||
|
+ if (res < 0)
|
||||||
|
+ return res;
|
||||||
|
+
|
||||||
|
+ set_binfmt(&wasm_format);
|
||||||
|
+
|
||||||
|
+#ifdef CONFIG_MMU
|
||||||
|
+ res = setup_arg_pages(bprm, STACK_TOP, EXSTACK_DEFAULT);
|
||||||
|
+ if (!res)
|
||||||
|
+ res = create_wasm_tables(bprm, bprm->p);
|
||||||
|
+#else
|
||||||
|
+ res = transfer_args_to_stack(bprm, ¤t->mm->start_stack);
|
||||||
|
+ if (!res)
|
||||||
|
+ res = create_wasm_tables(bprm, current->mm->start_stack);
|
||||||
|
+#endif
|
||||||
|
+ if (res)
|
||||||
|
+ return res;
|
||||||
|
+
|
||||||
|
+ finalize_exec(bprm);
|
||||||
|
+ start_thread(regs, current->mm->start_stack);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int __init init_wasm_binfmt(void)
|
||||||
|
+{
|
||||||
|
+ register_binfmt(&wasm_format);
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+core_initcall(init_wasm_binfmt);
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,170 @@
|
||||||
|
From 18c7f0ad07fdf735784c0125e5e05095c01c31eb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 12 May 2024 17:27:43 +0200
|
||||||
|
Subject: [PATCH] Use .section format compatible with LLVM as when targeting
|
||||||
|
Wasm
|
||||||
|
|
||||||
|
LLVM as does apparently need sizes and no "a" flag for sections when
|
||||||
|
assembling Wasm files. This seems to differ from other targets.
|
||||||
|
---
|
||||||
|
scripts/kallsyms.c | 38 +++++++++++++++++++++++++++-----------
|
||||||
|
usr/initramfs_data.S | 7 +++++--
|
||||||
|
2 files changed, 32 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c
|
||||||
|
index 13af6d0ff..f090766f5 100644
|
||||||
|
--- a/scripts/kallsyms.c
|
||||||
|
+++ b/scripts/kallsyms.c
|
||||||
|
@@ -287,13 +287,18 @@ static void read_map(const char *in)
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void output_label(const char *label)
|
||||||
|
+static void output_label_begin(const char *label)
|
||||||
|
{
|
||||||
|
printf(".globl %s\n", label);
|
||||||
|
printf("\tALGN\n");
|
||||||
|
printf("%s:\n", label);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void output_label_end(const char *label)
|
||||||
|
+{
|
||||||
|
+ printf(".size\t%s,.-%s\n", label, label);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Provide proper symbols relocatability by their '_text' relativeness. */
|
||||||
|
static void output_address(unsigned long long addr)
|
||||||
|
{
|
||||||
|
@@ -395,10 +400,11 @@ static void write_src(void)
|
||||||
|
printf("#define ALGN .balign 4\n");
|
||||||
|
printf("#endif\n");
|
||||||
|
|
||||||
|
- printf("\t.section .rodata, \"a\"\n");
|
||||||
|
+ printf("\t.section .rodata, \"\", @\n");
|
||||||
|
|
||||||
|
- output_label("kallsyms_num_syms");
|
||||||
|
+ output_label_begin("kallsyms_num_syms");
|
||||||
|
printf("\t.long\t%u\n", table_cnt);
|
||||||
|
+ output_label_end("kallsyms_num_syms");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
/* table of offset markers, that give the offset in the compressed stream
|
||||||
|
@@ -410,7 +416,7 @@ static void write_src(void)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
- output_label("kallsyms_names");
|
||||||
|
+ output_label_begin("kallsyms_names");
|
||||||
|
off = 0;
|
||||||
|
for (i = 0; i < table_cnt; i++) {
|
||||||
|
if ((i & 0xFF) == 0)
|
||||||
|
@@ -447,6 +453,7 @@ static void write_src(void)
|
||||||
|
printf(", 0x%02x", table[i]->sym[k]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
+ output_label_end("kallsyms_names");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
@@ -458,14 +465,15 @@ static void write_src(void)
|
||||||
|
strcpy((char *)table[i]->sym, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
- output_label("kallsyms_markers");
|
||||||
|
+ output_label_begin("kallsyms_markers");
|
||||||
|
for (i = 0; i < ((table_cnt + 255) >> 8); i++)
|
||||||
|
printf("\t.long\t%u\n", markers[i]);
|
||||||
|
+ output_label_end("kallsyms_markers");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
free(markers);
|
||||||
|
|
||||||
|
- output_label("kallsyms_token_table");
|
||||||
|
+ output_label_begin("kallsyms_token_table");
|
||||||
|
off = 0;
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
best_idx[i] = off;
|
||||||
|
@@ -473,17 +481,19 @@ static void write_src(void)
|
||||||
|
printf("\t.asciz\t\"%s\"\n", buf);
|
||||||
|
off += strlen(buf) + 1;
|
||||||
|
}
|
||||||
|
+ output_label_end("kallsyms_token_table");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
- output_label("kallsyms_token_index");
|
||||||
|
+ output_label_begin("kallsyms_token_index");
|
||||||
|
for (i = 0; i < 256; i++)
|
||||||
|
printf("\t.short\t%d\n", best_idx[i]);
|
||||||
|
+ output_label_end("kallsyms_token_index");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (!base_relative)
|
||||||
|
- output_label("kallsyms_addresses");
|
||||||
|
+ output_label_begin("kallsyms_addresses");
|
||||||
|
else
|
||||||
|
- output_label("kallsyms_offsets");
|
||||||
|
+ output_label_begin("kallsyms_offsets");
|
||||||
|
|
||||||
|
for (i = 0; i < table_cnt; i++) {
|
||||||
|
if (base_relative) {
|
||||||
|
@@ -521,11 +531,16 @@ static void write_src(void)
|
||||||
|
printf("\tPTR\t%#llx\n", table[i]->addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ if (!base_relative)
|
||||||
|
+ output_label_end("kallsyms_addresses");
|
||||||
|
+ else
|
||||||
|
+ output_label_end("kallsyms_offsets");
|
||||||
|
printf("\n");
|
||||||
|
|
||||||
|
if (base_relative) {
|
||||||
|
- output_label("kallsyms_relative_base");
|
||||||
|
+ output_label_begin("kallsyms_relative_base");
|
||||||
|
output_address(relative_base);
|
||||||
|
+ output_label_end("kallsyms_relative_base");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -534,12 +549,13 @@ static void write_src(void)
|
||||||
|
cleanup_symbol_name((char *)table[i]->sym);
|
||||||
|
|
||||||
|
sort_symbols_by_name();
|
||||||
|
- output_label("kallsyms_seqs_of_names");
|
||||||
|
+ output_label_begin("kallsyms_seqs_of_names");
|
||||||
|
for (i = 0; i < table_cnt; i++)
|
||||||
|
printf("\t.byte 0x%02x, 0x%02x, 0x%02x\n",
|
||||||
|
(unsigned char)(table[i]->seq >> 16),
|
||||||
|
(unsigned char)(table[i]->seq >> 8),
|
||||||
|
(unsigned char)(table[i]->seq >> 0));
|
||||||
|
+ output_label_end("kallsyms_seqs_of_names");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/usr/initramfs_data.S b/usr/initramfs_data.S
|
||||||
|
index cd67edc38..dd1990aaf 100644
|
||||||
|
--- a/usr/initramfs_data.S
|
||||||
|
+++ b/usr/initramfs_data.S
|
||||||
|
@@ -22,11 +22,13 @@
|
||||||
|
in the ELF header, as required by certain architectures.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-.section .init.ramfs,"a"
|
||||||
|
+.section .init.ramfs,"",@
|
||||||
|
__irf_start:
|
||||||
|
.incbin "usr/initramfs_inc_data"
|
||||||
|
+.size __irf_start,.-__irf_start
|
||||||
|
__irf_end:
|
||||||
|
-.section .init.ramfs.info,"a"
|
||||||
|
+.size __irf_end,0
|
||||||
|
+.section .init.ramfs.info,"",@
|
||||||
|
.globl __initramfs_size
|
||||||
|
__initramfs_size:
|
||||||
|
#ifdef CONFIG_64BIT
|
||||||
|
@@ -34,3 +36,4 @@ __initramfs_size:
|
||||||
|
#else
|
||||||
|
.long __irf_end - __irf_start
|
||||||
|
#endif
|
||||||
|
+.size __initramfs_size,.-__initramfs_size
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
From dd91ef3a67b1034191966eccdee8f583a69db9fa Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 12 May 2024 19:22:35 +0200
|
||||||
|
Subject: [PATCH] Provide Wasm support in mk_elfconfig
|
||||||
|
|
||||||
|
This is some kind of emulation for the modpost parts of Kbuild which
|
||||||
|
currently assumes that ELF is used by all targets.
|
||||||
|
---
|
||||||
|
scripts/mod/mk_elfconfig.c | 48 +++++++++++++++++++++-----------------
|
||||||
|
1 file changed, 27 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c
|
||||||
|
index 680eade89..782522b23 100644
|
||||||
|
--- a/scripts/mod/mk_elfconfig.c
|
||||||
|
+++ b/scripts/mod/mk_elfconfig.c
|
||||||
|
@@ -14,29 +14,35 @@ main(int argc, char **argv)
|
||||||
|
fprintf(stderr, "Error: input truncated\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
- if (memcmp(ei, ELFMAG, SELFMAG) != 0) {
|
||||||
|
- fprintf(stderr, "Error: not ELF\n");
|
||||||
|
- return 1;
|
||||||
|
- }
|
||||||
|
- switch (ei[EI_CLASS]) {
|
||||||
|
- case ELFCLASS32:
|
||||||
|
+
|
||||||
|
+ if (memcmp(ei, "\x00" "asm", 4UL) == 0) {
|
||||||
|
+ /* Wasm (not ELF) - provide some emulation. */
|
||||||
|
printf("#define KERNEL_ELFCLASS ELFCLASS32\n");
|
||||||
|
- break;
|
||||||
|
- case ELFCLASS64:
|
||||||
|
- printf("#define KERNEL_ELFCLASS ELFCLASS64\n");
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- exit(1);
|
||||||
|
- }
|
||||||
|
- switch (ei[EI_DATA]) {
|
||||||
|
- case ELFDATA2LSB:
|
||||||
|
printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
|
||||||
|
- break;
|
||||||
|
- case ELFDATA2MSB:
|
||||||
|
- printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
|
||||||
|
- break;
|
||||||
|
- default:
|
||||||
|
- exit(1);
|
||||||
|
+ } else if (memcmp(ei, ELFMAG, SELFMAG) != 0) {
|
||||||
|
+ fprintf(stderr, "Error: not ELF, nor Wasm\n");
|
||||||
|
+ return 1;
|
||||||
|
+ } else {
|
||||||
|
+ switch (ei[EI_CLASS]) {
|
||||||
|
+ case ELFCLASS32:
|
||||||
|
+ printf("#define KERNEL_ELFCLASS ELFCLASS32\n");
|
||||||
|
+ break;
|
||||||
|
+ case ELFCLASS64:
|
||||||
|
+ printf("#define KERNEL_ELFCLASS ELFCLASS64\n");
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
+ switch (ei[EI_DATA]) {
|
||||||
|
+ case ELFDATA2LSB:
|
||||||
|
+ printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
|
||||||
|
+ break;
|
||||||
|
+ case ELFDATA2MSB:
|
||||||
|
+ printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ exit(1);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sizeof(unsigned long) == 4) {
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
101
patches/kernel/0009-Add-dummy-ELF-constants-for-Wasm.patch
Normal file
101
patches/kernel/0009-Add-dummy-ELF-constants-for-Wasm.patch
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
From 452439e4c22ae6cb0c3f9055a572ba862c78271a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 12 May 2024 19:26:03 +0200
|
||||||
|
Subject: [PATCH] Add dummy ELF constants for Wasm
|
||||||
|
|
||||||
|
The kernel needs ELF to build, but Wasm currently only support for the
|
||||||
|
.wasm file format. Some dummy ELF constants are added as a workaround.
|
||||||
|
---
|
||||||
|
arch/wasm/include/uapi/asm/elf.h | 80 ++++++++++++++++++++++++++++++++
|
||||||
|
1 file changed, 80 insertions(+)
|
||||||
|
create mode 100644 arch/wasm/include/uapi/asm/elf.h
|
||||||
|
|
||||||
|
diff --git a/arch/wasm/include/uapi/asm/elf.h b/arch/wasm/include/uapi/asm/elf.h
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..853cd3786
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/wasm/include/uapi/asm/elf.h
|
||||||
|
@@ -0,0 +1,80 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||||
|
+
|
||||||
|
+#ifndef _UAPI_ASM_WASM_ELF_H
|
||||||
|
+#define _UAPI_ASM_WASM_ELF_H
|
||||||
|
+
|
||||||
|
+#include <asm/ptrace.h>
|
||||||
|
+
|
||||||
|
+/* ELF register definitions */
|
||||||
|
+typedef unsigned long elf_greg_t;
|
||||||
|
+typedef struct user_regs_struct elf_gregset_t;
|
||||||
|
+#define ELF_NGREG (sizeof(elf_gregset_t) / sizeof(elf_greg_t))
|
||||||
|
+
|
||||||
|
+/* We don't support f without d, or q. */
|
||||||
|
+typedef __u64 elf_fpreg_t;
|
||||||
|
+typedef union __wasm_fp_state elf_fpregset_t;
|
||||||
|
+#define ELF_NFPREG (sizeof(struct __wasm_d_ext_state) / sizeof(elf_fpreg_t))
|
||||||
|
+
|
||||||
|
+//#define ELF_WASM_R_SYM(r_info) ELF32_R_SYM(r_info)
|
||||||
|
+//#define ELF_WASM_R_TYPE(r_info) ELF32_R_TYPE(r_info)
|
||||||
|
+
|
||||||
|
+/* Relocation types used by the dynamic linker */
|
||||||
|
+#define R_WASM_NONE 0
|
||||||
|
+#define R_WASM_32 1
|
||||||
|
+#define R_WASM_64 2
|
||||||
|
+#define R_WASM_RELATIVE 3
|
||||||
|
+#define R_WASM_COPY 4
|
||||||
|
+#define R_WASM_JUMP_SLOT 5
|
||||||
|
+#define R_WASM_TLS_DTPMOD32 6
|
||||||
|
+#define R_WASM_TLS_DTPMOD64 7
|
||||||
|
+#define R_WASM_TLS_DTPREL32 8
|
||||||
|
+#define R_WASM_TLS_DTPREL64 9
|
||||||
|
+#define R_WASM_TLS_TPREL32 10
|
||||||
|
+#define R_WASM_TLS_TPREL64 11
|
||||||
|
+
|
||||||
|
+/* Relocation types not used by the dynamic linker */
|
||||||
|
+#define R_WASM_BRANCH 16
|
||||||
|
+#define R_WASM_JAL 17
|
||||||
|
+#define R_WASM_CALL 18
|
||||||
|
+#define R_WASM_CALL_PLT 19
|
||||||
|
+#define R_WASM_GOT_HI20 20
|
||||||
|
+#define R_WASM_TLS_GOT_HI20 21
|
||||||
|
+#define R_WASM_TLS_GD_HI20 22
|
||||||
|
+#define R_WASM_PCREL_HI20 23
|
||||||
|
+#define R_WASM_PCREL_LO12_I 24
|
||||||
|
+#define R_WASM_PCREL_LO12_S 25
|
||||||
|
+#define R_WASM_HI20 26
|
||||||
|
+#define R_WASM_LO12_I 27
|
||||||
|
+#define R_WASM_LO12_S 28
|
||||||
|
+#define R_WASM_TPREL_HI20 29
|
||||||
|
+#define R_WASM_TPREL_LO12_I 30
|
||||||
|
+#define R_WASM_TPREL_LO12_S 31
|
||||||
|
+#define R_WASM_TPREL_ADD 32
|
||||||
|
+#define R_WASM_ADD8 33
|
||||||
|
+#define R_WASM_ADD16 34
|
||||||
|
+#define R_WASM_ADD32 35
|
||||||
|
+#define R_WASM_ADD64 36
|
||||||
|
+#define R_WASM_SUB8 37
|
||||||
|
+#define R_WASM_SUB16 38
|
||||||
|
+#define R_WASM_SUB32 39
|
||||||
|
+#define R_WASM_SUB64 40
|
||||||
|
+#define R_WASM_GNU_VTINHERIT 41
|
||||||
|
+#define R_WASM_GNU_VTENTRY 42
|
||||||
|
+#define R_WASM_ALIGN 43
|
||||||
|
+#define R_WASM_RVC_BRANCH 44
|
||||||
|
+#define R_WASM_RVC_JUMP 45
|
||||||
|
+#define R_WASM_LUI 46
|
||||||
|
+#define R_WASM_GPREL_I 47
|
||||||
|
+#define R_WASM_GPREL_S 48
|
||||||
|
+#define R_WASM_TPREL_I 49
|
||||||
|
+#define R_WASM_TPREL_S 50
|
||||||
|
+#define R_WASM_RELAX 51
|
||||||
|
+#define R_WASM_SUB6 52
|
||||||
|
+#define R_WASM_SET6 53
|
||||||
|
+#define R_WASM_SET8 54
|
||||||
|
+#define R_WASM_SET16 55
|
||||||
|
+#define R_WASM_SET32 56
|
||||||
|
+#define R_WASM_32_PCREL 57
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+#endif /* _UAPI_ASM_WASM_ELF_H */
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
121
patches/kernel/0010-Add-Wasm-console-support.patch
Normal file
121
patches/kernel/0010-Add-Wasm-console-support.patch
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
From 2a52409cba31a1d5709451eceedfa7c8868bcfb8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 30 Jun 2024 00:47:26 +0200
|
||||||
|
Subject: [PATCH] Add Wasm console support
|
||||||
|
|
||||||
|
Adds a simple HVC + earlycon tty driver that calls out to the Wasm host
|
||||||
|
using simple exported functions on the vmlinux Module for reads/writes.
|
||||||
|
---
|
||||||
|
arch/wasm/Kconfig | 2 +-
|
||||||
|
arch/wasm/Makefile | 1 +
|
||||||
|
arch/wasm/drivers/Kconfig | 22 ++++++++++++++++++++++
|
||||||
|
arch/wasm/drivers/Makefile | 3 +++
|
||||||
|
arch/wasm/drivers/hvc_wasm.c | 35 +++++++++++++++++++++++++++++++++++
|
||||||
|
5 files changed, 62 insertions(+), 1 deletion(-)
|
||||||
|
create mode 100644 arch/wasm/drivers/Kconfig
|
||||||
|
create mode 100644 arch/wasm/drivers/Makefile
|
||||||
|
create mode 100644 arch/wasm/drivers/hvc_wasm.c
|
||||||
|
|
||||||
|
diff --git a/arch/wasm/Kconfig b/arch/wasm/Kconfig
|
||||||
|
index 744e8c676..2e01d91b3 100644
|
||||||
|
--- a/arch/wasm/Kconfig
|
||||||
|
+++ b/arch/wasm/Kconfig
|
||||||
|
@@ -77,4 +77,4 @@ config ARCH_HAVE_PANIC_NOTIFY
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
-source "drivers/Kconfig"
|
||||||
|
+source "arch/wasm/drivers/Kconfig"
|
||||||
|
diff --git a/arch/wasm/Makefile b/arch/wasm/Makefile
|
||||||
|
index b86103e0b..841f3b006 100644
|
||||||
|
--- a/arch/wasm/Makefile
|
||||||
|
+++ b/arch/wasm/Makefile
|
||||||
|
@@ -12,6 +12,7 @@ KCFLAGS += -Xclang -target-feature -Xclang +bulk-memory
|
||||||
|
core-y += arch/wasm/kernel/
|
||||||
|
core-y += arch/wasm/mm/
|
||||||
|
libs-y += arch/wasm/lib/
|
||||||
|
+drivers-y += arch/wasm/drivers/
|
||||||
|
|
||||||
|
PHONY += bzImage
|
||||||
|
|
||||||
|
diff --git a/arch/wasm/drivers/Kconfig b/arch/wasm/drivers/Kconfig
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..be8b75496
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/wasm/drivers/Kconfig
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
+
|
||||||
|
+menu "Wasm Character Devices"
|
||||||
|
+
|
||||||
|
+config HVC_WASM
|
||||||
|
+ bool "Wasm console support"
|
||||||
|
+ select HVC_DRIVER
|
||||||
|
+ help
|
||||||
|
+ This config option enables support for a console managed by the Wasm
|
||||||
|
+ host, for example to read printk output during boot as well as
|
||||||
|
+ receiving user input. It works both as an earlycon and a tty. As an
|
||||||
|
+ earlycon, very early debug logging is output. As a tty (enabled later
|
||||||
|
+ on in the boot process), it also supports user input from the host.
|
||||||
|
+
|
||||||
|
+ In addition to enabling this config option at build time, you also
|
||||||
|
+ need to specify console=hvc as a parameter on the kernel command line
|
||||||
|
+ to activate the feature at runtime. Just specifying console=hvc is
|
||||||
|
+ enough to enable the earlycon aspects of this console driver as well.
|
||||||
|
+
|
||||||
|
+ If you don't know what to do here, say Y.
|
||||||
|
+
|
||||||
|
+endmenu
|
||||||
|
diff --git a/arch/wasm/drivers/Makefile b/arch/wasm/drivers/Makefile
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..0ebdc20a8
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/wasm/drivers/Makefile
|
||||||
|
@@ -0,0 +1,3 @@
|
||||||
|
+# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
+
|
||||||
|
+obj-$(CONFIG_HVC_WASM) += hvc_wasm.o
|
||||||
|
diff --git a/arch/wasm/drivers/hvc_wasm.c b/arch/wasm/drivers/hvc_wasm.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..78f34c060
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/wasm/drivers/hvc_wasm.c
|
||||||
|
@@ -0,0 +1,35 @@
|
||||||
|
+/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
+
|
||||||
|
+#include "../../../drivers/tty/hvc/hvc_console.h"
|
||||||
|
+
|
||||||
|
+extern int wasm_driver_hvc_put(const char *buf, int count);
|
||||||
|
+extern int wasm_driver_hvc_get(char *buf, int count);
|
||||||
|
+
|
||||||
|
+static int hvc_wasm_put_chars(uint32_t vtermno, const char *buf, int count)
|
||||||
|
+{
|
||||||
|
+ return wasm_driver_hvc_put(buf, count);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int hvc_wasm_get_chars(uint32_t vtermno, char *buf, int count)
|
||||||
|
+{
|
||||||
|
+ return wasm_driver_hvc_get(buf, count);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct hv_ops hvc_wasm_ops = {
|
||||||
|
+ .get_chars = hvc_wasm_get_chars,
|
||||||
|
+ .put_chars = hvc_wasm_put_chars,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+static int __init hvc_wasm_init(void)
|
||||||
|
+{
|
||||||
|
+ return PTR_ERR_OR_ZERO(hvc_alloc(0, 0, &hvc_wasm_ops, PAGE_SIZE));
|
||||||
|
+}
|
||||||
|
+device_initcall(hvc_wasm_init);
|
||||||
|
+
|
||||||
|
+static int __init hvc_wasm_console_init(void)
|
||||||
|
+{
|
||||||
|
+ hvc_instantiate(0, 0, &hvc_wasm_ops);
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+console_initcall(hvc_wasm_console_init);
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
41
patches/kernel/0011-Add-wasm_defconfig.patch
Normal file
41
patches/kernel/0011-Add-wasm_defconfig.patch
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
From d1f576fb102da92fe3392c12125b5f0be03601f1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sun, 12 May 2024 19:31:55 +0200
|
||||||
|
Subject: [PATCH] Add wasm_defconfig
|
||||||
|
|
||||||
|
This patch needs to be updated to use an auto-generated config instead.
|
||||||
|
---
|
||||||
|
arch/wasm/configs/wasm_defconfig | 21 +++++++++++++++++++++
|
||||||
|
1 file changed, 21 insertions(+)
|
||||||
|
create mode 100644 arch/wasm/configs/wasm_defconfig
|
||||||
|
|
||||||
|
diff --git a/arch/wasm/configs/wasm_defconfig b/arch/wasm/configs/wasm_defconfig
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..10fb9e0ab
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/arch/wasm/configs/wasm_defconfig
|
||||||
|
@@ -0,0 +1,21 @@
|
||||||
|
+CONFIG_SLAB=y
|
||||||
|
+
|
||||||
|
+CONFIG_NO_HZ_FULL=y
|
||||||
|
+
|
||||||
|
+CONFIG_MAGIC_SYSRQ=y
|
||||||
|
+CONFIG_DEBUG_KERNEL=y
|
||||||
|
+CONFIG_DEBUG_INFO_DWARF5=y
|
||||||
|
+CONFIG_HVC_WASM=y
|
||||||
|
+
|
||||||
|
+CONFIG_BLK_DEV_INITRD=y
|
||||||
|
+
|
||||||
|
+CONFIG_BINFMT_WASM=y
|
||||||
|
+CONFIG_BINFMT_MISC=m
|
||||||
|
+
|
||||||
|
+#CONFIG_MODULES=y
|
||||||
|
+#CONFIG_MODULE_UNLOAD=y
|
||||||
|
+
|
||||||
|
+#CONFIG_NET=y
|
||||||
|
+#CONFIG_PACKET=y
|
||||||
|
+#CONFIG_UNIX=y
|
||||||
|
+#CONFIG_INET=y
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
From f3e782cb608b0bdb63bc3a2280cfbbb8acf464c0 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Joel Severin <joel.severin@icemanor.se>
|
||||||
|
Date: Sat, 13 Sep 2025 21:55:10 +0200
|
||||||
|
Subject: [PATCH] HACK: Workaround broken wq_worker_comm
|
||||||
|
|
||||||
|
worker->pool seems to be corrupted somehow, root cause unknown. This
|
||||||
|
likely happens due to an unrelated memory corruption bug.
|
||||||
|
---
|
||||||
|
kernel/workqueue.c | 4 +++-
|
||||||
|
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
|
||||||
|
index c913e333c..317e62987 100644
|
||||||
|
--- a/kernel/workqueue.c
|
||||||
|
+++ b/kernel/workqueue.c
|
||||||
|
@@ -5129,7 +5129,9 @@ void wq_worker_comm(char *buf, size_t size, struct task_struct *task)
|
||||||
|
struct worker *worker = kthread_data(task);
|
||||||
|
struct worker_pool *pool = worker->pool;
|
||||||
|
|
||||||
|
- if (pool) {
|
||||||
|
+ if ((unsigned long)pool == -1UL)
|
||||||
|
+ scnprintf(buf + off, size - off, "-BROKEN");
|
||||||
|
+ else if (pool) {
|
||||||
|
raw_spin_lock_irq(&pool->lock);
|
||||||
|
/*
|
||||||
|
* ->desc tracks information (wq name or
|
||||||
|
--
|
||||||
|
2.25.1
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user