Root/package/kexec-tools/patches/0005-mips64_support.patch

1--- a/kexec/arch/mips/Makefile
2+++ b/kexec/arch/mips/Makefile
3@@ -4,7 +4,7 @@
4 mips_KEXEC_SRCS = kexec/arch/mips/kexec-mips.c
5 mips_KEXEC_SRCS += kexec/arch/mips/kexec-elf-mips.c
6 mips_KEXEC_SRCS += kexec/arch/mips/kexec-elf-rel-mips.c
7-mips_KEXEC_SRCS += kexec/arch/mips/mips-setup-simple.S
8+mips_KEXEC_SRCS += kexec/arch/mips/crashdump-mips.c
9 
10 mips_ADD_BUFFER =
11 mips_ADD_SEGMENT =
12--- /dev/null
13+++ b/kexec/arch/mips/crashdump-mips.c
14@@ -0,0 +1,371 @@
15+/*
16+ * kexec: Linux boots Linux
17+ *
18+ * 2005 (C) IBM Corporation.
19+ * 2008 (C) MontaVista Software, Inc.
20+ *
21+ * This program is free software; you can redistribute it and/or modify
22+ * it under the terms of the GNU General Public License as published by
23+ * the Free Software Foundation (version 2 of the License).
24+ *
25+ * This program is distributed in the hope that it will be useful,
26+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
27+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28+ * GNU General Public License for more details.
29+ *
30+ * You should have received a copy of the GNU General Public License
31+ * along with this program; if not, write to the Free Software
32+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
33+ */
34+#include <stdio.h>
35+#include <string.h>
36+#include <stdlib.h>
37+#include <errno.h>
38+#include <elf.h>
39+#include <sys/types.h>
40+#include <sys/stat.h>
41+#include <unistd.h>
42+#include "../../kexec.h"
43+#include "../../kexec-elf.h"
44+#include "../../kexec-syscall.h"
45+#include "../../crashdump.h"
46+#include "kexec-mips.h"
47+#include "crashdump-mips.h"
48+
49+extern struct arch_options_t arch_options;
50+
51+/* Stores a sorted list of RAM memory ranges for which to create elf headers.
52+ * A separate program header is created for backup region */
53+static struct memory_range crash_memory_range[CRASH_MAX_MEMORY_RANGES];
54+
55+/* Memory region reserved for storing panic kernel and other data. */
56+static struct memory_range crash_reserved_mem;
57+
58+/*
59+ * To store the memory size of the first kernel and this value will be
60+ * passed to the second kernel as command line (savemaxmem=xM).
61+ * The second kernel will be calculated saved_max_pfn based on this
62+ * variable.
63+ */
64+unsigned long long saved_max_mem = 0;
65+
66+/* Removes crash reserve region from list of memory chunks for whom elf program
67+ * headers have to be created. Assuming crash reserve region to be a single
68+ * continuous area fully contained inside one of the memory chunks */
69+static int exclude_crash_reserve_region(int *nr_ranges)
70+{
71+ int i, j, tidx = -1;
72+ unsigned long long cstart, cend;
73+ struct memory_range temp_region;
74+
75+ /* Crash reserved region. */
76+ cstart = crash_reserved_mem.start;
77+ cend = crash_reserved_mem.end;
78+
79+ for (i = 0; i < (*nr_ranges); i++) {
80+ unsigned long long mstart, mend;
81+ mstart = crash_memory_range[i].start;
82+ mend = crash_memory_range[i].end;
83+ if (cstart < mend && cend > mstart) {
84+ if (cstart != mstart && cend != mend) {
85+ /* Split memory region */
86+ crash_memory_range[i].end = cstart - 1;
87+ temp_region.start = cend + 1;
88+ temp_region.end = mend;
89+ temp_region.type = RANGE_RAM;
90+ tidx = i+1;
91+ } else if (cstart != mstart)
92+ crash_memory_range[i].end = cstart - 1;
93+ else
94+ crash_memory_range[i].start = cend + 1;
95+ }
96+ }
97+ /* Insert split memory region, if any. */
98+ if (tidx >= 0) {
99+ if (*nr_ranges == CRASH_MAX_MEMORY_RANGES) {
100+ /* No space to insert another element. */
101+ fprintf(stderr, "Error: Number of crash memory ranges"
102+ " excedeed the max limit\n");
103+ return -1;
104+ }
105+ for (j = (*nr_ranges - 1); j >= tidx; j--)
106+ crash_memory_range[j+1] = crash_memory_range[j];
107+ crash_memory_range[tidx].start = temp_region.start;
108+ crash_memory_range[tidx].end = temp_region.end;
109+ crash_memory_range[tidx].type = temp_region.type;
110+ (*nr_ranges)++;
111+ }
112+ return 0;
113+}
114+/* Reads the appropriate file and retrieves the SYSTEM RAM regions for whom to
115+ * create Elf headers. Keeping it separate from get_memory_ranges() as
116+ * requirements are different in the case of normal kexec and crashdumps.
117+ *
118+ * Normal kexec needs to look at all of available physical memory irrespective
119+ * of the fact how much of it is being used by currently running kernel.
120+ * Crashdumps need to have access to memory regions actually being used by
121+ * running kernel. Expecting a different file/data structure than /proc/iomem
122+ * to look into down the line. May be something like /proc/kernelmem or may
123+ * be zone data structures exported from kernel.
124+ */
125+static int get_crash_memory_ranges(struct memory_range **range, int *ranges)
126+{
127+ const char iomem[]= "/proc/iomem";
128+ int i, memory_ranges = 0;
129+ char line[MAX_LINE];
130+ FILE *fp;
131+ unsigned long long start, end;
132+
133+ fp = fopen(iomem, "r");
134+ if (!fp) {
135+ fprintf(stderr, "Cannot open %s: %s\n",
136+ iomem, strerror(errno));
137+ return -1;
138+ }
139+
140+ /* Separate segment for backup region */
141+ crash_memory_range[0].start = BACKUP_SRC_START;
142+ crash_memory_range[0].end = BACKUP_SRC_END;
143+ crash_memory_range[0].type = RANGE_RAM;
144+ memory_ranges++;
145+
146+ while(fgets(line, sizeof(line), fp) != 0) {
147+ char *str;
148+ int type, consumed, count;
149+ if (memory_ranges >= CRASH_MAX_MEMORY_RANGES)
150+ break;
151+ count = sscanf(line, "%Lx-%Lx : %n",
152+ &start, &end, &consumed);
153+ if (count != 2)
154+ continue;
155+ str = line + consumed;
156+
157+ /* Only Dumping memory of type System RAM. */
158+ if (memcmp(str, "System RAM\n", 11) == 0) {
159+ type = RANGE_RAM;
160+ } else if (memcmp(str, "Crash kernel\n", 13) == 0) {
161+ /* Reserved memory region. New kernel can
162+ * use this region to boot into. */
163+ crash_reserved_mem.start = start;
164+ crash_reserved_mem.end = end;
165+ crash_reserved_mem.type = RANGE_RAM;
166+ continue;
167+ } else {
168+ continue;
169+ }
170+
171+ if (start == BACKUP_SRC_START && end >= (BACKUP_SRC_END + 1))
172+ start = BACKUP_SRC_END + 1;
173+
174+ crash_memory_range[memory_ranges].start = start;
175+ crash_memory_range[memory_ranges].end = end;
176+ crash_memory_range[memory_ranges].type = type;
177+ memory_ranges++;
178+
179+ /* Segregate linearly mapped region. */
180+ if ((MAXMEM - 1) >= start && (MAXMEM - 1) <= end) {
181+ crash_memory_range[memory_ranges-1].end = MAXMEM -1;
182+
183+ /* Add segregated region. */
184+ crash_memory_range[memory_ranges].start = MAXMEM;
185+ crash_memory_range[memory_ranges].end = end;
186+ crash_memory_range[memory_ranges].type = type;
187+ memory_ranges++;
188+ }
189+ }
190+ fclose(fp);
191+
192+ if (exclude_crash_reserve_region(&memory_ranges) < 0)
193+ return -1;
194+
195+ for (i = 0; i < memory_ranges; i++)
196+ if (saved_max_mem < crash_memory_range[i].end)
197+ saved_max_mem = crash_memory_range[i].end + 1;
198+
199+ *range = crash_memory_range;
200+ *ranges = memory_ranges;
201+ return 0;
202+}
203+
204+/* Converts unsigned long to ascii string. */
205+static void ultoa(unsigned long i, char *str)
206+{
207+ int j = 0, k;
208+ char tmp;
209+
210+ do {
211+ str[j++] = i % 10 + '0';
212+ } while ((i /=10) > 0);
213+ str[j] = '\0';
214+
215+ /* Reverse the string. */
216+ for (j = 0, k = strlen(str) - 1; j < k; j++, k--) {
217+ tmp = str[k];
218+ str[k] = str[j];
219+ str[j] = tmp;
220+ }
221+}
222+
223+/* Adds the appropriate mem= options to command line, indicating the
224+ * memory region the new kernel can use to boot into. */
225+static int cmdline_add_mem(char *cmdline, unsigned long addr, unsigned long size)
226+{
227+ int cmdlen, len;
228+ char str[50], *ptr;
229+
230+ addr = addr/1024;
231+ size = size/1024;
232+ ptr = str;
233+ strcpy (str, " mem=");
234+ ptr += strlen(str);
235+ ultoa(size, ptr);
236+ strcat (str, "K@");
237+ ptr = str + strlen(str);
238+ ultoa(addr, ptr);
239+ strcat (str, "K");
240+ len = strlen(str);
241+ cmdlen = strlen(cmdline) + len;
242+ if (cmdlen > (COMMAND_LINE_SIZE - 1))
243+ die("Command line overflow\n");
244+ strcat(cmdline, str);
245+
246+ return 0;
247+}
248+
249+/* Adds the elfcorehdr= command line parameter to command line. */
250+static int cmdline_add_elfcorehdr(char *cmdline, unsigned long addr)
251+{
252+ int cmdlen, len, align = 1024;
253+ char str[30], *ptr;
254+
255+ /* Passing in elfcorehdr=xxxK format. Saves space required in cmdline.
256+ * Ensure 1K alignment*/
257+ if (addr%align)
258+ return -1;
259+ addr = addr/align;
260+ ptr = str;
261+ strcpy(str, " elfcorehdr=");
262+ ptr += strlen(str);
263+ ultoa(addr, ptr);
264+ strcat(str, "K");
265+ len = strlen(str);
266+ cmdlen = strlen(cmdline) + len;
267+ if (cmdlen > (COMMAND_LINE_SIZE - 1))
268+ die("Command line overflow\n");
269+ strcat(cmdline, str);
270+ return 0;
271+}
272+
273+/* Adds the elfcorehdr= command line parameter to command line. */
274+static int cmdline_add_savemaxmem(char *cmdline, unsigned long addr)
275+{
276+ int cmdlen, len, align = 1024;
277+ char str[30], *ptr;
278+
279+ /* Passing in savemaxmem=xxxM format. Saves space required in cmdline.*/
280+ addr = addr/(align*align);
281+ ptr = str;
282+ strcpy(str, " savemaxmem=");
283+ ptr += strlen(str);
284+ ultoa(addr, ptr);
285+ strcat(str, "M");
286+ len = strlen(str);
287+ cmdlen = strlen(cmdline) + len;
288+ if (cmdlen > (COMMAND_LINE_SIZE - 1))
289+ die("Command line overflow\n");
290+ strcat(cmdline, str);
291+ return 0;
292+}
293+
294+#ifdef __mips64
295+static struct crash_elf_info elf_info64 =
296+{
297+ class: ELFCLASS64,
298+ data: ELFDATA2MSB,
299+ machine: EM_MIPS,
300+ backup_src_start: BACKUP_SRC_START,
301+ backup_src_end: BACKUP_SRC_END,
302+ page_offset: PAGE_OFFSET,
303+ lowmem_limit: MAXMEM,
304+};
305+#endif
306+static struct crash_elf_info elf_info32 =
307+{
308+ class: ELFCLASS32,
309+ data: ELFDATA2MSB,
310+ machine: EM_MIPS,
311+ backup_src_start: BACKUP_SRC_START,
312+ backup_src_end: BACKUP_SRC_END,
313+ page_offset: PAGE_OFFSET,
314+ lowmem_limit: MAXMEM,
315+};
316+
317+/* Loads additional segments in case of a panic kernel is being loaded.
318+ * One segment for backup region, another segment for storing elf headers
319+ * for crash memory image.
320+ */
321+int load_crashdump_segments(struct kexec_info *info, char* mod_cmdline,
322+ unsigned long max_addr, unsigned long min_base)
323+{
324+ void *tmp;
325+ unsigned long sz, elfcorehdr;
326+ int nr_ranges, align = 1024;
327+ struct memory_range *mem_range;
328+
329+ if (get_crash_memory_ranges(&mem_range, &nr_ranges) < 0)
330+ return -1;
331+
332+ /* Create a backup region segment to store backup data*/
333+ sz = (BACKUP_SRC_SIZE + align - 1) & ~(align - 1);
334+ tmp = xmalloc(sz);
335+ memset(tmp, 0, sz);
336+ info->backup_start = add_buffer(info, tmp, sz, sz, align,
337+ crash_reserved_mem.start,
338+ crash_reserved_mem.end,-1);
339+
340+#ifdef __mips64
341+ /* Create elf header segment and store crash image data. */
342+ if (arch_options.core_header_type == CORE_TYPE_ELF64) {
343+ if (crash_create_elf64_headers(info, &elf_info64,
344+ crash_memory_range, nr_ranges,
345+ &tmp, &sz,
346+ ELF_CORE_HEADER_ALIGN) < 0)
347+ return -1;
348+ }
349+ else {
350+ if (crash_create_elf32_headers(info, &elf_info32,
351+ crash_memory_range, nr_ranges,
352+ &tmp, &sz,
353+ ELF_CORE_HEADER_ALIGN) < 0)
354+ return -1;
355+ }
356+#else
357+ if (crash_create_elf32_headers(info, &elf_info32,
358+ crash_memory_range, nr_ranges,
359+ &tmp, &sz,
360+ ELF_CORE_HEADER_ALIGN) < 0)
361+ return -1;
362+#endif
363+ elfcorehdr = add_buffer(info, tmp, sz, sz, align,
364+ crash_reserved_mem.start,
365+ crash_reserved_mem.end, -1);
366+
367+ /*
368+ * backup segment is after elfcorehdr, so use elfcorehdr as top of
369+ * kernel's available memory
370+ */
371+ cmdline_add_mem(mod_cmdline, crash_reserved_mem.start,
372+ elfcorehdr - crash_reserved_mem.start);
373+ cmdline_add_elfcorehdr(mod_cmdline, elfcorehdr);
374+ cmdline_add_savemaxmem(mod_cmdline, saved_max_mem);
375+ return 0;
376+}
377+
378+int is_crashkernel_mem_reserved(void)
379+{
380+ uint64_t start, end;
381+
382+ return parse_iomem_single("Crash kernel\n", &start, &end) == 0 ?
383+ (start != end) : 0;
384+}
385+
386--- /dev/null
387+++ b/kexec/arch/mips/crashdump-mips.h
388@@ -0,0 +1,26 @@
389+#ifndef CRASHDUMP_MIPS_H
390+#define CRASHDUMP_MIPS_H
391+
392+struct kexec_info;
393+int load_crashdump_segments(struct kexec_info *info, char *mod_cmdline,
394+ unsigned long max_addr, unsigned long min_base);
395+#ifdef __mips64
396+#define PAGE_OFFSET 0xa800000000000000ULL
397+#else
398+#define PAGE_OFFSET 0x80000000
399+#endif
400+#define __pa(x) ((unsigned long)(X)& 0x7fffffff)
401+
402+#define MAXMEM 0x80000000
403+
404+#define CRASH_MAX_MEMMAP_NR (KEXEC_MAX_SEGMENTS + 1)
405+#define CRASH_MAX_MEMORY_RANGES (MAX_MEMORY_RANGES + 2)
406+
407+#define COMMAND_LINE_SIZE 512
408+
409+/* Backup Region, First 1M of System RAM. */
410+#define BACKUP_SRC_START 0x00000000
411+#define BACKUP_SRC_END 0x000fffff
412+#define BACKUP_SRC_SIZE (BACKUP_SRC_END - BACKUP_SRC_START + 1)
413+
414+#endif /* CRASHDUMP_MIPS_H */
415--- a/kexec/arch/mips/include/arch/options.h
416+++ b/kexec/arch/mips/include/arch/options.h
417@@ -2,10 +2,21 @@
418 #define KEXEC_ARCH_MIPS_OPTIONS_H
419 
420 #define OPT_ARCH_MAX (OPT_MAX+0)
421+#define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
422 
423+#ifdef __mips64
424+#define OPT_ELF64_CORE (OPT_MAX+1)
425 #define KEXEC_ARCH_OPTIONS \
426     KEXEC_OPTIONS \
427+ { "elf64-core-headers", 0, 0, OPT_ELF64_CORE }, \
428 
429 #define KEXEC_ARCH_OPT_STR KEXEC_OPT_STR ""
430+#define OPT_ARCH_MAX (OPT_MAX+2)
431+#else
432+#define KEXEC_ARCH_OPTIONS \
433+ KEXEC_OPTIONS \
434+
435+#define OPT_ARCH_MAX (OPT_MAX+0)
436+#endif
437 
438 #endif /* KEXEC_ARCH_MIPS_OPTIONS_H */
439--- a/kexec/arch/mips/kexec-elf-mips.c
440+++ b/kexec/arch/mips/kexec-elf-mips.c
441@@ -25,51 +25,18 @@
442 #include <ip_checksum.h>
443 #include "../../kexec.h"
444 #include "../../kexec-elf.h"
445+#include "../../kexec-syscall.h"
446 #include "kexec-mips.h"
447 #include <arch/options.h>
448+#include "crashdump-mips.h"
449 
450 static const int probe_debug = 0;
451 
452 #define BOOTLOADER "kexec"
453 #define MAX_COMMAND_LINE 256
454 
455-#define UPSZ(X) ((sizeof(X) + 3) & ~3)
456-static struct boot_notes {
457- Elf_Bhdr hdr;
458- Elf_Nhdr bl_hdr;
459- unsigned char bl_desc[UPSZ(BOOTLOADER)];
460- Elf_Nhdr blv_hdr;
461- unsigned char blv_desc[UPSZ(BOOTLOADER_VERSION)];
462- Elf_Nhdr cmd_hdr;
463- unsigned char command_line[0];
464-} elf_boot_notes = {
465- .hdr = {
466- .b_signature = 0x0E1FB007,
467- .b_size = sizeof(elf_boot_notes),
468- .b_checksum = 0,
469- .b_records = 3,
470- },
471- .bl_hdr = {
472- .n_namesz = 0,
473- .n_descsz = sizeof(BOOTLOADER),
474- .n_type = EBN_BOOTLOADER_NAME,
475- },
476- .bl_desc = BOOTLOADER,
477- .blv_hdr = {
478- .n_namesz = 0,
479- .n_descsz = sizeof(BOOTLOADER_VERSION),
480- .n_type = EBN_BOOTLOADER_VERSION,
481- },
482- .blv_desc = BOOTLOADER_VERSION,
483- .cmd_hdr = {
484- .n_namesz = 0,
485- .n_descsz = 0,
486- .n_type = EBN_COMMAND_LINE,
487- },
488-};
489-
490-
491-#define OPT_APPEND (OPT_ARCH_MAX+0)
492+/* 'kexec' in cmdline is used to find cmdline buffer by kernel */
493+static char cmdline_buf[256] = "kexec ";
494 
495 int elf_mips_probe(const char *buf, off_t len)
496 {
497@@ -108,16 +75,14 @@ int elf_mips_load(int argc, char **argv,
498     struct kexec_info *info)
499 {
500     struct mem_ehdr ehdr;
501- char *arg_buf;
502- size_t arg_bytes;
503- unsigned long arg_base;
504- struct boot_notes *notes;
505- size_t note_bytes;
506- const char *command_line;
507- int command_line_len;
508- unsigned char *setup_start;
509- uint32_t setup_size;
510+ unsigned long bss_start, bss_size = 0;
511+ const char *command_line = NULL;
512+ char *modified_cmdline;
513+ int modified_cmdline_len;
514+ unsigned long cmdline_addr;
515+ int result,i;
516     int opt;
517+#define OPT_APPEND (OPT_ARCH_MAX+0)
518     static const struct option options[] = {
519         KEXEC_ARCH_OPTIONS
520         {"command-line", 1, 0, OPT_APPEND},
521@@ -144,38 +109,81 @@ int elf_mips_load(int argc, char **argv,
522             break;
523         }
524     }
525- command_line_len = 0;
526- setup_simple_regs.spr9 = 0;
527- if (command_line) {
528- command_line_len = strlen(command_line) + 1;
529- setup_simple_regs.spr9 = 2;
530+ /* Need to append some command line parameters internally in case of
531+ * taking crash dumps.
532+ */
533+ if (info->kexec_flags & KEXEC_ON_CRASH) {
534+ modified_cmdline = xmalloc(COMMAND_LINE_SIZE);
535+ memset((void *)modified_cmdline, 0, COMMAND_LINE_SIZE);
536+ if (command_line) {
537+ strncpy(modified_cmdline, command_line, COMMAND_LINE_SIZE);
538+ modified_cmdline[COMMAND_LINE_SIZE - 1] = '\0';
539+ }
540+ modified_cmdline_len = strlen(modified_cmdline);
541     }
542 
543- /* Load the ELF executable */
544- elf_exec_build_load(info, &ehdr, buf, len, 0);
545-
546- setup_start = setup_simple_start;
547- setup_size = setup_simple_size;
548- setup_simple_regs.spr8 = ehdr.e_entry;
549-
550- note_bytes = sizeof(elf_boot_notes) + ((command_line_len + 3) & ~3);
551- arg_bytes = note_bytes + ((setup_size + 3) & ~3);
552-
553- arg_buf = xmalloc(arg_bytes);
554- arg_base = add_buffer_virt(info,
555- arg_buf, arg_bytes, arg_bytes, 4, 0, elf_max_addr(&ehdr), 1);
556+ /* Parse the Elf file */
557+ result = build_elf_exec_info(buf, len, &ehdr, 0);
558+ if (result < 0) {
559+ die("ELF exec parse failed\n");
560+ }
561 
562- notes = (struct boot_notes *)(arg_buf + ((setup_size + 3) & ~3));
563+ /* Read in the PT_LOAD segments and remove CKSEG0 mask from address*/
564+ for(i = 0; i < ehdr.e_phnum; i++) {
565+ struct mem_phdr *phdr;
566+ phdr = &ehdr.e_phdr[i];
567+ if (phdr->p_type == PT_LOAD) {
568+ phdr->p_paddr = virt_to_phys(phdr->p_paddr);
569+ }
570+ }
571 
572- memcpy(arg_buf, setup_start, setup_size);
573- memcpy(notes, &elf_boot_notes, sizeof(elf_boot_notes));
574- memcpy(notes->command_line, command_line, command_line_len);
575+ for(i = 0; i < ehdr.e_shnum; i++) {
576+ struct mem_shdr *shdr;
577+ unsigned char *strtab;
578+ strtab = (unsigned char *)ehdr.e_shdr[ehdr.e_shstrndx].sh_data;
579+
580+ shdr = &ehdr.e_shdr[i];
581+ if ( shdr->sh_size &&
582+ strcmp((char *)&strtab[shdr->sh_name],
583+ ".bss") == 0) {
584+ bss_start = virt_to_phys(shdr->sh_addr);
585+ bss_size = shdr->sh_size;
586+ break;
587+ }
588+ }
589 
590- notes->hdr.b_size = note_bytes;
591- notes->cmd_hdr.n_descsz = command_line_len;
592- notes->hdr.b_checksum = compute_ip_checksum(notes, note_bytes);
593+ /* Load the Elf data */
594+ result = elf_exec_load(&ehdr, info);
595+ if (result < 0) {
596+ die("ELF exec load failed\n");
597+ }
598+ info->entry = (void *)virt_to_phys(ehdr.e_entry);
599+ if(!bss_size)
600+ die("No .bss segment present\n");
601+
602+ /* Put cmdline right after bss */
603+ cmdline_addr = bss_start + bss_size;
604+
605+ /* If panic kernel is being loaded, additional segments need
606+ * to be created.
607+ */
608+ if (info->kexec_flags & KEXEC_ON_CRASH) {
609+ result = load_crashdump_segments(info, modified_cmdline,
610+ 0, 0);
611+ if (result < 0)
612+ return -1;
613+ /* Use new command line. */
614+ command_line = modified_cmdline;
615+ }
616 
617- info->entry = (void *)arg_base;
618+ if (command_line)
619+ {
620+ strncat(cmdline_buf,command_line,
621+ sizeof(cmdline_buf) - strlen(cmdline_buf) - 1);
622+ add_buffer(info, cmdline_buf, sizeof(cmdline_buf),
623+ sizeof(cmdline_buf), sizeof(void*),
624+ cmdline_addr, 0x0fffffff, 1);
625+ }
626 
627     return 0;
628 }
629--- a/kexec/arch/mips/kexec-mips.c
630+++ b/kexec/arch/mips/kexec-mips.c
631@@ -97,8 +97,18 @@ int file_types = sizeof(file_type) / siz
632 
633 void arch_usage(void)
634 {
635+#ifdef __mips64
636+ fprintf(stderr, " --elf32-core-headers Prepare core headers in "
637+ "ELF32 format\n");
638+#endif
639 }
640 
641+#ifdef __mips64
642+struct arch_options_t arch_options = {
643+ .core_header_type = CORE_TYPE_ELF64
644+};
645+#endif
646+
647 int arch_process_options(int argc, char **argv)
648 {
649     static const struct option options[] = {
650@@ -113,6 +123,11 @@ int arch_process_options(int argc, char
651         switch(opt) {
652         default:
653             break;
654+#ifdef __mips64
655+ case OPT_ELF64_CORE:
656+ arch_options.core_header_type = CORE_TYPE_ELF64;
657+ break;
658+#endif
659         }
660     }
661     /* Reset getopt for the next pass; called in other source modules */
662@@ -126,6 +141,10 @@ const struct arch_map_entry arches[] = {
663      * use KEXEC_ARCH_DEFAULT instead of KEXEC_ARCH_MIPS here.
664      */
665     { "mips", KEXEC_ARCH_DEFAULT },
666+ /* Not using KEXEC_ARCH_DEFAULT because that will fail
667+ * in the kernel's compat_sys_kexec_load() routine.
668+ */
669+ { "mips64", KEXEC_ARCH_MIPS },
670     { 0 },
671 };
672 
673@@ -138,18 +157,9 @@ void arch_update_purgatory(struct kexec_
674 {
675 }
676 
677-/*
678- * Adding a dummy function, so that build on mips will not break.
679- * Need to implement the actual checking code
680- */
681-int is_crashkernel_mem_reserved(void)
682-{
683- return 1;
684-}
685-
686 unsigned long virt_to_phys(unsigned long addr)
687 {
688- return addr - 0x80000000;
689+ return ((addr)& 0x7fffffff);
690 }
691 
692 /*
693--- a/kexec/arch/mips/kexec-mips.h
694+++ b/kexec/arch/mips/kexec-mips.h
695@@ -1,17 +1,16 @@
696 #ifndef KEXEC_MIPS_H
697 #define KEXEC_MIPS_H
698 
699-extern unsigned char setup_simple_start[];
700-extern uint32_t setup_simple_size;
701-
702-extern struct {
703- uint32_t spr8;
704- uint32_t spr9;
705-} setup_simple_regs;
706+#define MAX_MEMORY_RANGES 64
707+#define CORE_TYPE_ELF32 1
708+#define CORE_TYPE_ELF64 2
709 
710 int elf_mips_probe(const char *buf, off_t len);
711 int elf_mips_load(int argc, char **argv, const char *buf, off_t len,
712     struct kexec_info *info);
713 void elf_mips_usage(void);
714 
715+struct arch_options_t {
716+ int core_header_type;
717+};
718 #endif /* KEXEC_MIPS_H */
719

Archive Download this file



interactive