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