xref: /linux/tools/testing/selftests/kho/init.c (revision 8804d970fab45726b3c7cd7f240b31122aa94219)
1 // SPDX-License-Identifier: GPL-2.0
2 
3 #include <stdio.h>
4 #include <unistd.h>
5 #include <fcntl.h>
6 #include <sys/syscall.h>
7 #include <sys/mount.h>
8 #include <sys/reboot.h>
9 #include <linux/kexec.h>
10 
11 /* from arch/x86/include/asm/setup.h */
12 #define COMMAND_LINE_SIZE	2048
13 
14 #define KHO_FINALIZE "/debugfs/kho/out/finalize"
15 #define KERNEL_IMAGE "/kernel"
16 
mount_filesystems(void)17 static int mount_filesystems(void)
18 {
19 	if (mount("debugfs", "/debugfs", "debugfs", 0, NULL) < 0)
20 		return -1;
21 
22 	return mount("proc", "/proc", "proc", 0, NULL);
23 }
24 
kho_enable(void)25 static int kho_enable(void)
26 {
27 	const char enable[] = "1";
28 	int fd;
29 
30 	fd = open(KHO_FINALIZE, O_RDWR);
31 	if (fd < 0)
32 		return -1;
33 
34 	if (write(fd, enable, sizeof(enable)) != sizeof(enable))
35 		return 1;
36 
37 	close(fd);
38 	return 0;
39 }
40 
kexec_file_load(int kernel_fd,int initrd_fd,unsigned long cmdline_len,const char * cmdline,unsigned long flags)41 static long kexec_file_load(int kernel_fd, int initrd_fd,
42 			    unsigned long cmdline_len, const char *cmdline,
43 			    unsigned long flags)
44 {
45 	return syscall(__NR_kexec_file_load, kernel_fd, initrd_fd, cmdline_len,
46 		       cmdline, flags);
47 }
48 
kexec_load(void)49 static int kexec_load(void)
50 {
51 	char cmdline[COMMAND_LINE_SIZE];
52 	ssize_t len;
53 	int fd, err;
54 
55 	fd = open("/proc/cmdline", O_RDONLY);
56 	if (fd < 0)
57 		return -1;
58 
59 	len = read(fd, cmdline, sizeof(cmdline));
60 	close(fd);
61 	if (len < 0)
62 		return -1;
63 
64 	/* replace \n with \0 */
65 	cmdline[len - 1] = 0;
66 	fd = open(KERNEL_IMAGE, O_RDONLY);
67 	if (fd < 0)
68 		return -1;
69 
70 	err = kexec_file_load(fd, -1, len, cmdline, KEXEC_FILE_NO_INITRAMFS);
71 	close(fd);
72 
73 	return err ? : 0;
74 }
75 
main(int argc,char * argv[])76 int main(int argc, char *argv[])
77 {
78 	if (mount_filesystems())
79 		goto err_reboot;
80 
81 	if (kho_enable())
82 		goto err_reboot;
83 
84 	if (kexec_load())
85 		goto err_reboot;
86 
87 	if (reboot(RB_KEXEC))
88 		goto err_reboot;
89 
90 	return 0;
91 
92 err_reboot:
93 	reboot(RB_AUTOBOOT);
94 	return -1;
95 }
96