1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#undef DEBUG
28#define pr_fmt(fmt) "fadump: " fmt
29
30#include <linux/string.h>
31#include <linux/memblock.h>
32#include <linux/delay.h>
33#include <linux/debugfs.h>
34#include <linux/seq_file.h>
35#include <linux/crash_dump.h>
36#include <linux/kobject.h>
37#include <linux/sysfs.h>
38#include <linux/slab.h>
39
40#include <asm/page.h>
41#include <asm/prom.h>
42#include <asm/rtas.h>
43#include <asm/fadump.h>
44#include <asm/debug.h>
45#include <asm/setup.h>
46
47static struct fw_dump fw_dump;
48static struct fadump_mem_struct fdm;
49static const struct fadump_mem_struct *fdm_active;
50
51static DEFINE_MUTEX(fadump_mutex);
52struct fad_crash_memory_ranges *crash_memory_ranges;
53int crash_memory_ranges_size;
54int crash_mem_ranges;
55int max_crash_mem_ranges;
56
57
58int __init early_init_dt_scan_fw_dump(unsigned long node,
59 const char *uname, int depth, void *data)
60{
61 __be32 *sections;
62 int i, num_sections;
63 unsigned long size;
64 const __be32 *token;
65
66 if (depth != 1 || strcmp(uname, "rtas") != 0)
67 return 0;
68
69
70
71
72
73 token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL);
74 if (!token)
75 return 1;
76
77 fw_dump.fadump_supported = 1;
78 fw_dump.ibm_configure_kernel_dump = be32_to_cpu(*token);
79
80
81
82
83
84 fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);
85 if (fdm_active)
86 fw_dump.dump_active = 1;
87
88
89
90
91
92
93
94 sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
95 &size);
96
97 if (!sections)
98 return 1;
99
100 num_sections = size / (3 * sizeof(u32));
101
102 for (i = 0; i < num_sections; i++, sections += 3) {
103 u32 type = (u32)of_read_number(sections, 1);
104
105 switch (type) {
106 case FADUMP_CPU_STATE_DATA:
107 fw_dump.cpu_state_data_size =
108 of_read_ulong(§ions[1], 2);
109 break;
110 case FADUMP_HPTE_REGION:
111 fw_dump.hpte_region_size =
112 of_read_ulong(§ions[1], 2);
113 break;
114 }
115 }
116
117 return 1;
118}
119
120int is_fadump_enabled(void)
121{
122 return fw_dump.fadump_enabled;
123}
124
125
126
127
128
129int is_fadump_boot_memory_area(u64 addr, ulong size)
130{
131 if (!fw_dump.dump_registered)
132 return 0;
133
134 return (addr + size) > RMA_START && addr <= fw_dump.boot_memory_size;
135}
136
137int is_fadump_active(void)
138{
139 return fw_dump.dump_active;
140}
141
142
143
144
145
146static int is_boot_memory_area_contiguous(void)
147{
148 struct memblock_region *reg;
149 unsigned long tstart, tend;
150 unsigned long start_pfn = PHYS_PFN(RMA_START);
151 unsigned long end_pfn = PHYS_PFN(RMA_START + fw_dump.boot_memory_size);
152 unsigned int ret = 0;
153
154 for_each_memblock(memory, reg) {
155 tstart = max(start_pfn, memblock_region_memory_base_pfn(reg));
156 tend = min(end_pfn, memblock_region_memory_end_pfn(reg));
157 if (tstart < tend) {
158
159 if (tstart > start_pfn)
160 break;
161
162 if (tend == end_pfn) {
163 ret = 1;
164 break;
165 }
166
167 start_pfn = tend + 1;
168 }
169 }
170
171 return ret;
172}
173
174
175static void fadump_show_config(void)
176{
177 pr_debug("Support for firmware-assisted dump (fadump): %s\n",
178 (fw_dump.fadump_supported ? "present" : "no support"));
179
180 if (!fw_dump.fadump_supported)
181 return;
182
183 pr_debug("Fadump enabled : %s\n",
184 (fw_dump.fadump_enabled ? "yes" : "no"));
185 pr_debug("Dump Active : %s\n",
186 (fw_dump.dump_active ? "yes" : "no"));
187 pr_debug("Dump section sizes:\n");
188 pr_debug(" CPU state data size: %lx\n", fw_dump.cpu_state_data_size);
189 pr_debug(" HPTE region size : %lx\n", fw_dump.hpte_region_size);
190 pr_debug("Boot memory size : %lx\n", fw_dump.boot_memory_size);
191}
192
193static unsigned long init_fadump_mem_struct(struct fadump_mem_struct *fdm,
194 unsigned long addr)
195{
196 if (!fdm)
197 return 0;
198
199 memset(fdm, 0, sizeof(struct fadump_mem_struct));
200 addr = addr & PAGE_MASK;
201
202 fdm->header.dump_format_version = cpu_to_be32(0x00000001);
203 fdm->header.dump_num_sections = cpu_to_be16(3);
204 fdm->header.dump_status_flag = 0;
205 fdm->header.offset_first_dump_section =
206 cpu_to_be32((u32)offsetof(struct fadump_mem_struct, cpu_state_data));
207
208
209
210
211
212 fdm->header.dd_block_size = 0;
213 fdm->header.dd_block_offset = 0;
214 fdm->header.dd_num_blocks = 0;
215 fdm->header.dd_offset_disk_path = 0;
216
217
218 fdm->header.max_time_auto = 0;
219
220
221
222 fdm->cpu_state_data.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
223 fdm->cpu_state_data.source_data_type = cpu_to_be16(FADUMP_CPU_STATE_DATA);
224 fdm->cpu_state_data.source_address = 0;
225 fdm->cpu_state_data.source_len = cpu_to_be64(fw_dump.cpu_state_data_size);
226 fdm->cpu_state_data.destination_address = cpu_to_be64(addr);
227 addr += fw_dump.cpu_state_data_size;
228
229
230 fdm->hpte_region.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
231 fdm->hpte_region.source_data_type = cpu_to_be16(FADUMP_HPTE_REGION);
232 fdm->hpte_region.source_address = 0;
233 fdm->hpte_region.source_len = cpu_to_be64(fw_dump.hpte_region_size);
234 fdm->hpte_region.destination_address = cpu_to_be64(addr);
235 addr += fw_dump.hpte_region_size;
236
237
238 fdm->rmr_region.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
239 fdm->rmr_region.source_data_type = cpu_to_be16(FADUMP_REAL_MODE_REGION);
240 fdm->rmr_region.source_address = cpu_to_be64(RMA_START);
241 fdm->rmr_region.source_len = cpu_to_be64(fw_dump.boot_memory_size);
242 fdm->rmr_region.destination_address = cpu_to_be64(addr);
243 addr += fw_dump.boot_memory_size;
244
245 return addr;
246}
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263static inline unsigned long fadump_calculate_reserve_size(void)
264{
265 int ret;
266 unsigned long long base, size;
267
268 if (fw_dump.reserve_bootvar)
269 pr_warn("'fadump_reserve_mem=' parameter is deprecated in "
270 "favor of 'crashkernel=' parameter.\n");
271
272
273
274
275
276
277 ret = parse_crashkernel(boot_command_line, memblock_phys_mem_size(),
278 &size, &base);
279 if (ret == 0 && size > 0) {
280 if (fw_dump.reserve_bootvar)
281 pr_info("Using 'crashkernel=' parameter for"
282 " memory reservation.\n");
283
284 fw_dump.reserve_bootvar = (unsigned long)size;
285 return fw_dump.reserve_bootvar;
286 } else if (fw_dump.reserve_bootvar) {
287
288
289
290
291 return fw_dump.reserve_bootvar;
292 }
293
294 return fadump_default_reserve_size();
295}
296
297unsigned long long fadump_default_reserve_size(void)
298{
299 unsigned long long size;
300
301
302 size = memblock_end_of_DRAM() / 20;
303
304
305 size = size & ~0x0FFFFFFFUL;
306
307
308 if (memory_limit && size > memory_limit)
309 size = memory_limit;
310
311 return (size > MIN_BOOT_MEM ? size : MIN_BOOT_MEM);
312}
313
314
315
316
317
318static unsigned long get_fadump_area_size(void)
319{
320 unsigned long size = 0;
321
322 size += fw_dump.cpu_state_data_size;
323 size += fw_dump.hpte_region_size;
324 size += fw_dump.boot_memory_size;
325 size += sizeof(struct fadump_crash_info_header);
326 size += sizeof(struct elfhdr);
327 size += sizeof(struct elf_phdr);
328
329 size += sizeof(struct elf_phdr) * (memblock_num_regions(memory) + 2);
330
331 size = PAGE_ALIGN(size);
332 return size;
333}
334
335static void __init fadump_reserve_crash_area(unsigned long base,
336 unsigned long size)
337{
338 struct memblock_region *reg;
339 unsigned long mstart, mend, msize;
340
341 for_each_memblock(memory, reg) {
342 mstart = max_t(unsigned long, base, reg->base);
343 mend = reg->base + reg->size;
344 mend = min(base + size, mend);
345
346 if (mstart < mend) {
347 msize = mend - mstart;
348 memblock_reserve(mstart, msize);
349 pr_info("Reserved %ldMB of memory at %#016lx for saving crash dump\n",
350 (msize >> 20), mstart);
351 }
352 }
353}
354
355int __init fadump_reserve_mem(void)
356{
357 unsigned long base, size, memory_boundary;
358
359 if (!fw_dump.fadump_enabled)
360 return 0;
361
362 if (!fw_dump.fadump_supported) {
363 printk(KERN_INFO "Firmware-assisted dump is not supported on"
364 " this hardware\n");
365 fw_dump.fadump_enabled = 0;
366 return 0;
367 }
368
369
370
371
372
373 if (fdm_active)
374 fw_dump.boot_memory_size = be64_to_cpu(fdm_active->rmr_region.source_len);
375 else
376 fw_dump.boot_memory_size = fadump_calculate_reserve_size();
377
378
379
380
381
382
383
384
385 if (memory_limit && memory_limit < memblock_end_of_DRAM()) {
386 size = get_fadump_area_size();
387 if ((memory_limit + size) < memblock_end_of_DRAM())
388 memory_limit += size;
389 else
390 memory_limit = memblock_end_of_DRAM();
391 printk(KERN_INFO "Adjusted memory_limit for firmware-assisted"
392 " dump, now %#016llx\n", memory_limit);
393 }
394 if (memory_limit)
395 memory_boundary = memory_limit;
396 else
397 memory_boundary = memblock_end_of_DRAM();
398
399 if (fw_dump.dump_active) {
400 pr_info("Firmware-assisted dump is active.\n");
401
402#ifdef CONFIG_HUGETLB_PAGE
403
404
405
406
407
408 hugetlb_disabled = true;
409#endif
410
411
412
413
414
415
416 base = fw_dump.boot_memory_size;
417 size = memory_boundary - base;
418 fadump_reserve_crash_area(base, size);
419
420 fw_dump.fadumphdr_addr =
421 be64_to_cpu(fdm_active->rmr_region.destination_address) +
422 be64_to_cpu(fdm_active->rmr_region.source_len);
423 pr_debug("fadumphdr_addr = %p\n",
424 (void *) fw_dump.fadumphdr_addr);
425 } else {
426 size = get_fadump_area_size();
427
428
429
430
431
432
433
434 for (base = fw_dump.boot_memory_size;
435 base <= (memory_boundary - size);
436 base += size) {
437 if (memblock_is_region_memory(base, size) &&
438 !memblock_is_region_reserved(base, size))
439 break;
440 }
441 if ((base > (memory_boundary - size)) ||
442 memblock_reserve(base, size)) {
443 pr_err("Failed to reserve memory\n");
444 return 0;
445 }
446
447 pr_info("Reserved %ldMB of memory at %ldMB for firmware-"
448 "assisted dump (System RAM: %ldMB)\n",
449 (unsigned long)(size >> 20),
450 (unsigned long)(base >> 20),
451 (unsigned long)(memblock_phys_mem_size() >> 20));
452 }
453
454 fw_dump.reserve_dump_area_start = base;
455 fw_dump.reserve_dump_area_size = size;
456 return 1;
457}
458
459
460static int __init early_fadump_param(char *p)
461{
462 if (!p)
463 return 1;
464
465 if (strncmp(p, "on", 2) == 0)
466 fw_dump.fadump_enabled = 1;
467 else if (strncmp(p, "off", 3) == 0)
468 fw_dump.fadump_enabled = 0;
469
470 return 0;
471}
472early_param("fadump", early_fadump_param);
473
474
475
476
477
478
479static int __init early_fadump_reserve_mem(char *p)
480{
481 if (p)
482 fw_dump.reserve_bootvar = memparse(p, &p);
483 return 0;
484}
485early_param("fadump_reserve_mem", early_fadump_reserve_mem);
486
487static int register_fw_dump(struct fadump_mem_struct *fdm)
488{
489 int rc, err;
490 unsigned int wait_time;
491
492 pr_debug("Registering for firmware-assisted kernel dump...\n");
493
494
495 do {
496 rc = rtas_call(fw_dump.ibm_configure_kernel_dump, 3, 1, NULL,
497 FADUMP_REGISTER, fdm,
498 sizeof(struct fadump_mem_struct));
499
500 wait_time = rtas_busy_delay_time(rc);
501 if (wait_time)
502 mdelay(wait_time);
503
504 } while (wait_time);
505
506 err = -EIO;
507 switch (rc) {
508 default:
509 pr_err("Failed to register. Unknown Error(%d).\n", rc);
510 break;
511 case -1:
512 printk(KERN_ERR "Failed to register firmware-assisted kernel"
513 " dump. Hardware Error(%d).\n", rc);
514 break;
515 case -3:
516 if (!is_boot_memory_area_contiguous())
517 pr_err("Can't have holes in boot memory area while "
518 "registering fadump\n");
519 printk(KERN_ERR "Failed to register firmware-assisted kernel"
520 " dump. Parameter Error(%d).\n", rc);
521 err = -EINVAL;
522 break;
523 case -9:
524 printk(KERN_ERR "firmware-assisted kernel dump is already "
525 " registered.");
526 fw_dump.dump_registered = 1;
527 err = -EEXIST;
528 break;
529 case 0:
530 printk(KERN_INFO "firmware-assisted kernel dump registration"
531 " is successful\n");
532 fw_dump.dump_registered = 1;
533 err = 0;
534 break;
535 }
536 return err;
537}
538
539void crash_fadump(struct pt_regs *regs, const char *str)
540{
541 struct fadump_crash_info_header *fdh = NULL;
542 int old_cpu, this_cpu;
543
544 if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr)
545 return;
546
547
548
549
550
551
552
553
554 this_cpu = smp_processor_id();
555 old_cpu = cmpxchg(&crashing_cpu, -1, this_cpu);
556
557 if (old_cpu != -1) {
558
559
560
561
562
563
564
565 while (fw_dump.dump_registered)
566 cpu_relax();
567 return;
568 }
569
570 fdh = __va(fw_dump.fadumphdr_addr);
571 fdh->crashing_cpu = crashing_cpu;
572 crash_save_vmcoreinfo();
573
574 if (regs)
575 fdh->regs = *regs;
576 else
577 ppc_save_regs(&fdh->regs);
578
579 fdh->cpu_online_mask = *cpu_online_mask;
580
581
582 rtas_os_term((char *)str);
583}
584
585#define GPR_MASK 0xffffff0000000000
586static inline int fadump_gpr_index(u64 id)
587{
588 int i = -1;
589 char str[3];
590
591 if ((id & GPR_MASK) == REG_ID("GPR")) {
592
593 id &= ~GPR_MASK;
594 id >>= 24;
595 str[2] = '\0';
596 str[1] = id & 0xff;
597 str[0] = (id >> 8) & 0xff;
598 sscanf(str, "%d", &i);
599 if (i > 31)
600 i = -1;
601 }
602 return i;
603}
604
605static inline void fadump_set_regval(struct pt_regs *regs, u64 reg_id,
606 u64 reg_val)
607{
608 int i;
609
610 i = fadump_gpr_index(reg_id);
611 if (i >= 0)
612 regs->gpr[i] = (unsigned long)reg_val;
613 else if (reg_id == REG_ID("NIA"))
614 regs->nip = (unsigned long)reg_val;
615 else if (reg_id == REG_ID("MSR"))
616 regs->msr = (unsigned long)reg_val;
617 else if (reg_id == REG_ID("CTR"))
618 regs->ctr = (unsigned long)reg_val;
619 else if (reg_id == REG_ID("LR"))
620 regs->link = (unsigned long)reg_val;
621 else if (reg_id == REG_ID("XER"))
622 regs->xer = (unsigned long)reg_val;
623 else if (reg_id == REG_ID("CR"))
624 regs->ccr = (unsigned long)reg_val;
625 else if (reg_id == REG_ID("DAR"))
626 regs->dar = (unsigned long)reg_val;
627 else if (reg_id == REG_ID("DSISR"))
628 regs->dsisr = (unsigned long)reg_val;
629}
630
631static struct fadump_reg_entry*
632fadump_read_registers(struct fadump_reg_entry *reg_entry, struct pt_regs *regs)
633{
634 memset(regs, 0, sizeof(struct pt_regs));
635
636 while (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUEND")) {
637 fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
638 be64_to_cpu(reg_entry->reg_value));
639 reg_entry++;
640 }
641 reg_entry++;
642 return reg_entry;
643}
644
645static u32 *fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs)
646{
647 struct elf_prstatus prstatus;
648
649 memset(&prstatus, 0, sizeof(prstatus));
650
651
652
653
654 elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
655 buf = append_elf_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
656 &prstatus, sizeof(prstatus));
657 return buf;
658}
659
660static void fadump_update_elfcore_header(char *bufp)
661{
662 struct elfhdr *elf;
663 struct elf_phdr *phdr;
664
665 elf = (struct elfhdr *)bufp;
666 bufp += sizeof(struct elfhdr);
667
668
669 phdr = (struct elf_phdr *)bufp;
670
671 if (phdr->p_type == PT_NOTE) {
672 phdr->p_paddr = fw_dump.cpu_notes_buf;
673 phdr->p_offset = phdr->p_paddr;
674 phdr->p_filesz = fw_dump.cpu_notes_buf_size;
675 phdr->p_memsz = fw_dump.cpu_notes_buf_size;
676 }
677 return;
678}
679
680static void *fadump_cpu_notes_buf_alloc(unsigned long size)
681{
682 void *vaddr;
683 struct page *page;
684 unsigned long order, count, i;
685
686 order = get_order(size);
687 vaddr = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
688 if (!vaddr)
689 return NULL;
690
691 count = 1 << order;
692 page = virt_to_page(vaddr);
693 for (i = 0; i < count; i++)
694 SetPageReserved(page + i);
695 return vaddr;
696}
697
698static void fadump_cpu_notes_buf_free(unsigned long vaddr, unsigned long size)
699{
700 struct page *page;
701 unsigned long order, count, i;
702
703 order = get_order(size);
704 count = 1 << order;
705 page = virt_to_page(vaddr);
706 for (i = 0; i < count; i++)
707 ClearPageReserved(page + i);
708 __free_pages(page, order);
709}
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm)
726{
727 struct fadump_reg_save_area_header *reg_header;
728 struct fadump_reg_entry *reg_entry;
729 struct fadump_crash_info_header *fdh = NULL;
730 void *vaddr;
731 unsigned long addr;
732 u32 num_cpus, *note_buf;
733 struct pt_regs regs;
734 int i, rc = 0, cpu = 0;
735
736 if (!fdm->cpu_state_data.bytes_dumped)
737 return -EINVAL;
738
739 addr = be64_to_cpu(fdm->cpu_state_data.destination_address);
740 vaddr = __va(addr);
741
742 reg_header = vaddr;
743 if (be64_to_cpu(reg_header->magic_number) != REGSAVE_AREA_MAGIC) {
744 printk(KERN_ERR "Unable to read register save area.\n");
745 return -ENOENT;
746 }
747 pr_debug("--------CPU State Data------------\n");
748 pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
749 pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
750
751 vaddr += be32_to_cpu(reg_header->num_cpu_offset);
752 num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
753 pr_debug("NumCpus : %u\n", num_cpus);
754 vaddr += sizeof(u32);
755 reg_entry = (struct fadump_reg_entry *)vaddr;
756
757
758 fw_dump.cpu_notes_buf_size = num_cpus * sizeof(note_buf_t);
759 fw_dump.cpu_notes_buf_size = PAGE_ALIGN(fw_dump.cpu_notes_buf_size);
760 note_buf = fadump_cpu_notes_buf_alloc(fw_dump.cpu_notes_buf_size);
761 if (!note_buf) {
762 printk(KERN_ERR "Failed to allocate 0x%lx bytes for "
763 "cpu notes buffer\n", fw_dump.cpu_notes_buf_size);
764 return -ENOMEM;
765 }
766 fw_dump.cpu_notes_buf = __pa(note_buf);
767
768 pr_debug("Allocated buffer for cpu notes of size %ld at %p\n",
769 (num_cpus * sizeof(note_buf_t)), note_buf);
770
771 if (fw_dump.fadumphdr_addr)
772 fdh = __va(fw_dump.fadumphdr_addr);
773
774 for (i = 0; i < num_cpus; i++) {
775 if (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUSTRT")) {
776 printk(KERN_ERR "Unable to read CPU state data\n");
777 rc = -ENOENT;
778 goto error_out;
779 }
780
781 cpu = be64_to_cpu(reg_entry->reg_value) & FADUMP_CPU_ID_MASK;
782 if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_online_mask)) {
783 SKIP_TO_NEXT_CPU(reg_entry);
784 continue;
785 }
786 pr_debug("Reading register data for cpu %d...\n", cpu);
787 if (fdh && fdh->crashing_cpu == cpu) {
788 regs = fdh->regs;
789 note_buf = fadump_regs_to_elf_notes(note_buf, ®s);
790 SKIP_TO_NEXT_CPU(reg_entry);
791 } else {
792 reg_entry++;
793 reg_entry = fadump_read_registers(reg_entry, ®s);
794 note_buf = fadump_regs_to_elf_notes(note_buf, ®s);
795 }
796 }
797 final_note(note_buf);
798
799 if (fdh) {
800 pr_debug("Updating elfcore header (%llx) with cpu notes\n",
801 fdh->elfcorehdr_addr);
802 fadump_update_elfcore_header((char *)__va(fdh->elfcorehdr_addr));
803 }
804 return 0;
805
806error_out:
807 fadump_cpu_notes_buf_free((unsigned long)__va(fw_dump.cpu_notes_buf),
808 fw_dump.cpu_notes_buf_size);
809 fw_dump.cpu_notes_buf = 0;
810 fw_dump.cpu_notes_buf_size = 0;
811 return rc;
812
813}
814
815
816
817
818
819static int __init process_fadump(const struct fadump_mem_struct *fdm_active)
820{
821 struct fadump_crash_info_header *fdh;
822 int rc = 0;
823
824 if (!fdm_active || !fw_dump.fadumphdr_addr)
825 return -EINVAL;
826
827
828 if ((be16_to_cpu(fdm_active->header.dump_status_flag) == FADUMP_ERROR_FLAG) ||
829 (fdm_active->cpu_state_data.error_flags != 0) ||
830 (fdm_active->rmr_region.error_flags != 0)) {
831 printk(KERN_ERR "Dump taken by platform is not valid\n");
832 return -EINVAL;
833 }
834 if ((fdm_active->rmr_region.bytes_dumped !=
835 fdm_active->rmr_region.source_len) ||
836 !fdm_active->cpu_state_data.bytes_dumped) {
837 printk(KERN_ERR "Dump taken by platform is incomplete\n");
838 return -EINVAL;
839 }
840
841
842 fdh = __va(fw_dump.fadumphdr_addr);
843 if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
844 printk(KERN_ERR "Crash info header is not valid.\n");
845 return -EINVAL;
846 }
847
848 rc = fadump_build_cpu_notes(fdm_active);
849 if (rc)
850 return rc;
851
852
853
854
855
856
857 elfcorehdr_addr = fdh->elfcorehdr_addr;
858
859 return 0;
860}
861
862static void free_crash_memory_ranges(void)
863{
864 kfree(crash_memory_ranges);
865 crash_memory_ranges = NULL;
866 crash_memory_ranges_size = 0;
867 max_crash_mem_ranges = 0;
868}
869
870
871
872
873
874static int allocate_crash_memory_ranges(void)
875{
876 struct fad_crash_memory_ranges *new_array;
877 u64 new_size;
878
879 new_size = crash_memory_ranges_size + PAGE_SIZE;
880 pr_debug("Allocating %llu bytes of memory for crash memory ranges\n",
881 new_size);
882
883 new_array = krealloc(crash_memory_ranges, new_size, GFP_KERNEL);
884 if (new_array == NULL) {
885 pr_err("Insufficient memory for setting up crash memory ranges\n");
886 free_crash_memory_ranges();
887 return -ENOMEM;
888 }
889
890 crash_memory_ranges = new_array;
891 crash_memory_ranges_size = new_size;
892 max_crash_mem_ranges = (new_size /
893 sizeof(struct fad_crash_memory_ranges));
894 return 0;
895}
896
897static inline int fadump_add_crash_memory(unsigned long long base,
898 unsigned long long end)
899{
900 u64 start, size;
901 bool is_adjacent = false;
902
903 if (base == end)
904 return 0;
905
906
907
908
909
910 if (crash_mem_ranges) {
911 start = crash_memory_ranges[crash_mem_ranges - 1].base;
912 size = crash_memory_ranges[crash_mem_ranges - 1].size;
913
914 if ((start + size) == base)
915 is_adjacent = true;
916 }
917 if (!is_adjacent) {
918
919 if (crash_mem_ranges == max_crash_mem_ranges) {
920 int ret;
921
922 ret = allocate_crash_memory_ranges();
923 if (ret)
924 return ret;
925 }
926
927 start = base;
928 crash_memory_ranges[crash_mem_ranges].base = start;
929 crash_mem_ranges++;
930 }
931
932 crash_memory_ranges[crash_mem_ranges - 1].size = (end - start);
933 pr_debug("crash_memory_range[%d] [%#016llx-%#016llx], %#llx bytes\n",
934 (crash_mem_ranges - 1), start, end - 1, (end - start));
935 return 0;
936}
937
938static int fadump_exclude_reserved_area(unsigned long long start,
939 unsigned long long end)
940{
941 unsigned long long ra_start, ra_end;
942 int ret = 0;
943
944 ra_start = fw_dump.reserve_dump_area_start;
945 ra_end = ra_start + fw_dump.reserve_dump_area_size;
946
947 if ((ra_start < end) && (ra_end > start)) {
948 if ((start < ra_start) && (end > ra_end)) {
949 ret = fadump_add_crash_memory(start, ra_start);
950 if (ret)
951 return ret;
952
953 ret = fadump_add_crash_memory(ra_end, end);
954 } else if (start < ra_start) {
955 ret = fadump_add_crash_memory(start, ra_start);
956 } else if (ra_end < end) {
957 ret = fadump_add_crash_memory(ra_end, end);
958 }
959 } else
960 ret = fadump_add_crash_memory(start, end);
961
962 return ret;
963}
964
965static int fadump_init_elfcore_header(char *bufp)
966{
967 struct elfhdr *elf;
968
969 elf = (struct elfhdr *) bufp;
970 bufp += sizeof(struct elfhdr);
971 memcpy(elf->e_ident, ELFMAG, SELFMAG);
972 elf->e_ident[EI_CLASS] = ELF_CLASS;
973 elf->e_ident[EI_DATA] = ELF_DATA;
974 elf->e_ident[EI_VERSION] = EV_CURRENT;
975 elf->e_ident[EI_OSABI] = ELF_OSABI;
976 memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
977 elf->e_type = ET_CORE;
978 elf->e_machine = ELF_ARCH;
979 elf->e_version = EV_CURRENT;
980 elf->e_entry = 0;
981 elf->e_phoff = sizeof(struct elfhdr);
982 elf->e_shoff = 0;
983 elf->e_flags = ELF_CORE_EFLAGS;
984 elf->e_ehsize = sizeof(struct elfhdr);
985 elf->e_phentsize = sizeof(struct elf_phdr);
986 elf->e_phnum = 0;
987 elf->e_shentsize = 0;
988 elf->e_shnum = 0;
989 elf->e_shstrndx = 0;
990
991 return 0;
992}
993
994
995
996
997
998static int fadump_setup_crash_memory_ranges(void)
999{
1000 struct memblock_region *reg;
1001 unsigned long long start, end;
1002 int ret;
1003
1004 pr_debug("Setup crash memory ranges.\n");
1005 crash_mem_ranges = 0;
1006
1007
1008
1009
1010
1011
1012
1013
1014 ret = fadump_add_crash_memory(RMA_START, fw_dump.boot_memory_size);
1015 if (ret)
1016 return ret;
1017
1018 for_each_memblock(memory, reg) {
1019 start = (unsigned long long)reg->base;
1020 end = start + (unsigned long long)reg->size;
1021
1022
1023
1024
1025
1026
1027 BUILD_BUG_ON(RMA_START != 0);
1028 if (start < fw_dump.boot_memory_size) {
1029 if (end > fw_dump.boot_memory_size)
1030 start = fw_dump.boot_memory_size;
1031 else
1032 continue;
1033 }
1034
1035
1036 ret = fadump_exclude_reserved_area(start, end);
1037 if (ret)
1038 return ret;
1039 }
1040
1041 return 0;
1042}
1043
1044
1045
1046
1047
1048
1049static inline unsigned long fadump_relocate(unsigned long paddr)
1050{
1051 if (paddr > RMA_START && paddr < fw_dump.boot_memory_size)
1052 return be64_to_cpu(fdm.rmr_region.destination_address) + paddr;
1053 else
1054 return paddr;
1055}
1056
1057static int fadump_create_elfcore_headers(char *bufp)
1058{
1059 struct elfhdr *elf;
1060 struct elf_phdr *phdr;
1061 int i;
1062
1063 fadump_init_elfcore_header(bufp);
1064 elf = (struct elfhdr *)bufp;
1065 bufp += sizeof(struct elfhdr);
1066
1067
1068
1069
1070
1071
1072
1073
1074 phdr = (struct elf_phdr *)bufp;
1075 bufp += sizeof(struct elf_phdr);
1076 phdr->p_type = PT_NOTE;
1077 phdr->p_flags = 0;
1078 phdr->p_vaddr = 0;
1079 phdr->p_align = 0;
1080
1081 phdr->p_offset = 0;
1082 phdr->p_paddr = 0;
1083 phdr->p_filesz = 0;
1084 phdr->p_memsz = 0;
1085
1086 (elf->e_phnum)++;
1087
1088
1089 phdr = (struct elf_phdr *)bufp;
1090 bufp += sizeof(struct elf_phdr);
1091 phdr->p_type = PT_NOTE;
1092 phdr->p_flags = 0;
1093 phdr->p_vaddr = 0;
1094 phdr->p_align = 0;
1095
1096 phdr->p_paddr = fadump_relocate(paddr_vmcoreinfo_note());
1097 phdr->p_offset = phdr->p_paddr;
1098 phdr->p_memsz = vmcoreinfo_max_size;
1099 phdr->p_filesz = vmcoreinfo_max_size;
1100
1101
1102 (elf->e_phnum)++;
1103
1104
1105
1106 for (i = 0; i < crash_mem_ranges; i++) {
1107 unsigned long long mbase, msize;
1108 mbase = crash_memory_ranges[i].base;
1109 msize = crash_memory_ranges[i].size;
1110
1111 if (!msize)
1112 continue;
1113
1114 phdr = (struct elf_phdr *)bufp;
1115 bufp += sizeof(struct elf_phdr);
1116 phdr->p_type = PT_LOAD;
1117 phdr->p_flags = PF_R|PF_W|PF_X;
1118 phdr->p_offset = mbase;
1119
1120 if (mbase == RMA_START) {
1121
1122
1123
1124
1125
1126 phdr->p_offset = be64_to_cpu(fdm.rmr_region.destination_address);
1127 }
1128
1129 phdr->p_paddr = mbase;
1130 phdr->p_vaddr = (unsigned long)__va(mbase);
1131 phdr->p_filesz = msize;
1132 phdr->p_memsz = msize;
1133 phdr->p_align = 0;
1134
1135
1136 (elf->e_phnum)++;
1137 }
1138 return 0;
1139}
1140
1141static unsigned long init_fadump_header(unsigned long addr)
1142{
1143 struct fadump_crash_info_header *fdh;
1144
1145 if (!addr)
1146 return 0;
1147
1148 fw_dump.fadumphdr_addr = addr;
1149 fdh = __va(addr);
1150 addr += sizeof(struct fadump_crash_info_header);
1151
1152 memset(fdh, 0, sizeof(struct fadump_crash_info_header));
1153 fdh->magic_number = FADUMP_CRASH_INFO_MAGIC;
1154 fdh->elfcorehdr_addr = addr;
1155
1156 fdh->crashing_cpu = CPU_UNKNOWN;
1157
1158 return addr;
1159}
1160
1161static int register_fadump(void)
1162{
1163 unsigned long addr;
1164 void *vaddr;
1165 int ret;
1166
1167
1168
1169
1170
1171 if (!fw_dump.reserve_dump_area_size)
1172 return -ENODEV;
1173
1174 ret = fadump_setup_crash_memory_ranges();
1175 if (ret)
1176 return ret;
1177
1178 addr = be64_to_cpu(fdm.rmr_region.destination_address) + be64_to_cpu(fdm.rmr_region.source_len);
1179
1180 addr = init_fadump_header(addr);
1181 vaddr = __va(addr);
1182
1183 pr_debug("Creating ELF core headers at %#016lx\n", addr);
1184 fadump_create_elfcore_headers(vaddr);
1185
1186
1187 return register_fw_dump(&fdm);
1188}
1189
1190static int fadump_unregister_dump(struct fadump_mem_struct *fdm)
1191{
1192 int rc = 0;
1193 unsigned int wait_time;
1194
1195 pr_debug("Un-register firmware-assisted dump\n");
1196
1197
1198 do {
1199 rc = rtas_call(fw_dump.ibm_configure_kernel_dump, 3, 1, NULL,
1200 FADUMP_UNREGISTER, fdm,
1201 sizeof(struct fadump_mem_struct));
1202
1203 wait_time = rtas_busy_delay_time(rc);
1204 if (wait_time)
1205 mdelay(wait_time);
1206 } while (wait_time);
1207
1208 if (rc) {
1209 printk(KERN_ERR "Failed to un-register firmware-assisted dump."
1210 " unexpected error(%d).\n", rc);
1211 return rc;
1212 }
1213 fw_dump.dump_registered = 0;
1214 return 0;
1215}
1216
1217static int fadump_invalidate_dump(struct fadump_mem_struct *fdm)
1218{
1219 int rc = 0;
1220 unsigned int wait_time;
1221
1222 pr_debug("Invalidating firmware-assisted dump registration\n");
1223
1224
1225 do {
1226 rc = rtas_call(fw_dump.ibm_configure_kernel_dump, 3, 1, NULL,
1227 FADUMP_INVALIDATE, fdm,
1228 sizeof(struct fadump_mem_struct));
1229
1230 wait_time = rtas_busy_delay_time(rc);
1231 if (wait_time)
1232 mdelay(wait_time);
1233 } while (wait_time);
1234
1235 if (rc) {
1236 printk(KERN_ERR "Failed to invalidate firmware-assisted dump "
1237 "rgistration. unexpected error(%d).\n", rc);
1238 return rc;
1239 }
1240 fw_dump.dump_active = 0;
1241 fdm_active = NULL;
1242 return 0;
1243}
1244
1245void fadump_cleanup(void)
1246{
1247
1248 if (fw_dump.dump_active) {
1249 init_fadump_mem_struct(&fdm,
1250 be64_to_cpu(fdm_active->cpu_state_data.destination_address));
1251 fadump_invalidate_dump(&fdm);
1252 } else if (fw_dump.dump_registered) {
1253
1254 fadump_unregister_dump(&fdm);
1255 free_crash_memory_ranges();
1256 }
1257}
1258
1259
1260
1261
1262
1263static void fadump_release_memory(unsigned long begin, unsigned long end)
1264{
1265 unsigned long addr;
1266 unsigned long ra_start, ra_end;
1267
1268 ra_start = fw_dump.reserve_dump_area_start;
1269 ra_end = ra_start + fw_dump.reserve_dump_area_size;
1270
1271 for (addr = begin; addr < end; addr += PAGE_SIZE) {
1272
1273
1274
1275
1276 if (addr <= ra_end && ((addr + PAGE_SIZE) > ra_start))
1277 continue;
1278
1279 free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT));
1280 }
1281}
1282
1283static void fadump_invalidate_release_mem(void)
1284{
1285 unsigned long reserved_area_start, reserved_area_end;
1286 unsigned long destination_address;
1287
1288 mutex_lock(&fadump_mutex);
1289 if (!fw_dump.dump_active) {
1290 mutex_unlock(&fadump_mutex);
1291 return;
1292 }
1293
1294 destination_address = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
1295 fadump_cleanup();
1296 mutex_unlock(&fadump_mutex);
1297
1298
1299
1300
1301
1302 reserved_area_start = fw_dump.reserve_dump_area_start;
1303 reserved_area_end = reserved_area_start +
1304 fw_dump.reserve_dump_area_size;
1305
1306
1307
1308
1309 fw_dump.reserve_dump_area_start = destination_address;
1310 fw_dump.reserve_dump_area_size = get_fadump_area_size();
1311
1312 fadump_release_memory(reserved_area_start, reserved_area_end);
1313 if (fw_dump.cpu_notes_buf) {
1314 fadump_cpu_notes_buf_free(
1315 (unsigned long)__va(fw_dump.cpu_notes_buf),
1316 fw_dump.cpu_notes_buf_size);
1317 fw_dump.cpu_notes_buf = 0;
1318 fw_dump.cpu_notes_buf_size = 0;
1319 }
1320
1321 init_fadump_mem_struct(&fdm, fw_dump.reserve_dump_area_start);
1322}
1323
1324static ssize_t fadump_release_memory_store(struct kobject *kobj,
1325 struct kobj_attribute *attr,
1326 const char *buf, size_t count)
1327{
1328 if (!fw_dump.dump_active)
1329 return -EPERM;
1330
1331 if (buf[0] == '1') {
1332
1333
1334
1335
1336 vmcore_cleanup();
1337 fadump_invalidate_release_mem();
1338
1339 } else
1340 return -EINVAL;
1341 return count;
1342}
1343
1344static ssize_t fadump_enabled_show(struct kobject *kobj,
1345 struct kobj_attribute *attr,
1346 char *buf)
1347{
1348 return sprintf(buf, "%d\n", fw_dump.fadump_enabled);
1349}
1350
1351static ssize_t fadump_register_show(struct kobject *kobj,
1352 struct kobj_attribute *attr,
1353 char *buf)
1354{
1355 return sprintf(buf, "%d\n", fw_dump.dump_registered);
1356}
1357
1358static ssize_t fadump_register_store(struct kobject *kobj,
1359 struct kobj_attribute *attr,
1360 const char *buf, size_t count)
1361{
1362 int ret = 0;
1363
1364 if (!fw_dump.fadump_enabled || fdm_active)
1365 return -EPERM;
1366
1367 mutex_lock(&fadump_mutex);
1368
1369 switch (buf[0]) {
1370 case '0':
1371 if (fw_dump.dump_registered == 0) {
1372 goto unlock_out;
1373 }
1374
1375 fadump_unregister_dump(&fdm);
1376 break;
1377 case '1':
1378 if (fw_dump.dump_registered == 1) {
1379 ret = -EEXIST;
1380 goto unlock_out;
1381 }
1382
1383 ret = register_fadump();
1384 break;
1385 default:
1386 ret = -EINVAL;
1387 break;
1388 }
1389
1390unlock_out:
1391 mutex_unlock(&fadump_mutex);
1392 return ret < 0 ? ret : count;
1393}
1394
1395static int fadump_region_show(struct seq_file *m, void *private)
1396{
1397 const struct fadump_mem_struct *fdm_ptr;
1398
1399 if (!fw_dump.fadump_enabled)
1400 return 0;
1401
1402 mutex_lock(&fadump_mutex);
1403 if (fdm_active)
1404 fdm_ptr = fdm_active;
1405 else {
1406 mutex_unlock(&fadump_mutex);
1407 fdm_ptr = &fdm;
1408 }
1409
1410 seq_printf(m,
1411 "CPU : [%#016llx-%#016llx] %#llx bytes, "
1412 "Dumped: %#llx\n",
1413 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address),
1414 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) +
1415 be64_to_cpu(fdm_ptr->cpu_state_data.source_len) - 1,
1416 be64_to_cpu(fdm_ptr->cpu_state_data.source_len),
1417 be64_to_cpu(fdm_ptr->cpu_state_data.bytes_dumped));
1418 seq_printf(m,
1419 "HPTE: [%#016llx-%#016llx] %#llx bytes, "
1420 "Dumped: %#llx\n",
1421 be64_to_cpu(fdm_ptr->hpte_region.destination_address),
1422 be64_to_cpu(fdm_ptr->hpte_region.destination_address) +
1423 be64_to_cpu(fdm_ptr->hpte_region.source_len) - 1,
1424 be64_to_cpu(fdm_ptr->hpte_region.source_len),
1425 be64_to_cpu(fdm_ptr->hpte_region.bytes_dumped));
1426 seq_printf(m,
1427 "DUMP: [%#016llx-%#016llx] %#llx bytes, "
1428 "Dumped: %#llx\n",
1429 be64_to_cpu(fdm_ptr->rmr_region.destination_address),
1430 be64_to_cpu(fdm_ptr->rmr_region.destination_address) +
1431 be64_to_cpu(fdm_ptr->rmr_region.source_len) - 1,
1432 be64_to_cpu(fdm_ptr->rmr_region.source_len),
1433 be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
1434
1435 if (!fdm_active ||
1436 (fw_dump.reserve_dump_area_start ==
1437 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address)))
1438 goto out;
1439
1440
1441 seq_printf(m,
1442 " : [%#016llx-%#016llx] %#llx bytes, "
1443 "Dumped: %#llx\n",
1444 (unsigned long long)fw_dump.reserve_dump_area_start,
1445 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) - 1,
1446 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
1447 fw_dump.reserve_dump_area_start,
1448 be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
1449 fw_dump.reserve_dump_area_start);
1450out:
1451 if (fdm_active)
1452 mutex_unlock(&fadump_mutex);
1453 return 0;
1454}
1455
1456static struct kobj_attribute fadump_release_attr = __ATTR(fadump_release_mem,
1457 0200, NULL,
1458 fadump_release_memory_store);
1459static struct kobj_attribute fadump_attr = __ATTR(fadump_enabled,
1460 0444, fadump_enabled_show,
1461 NULL);
1462static struct kobj_attribute fadump_register_attr = __ATTR(fadump_registered,
1463 0644, fadump_register_show,
1464 fadump_register_store);
1465
1466static int fadump_region_open(struct inode *inode, struct file *file)
1467{
1468 return single_open(file, fadump_region_show, inode->i_private);
1469}
1470
1471static const struct file_operations fadump_region_fops = {
1472 .open = fadump_region_open,
1473 .read = seq_read,
1474 .llseek = seq_lseek,
1475 .release = single_release,
1476};
1477
1478static void fadump_init_files(void)
1479{
1480 struct dentry *debugfs_file;
1481 int rc = 0;
1482
1483 rc = sysfs_create_file(kernel_kobj, &fadump_attr.attr);
1484 if (rc)
1485 printk(KERN_ERR "fadump: unable to create sysfs file"
1486 " fadump_enabled (%d)\n", rc);
1487
1488 rc = sysfs_create_file(kernel_kobj, &fadump_register_attr.attr);
1489 if (rc)
1490 printk(KERN_ERR "fadump: unable to create sysfs file"
1491 " fadump_registered (%d)\n", rc);
1492
1493 debugfs_file = debugfs_create_file("fadump_region", 0444,
1494 powerpc_debugfs_root, NULL,
1495 &fadump_region_fops);
1496 if (!debugfs_file)
1497 printk(KERN_ERR "fadump: unable to create debugfs file"
1498 " fadump_region\n");
1499
1500 if (fw_dump.dump_active) {
1501 rc = sysfs_create_file(kernel_kobj, &fadump_release_attr.attr);
1502 if (rc)
1503 printk(KERN_ERR "fadump: unable to create sysfs file"
1504 " fadump_release_mem (%d)\n", rc);
1505 }
1506 return;
1507}
1508
1509
1510
1511
1512int __init setup_fadump(void)
1513{
1514 if (!fw_dump.fadump_enabled)
1515 return 0;
1516
1517 if (!fw_dump.fadump_supported) {
1518 printk(KERN_ERR "Firmware-assisted dump is not supported on"
1519 " this hardware\n");
1520 return 0;
1521 }
1522
1523 fadump_show_config();
1524
1525
1526
1527
1528 if (fw_dump.dump_active) {
1529
1530
1531
1532
1533 if (process_fadump(fdm_active) < 0)
1534 fadump_invalidate_release_mem();
1535 }
1536
1537 else if (fw_dump.reserve_dump_area_size)
1538 init_fadump_mem_struct(&fdm, fw_dump.reserve_dump_area_start);
1539 fadump_init_files();
1540
1541 return 1;
1542}
1543subsys_initcall(setup_fadump);
1544