Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Firmware-Assisted Dump support on POWERVM platform.
0004  *
0005  * Copyright 2011, Mahesh Salgaonkar, IBM Corporation.
0006  * Copyright 2019, Hari Bathini, IBM Corporation.
0007  */
0008 
0009 #define pr_fmt(fmt) "rtas fadump: " fmt
0010 
0011 #include <linux/string.h>
0012 #include <linux/memblock.h>
0013 #include <linux/delay.h>
0014 #include <linux/seq_file.h>
0015 #include <linux/crash_dump.h>
0016 #include <linux/of.h>
0017 #include <linux/of_fdt.h>
0018 
0019 #include <asm/page.h>
0020 #include <asm/rtas.h>
0021 #include <asm/fadump.h>
0022 #include <asm/fadump-internal.h>
0023 
0024 #include "rtas-fadump.h"
0025 
0026 static struct rtas_fadump_mem_struct fdm;
0027 static const struct rtas_fadump_mem_struct *fdm_active;
0028 
0029 static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
0030                       const struct rtas_fadump_mem_struct *fdm)
0031 {
0032     fadump_conf->boot_mem_dest_addr =
0033         be64_to_cpu(fdm->rmr_region.destination_address);
0034 
0035     fadump_conf->fadumphdr_addr = (fadump_conf->boot_mem_dest_addr +
0036                        fadump_conf->boot_memory_size);
0037 }
0038 
0039 /*
0040  * This function is called in the capture kernel to get configuration details
0041  * setup in the first kernel and passed to the f/w.
0042  */
0043 static void __init rtas_fadump_get_config(struct fw_dump *fadump_conf,
0044                    const struct rtas_fadump_mem_struct *fdm)
0045 {
0046     fadump_conf->boot_mem_addr[0] =
0047         be64_to_cpu(fdm->rmr_region.source_address);
0048     fadump_conf->boot_mem_sz[0] = be64_to_cpu(fdm->rmr_region.source_len);
0049     fadump_conf->boot_memory_size = fadump_conf->boot_mem_sz[0];
0050 
0051     fadump_conf->boot_mem_top = fadump_conf->boot_memory_size;
0052     fadump_conf->boot_mem_regs_cnt = 1;
0053 
0054     /*
0055      * Start address of reserve dump area (permanent reservation) for
0056      * re-registering FADump after dump capture.
0057      */
0058     fadump_conf->reserve_dump_area_start =
0059         be64_to_cpu(fdm->cpu_state_data.destination_address);
0060 
0061     rtas_fadump_update_config(fadump_conf, fdm);
0062 }
0063 
0064 static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
0065 {
0066     u64 addr = fadump_conf->reserve_dump_area_start;
0067 
0068     memset(&fdm, 0, sizeof(struct rtas_fadump_mem_struct));
0069     addr = addr & PAGE_MASK;
0070 
0071     fdm.header.dump_format_version = cpu_to_be32(0x00000001);
0072     fdm.header.dump_num_sections = cpu_to_be16(3);
0073     fdm.header.dump_status_flag = 0;
0074     fdm.header.offset_first_dump_section =
0075         cpu_to_be32((u32)offsetof(struct rtas_fadump_mem_struct,
0076                       cpu_state_data));
0077 
0078     /*
0079      * Fields for disk dump option.
0080      * We are not using disk dump option, hence set these fields to 0.
0081      */
0082     fdm.header.dd_block_size = 0;
0083     fdm.header.dd_block_offset = 0;
0084     fdm.header.dd_num_blocks = 0;
0085     fdm.header.dd_offset_disk_path = 0;
0086 
0087     /* set 0 to disable an automatic dump-reboot. */
0088     fdm.header.max_time_auto = 0;
0089 
0090     /* Kernel dump sections */
0091     /* cpu state data section. */
0092     fdm.cpu_state_data.request_flag =
0093         cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
0094     fdm.cpu_state_data.source_data_type =
0095         cpu_to_be16(RTAS_FADUMP_CPU_STATE_DATA);
0096     fdm.cpu_state_data.source_address = 0;
0097     fdm.cpu_state_data.source_len =
0098         cpu_to_be64(fadump_conf->cpu_state_data_size);
0099     fdm.cpu_state_data.destination_address = cpu_to_be64(addr);
0100     addr += fadump_conf->cpu_state_data_size;
0101 
0102     /* hpte region section */
0103     fdm.hpte_region.request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
0104     fdm.hpte_region.source_data_type =
0105         cpu_to_be16(RTAS_FADUMP_HPTE_REGION);
0106     fdm.hpte_region.source_address = 0;
0107     fdm.hpte_region.source_len =
0108         cpu_to_be64(fadump_conf->hpte_region_size);
0109     fdm.hpte_region.destination_address = cpu_to_be64(addr);
0110     addr += fadump_conf->hpte_region_size;
0111 
0112     /*
0113      * Align boot memory area destination address to page boundary to
0114      * be able to mmap read this area in the vmcore.
0115      */
0116     addr = PAGE_ALIGN(addr);
0117 
0118     /* RMA region section */
0119     fdm.rmr_region.request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
0120     fdm.rmr_region.source_data_type =
0121         cpu_to_be16(RTAS_FADUMP_REAL_MODE_REGION);
0122     fdm.rmr_region.source_address = cpu_to_be64(0);
0123     fdm.rmr_region.source_len = cpu_to_be64(fadump_conf->boot_memory_size);
0124     fdm.rmr_region.destination_address = cpu_to_be64(addr);
0125     addr += fadump_conf->boot_memory_size;
0126 
0127     rtas_fadump_update_config(fadump_conf, &fdm);
0128 
0129     return addr;
0130 }
0131 
0132 static u64 rtas_fadump_get_bootmem_min(void)
0133 {
0134     return RTAS_FADUMP_MIN_BOOT_MEM;
0135 }
0136 
0137 static int rtas_fadump_register(struct fw_dump *fadump_conf)
0138 {
0139     unsigned int wait_time;
0140     int rc, err = -EIO;
0141 
0142     /* TODO: Add upper time limit for the delay */
0143     do {
0144         rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
0145                 NULL, FADUMP_REGISTER, &fdm,
0146                 sizeof(struct rtas_fadump_mem_struct));
0147 
0148         wait_time = rtas_busy_delay_time(rc);
0149         if (wait_time)
0150             mdelay(wait_time);
0151 
0152     } while (wait_time);
0153 
0154     switch (rc) {
0155     case 0:
0156         pr_info("Registration is successful!\n");
0157         fadump_conf->dump_registered = 1;
0158         err = 0;
0159         break;
0160     case -1:
0161         pr_err("Failed to register. Hardware Error(%d).\n", rc);
0162         break;
0163     case -3:
0164         if (!is_fadump_boot_mem_contiguous())
0165             pr_err("Can't have holes in boot memory area.\n");
0166         else if (!is_fadump_reserved_mem_contiguous())
0167             pr_err("Can't have holes in reserved memory area.\n");
0168 
0169         pr_err("Failed to register. Parameter Error(%d).\n", rc);
0170         err = -EINVAL;
0171         break;
0172     case -9:
0173         pr_err("Already registered!\n");
0174         fadump_conf->dump_registered = 1;
0175         err = -EEXIST;
0176         break;
0177     default:
0178         pr_err("Failed to register. Unknown Error(%d).\n", rc);
0179         break;
0180     }
0181 
0182     return err;
0183 }
0184 
0185 static int rtas_fadump_unregister(struct fw_dump *fadump_conf)
0186 {
0187     unsigned int wait_time;
0188     int rc;
0189 
0190     /* TODO: Add upper time limit for the delay */
0191     do {
0192         rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
0193                 NULL, FADUMP_UNREGISTER, &fdm,
0194                 sizeof(struct rtas_fadump_mem_struct));
0195 
0196         wait_time = rtas_busy_delay_time(rc);
0197         if (wait_time)
0198             mdelay(wait_time);
0199     } while (wait_time);
0200 
0201     if (rc) {
0202         pr_err("Failed to un-register - unexpected error(%d).\n", rc);
0203         return -EIO;
0204     }
0205 
0206     fadump_conf->dump_registered = 0;
0207     return 0;
0208 }
0209 
0210 static int rtas_fadump_invalidate(struct fw_dump *fadump_conf)
0211 {
0212     unsigned int wait_time;
0213     int rc;
0214 
0215     /* TODO: Add upper time limit for the delay */
0216     do {
0217         rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
0218                 NULL, FADUMP_INVALIDATE, fdm_active,
0219                 sizeof(struct rtas_fadump_mem_struct));
0220 
0221         wait_time = rtas_busy_delay_time(rc);
0222         if (wait_time)
0223             mdelay(wait_time);
0224     } while (wait_time);
0225 
0226     if (rc) {
0227         pr_err("Failed to invalidate - unexpected error (%d).\n", rc);
0228         return -EIO;
0229     }
0230 
0231     fadump_conf->dump_active = 0;
0232     fdm_active = NULL;
0233     return 0;
0234 }
0235 
0236 #define RTAS_FADUMP_GPR_MASK        0xffffff0000000000
0237 static inline int rtas_fadump_gpr_index(u64 id)
0238 {
0239     char str[3];
0240     int i = -1;
0241 
0242     if ((id & RTAS_FADUMP_GPR_MASK) == fadump_str_to_u64("GPR")) {
0243         /* get the digits at the end */
0244         id &= ~RTAS_FADUMP_GPR_MASK;
0245         id >>= 24;
0246         str[2] = '\0';
0247         str[1] = id & 0xff;
0248         str[0] = (id >> 8) & 0xff;
0249         if (kstrtoint(str, 10, &i))
0250             i = -EINVAL;
0251         if (i > 31)
0252             i = -1;
0253     }
0254     return i;
0255 }
0256 
0257 static void __init rtas_fadump_set_regval(struct pt_regs *regs, u64 reg_id, u64 reg_val)
0258 {
0259     int i;
0260 
0261     i = rtas_fadump_gpr_index(reg_id);
0262     if (i >= 0)
0263         regs->gpr[i] = (unsigned long)reg_val;
0264     else if (reg_id == fadump_str_to_u64("NIA"))
0265         regs->nip = (unsigned long)reg_val;
0266     else if (reg_id == fadump_str_to_u64("MSR"))
0267         regs->msr = (unsigned long)reg_val;
0268     else if (reg_id == fadump_str_to_u64("CTR"))
0269         regs->ctr = (unsigned long)reg_val;
0270     else if (reg_id == fadump_str_to_u64("LR"))
0271         regs->link = (unsigned long)reg_val;
0272     else if (reg_id == fadump_str_to_u64("XER"))
0273         regs->xer = (unsigned long)reg_val;
0274     else if (reg_id == fadump_str_to_u64("CR"))
0275         regs->ccr = (unsigned long)reg_val;
0276     else if (reg_id == fadump_str_to_u64("DAR"))
0277         regs->dar = (unsigned long)reg_val;
0278     else if (reg_id == fadump_str_to_u64("DSISR"))
0279         regs->dsisr = (unsigned long)reg_val;
0280 }
0281 
0282 static struct rtas_fadump_reg_entry* __init
0283 rtas_fadump_read_regs(struct rtas_fadump_reg_entry *reg_entry,
0284               struct pt_regs *regs)
0285 {
0286     memset(regs, 0, sizeof(struct pt_regs));
0287 
0288     while (be64_to_cpu(reg_entry->reg_id) != fadump_str_to_u64("CPUEND")) {
0289         rtas_fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
0290                        be64_to_cpu(reg_entry->reg_value));
0291         reg_entry++;
0292     }
0293     reg_entry++;
0294     return reg_entry;
0295 }
0296 
0297 /*
0298  * Read CPU state dump data and convert it into ELF notes.
0299  * The CPU dump starts with magic number "REGSAVE". NumCpusOffset should be
0300  * used to access the data to allow for additional fields to be added without
0301  * affecting compatibility. Each list of registers for a CPU starts with
0302  * "CPUSTRT" and ends with "CPUEND". Each register entry is of 16 bytes,
0303  * 8 Byte ASCII identifier and 8 Byte register value. The register entry
0304  * with identifier "CPUSTRT" and "CPUEND" contains 4 byte cpu id as part
0305  * of register value. For more details refer to PAPR document.
0306  *
0307  * Only for the crashing cpu we ignore the CPU dump data and get exact
0308  * state from fadump crash info structure populated by first kernel at the
0309  * time of crash.
0310  */
0311 static int __init rtas_fadump_build_cpu_notes(struct fw_dump *fadump_conf)
0312 {
0313     struct rtas_fadump_reg_save_area_header *reg_header;
0314     struct fadump_crash_info_header *fdh = NULL;
0315     struct rtas_fadump_reg_entry *reg_entry;
0316     u32 num_cpus, *note_buf;
0317     int i, rc = 0, cpu = 0;
0318     struct pt_regs regs;
0319     unsigned long addr;
0320     void *vaddr;
0321 
0322     addr = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
0323     vaddr = __va(addr);
0324 
0325     reg_header = vaddr;
0326     if (be64_to_cpu(reg_header->magic_number) !=
0327         fadump_str_to_u64("REGSAVE")) {
0328         pr_err("Unable to read register save area.\n");
0329         return -ENOENT;
0330     }
0331 
0332     pr_debug("--------CPU State Data------------\n");
0333     pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
0334     pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
0335 
0336     vaddr += be32_to_cpu(reg_header->num_cpu_offset);
0337     num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
0338     pr_debug("NumCpus     : %u\n", num_cpus);
0339     vaddr += sizeof(u32);
0340     reg_entry = (struct rtas_fadump_reg_entry *)vaddr;
0341 
0342     rc = fadump_setup_cpu_notes_buf(num_cpus);
0343     if (rc != 0)
0344         return rc;
0345 
0346     note_buf = (u32 *)fadump_conf->cpu_notes_buf_vaddr;
0347 
0348     if (fadump_conf->fadumphdr_addr)
0349         fdh = __va(fadump_conf->fadumphdr_addr);
0350 
0351     for (i = 0; i < num_cpus; i++) {
0352         if (be64_to_cpu(reg_entry->reg_id) !=
0353             fadump_str_to_u64("CPUSTRT")) {
0354             pr_err("Unable to read CPU state data\n");
0355             rc = -ENOENT;
0356             goto error_out;
0357         }
0358         /* Lower 4 bytes of reg_value contains logical cpu id */
0359         cpu = (be64_to_cpu(reg_entry->reg_value) &
0360                RTAS_FADUMP_CPU_ID_MASK);
0361         if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_mask)) {
0362             RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
0363             continue;
0364         }
0365         pr_debug("Reading register data for cpu %d...\n", cpu);
0366         if (fdh && fdh->crashing_cpu == cpu) {
0367             regs = fdh->regs;
0368             note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
0369             RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
0370         } else {
0371             reg_entry++;
0372             reg_entry = rtas_fadump_read_regs(reg_entry, &regs);
0373             note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
0374         }
0375     }
0376     final_note(note_buf);
0377 
0378     if (fdh) {
0379         pr_debug("Updating elfcore header (%llx) with cpu notes\n",
0380              fdh->elfcorehdr_addr);
0381         fadump_update_elfcore_header(__va(fdh->elfcorehdr_addr));
0382     }
0383     return 0;
0384 
0385 error_out:
0386     fadump_free_cpu_notes_buf();
0387     return rc;
0388 
0389 }
0390 
0391 /*
0392  * Validate and process the dump data stored by firmware before exporting
0393  * it through '/proc/vmcore'.
0394  */
0395 static int __init rtas_fadump_process(struct fw_dump *fadump_conf)
0396 {
0397     struct fadump_crash_info_header *fdh;
0398     int rc = 0;
0399 
0400     if (!fdm_active || !fadump_conf->fadumphdr_addr)
0401         return -EINVAL;
0402 
0403     /* Check if the dump data is valid. */
0404     if ((be16_to_cpu(fdm_active->header.dump_status_flag) ==
0405             RTAS_FADUMP_ERROR_FLAG) ||
0406             (fdm_active->cpu_state_data.error_flags != 0) ||
0407             (fdm_active->rmr_region.error_flags != 0)) {
0408         pr_err("Dump taken by platform is not valid\n");
0409         return -EINVAL;
0410     }
0411     if ((fdm_active->rmr_region.bytes_dumped !=
0412             fdm_active->rmr_region.source_len) ||
0413             !fdm_active->cpu_state_data.bytes_dumped) {
0414         pr_err("Dump taken by platform is incomplete\n");
0415         return -EINVAL;
0416     }
0417 
0418     /* Validate the fadump crash info header */
0419     fdh = __va(fadump_conf->fadumphdr_addr);
0420     if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
0421         pr_err("Crash info header is not valid.\n");
0422         return -EINVAL;
0423     }
0424 
0425     rc = rtas_fadump_build_cpu_notes(fadump_conf);
0426     if (rc)
0427         return rc;
0428 
0429     /*
0430      * We are done validating dump info and elfcore header is now ready
0431      * to be exported. set elfcorehdr_addr so that vmcore module will
0432      * export the elfcore header through '/proc/vmcore'.
0433      */
0434     elfcorehdr_addr = fdh->elfcorehdr_addr;
0435 
0436     return 0;
0437 }
0438 
0439 static void rtas_fadump_region_show(struct fw_dump *fadump_conf,
0440                     struct seq_file *m)
0441 {
0442     const struct rtas_fadump_section *cpu_data_section;
0443     const struct rtas_fadump_mem_struct *fdm_ptr;
0444 
0445     if (fdm_active)
0446         fdm_ptr = fdm_active;
0447     else
0448         fdm_ptr = &fdm;
0449 
0450     cpu_data_section = &(fdm_ptr->cpu_state_data);
0451     seq_printf(m, "CPU :[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
0452            be64_to_cpu(cpu_data_section->destination_address),
0453            be64_to_cpu(cpu_data_section->destination_address) +
0454            be64_to_cpu(cpu_data_section->source_len) - 1,
0455            be64_to_cpu(cpu_data_section->source_len),
0456            be64_to_cpu(cpu_data_section->bytes_dumped));
0457 
0458     seq_printf(m, "HPTE:[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
0459            be64_to_cpu(fdm_ptr->hpte_region.destination_address),
0460            be64_to_cpu(fdm_ptr->hpte_region.destination_address) +
0461            be64_to_cpu(fdm_ptr->hpte_region.source_len) - 1,
0462            be64_to_cpu(fdm_ptr->hpte_region.source_len),
0463            be64_to_cpu(fdm_ptr->hpte_region.bytes_dumped));
0464 
0465     seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ",
0466            be64_to_cpu(fdm_ptr->rmr_region.source_address),
0467            be64_to_cpu(fdm_ptr->rmr_region.destination_address));
0468     seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n",
0469            be64_to_cpu(fdm_ptr->rmr_region.source_len),
0470            be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
0471 
0472     /* Dump is active. Show preserved area start address. */
0473     if (fdm_active) {
0474         seq_printf(m, "\nMemory above %#016llx is reserved for saving crash dump\n",
0475                fadump_conf->boot_mem_top);
0476     }
0477 }
0478 
0479 static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh,
0480                 const char *msg)
0481 {
0482     /* Call ibm,os-term rtas call to trigger firmware assisted dump */
0483     rtas_os_term((char *)msg);
0484 }
0485 
0486 static struct fadump_ops rtas_fadump_ops = {
0487     .fadump_init_mem_struct     = rtas_fadump_init_mem_struct,
0488     .fadump_get_bootmem_min     = rtas_fadump_get_bootmem_min,
0489     .fadump_register        = rtas_fadump_register,
0490     .fadump_unregister      = rtas_fadump_unregister,
0491     .fadump_invalidate      = rtas_fadump_invalidate,
0492     .fadump_process         = rtas_fadump_process,
0493     .fadump_region_show     = rtas_fadump_region_show,
0494     .fadump_trigger         = rtas_fadump_trigger,
0495 };
0496 
0497 void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
0498 {
0499     int i, size, num_sections;
0500     const __be32 *sections;
0501     const __be32 *token;
0502 
0503     /*
0504      * Check if Firmware Assisted dump is supported. if yes, check
0505      * if dump has been initiated on last reboot.
0506      */
0507     token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL);
0508     if (!token)
0509         return;
0510 
0511     fadump_conf->ibm_configure_kernel_dump = be32_to_cpu(*token);
0512     fadump_conf->ops        = &rtas_fadump_ops;
0513     fadump_conf->fadump_supported   = 1;
0514 
0515     /* Firmware supports 64-bit value for size, align it to pagesize. */
0516     fadump_conf->max_copy_size = ALIGN_DOWN(U64_MAX, PAGE_SIZE);
0517 
0518     /*
0519      * The 'ibm,kernel-dump' rtas node is present only if there is
0520      * dump data waiting for us.
0521      */
0522     fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);
0523     if (fdm_active) {
0524         pr_info("Firmware-assisted dump is active.\n");
0525         fadump_conf->dump_active = 1;
0526         rtas_fadump_get_config(fadump_conf, (void *)__pa(fdm_active));
0527     }
0528 
0529     /* Get the sizes required to store dump data for the firmware provided
0530      * dump sections.
0531      * For each dump section type supported, a 32bit cell which defines
0532      * the ID of a supported section followed by two 32 bit cells which
0533      * gives the size of the section in bytes.
0534      */
0535     sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
0536                     &size);
0537 
0538     if (!sections)
0539         return;
0540 
0541     num_sections = size / (3 * sizeof(u32));
0542 
0543     for (i = 0; i < num_sections; i++, sections += 3) {
0544         u32 type = (u32)of_read_number(sections, 1);
0545 
0546         switch (type) {
0547         case RTAS_FADUMP_CPU_STATE_DATA:
0548             fadump_conf->cpu_state_data_size =
0549                     of_read_ulong(&sections[1], 2);
0550             break;
0551         case RTAS_FADUMP_HPTE_REGION:
0552             fadump_conf->hpte_region_size =
0553                     of_read_ulong(&sections[1], 2);
0554             break;
0555         }
0556     }
0557 }