git: 27a094a2e66c - stable/13 - kboot: Refinements to host_kexec_load

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 24 Jan 2023 22:11:05 UTC
The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=27a094a2e66c2641f18b05558cb6b28582e413dc

commit 27a094a2e66c2641f18b05558cb6b28582e413dc
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-06-28 16:40:04 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-24 21:49:25 +0000

    kboot: Refinements to host_kexec_load
    
    Move kexec_segments to host_syscall.h and pre-pend host_ to it.  Correct
    args to host_exec_load.
    
    Sponsored by:           Netflix
    
    (cherry picked from commit ffb0d016df7e5526e4b8fd74a1f0617c81478328)
---
 stand/kboot/arch/amd64/syscall_nr.h            |  3 ---
 stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c |  2 +-
 stand/kboot/arch/powerpc64/syscall_nr.h        |  3 ---
 stand/kboot/host_syscall.h                     | 25 ++++++++++++++++++++++++-
 stand/kboot/host_syscalls.c                    |  4 ++--
 stand/kboot/main.c                             |  9 +--------
 6 files changed, 28 insertions(+), 18 deletions(-)

diff --git a/stand/kboot/arch/amd64/syscall_nr.h b/stand/kboot/arch/amd64/syscall_nr.h
index 4e2f686e7ae5..4d8db2083ebc 100644
--- a/stand/kboot/arch/amd64/syscall_nr.h
+++ b/stand/kboot/arch/amd64/syscall_nr.h
@@ -18,6 +18,3 @@
 #define SYS_symlinkat		266
 #define SYS_uname		 63
 #define SYS_write		  1
-
-#define KEXEC_ARCH_X86_64	 62
-#define KEXEC_ARCH		KEXEC_ARCH_X86_64
diff --git a/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c b/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c
index 94f27d13f1b9..93dcb2ea9c3b 100644
--- a/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c
+++ b/stand/kboot/arch/powerpc64/ppc64_elf_freebsd.c
@@ -153,7 +153,7 @@ ppc64_elf_exec(struct preloaded_file *fp)
 		panic("architecture did not provide kexec segment mapping");
 	archsw.arch_kexec_kseg_get(&nseg, &kseg);
 
-	error = host_kexec_load(trampolinebase, nseg, (uintptr_t)kseg, KEXEC_ARCH << 16);
+	error = host_kexec_load(trampolinebase, nseg, kseg, HOST_KEXEC_ARCH_PPC64);
 	if (error != 0)
 		panic("kexec_load returned error: %d", error);
 
diff --git a/stand/kboot/arch/powerpc64/syscall_nr.h b/stand/kboot/arch/powerpc64/syscall_nr.h
index 404a6f15fafc..a467259e8b60 100644
--- a/stand/kboot/arch/powerpc64/syscall_nr.h
+++ b/stand/kboot/arch/powerpc64/syscall_nr.h
@@ -19,6 +19,3 @@
 #define SYS_symlinkat		295
 #define SYS_uname		120
 #define SYS_write		  4
-
-#define KEXEC_ARCH_PPC64	 21
-#define KEXEC_ARCH		KEXEC_ARCH_PPC64
diff --git a/stand/kboot/host_syscall.h b/stand/kboot/host_syscall.h
index 1b12ffc3d4e6..061f82b062b0 100644
--- a/stand/kboot/host_syscall.h
+++ b/stand/kboot/host_syscall.h
@@ -95,6 +95,29 @@ struct host_timeval {
 #define HOST_REBOOT_MAGIC2	672274793
 #define HOST_REBOOT_CMD_KEXEC	0x45584543
 
+/*
+ * Values from linux/tools/include/uapi/linux/kexec.h
+ */
+
+/*
+ * Values match ELF architecture types.
+ */
+#define HOST_KEXEC_ARCH_X86_64  (62 << 16)
+#define HOST_KEXEC_ARCH_PPC64   (21 << 16)
+#define HOST_KEXEC_ARCH_ARM     (40 << 16)
+#define HOST_KEXEC_ARCH_AARCH64 (183 << 16)
+#define HOST_KEXEC_ARCH_RISCV   (243 << 16)
+
+/* Arbitrary cap on segments */
+#define HOST_KEXEC_SEGMENT_MAX 16
+
+struct host_kexec_segment {
+	void *buf;
+	int bufsz;
+	void *mem;
+	int memsz;
+};
+
 /*
  * System Calls
  */
@@ -104,7 +127,7 @@ int host_fstat(int fd, struct host_kstat *sb);
 int host_getdents(int fd, void *dirp, int count);
 int host_getpid(void);
 int host_gettimeofday(struct host_timeval *a, void *b);
-int host_kexec_load(uint32_t start, int nsegs, uint32_t segs, uint32_t flags);
+int host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags);
 ssize_t host_llseek(int fd, int32_t offset_high, int32_t offset_lo, uint64_t *result, int whence);
 int host_mkdir(const char *, host_mode_t);
 void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t off);
diff --git a/stand/kboot/host_syscalls.c b/stand/kboot/host_syscalls.c
index 1dd7aeb1963b..865107263d7b 100644
--- a/stand/kboot/host_syscalls.c
+++ b/stand/kboot/host_syscalls.c
@@ -44,9 +44,9 @@ host_gettimeofday(struct host_timeval *a, void *b)
 }
 
 int
-host_kexec_load(uint32_t start, int nsegs, uint32_t segs, uint32_t flags)
+host_kexec_load(unsigned long entry, unsigned long nsegs, struct host_kexec_segment *segs, unsigned long flags)
 {
-	return host_syscall(SYS_kexec_load, start, nsegs, segs, flags);
+	return host_syscall(SYS_kexec_load, entry, nsegs, segs, flags);
 }
 
 ssize_t
diff --git a/stand/kboot/main.c b/stand/kboot/main.c
index 3fab25132f15..79c03398ba6d 100644
--- a/stand/kboot/main.c
+++ b/stand/kboot/main.c
@@ -340,14 +340,7 @@ time(time_t *tloc)
 	return (rv);
 }
 
-struct kexec_segment {
-	void *buf;
-	int bufsz;
-	void *mem;
-	int memsz;
-};
-
-struct kexec_segment loaded_segments[128];
+struct host_kexec_segment loaded_segments[128];
 int nkexec_segments = 0;
 
 static ssize_t