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 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 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