]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
libc: Add kexec_file_load() syscall wrapper
authorDaan De Meyer <daan@amutable.com>
Fri, 10 Apr 2026 10:23:22 +0000 (10:23 +0000)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Mon, 13 Apr 2026 09:13:04 +0000 (11:13 +0200)
Allow tabs in UAPI headers in .gitattributes since they are copied
verbatim from the kernel.

.gitattributes
README
meson.build
src/include/override/sys/kexec.h [new file with mode: 0644]
src/include/uapi/linux/kexec.h [new file with mode: 0644]
src/libc/kexec.c [new file with mode: 0644]
src/libc/meson.build

index dae59aa844a2e7b21787551379faf7f1588e6307..6c6c4a8beaab192a88040bac2b13ce54a49e0189 100644 (file)
@@ -1,4 +1,5 @@
 *.[ch] whitespace=tab-in-indent,trailing-space
+src/include/uapi/**/*.[ch] whitespace=trailing-space
 *.gpg  binary generated
 *.bmp  binary
 *.base64 generated
diff --git a/README b/README
index 359db5c3f433f0c5e2628325500ec1a52129071d..ccb6f86bfe8ea91c316c907bb9cc6d71207fdec5 100644 (file)
--- a/README
+++ b/README
@@ -30,7 +30,7 @@ LICENSE:
 
 REQUIREMENTS:
         Linux kernel ≥ 3.15 for timerfd_create() CLOCK_BOOTTIME support
-                     ≥ 3.17 for memfd_create() and getrandom()
+                     ≥ 3.17 for memfd_create(), getrandom(), and kexec_file_load() (x86-64)
                      ≥ 4.3 for ambient capabilities
                      ≥ 4.5 for pids controller in cgroup v2
                      ≥ 4.6 for cgroup namespaces
index 1c296073c2996717524c0e65daa472fddf56ee19..e0e7102a39f42316633435152d1eb80bcae812ad 100644 (file)
@@ -605,6 +605,7 @@ foreach ident : [
         ['fchmodat2',         '''#include <sys/stat.h>'''],     # no known header declares fchmodat2
         ['bpf',               '''#include <sys/syscall.h>'''],  # no known header declares bpf
         ['kcmp',              '''#include <sys/syscall.h>'''],  # no known header declares kcmp
+        ['kexec_file_load',   '''#include <sys/syscall.h>'''],  # no known header declares kexec_file_load
         ['keyctl',            '''#include <sys/syscall.h>'''],  # no known header declares keyctl
         ['add_key',           '''#include <sys/syscall.h>'''],  # no known header declares add_key
         ['request_key',       '''#include <sys/syscall.h>'''],  # no known header declares request_key
diff --git a/src/include/override/sys/kexec.h b/src/include/override/sys/kexec.h
new file mode 100644 (file)
index 0000000..4e256bd
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+#include <linux/kexec.h>          /* IWYU pragma: export */
+#include <sys/syscall.h>
+
+/* Supported since kernel v3.17 (cb1052581e2bddd6096544f3f944f4e7fdad4c4f).
+ * Not available on all architectures. */
+#if HAVE_KEXEC_FILE_LOAD || defined __NR_kexec_file_load
+#  if !HAVE_KEXEC_FILE_LOAD
+int missing_kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char *cmdline, unsigned long flags);
+#    define kexec_file_load missing_kexec_file_load
+#  endif
+#  define HAVE_KEXEC_FILE_LOAD_SYSCALL 1
+#else
+#  define HAVE_KEXEC_FILE_LOAD_SYSCALL 0
+#endif
diff --git a/src/include/uapi/linux/kexec.h b/src/include/uapi/linux/kexec.h
new file mode 100644 (file)
index 0000000..e26e211
--- /dev/null
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef LINUX_KEXEC_H
+#define LINUX_KEXEC_H
+
+/* kexec system call -  It loads the new kernel to boot into.
+ * kexec does not sync, or unmount filesystems so if you need
+ * that to happen you need to do that yourself.
+ */
+
+#include <linux/types.h>
+
+/* kexec flags for different usage scenarios */
+#define KEXEC_ON_CRASH         0x00000001
+#define KEXEC_PRESERVE_CONTEXT 0x00000002
+#define KEXEC_UPDATE_ELFCOREHDR        0x00000004
+#define KEXEC_CRASH_HOTPLUG_SUPPORT 0x00000008
+#define KEXEC_ARCH_MASK                0xffff0000
+
+/*
+ * Kexec file load interface flags.
+ * KEXEC_FILE_UNLOAD : Unload already loaded kexec/kdump image.
+ * KEXEC_FILE_ON_CRASH : Load/unload operation belongs to kdump image.
+ * KEXEC_FILE_NO_INITRAMFS : No initramfs is being loaded. Ignore the initrd
+ *                           fd field.
+ * KEXEC_FILE_FORCE_DTB : Force carrying over the current boot's DTB to the new
+ *                        kernel on x86. This is already the default behavior on
+ *                        some other architectures, like ARM64 and PowerPC.
+ */
+#define KEXEC_FILE_UNLOAD      0x00000001
+#define KEXEC_FILE_ON_CRASH    0x00000002
+#define KEXEC_FILE_NO_INITRAMFS        0x00000004
+#define KEXEC_FILE_DEBUG       0x00000008
+#define KEXEC_FILE_NO_CMA      0x00000010
+#define KEXEC_FILE_FORCE_DTB   0x00000020
+
+/* These values match the ELF architecture values.
+ * Unless there is a good reason that should continue to be the case.
+ */
+#define KEXEC_ARCH_DEFAULT ( 0 << 16)
+#define KEXEC_ARCH_386     ( 3 << 16)
+#define KEXEC_ARCH_68K     ( 4 << 16)
+#define KEXEC_ARCH_PARISC  (15 << 16)
+#define KEXEC_ARCH_X86_64  (62 << 16)
+#define KEXEC_ARCH_PPC     (20 << 16)
+#define KEXEC_ARCH_PPC64   (21 << 16)
+#define KEXEC_ARCH_IA_64   (50 << 16)
+#define KEXEC_ARCH_ARM     (40 << 16)
+#define KEXEC_ARCH_S390    (22 << 16)
+#define KEXEC_ARCH_SH      (42 << 16)
+#define KEXEC_ARCH_MIPS_LE (10 << 16)
+#define KEXEC_ARCH_MIPS    ( 8 << 16)
+#define KEXEC_ARCH_AARCH64 (183 << 16)
+#define KEXEC_ARCH_RISCV   (243 << 16)
+#define KEXEC_ARCH_LOONGARCH   (258 << 16)
+
+/* The artificial cap on the number of segments passed to kexec_load. */
+#define KEXEC_SEGMENT_MAX 16
+
+/*
+ * This structure is used to hold the arguments that are used when
+ * loading  kernel binaries.
+ */
+struct kexec_segment {
+       const void *buf;
+       __kernel_size_t bufsz;
+       const void *mem;
+       __kernel_size_t memsz;
+};
+
+
+#endif /* LINUX_KEXEC_H */
diff --git a/src/libc/kexec.c b/src/libc/kexec.c
new file mode 100644 (file)
index 0000000..122acff
--- /dev/null
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <sys/kexec.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+#if !HAVE_KEXEC_FILE_LOAD && defined __NR_kexec_file_load
+int missing_kexec_file_load(int kernel_fd, int initrd_fd, unsigned long cmdline_len, const char *cmdline, unsigned long flags) {
+        return syscall(__NR_kexec_file_load, kernel_fd, initrd_fd, cmdline_len, cmdline, flags);
+}
+#endif
index 306512ffd7002acab9384a358596ca55cc8107a0..3b7b96d07f219e06e58c62f3a1268be87bed87ec 100644 (file)
@@ -4,6 +4,7 @@ libc_wrapper_sources = files(
         'bpf.c',
         'ioprio.c',
         'kcmp.c',
+        'kexec.c',
         'keyctl.c',
         'mempolicy.c',
         'mount.c',