Root/target/linux/generic/patches-2.6.39/335-mips-kexec-cleanup-kexec-tools-parameter-handling.patch

1--- a/arch/mips/kernel/machine_kexec.c
2+++ b/arch/mips/kernel/machine_kexec.c
3@@ -23,67 +23,104 @@ void (*relocated_kexec_smp_wait) (void *
4 atomic_t kexec_ready_to_reboot = ATOMIC_INIT(0);
5 #endif
6 
7-static void machine_kexec_init_args(void)
8+#define KEXEC_MIPS_ARGV_BUF_SIZE COMMAND_LINE_SIZE
9+#define KEXEC_MIPS_ARGV_MAX_ARGS (COMMAND_LINE_SIZE / 15)
10+
11+char kexec_argv_buf[KEXEC_MIPS_ARGV_BUF_SIZE] __kexec;
12+char *kexec_argv[KEXEC_MIPS_ARGV_MAX_ARGS] __kexec;
13+
14+static void
15+machine_kexec_print_args(void)
16 {
17- kexec_args[0] = fw_arg0;
18- kexec_args[1] = fw_arg1;
19- kexec_args[2] = fw_arg2;
20- kexec_args[3] = fw_arg3;
21+ int i;
22 
23     pr_info("kexec_args[0] (argc): %lu\n", kexec_args[0]);
24     pr_info("kexec_args[1] (argv): %p\n", (void *)kexec_args[1]);
25     pr_info("kexec_args[2] (env ): %p\n", (void *)kexec_args[2]);
26     pr_info("kexec_args[3] (desc): %p\n", (void *)kexec_args[3]);
27-}
28 
29-#define ARGV_MAX_ARGS (COMMAND_LINE_SIZE / 15)
30+ for (i = 0; i < kexec_args[0]; i++)
31+ pr_info("kexec_argv[%d] = %p, %s\n", i,
32+ (char *)kexec_argv[i], (char *)kexec_argv[i]);
33+}
34 
35-int machine_kexec_pass_args(struct kimage *image)
36+static void
37+machine_kexec_init_argv(struct kimage *image)
38 {
39- int i, argc = 0;
40- char *bootloader = "kexec";
41- int *kexec_argv = (int *)kexec_args[1];
42+ void __user *buf = NULL;
43+ size_t bufsz;
44+ size_t size;
45+ int i;
46 
47+ bufsz = 0;
48     for (i = 0; i < image->nr_segments; i++) {
49- if (!strncmp(bootloader, (char *)image->segment[i].buf,
50- strlen(bootloader))) {
51- /*
52- * convert command line string to array
53- * of parameters (as bootloader does).
54- */
55- /*
56- * Note: we do treat the 1st string "kexec" as an
57- * argument ;-) so, argc here is 1.
58- */
59- char *str = (char *)image->segment[i].buf;
60- char *ptr = strchr(str, ' ');
61- char *kbuf = (char *)kexec_argv[0];
62- /* Whenever --command-line or --append used, "kexec" is copied */
63- argc = 1;
64- /* Parse the offset */
65- while (ptr && (ARGV_MAX_ARGS > argc)) {
66- *ptr = '\0';
67- if (ptr[1] != ' ' && ptr[1] != '\0') {
68- int offt = (int)(ptr - str + 1);
69- kexec_argv[argc] = (int)kbuf + offt;
70- argc++;
71- }
72- ptr = strchr(ptr + 1, ' ');
73- }
74- if (argc > 1) {
75- /* Copy to kernel space */
76- copy_from_user(kbuf, (char *)image->segment[i].buf, image->segment[i].bufsz);
77- fw_arg0 = kexec_args[0] = argc;
78- }
79- break;
80+ struct kexec_segment *seg;
81+
82+ seg = &image->segment[i];
83+ if (seg->bufsz < 6)
84+ continue;
85+
86+ if (strncmp((char *) seg->buf, "kexec", 5))
87+ continue;
88+
89+ /* don't copy "kexec" */
90+ buf = seg->buf + 5;
91+ bufsz = seg->bufsz - 5;
92+ break;
93+ }
94+
95+ if (!buf)
96+ return;
97+
98+ size = KEXEC_MIPS_ARGV_BUF_SIZE - 1;
99+ size = min(size, bufsz);
100+ if (size < bufsz)
101+ pr_warn("kexec command line truncated to %zd bytes\n", size);
102+
103+ /* Copy to kernel space */
104+ copy_from_user(kexec_argv_buf, buf, size);
105+}
106+
107+static void
108+machine_kexec_parse_argv(struct kimage *image)
109+{
110+ char *reboot_code_buffer;
111+ int reloc_delta;
112+ char *ptr;
113+ int argc;
114+ int i;
115+
116+ ptr = kexec_argv_buf;
117+ argc = 0;
118+
119+ /*
120+ * convert command line string to array of parameters
121+ * (as bootloader does).
122+ */
123+ while (ptr && *ptr && (KEXEC_MIPS_ARGV_MAX_ARGS > argc)) {
124+ if (*ptr == ' ') {
125+ *ptr++ = '\0';
126+ continue;
127         }
128+
129+ kexec_argv[argc++] = ptr;
130+ ptr = strchr(ptr, ' ');
131     }
132 
133- pr_info("argc = %lu\n", kexec_args[0]);
134- for (i = 0; i < kexec_args[0]; i++)
135- pr_info("argv[%d] = %p, %s\n", i, (char *)kexec_argv[i], (char *)kexec_argv[i]);
136+ if (!argc)
137+ return;
138 
139- return 0;
140+ kexec_args[0] = argc;
141+ kexec_args[1] = (unsigned long)kexec_argv;
142+ kexec_args[2] = 0;
143+ kexec_args[3] = 0;
144+
145+ reboot_code_buffer = page_address(image->control_code_page);
146+ reloc_delta = reboot_code_buffer - (char *) &__start___kexec_relocate;
147+
148+ kexec_args[1] += reloc_delta;
149+ for (i = 0; i < argc; i++)
150+ kexec_argv[i] += reloc_delta;
151 }
152 
153 int
154@@ -95,8 +132,14 @@ machine_kexec_prepare(struct kimage *kim
155      *
156      * This can be overrided by _machine_kexec_prepare().
157      */
158- machine_kexec_init_args();
159- machine_kexec_pass_args(kimage);
160+
161+ kexec_args[0] = fw_arg0;
162+ kexec_args[1] = fw_arg1;
163+ kexec_args[2] = fw_arg2;
164+ kexec_args[3] = fw_arg3;
165+
166+ machine_kexec_init_argv(kimage);
167+ machine_kexec_parse_argv(kimage);
168 
169     if (_machine_kexec_prepare)
170         return _machine_kexec_prepare(kimage);
171@@ -152,11 +195,13 @@ machine_kexec(struct kimage *image)
172     pr_info("kexec_indirection_page = %p\n",
173             (void *)kexec_indirection_page);
174 
175+ pr_info("Copy kexec_relocate section from %p to reboot_code_buffer: %p\n",
176+ &__start___kexec_relocate, (void *)reboot_code_buffer);
177+
178     memcpy((void *)reboot_code_buffer, &__start___kexec_relocate,
179            kexec_relocate_size);
180 
181- pr_info("Copy kexec_relocate section from %p to reboot_code_buffer: %p\n",
182- &__start___kexec_relocate, (void *)reboot_code_buffer);
183+ machine_kexec_print_args();
184 
185     /*
186      * The generic kexec code builds a page list with physical
187

Archive Download this file



interactive