1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Firmware-Assisted Dump support on POWER platform (OPAL). 4 * 5 * Copyright 2019, Hari Bathini, IBM Corporation. 6 */ 7 8 #define pr_fmt(fmt) "opal fadump: " fmt 9 10 #include <linux/string.h> 11 #include <linux/seq_file.h> 12 #include <linux/of.h> 13 #include <linux/of_fdt.h> 14 #include <linux/libfdt.h> 15 #include <linux/mm.h> 16 #include <linux/crash_dump.h> 17 18 #include <asm/page.h> 19 #include <asm/opal.h> 20 #include <asm/fadump-internal.h> 21 22 #include "opal-fadump.h" 23 24 25 #ifdef CONFIG_PRESERVE_FA_DUMP 26 /* 27 * When dump is active but PRESERVE_FA_DUMP is enabled on the kernel, 28 * ensure crash data is preserved in hope that the subsequent memory 29 * preserving kernel boot is going to process this crash data. 30 */ 31 void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) 32 { 33 const struct opal_fadump_mem_struct *opal_fdm_active; 34 const __be32 *prop; 35 unsigned long dn; 36 u64 addr = 0; 37 s64 ret; 38 39 dn = of_get_flat_dt_subnode_by_name(node, "dump"); 40 if (dn == -FDT_ERR_NOTFOUND) 41 return; 42 43 /* 44 * Check if dump has been initiated on last reboot. 45 */ 46 prop = of_get_flat_dt_prop(dn, "mpipl-boot", NULL); 47 if (!prop) 48 return; 49 50 ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_KERNEL, &addr); 51 if ((ret != OPAL_SUCCESS) || !addr) { 52 pr_debug("Could not get Kernel metadata (%lld)\n", ret); 53 return; 54 } 55 56 /* 57 * Preserve memory only if kernel memory regions are registered 58 * with f/w for MPIPL. 59 */ 60 addr = be64_to_cpu(addr); 61 pr_debug("Kernel metadata addr: %llx\n", addr); 62 opal_fdm_active = (void *)addr; 63 if (opal_fdm_active->registered_regions == 0) 64 return; 65 66 ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_BOOT_MEM, &addr); 67 if ((ret != OPAL_SUCCESS) || !addr) { 68 pr_err("Failed to get boot memory tag (%lld)\n", ret); 69 return; 70 } 71 72 /* 73 * Memory below this address can be used for booting a 74 * capture kernel or petitboot kernel. Preserve everything 75 * above this address for processing crashdump. 76 */ 77 fadump_conf->boot_mem_top = be64_to_cpu(addr); 78 pr_debug("Preserve everything above %llx\n", fadump_conf->boot_mem_top); 79 80 pr_info("Firmware-assisted dump is active.\n"); 81 fadump_conf->dump_active = 1; 82 } 83 84 #else /* CONFIG_PRESERVE_FA_DUMP */ 85 static const struct opal_fadump_mem_struct *opal_fdm_active; 86 static const struct opal_mpipl_fadump *opal_cpu_metadata; 87 static struct opal_fadump_mem_struct *opal_fdm; 88 89 #ifdef CONFIG_OPAL_CORE 90 extern bool kernel_initiated; 91 #endif 92 93 static int opal_fadump_unregister(struct fw_dump *fadump_conf); 94 95 static void opal_fadump_update_config(struct fw_dump *fadump_conf, 96 const struct opal_fadump_mem_struct *fdm) 97 { 98 pr_debug("Boot memory regions count: %d\n", fdm->region_cnt); 99 100 /* 101 * The destination address of the first boot memory region is the 102 * destination address of boot memory regions. 103 */ 104 fadump_conf->boot_mem_dest_addr = fdm->rgn[0].dest; 105 pr_debug("Destination address of boot memory regions: %#016llx\n", 106 fadump_conf->boot_mem_dest_addr); 107 108 fadump_conf->fadumphdr_addr = fdm->fadumphdr_addr; 109 } 110 111 /* 112 * This function is called in the capture kernel to get configuration details 113 * from metadata setup by the first kernel. 114 */ 115 static void __init opal_fadump_get_config(struct fw_dump *fadump_conf, 116 const struct opal_fadump_mem_struct *fdm) 117 { 118 unsigned long base, size, last_end, hole_size; 119 int i; 120 121 if (!fadump_conf->dump_active) 122 return; 123 124 last_end = 0; 125 hole_size = 0; 126 fadump_conf->boot_memory_size = 0; 127 128 pr_debug("Boot memory regions:\n"); 129 for (i = 0; i < fdm->region_cnt; i++) { 130 base = fdm->rgn[i].src; 131 size = fdm->rgn[i].size; 132 pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size); 133 134 fadump_conf->boot_mem_addr[i] = base; 135 fadump_conf->boot_mem_sz[i] = size; 136 fadump_conf->boot_memory_size += size; 137 hole_size += (base - last_end); 138 139 last_end = base + size; 140 } 141 142 /* 143 * Start address of reserve dump area (permanent reservation) for 144 * re-registering FADump after dump capture. 145 */ 146 fadump_conf->reserve_dump_area_start = fdm->rgn[0].dest; 147 148 /* 149 * Rarely, but it can so happen that system crashes before all 150 * boot memory regions are registered for MPIPL. In such 151 * cases, warn that the vmcore may not be accurate and proceed 152 * anyway as that is the best bet considering free pages, cache 153 * pages, user pages, etc are usually filtered out. 154 * 155 * Hope the memory that could not be preserved only has pages 156 * that are usually filtered out while saving the vmcore. 157 */ 158 if (fdm->region_cnt > fdm->registered_regions) { 159 pr_warn("Not all memory regions were saved!!!\n"); 160 pr_warn(" Unsaved memory regions:\n"); 161 i = fdm->registered_regions; 162 while (i < fdm->region_cnt) { 163 pr_warn("\t[%03d] base: 0x%llx, size: 0x%llx\n", 164 i, fdm->rgn[i].src, fdm->rgn[i].size); 165 i++; 166 } 167 168 pr_warn("If the unsaved regions only contain pages that are filtered out (eg. free/user pages), the vmcore should still be usable.\n"); 169 pr_warn("WARNING: If the unsaved regions contain kernel pages, the vmcore will be corrupted.\n"); 170 } 171 172 fadump_conf->boot_mem_top = (fadump_conf->boot_memory_size + hole_size); 173 fadump_conf->boot_mem_regs_cnt = fdm->region_cnt; 174 opal_fadump_update_config(fadump_conf, fdm); 175 } 176 177 /* Initialize kernel metadata */ 178 static void opal_fadump_init_metadata(struct opal_fadump_mem_struct *fdm) 179 { 180 fdm->version = OPAL_FADUMP_VERSION; 181 fdm->region_cnt = 0; 182 fdm->registered_regions = 0; 183 fdm->fadumphdr_addr = 0; 184 } 185 186 static u64 opal_fadump_init_mem_struct(struct fw_dump *fadump_conf) 187 { 188 u64 addr = fadump_conf->reserve_dump_area_start; 189 int i; 190 191 opal_fdm = __va(fadump_conf->kernel_metadata); 192 opal_fadump_init_metadata(opal_fdm); 193 194 /* Boot memory regions */ 195 for (i = 0; i < fadump_conf->boot_mem_regs_cnt; i++) { 196 opal_fdm->rgn[i].src = fadump_conf->boot_mem_addr[i]; 197 opal_fdm->rgn[i].dest = addr; 198 opal_fdm->rgn[i].size = fadump_conf->boot_mem_sz[i]; 199 200 opal_fdm->region_cnt++; 201 addr += fadump_conf->boot_mem_sz[i]; 202 } 203 204 /* 205 * Kernel metadata is passed to f/w and retrieved in capture kerenl. 206 * So, use it to save fadump header address instead of calculating it. 207 */ 208 opal_fdm->fadumphdr_addr = (opal_fdm->rgn[0].dest + 209 fadump_conf->boot_memory_size); 210 211 opal_fadump_update_config(fadump_conf, opal_fdm); 212 213 return addr; 214 } 215 216 static u64 opal_fadump_get_metadata_size(void) 217 { 218 return PAGE_ALIGN(sizeof(struct opal_fadump_mem_struct)); 219 } 220 221 static int opal_fadump_setup_metadata(struct fw_dump *fadump_conf) 222 { 223 int err = 0; 224 s64 ret; 225 226 /* 227 * Use the last page(s) in FADump memory reservation for 228 * kernel metadata. 229 */ 230 fadump_conf->kernel_metadata = (fadump_conf->reserve_dump_area_start + 231 fadump_conf->reserve_dump_area_size - 232 opal_fadump_get_metadata_size()); 233 pr_info("Kernel metadata addr: %llx\n", fadump_conf->kernel_metadata); 234 235 /* Initialize kernel metadata before registering the address with f/w */ 236 opal_fdm = __va(fadump_conf->kernel_metadata); 237 opal_fadump_init_metadata(opal_fdm); 238 239 /* 240 * Register metadata address with f/w. Can be retrieved in 241 * the capture kernel. 242 */ 243 ret = opal_mpipl_register_tag(OPAL_MPIPL_TAG_KERNEL, 244 fadump_conf->kernel_metadata); 245 if (ret != OPAL_SUCCESS) { 246 pr_err("Failed to set kernel metadata tag!\n"); 247 err = -EPERM; 248 } 249 250 /* 251 * Register boot memory top address with f/w. Should be retrieved 252 * by a kernel that intends to preserve crash'ed kernel's memory. 253 */ 254 ret = opal_mpipl_register_tag(OPAL_MPIPL_TAG_BOOT_MEM, 255 fadump_conf->boot_mem_top); 256 if (ret != OPAL_SUCCESS) { 257 pr_err("Failed to set boot memory tag!\n"); 258 err = -EPERM; 259 } 260 261 return err; 262 } 263 264 static u64 opal_fadump_get_bootmem_min(void) 265 { 266 return OPAL_FADUMP_MIN_BOOT_MEM; 267 } 268 269 static int opal_fadump_register(struct fw_dump *fadump_conf) 270 { 271 s64 rc = OPAL_PARAMETER; 272 int i, err = -EIO; 273 274 for (i = 0; i < opal_fdm->region_cnt; i++) { 275 rc = opal_mpipl_update(OPAL_MPIPL_ADD_RANGE, 276 opal_fdm->rgn[i].src, 277 opal_fdm->rgn[i].dest, 278 opal_fdm->rgn[i].size); 279 if (rc != OPAL_SUCCESS) 280 break; 281 282 opal_fdm->registered_regions++; 283 } 284 285 switch (rc) { 286 case OPAL_SUCCESS: 287 pr_info("Registration is successful!\n"); 288 fadump_conf->dump_registered = 1; 289 err = 0; 290 break; 291 case OPAL_RESOURCE: 292 /* If MAX regions limit in f/w is hit, warn and proceed. */ 293 pr_warn("%d regions could not be registered for MPIPL as MAX limit is reached!\n", 294 (opal_fdm->region_cnt - opal_fdm->registered_regions)); 295 fadump_conf->dump_registered = 1; 296 err = 0; 297 break; 298 case OPAL_PARAMETER: 299 pr_err("Failed to register. Parameter Error(%lld).\n", rc); 300 break; 301 case OPAL_HARDWARE: 302 pr_err("Support not available.\n"); 303 fadump_conf->fadump_supported = 0; 304 fadump_conf->fadump_enabled = 0; 305 break; 306 default: 307 pr_err("Failed to register. Unknown Error(%lld).\n", rc); 308 break; 309 } 310 311 /* 312 * If some regions were registered before OPAL_MPIPL_ADD_RANGE 313 * OPAL call failed, unregister all regions. 314 */ 315 if ((err < 0) && (opal_fdm->registered_regions > 0)) 316 opal_fadump_unregister(fadump_conf); 317 318 return err; 319 } 320 321 static int opal_fadump_unregister(struct fw_dump *fadump_conf) 322 { 323 s64 rc; 324 325 rc = opal_mpipl_update(OPAL_MPIPL_REMOVE_ALL, 0, 0, 0); 326 if (rc) { 327 pr_err("Failed to un-register - unexpected Error(%lld).\n", rc); 328 return -EIO; 329 } 330 331 opal_fdm->registered_regions = 0; 332 fadump_conf->dump_registered = 0; 333 return 0; 334 } 335 336 static int opal_fadump_invalidate(struct fw_dump *fadump_conf) 337 { 338 s64 rc; 339 340 rc = opal_mpipl_update(OPAL_MPIPL_FREE_PRESERVED_MEMORY, 0, 0, 0); 341 if (rc) { 342 pr_err("Failed to invalidate - unexpected Error(%lld).\n", rc); 343 return -EIO; 344 } 345 346 fadump_conf->dump_active = 0; 347 opal_fdm_active = NULL; 348 return 0; 349 } 350 351 static void opal_fadump_cleanup(struct fw_dump *fadump_conf) 352 { 353 s64 ret; 354 355 ret = opal_mpipl_register_tag(OPAL_MPIPL_TAG_KERNEL, 0); 356 if (ret != OPAL_SUCCESS) 357 pr_warn("Could not reset (%llu) kernel metadata tag!\n", ret); 358 } 359 360 /* 361 * Verify if CPU state data is available. If available, do a bit of sanity 362 * checking before processing this data. 363 */ 364 static bool __init is_opal_fadump_cpu_data_valid(struct fw_dump *fadump_conf) 365 { 366 if (!opal_cpu_metadata) 367 return false; 368 369 fadump_conf->cpu_state_data_version = 370 be32_to_cpu(opal_cpu_metadata->cpu_data_version); 371 fadump_conf->cpu_state_entry_size = 372 be32_to_cpu(opal_cpu_metadata->cpu_data_size); 373 fadump_conf->cpu_state_dest_vaddr = 374 (u64)__va(be64_to_cpu(opal_cpu_metadata->region[0].dest)); 375 fadump_conf->cpu_state_data_size = 376 be64_to_cpu(opal_cpu_metadata->region[0].size); 377 378 if (fadump_conf->cpu_state_data_version != HDAT_FADUMP_CPU_DATA_VER) { 379 pr_warn("Supported CPU state data version: %u, found: %d!\n", 380 HDAT_FADUMP_CPU_DATA_VER, 381 fadump_conf->cpu_state_data_version); 382 pr_warn("WARNING: F/W using newer CPU state data format!!\n"); 383 } 384 385 if ((fadump_conf->cpu_state_dest_vaddr == 0) || 386 (fadump_conf->cpu_state_entry_size == 0) || 387 (fadump_conf->cpu_state_entry_size > 388 fadump_conf->cpu_state_data_size)) { 389 pr_err("CPU state data is invalid. Ignoring!\n"); 390 return false; 391 } 392 393 return true; 394 } 395 396 /* 397 * Convert CPU state data saved at the time of crash into ELF notes. 398 * 399 * While the crashing CPU's register data is saved by the kernel, CPU state 400 * data for all CPUs is saved by f/w. In CPU state data provided by f/w, 401 * each register entry is of 16 bytes, a numerical identifier along with 402 * a GPR/SPR flag in the first 8 bytes and the register value in the next 403 * 8 bytes. For more details refer to F/W documentation. If this data is 404 * missing or in unsupported format, append crashing CPU's register data 405 * saved by the kernel in the PT_NOTE, to have something to work with in 406 * the vmcore file. 407 */ 408 static int __init 409 opal_fadump_build_cpu_notes(struct fw_dump *fadump_conf, 410 struct fadump_crash_info_header *fdh) 411 { 412 u32 thread_pir, size_per_thread, regs_offset, regs_cnt, reg_esize; 413 struct hdat_fadump_thread_hdr *thdr; 414 bool is_cpu_data_valid = false; 415 u32 num_cpus = 1, *note_buf; 416 struct pt_regs regs; 417 char *bufp; 418 int rc, i; 419 420 if (is_opal_fadump_cpu_data_valid(fadump_conf)) { 421 size_per_thread = fadump_conf->cpu_state_entry_size; 422 num_cpus = (fadump_conf->cpu_state_data_size / size_per_thread); 423 bufp = __va(fadump_conf->cpu_state_dest_vaddr); 424 is_cpu_data_valid = true; 425 } 426 427 rc = fadump_setup_cpu_notes_buf(num_cpus); 428 if (rc != 0) 429 return rc; 430 431 note_buf = (u32 *)fadump_conf->cpu_notes_buf_vaddr; 432 if (!is_cpu_data_valid) 433 goto out; 434 435 /* 436 * Offset for register entries, entry size and registers count is 437 * duplicated in every thread header in keeping with HDAT format. 438 * Use these values from the first thread header. 439 */ 440 thdr = (struct hdat_fadump_thread_hdr *)bufp; 441 regs_offset = (offsetof(struct hdat_fadump_thread_hdr, offset) + 442 be32_to_cpu(thdr->offset)); 443 reg_esize = be32_to_cpu(thdr->esize); 444 regs_cnt = be32_to_cpu(thdr->ecnt); 445 446 pr_debug("--------CPU State Data------------\n"); 447 pr_debug("NumCpus : %u\n", num_cpus); 448 pr_debug("\tOffset: %u, Entry size: %u, Cnt: %u\n", 449 regs_offset, reg_esize, regs_cnt); 450 451 for (i = 0; i < num_cpus; i++, bufp += size_per_thread) { 452 thdr = (struct hdat_fadump_thread_hdr *)bufp; 453 454 thread_pir = be32_to_cpu(thdr->pir); 455 pr_debug("[%04d] PIR: 0x%x, core state: 0x%02x\n", 456 i, thread_pir, thdr->core_state); 457 458 /* 459 * If this is kernel initiated crash, crashing_cpu would be set 460 * appropriately and register data of the crashing CPU saved by 461 * crashing kernel. Add this saved register data of crashing CPU 462 * to elf notes and populate the pt_regs for the remaining CPUs 463 * from register state data provided by firmware. 464 */ 465 if (fdh->crashing_cpu == thread_pir) { 466 note_buf = fadump_regs_to_elf_notes(note_buf, 467 &fdh->regs); 468 pr_debug("Crashing CPU PIR: 0x%x - R1 : 0x%lx, NIP : 0x%lx\n", 469 fdh->crashing_cpu, fdh->regs.gpr[1], 470 fdh->regs.nip); 471 continue; 472 } 473 474 /* 475 * Register state data of MAX cores is provided by firmware, 476 * but some of this cores may not be active. So, while 477 * processing register state data, check core state and 478 * skip threads that belong to inactive cores. 479 */ 480 if (thdr->core_state == HDAT_FADUMP_CORE_INACTIVE) 481 continue; 482 483 opal_fadump_read_regs((bufp + regs_offset), regs_cnt, 484 reg_esize, true, ®s); 485 note_buf = fadump_regs_to_elf_notes(note_buf, ®s); 486 pr_debug("CPU PIR: 0x%x - R1 : 0x%lx, NIP : 0x%lx\n", 487 thread_pir, regs.gpr[1], regs.nip); 488 } 489 490 out: 491 /* 492 * CPU state data is invalid/unsupported. Try appending crashing CPU's 493 * register data, if it is saved by the kernel. 494 */ 495 if (fadump_conf->cpu_notes_buf_vaddr == (u64)note_buf) { 496 if (fdh->crashing_cpu == FADUMP_CPU_UNKNOWN) { 497 fadump_free_cpu_notes_buf(); 498 return -ENODEV; 499 } 500 501 pr_warn("WARNING: appending only crashing CPU's register data\n"); 502 note_buf = fadump_regs_to_elf_notes(note_buf, &(fdh->regs)); 503 } 504 505 final_note(note_buf); 506 507 pr_debug("Updating elfcore header (%llx) with cpu notes\n", 508 fdh->elfcorehdr_addr); 509 fadump_update_elfcore_header(__va(fdh->elfcorehdr_addr)); 510 return 0; 511 } 512 513 static int __init opal_fadump_process(struct fw_dump *fadump_conf) 514 { 515 struct fadump_crash_info_header *fdh; 516 int rc = -EINVAL; 517 518 if (!opal_fdm_active || !fadump_conf->fadumphdr_addr) 519 return rc; 520 521 /* Validate the fadump crash info header */ 522 fdh = __va(fadump_conf->fadumphdr_addr); 523 if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) { 524 pr_err("Crash info header is not valid.\n"); 525 return rc; 526 } 527 528 #ifdef CONFIG_OPAL_CORE 529 /* 530 * If this is a kernel initiated crash, crashing_cpu would be set 531 * appropriately and register data of the crashing CPU saved by 532 * crashing kernel. Add this saved register data of crashing CPU 533 * to elf notes and populate the pt_regs for the remaining CPUs 534 * from register state data provided by firmware. 535 */ 536 if (fdh->crashing_cpu != FADUMP_CPU_UNKNOWN) 537 kernel_initiated = true; 538 #endif 539 540 rc = opal_fadump_build_cpu_notes(fadump_conf, fdh); 541 if (rc) 542 return rc; 543 544 /* 545 * We are done validating dump info and elfcore header is now ready 546 * to be exported. set elfcorehdr_addr so that vmcore module will 547 * export the elfcore header through '/proc/vmcore'. 548 */ 549 elfcorehdr_addr = fdh->elfcorehdr_addr; 550 551 return rc; 552 } 553 554 static void opal_fadump_region_show(struct fw_dump *fadump_conf, 555 struct seq_file *m) 556 { 557 const struct opal_fadump_mem_struct *fdm_ptr; 558 u64 dumped_bytes = 0; 559 int i; 560 561 if (fadump_conf->dump_active) 562 fdm_ptr = opal_fdm_active; 563 else 564 fdm_ptr = opal_fdm; 565 566 for (i = 0; i < fdm_ptr->region_cnt; i++) { 567 /* 568 * Only regions that are registered for MPIPL 569 * would have dump data. 570 */ 571 if ((fadump_conf->dump_active) && 572 (i < fdm_ptr->registered_regions)) 573 dumped_bytes = fdm_ptr->rgn[i].size; 574 575 seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ", 576 fdm_ptr->rgn[i].src, fdm_ptr->rgn[i].dest); 577 seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n", 578 fdm_ptr->rgn[i].size, dumped_bytes); 579 } 580 581 /* Dump is active. Show reserved area start address. */ 582 if (fadump_conf->dump_active) { 583 seq_printf(m, "\nMemory above %#016lx is reserved for saving crash dump\n", 584 fadump_conf->reserve_dump_area_start); 585 } 586 } 587 588 static void opal_fadump_trigger(struct fadump_crash_info_header *fdh, 589 const char *msg) 590 { 591 int rc; 592 593 /* 594 * Unlike on pSeries platform, logical CPU number is not provided 595 * with architected register state data. So, store the crashing 596 * CPU's PIR instead to plug the appropriate register data for 597 * crashing CPU in the vmcore file. 598 */ 599 fdh->crashing_cpu = (u32)mfspr(SPRN_PIR); 600 601 rc = opal_cec_reboot2(OPAL_REBOOT_MPIPL, msg); 602 if (rc == OPAL_UNSUPPORTED) { 603 pr_emerg("Reboot type %d not supported.\n", 604 OPAL_REBOOT_MPIPL); 605 } else if (rc == OPAL_HARDWARE) 606 pr_emerg("No backend support for MPIPL!\n"); 607 } 608 609 static struct fadump_ops opal_fadump_ops = { 610 .fadump_init_mem_struct = opal_fadump_init_mem_struct, 611 .fadump_get_metadata_size = opal_fadump_get_metadata_size, 612 .fadump_setup_metadata = opal_fadump_setup_metadata, 613 .fadump_get_bootmem_min = opal_fadump_get_bootmem_min, 614 .fadump_register = opal_fadump_register, 615 .fadump_unregister = opal_fadump_unregister, 616 .fadump_invalidate = opal_fadump_invalidate, 617 .fadump_cleanup = opal_fadump_cleanup, 618 .fadump_process = opal_fadump_process, 619 .fadump_region_show = opal_fadump_region_show, 620 .fadump_trigger = opal_fadump_trigger, 621 }; 622 623 void __init opal_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node) 624 { 625 const __be32 *prop; 626 unsigned long dn; 627 u64 addr = 0; 628 int i, len; 629 s64 ret; 630 631 /* 632 * Check if Firmware-Assisted Dump is supported. if yes, check 633 * if dump has been initiated on last reboot. 634 */ 635 dn = of_get_flat_dt_subnode_by_name(node, "dump"); 636 if (dn == -FDT_ERR_NOTFOUND) { 637 pr_debug("FADump support is missing!\n"); 638 return; 639 } 640 641 if (!of_flat_dt_is_compatible(dn, "ibm,opal-dump")) { 642 pr_err("Support missing for this f/w version!\n"); 643 return; 644 } 645 646 prop = of_get_flat_dt_prop(dn, "fw-load-area", &len); 647 if (prop) { 648 /* 649 * Each f/w load area is an (address,size) pair, 650 * 2 cells each, totalling 4 cells per range. 651 */ 652 for (i = 0; i < len / (sizeof(*prop) * 4); i++) { 653 u64 base, end; 654 655 base = of_read_number(prop + (i * 4) + 0, 2); 656 end = base; 657 end += of_read_number(prop + (i * 4) + 2, 2); 658 if (end > OPAL_FADUMP_MIN_BOOT_MEM) { 659 pr_err("F/W load area: 0x%llx-0x%llx\n", 660 base, end); 661 pr_err("F/W version not supported!\n"); 662 return; 663 } 664 } 665 } 666 667 fadump_conf->ops = &opal_fadump_ops; 668 fadump_conf->fadump_supported = 1; 669 670 /* 671 * Firmware supports 32-bit field for size. Align it to PAGE_SIZE 672 * and request firmware to copy multiple kernel boot memory regions. 673 */ 674 fadump_conf->max_copy_size = ALIGN_DOWN(U32_MAX, PAGE_SIZE); 675 676 /* 677 * Check if dump has been initiated on last reboot. 678 */ 679 prop = of_get_flat_dt_prop(dn, "mpipl-boot", NULL); 680 if (!prop) 681 return; 682 683 ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_KERNEL, &addr); 684 if ((ret != OPAL_SUCCESS) || !addr) { 685 pr_err("Failed to get Kernel metadata (%lld)\n", ret); 686 return; 687 } 688 689 addr = be64_to_cpu(addr); 690 pr_debug("Kernel metadata addr: %llx\n", addr); 691 692 opal_fdm_active = __va(addr); 693 if (opal_fdm_active->version != OPAL_FADUMP_VERSION) { 694 pr_warn("Supported kernel metadata version: %u, found: %d!\n", 695 OPAL_FADUMP_VERSION, opal_fdm_active->version); 696 pr_warn("WARNING: Kernel metadata format mismatch identified! Core file maybe corrupted..\n"); 697 } 698 699 /* Kernel regions not registered with f/w for MPIPL */ 700 if (opal_fdm_active->registered_regions == 0) { 701 opal_fdm_active = NULL; 702 return; 703 } 704 705 ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_CPU, &addr); 706 if (addr) { 707 addr = be64_to_cpu(addr); 708 pr_debug("CPU metadata addr: %llx\n", addr); 709 opal_cpu_metadata = __va(addr); 710 } 711 712 pr_info("Firmware-assisted dump is active.\n"); 713 fadump_conf->dump_active = 1; 714 opal_fadump_get_config(fadump_conf, opal_fdm_active); 715 } 716 #endif /* !CONFIG_PRESERVE_FA_DUMP */ 717