blob: a920b42eb17de0f29c4601be234b52b5530decee [file] [log] [blame]
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +00001#include "defs.h"
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +00002
Dmitry V. Levinff6a55d2015-02-19 21:16:45 +00003#include "xlat/kexec_load_flags.h"
Dmitry V. Levin0ed617b2014-04-25 23:30:54 +00004#include "xlat/kexec_arch_values.h"
Dmitry V. Levinff6a55d2015-02-19 21:16:45 +00005
6#ifndef KEXEC_ARCH_MASK
7# define KEXEC_ARCH_MASK 0xffff0000
8#endif
9#ifndef KEXEC_SEGMENT_MAX
10# define KEXEC_SEGMENT_MAX 16
11#endif
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000012
13static void
Dmitry V. Levinb172a942015-09-15 02:17:32 +000014print_seg(const unsigned long *seg)
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000015{
16 tprints("{");
Dmitry V. Levinb172a942015-09-15 02:17:32 +000017 printaddr(seg[0]);
18 tprintf(", %lu, ", seg[1]);
19 printaddr(seg[2]);
20 tprintf(", %lu}", seg[3]);
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000021}
22
23static void
24print_kexec_segments(struct tcb *tcp, const unsigned long addr,
25 const unsigned long len)
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000026{
Dmitry V. Levinb172a942015-09-15 02:17:32 +000027 unsigned long seg[4];
28 const size_t sizeof_seg = ARRAY_SIZE(seg) * current_wordsize;
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000029 unsigned int i;
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000030
31 if (!len) {
32 tprints("[]");
33 return;
34 }
35
36 if (len > KEXEC_SEGMENT_MAX) {
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000037 printaddr(addr);
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000038 return;
39 }
40
Dmitry V. Levinb172a942015-09-15 02:17:32 +000041 if (umove_ulong_array_or_printaddr(tcp, addr, seg, ARRAY_SIZE(seg)))
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000042 return;
43
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000044 tprints("[");
Dmitry V. Levinb172a942015-09-15 02:17:32 +000045 print_seg(seg);
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000046
47 for (i = 1; i < len; ++i) {
48 tprints(", ");
Dmitry V. Levinb172a942015-09-15 02:17:32 +000049 if (umove_ulong_array_or_printaddr(tcp,
50 addr + i * sizeof_seg,
51 seg, ARRAY_SIZE(seg)))
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000052 break;
Dmitry V. Levinb172a942015-09-15 02:17:32 +000053 print_seg(seg);
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000054 }
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000055
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000056 tprints("]");
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000057}
58
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000059SYS_FUNC(kexec_load)
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000060{
61 unsigned long n;
62
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000063 /* entry, nr_segments */
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000064 printaddr(tcp->u_arg[0]);
65 tprintf(", %lu, ", tcp->u_arg[1]);
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000066
67 /* segments */
68 print_kexec_segments(tcp, tcp->u_arg[2], tcp->u_arg[1]);
69 tprints(", ");
70
71 /* flags */
72 n = tcp->u_arg[3];
73 printxval(kexec_arch_values, n & KEXEC_ARCH_MASK, "KEXEC_ARCH_???");
74 n &= ~KEXEC_ARCH_MASK;
75 if (n) {
76 tprints("|");
Dmitry V. Levinff6a55d2015-02-19 21:16:45 +000077 printflags(kexec_load_flags, n, "KEXEC_???");
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000078 }
79
Dmitry V. Levin2f444dc2015-07-20 01:20:44 +000080 return RVAL_DECODED;
Dmitry V. Levin90aa9f42014-02-05 13:48:26 +000081}
Dmitry V. Levinea197052015-11-22 18:51:05 +000082
83#include "xlat/kexec_file_load_flags.h"
84
85SYS_FUNC(kexec_file_load)
86{
87 /* kernel_fd */
88 printfd(tcp, tcp->u_arg[0]);
89 tprints(", ");
90 /* initrd_fd */
91 printfd(tcp, tcp->u_arg[1]);
92 tprints(", ");
93 /* cmdline_len */
94 tprintf("%lu, ", tcp->u_arg[2]);
95 /* cmdline */
96 printstr(tcp, tcp->u_arg[3], tcp->u_arg[2]);
97 tprints(", ");
98 /* flags */
99 printflags(kexec_file_load_flags, tcp->u_arg[4], "KEXEC_FILE_???");
100
101 return RVAL_DECODED;
102}