• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "defs.h"
2 #include <linux/kexec.h>
3 
4 #include "xlat/kexec_arch_values.h"
5 #include "xlat/kexec_flags.h"
6 
7 static void
print_kexec_segments(struct tcb * tcp,unsigned long addr,unsigned long len)8 print_kexec_segments(struct tcb *tcp, unsigned long addr, unsigned long len)
9 {
10 #if SUPPORTED_PERSONALITIES > 1
11 	union {
12 		struct { u_int32_t buf, bufsz, mem, memsz; } seg32;
13 		struct { u_int64_t buf, bufsz, mem, memsz; } seg64;
14 	} seg;
15 # define sizeof_seg \
16 	(current_wordsize == 4 ? sizeof(seg.seg32) : sizeof(seg.seg64))
17 # define seg_buf \
18 	(current_wordsize == 4 ? (uint64_t) seg.seg32.buf : seg.seg64.buf)
19 # define seg_bufsz \
20 	(current_wordsize == 4 ? (uint64_t) seg.seg32.bufsz : seg.seg64.bufsz)
21 # define seg_mem \
22 	(current_wordsize == 4 ? (uint64_t) seg.seg32.mem : seg.seg64.mem)
23 # define seg_memsz \
24 	(current_wordsize == 4 ? (uint64_t) seg.seg32.memsz : seg.seg64.memsz)
25 #else
26 	struct kexec_segment seg;
27 # define sizeof_seg sizeof(seg)
28 # define seg_buf seg.buf
29 # define seg_bufsz seg.bufsz
30 # define seg_mem seg.mem
31 # define seg_memsz seg.memsz
32 #endif
33 	unsigned int i, failed;
34 
35 	if (!len) {
36 		tprints("[]");
37 		return;
38 	}
39 
40 	if (len > KEXEC_SEGMENT_MAX) {
41 		tprintf("%#lx", addr);
42 		return;
43 	}
44 
45 	failed = 0;
46 	tprints("[");
47 	for (i = 0; i < len; ++i) {
48 		if (i)
49 			tprints(", ");
50 		if (umoven(tcp, addr + i * sizeof_seg, sizeof_seg,
51 			   (char *) &seg) < 0) {
52 			tprints("?");
53 			failed = 1;
54 			break;
55 		}
56 		tprintf("{%#lx, %lu, %#lx, %lu}",
57 			(long) seg_buf, (unsigned long) seg_bufsz,
58 			(long) seg_mem, (unsigned long) seg_memsz);
59 	}
60 	tprints("]");
61 	if (failed)
62 		tprintf(" %#lx", addr);
63 }
64 
65 int
sys_kexec_load(struct tcb * tcp)66 sys_kexec_load(struct tcb *tcp)
67 {
68 	unsigned long n;
69 
70 	if (exiting(tcp))
71 		return 0;
72 
73 	/* entry, nr_segments */
74 	tprintf("%#lx, %lu, ", tcp->u_arg[0], tcp->u_arg[1]);
75 
76 	/* segments */
77 	print_kexec_segments(tcp, tcp->u_arg[2], tcp->u_arg[1]);
78 	tprints(", ");
79 
80 	/* flags */
81 	n = tcp->u_arg[3];
82 	printxval(kexec_arch_values, n & KEXEC_ARCH_MASK, "KEXEC_ARCH_???");
83 	n &= ~KEXEC_ARCH_MASK;
84 	if (n) {
85 		tprints("|");
86 		printflags(kexec_flags, n, "KEXEC_???");
87 	}
88 
89 	return 0;
90 }
91