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