1#include "defs.h" 2#include <linux/kexec.h> 3 4#include "xlat/kexec_arch_values.h" 5#include "xlat/kexec_flags.h" 6 7static void 8print_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 65int 66sys_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