linux/arch/powerpc/kernel/fadump.c
<<
>>
Prefs
   1/*
   2 * Firmware Assisted dump: A robust mechanism to get reliable kernel crash
   3 * dump with assistance from firmware. This approach does not use kexec,
   4 * instead firmware assists in booting the kdump kernel while preserving
   5 * memory contents. The most of the code implementation has been adapted
   6 * from phyp assisted dump implementation written by Linas Vepstas and
   7 * Manish Ahuja
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 *
  19 * You should have received a copy of the GNU General Public License
  20 * along with this program; if not, write to the Free Software
  21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  22 *
  23 * Copyright 2011 IBM Corporation
  24 * Author: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com>
  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
  39#include <asm/page.h>
  40#include <asm/prom.h>
  41#include <asm/rtas.h>
  42#include <asm/fadump.h>
  43#include <asm/debug.h>
  44#include <asm/setup.h>
  45
  46static struct fw_dump fw_dump;
  47static struct fadump_mem_struct fdm;
  48static const struct fadump_mem_struct *fdm_active;
  49
  50static DEFINE_MUTEX(fadump_mutex);
  51struct fad_crash_memory_ranges crash_memory_ranges[INIT_CRASHMEM_RANGES];
  52int crash_mem_ranges;
  53
  54/* Scan the Firmware Assisted dump configuration details. */
  55int __init early_init_dt_scan_fw_dump(unsigned long node,
  56                        const char *uname, int depth, void *data)
  57{
  58        const __be32 *sections;
  59        int i, num_sections;
  60        int size;
  61        const __be32 *token;
  62
  63        if (depth != 1 || strcmp(uname, "rtas") != 0)
  64                return 0;
  65
  66        /*
  67         * Check if Firmware Assisted dump is supported. if yes, check
  68         * if dump has been initiated on last reboot.
  69         */
  70        token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL);
  71        if (!token)
  72                return 1;
  73
  74        fw_dump.fadump_supported = 1;
  75        fw_dump.ibm_configure_kernel_dump = be32_to_cpu(*token);
  76
  77        /*
  78         * The 'ibm,kernel-dump' rtas node is present only if there is
  79         * dump data waiting for us.
  80         */
  81        fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);
  82        if (fdm_active)
  83                fw_dump.dump_active = 1;
  84
  85        /* Get the sizes required to store dump data for the firmware provided
  86         * dump sections.
  87         * For each dump section type supported, a 32bit cell which defines
  88         * the ID of a supported section followed by two 32 bit cells which
  89         * gives teh size of the section in bytes.
  90         */
  91        sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
  92                                        &size);
  93
  94        if (!sections)
  95                return 1;
  96
  97        num_sections = size / (3 * sizeof(u32));
  98
  99        for (i = 0; i < num_sections; i++, sections += 3) {
 100                u32 type = (u32)of_read_number(sections, 1);
 101
 102                switch (type) {
 103                case FADUMP_CPU_STATE_DATA:
 104                        fw_dump.cpu_state_data_size =
 105                                        of_read_ulong(&sections[1], 2);
 106                        break;
 107                case FADUMP_HPTE_REGION:
 108                        fw_dump.hpte_region_size =
 109                                        of_read_ulong(&sections[1], 2);
 110                        break;
 111                }
 112        }
 113
 114        return 1;
 115}
 116
 117int is_fadump_active(void)
 118{
 119        return fw_dump.dump_active;
 120}
 121
 122/* Print firmware assisted dump configurations for debugging purpose. */
 123static void fadump_show_config(void)
 124{
 125        pr_debug("Support for firmware-assisted dump (fadump): %s\n",
 126                        (fw_dump.fadump_supported ? "present" : "no support"));
 127
 128        if (!fw_dump.fadump_supported)
 129                return;
 130
 131        pr_debug("Fadump enabled    : %s\n",
 132                                (fw_dump.fadump_enabled ? "yes" : "no"));
 133        pr_debug("Dump Active       : %s\n",
 134                                (fw_dump.dump_active ? "yes" : "no"));
 135        pr_debug("Dump section sizes:\n");
 136        pr_debug("    CPU state data size: %lx\n", fw_dump.cpu_state_data_size);
 137        pr_debug("    HPTE region size   : %lx\n", fw_dump.hpte_region_size);
 138        pr_debug("Boot memory size  : %lx\n", fw_dump.boot_memory_size);
 139}
 140
 141static unsigned long init_fadump_mem_struct(struct fadump_mem_struct *fdm,
 142                                unsigned long addr)
 143{
 144        if (!fdm)
 145                return 0;
 146
 147        memset(fdm, 0, sizeof(struct fadump_mem_struct));
 148        addr = addr & PAGE_MASK;
 149
 150        fdm->header.dump_format_version = cpu_to_be32(0x00000001);
 151        fdm->header.dump_num_sections = cpu_to_be16(3);
 152        fdm->header.dump_status_flag = 0;
 153        fdm->header.offset_first_dump_section =
 154                cpu_to_be32((u32)offsetof(struct fadump_mem_struct, cpu_state_data));
 155
 156        /*
 157         * Fields for disk dump option.
 158         * We are not using disk dump option, hence set these fields to 0.
 159         */
 160        fdm->header.dd_block_size = 0;
 161        fdm->header.dd_block_offset = 0;
 162        fdm->header.dd_num_blocks = 0;
 163        fdm->header.dd_offset_disk_path = 0;
 164
 165        /* set 0 to disable an automatic dump-reboot. */
 166        fdm->header.max_time_auto = 0;
 167
 168        /* Kernel dump sections */
 169        /* cpu state data section. */
 170        fdm->cpu_state_data.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
 171        fdm->cpu_state_data.source_data_type = cpu_to_be16(FADUMP_CPU_STATE_DATA);
 172        fdm->cpu_state_data.source_address = 0;
 173        fdm->cpu_state_data.source_len = cpu_to_be64(fw_dump.cpu_state_data_size);
 174        fdm->cpu_state_data.destination_address = cpu_to_be64(addr);
 175        addr += fw_dump.cpu_state_data_size;
 176
 177        /* hpte region section */
 178        fdm->hpte_region.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
 179        fdm->hpte_region.source_data_type = cpu_to_be16(FADUMP_HPTE_REGION);
 180        fdm->hpte_region.source_address = 0;
 181        fdm->hpte_region.source_len = cpu_to_be64(fw_dump.hpte_region_size);
 182        fdm->hpte_region.destination_address = cpu_to_be64(addr);
 183        addr += fw_dump.hpte_region_size;
 184
 185        /* RMA region section */
 186        fdm->rmr_region.request_flag = cpu_to_be32(FADUMP_REQUEST_FLAG);
 187        fdm->rmr_region.source_data_type = cpu_to_be16(FADUMP_REAL_MODE_REGION);
 188        fdm->rmr_region.source_address = cpu_to_be64(RMA_START);
 189        fdm->rmr_region.source_len = cpu_to_be64(fw_dump.boot_memory_size);
 190        fdm->rmr_region.destination_address = cpu_to_be64(addr);
 191        addr += fw_dump.boot_memory_size;
 192
 193        return addr;
 194}
 195
 196/**
 197 * fadump_calculate_reserve_size(): reserve variable boot area 5% of System RAM
 198 *
 199 * Function to find the largest memory size we need to reserve during early
 200 * boot process. This will be the size of the memory that is required for a
 201 * kernel to boot successfully.
 202 *
 203 * This function has been taken from phyp-assisted dump feature implementation.
 204 *
 205 * returns larger of 256MB or 5% rounded down to multiples of 256MB.
 206 *
 207 * TODO: Come up with better approach to find out more accurate memory size
 208 * that is required for a kernel to boot successfully.
 209 *
 210 */
 211static inline unsigned long fadump_calculate_reserve_size(void)
 212{
 213        unsigned long size;
 214
 215        /*
 216         * Check if the size is specified through fadump_reserve_mem= cmdline
 217         * option. If yes, then use that.
 218         */
 219        if (fw_dump.reserve_bootvar)
 220                return fw_dump.reserve_bootvar;
 221
 222        /* divide by 20 to get 5% of value */
 223        size = memblock_end_of_DRAM() / 20;
 224
 225        /* round it down in multiples of 256 */
 226        size = size & ~0x0FFFFFFFUL;
 227
 228        /* Truncate to memory_limit. We don't want to over reserve the memory.*/
 229        if (memory_limit && size > memory_limit)
 230                size = memory_limit;
 231
 232        return (size > MIN_BOOT_MEM ? size : MIN_BOOT_MEM);
 233}
 234
 235/*
 236 * Calculate the total memory size required to be reserved for
 237 * firmware-assisted dump registration.
 238 */
 239static unsigned long get_fadump_area_size(void)
 240{
 241        unsigned long size = 0;
 242
 243        size += fw_dump.cpu_state_data_size;
 244        size += fw_dump.hpte_region_size;
 245        size += fw_dump.boot_memory_size;
 246        size += sizeof(struct fadump_crash_info_header);
 247        size += sizeof(struct elfhdr); /* ELF core header.*/
 248        size += sizeof(struct elf_phdr); /* place holder for cpu notes */
 249        /* Program headers for crash memory regions. */
 250        size += sizeof(struct elf_phdr) * (memblock_num_regions(memory) + 2);
 251
 252        size = PAGE_ALIGN(size);
 253        return size;
 254}
 255
 256int __init fadump_reserve_mem(void)
 257{
 258        unsigned long base, size, memory_boundary;
 259
 260        if (!fw_dump.fadump_enabled)
 261                return 0;
 262
 263        if (!fw_dump.fadump_supported) {
 264                printk(KERN_INFO "Firmware-assisted dump is not supported on"
 265                                " this hardware\n");
 266                fw_dump.fadump_enabled = 0;
 267                return 0;
 268        }
 269        /*
 270         * Initialize boot memory size
 271         * If dump is active then we have already calculated the size during
 272         * first kernel.
 273         */
 274        if (fdm_active)
 275                fw_dump.boot_memory_size = be64_to_cpu(fdm_active->rmr_region.source_len);
 276        else
 277                fw_dump.boot_memory_size = fadump_calculate_reserve_size();
 278
 279        /*
 280         * Calculate the memory boundary.
 281         * If memory_limit is less than actual memory boundary then reserve
 282         * the memory for fadump beyond the memory_limit and adjust the
 283         * memory_limit accordingly, so that the running kernel can run with
 284         * specified memory_limit.
 285         */
 286        if (memory_limit && memory_limit < memblock_end_of_DRAM()) {
 287                size = get_fadump_area_size();
 288                if ((memory_limit + size) < memblock_end_of_DRAM())
 289                        memory_limit += size;
 290                else
 291                        memory_limit = memblock_end_of_DRAM();
 292                printk(KERN_INFO "Adjusted memory_limit for firmware-assisted"
 293                                " dump, now %#016llx\n", memory_limit);
 294        }
 295        if (memory_limit)
 296                memory_boundary = memory_limit;
 297        else
 298                memory_boundary = memblock_end_of_DRAM();
 299
 300        if (fw_dump.dump_active) {
 301                printk(KERN_INFO "Firmware-assisted dump is active.\n");
 302                /*
 303                 * If last boot has crashed then reserve all the memory
 304                 * above boot_memory_size so that we don't touch it until
 305                 * dump is written to disk by userspace tool. This memory
 306                 * will be released for general use once the dump is saved.
 307                 */
 308                base = fw_dump.boot_memory_size;
 309                size = memory_boundary - base;
 310                memblock_reserve(base, size);
 311                printk(KERN_INFO "Reserved %ldMB of memory at %ldMB "
 312                                "for saving crash dump\n",
 313                                (unsigned long)(size >> 20),
 314                                (unsigned long)(base >> 20));
 315
 316                fw_dump.fadumphdr_addr =
 317                                be64_to_cpu(fdm_active->rmr_region.destination_address) +
 318                                be64_to_cpu(fdm_active->rmr_region.source_len);
 319                pr_debug("fadumphdr_addr = %p\n",
 320                                (void *) fw_dump.fadumphdr_addr);
 321        } else {
 322                /* Reserve the memory at the top of memory. */
 323                size = get_fadump_area_size();
 324                base = memory_boundary - size;
 325                memblock_reserve(base, size);
 326                printk(KERN_INFO "Reserved %ldMB of memory at %ldMB "
 327                                "for firmware-assisted dump\n",
 328                                (unsigned long)(size >> 20),
 329                                (unsigned long)(base >> 20));
 330        }
 331        fw_dump.reserve_dump_area_start = base;
 332        fw_dump.reserve_dump_area_size = size;
 333        return 1;
 334}
 335
 336unsigned long __init arch_reserved_kernel_pages(void)
 337{
 338        return memblock_reserved_size() / PAGE_SIZE;
 339}
 340
 341/* Look for fadump= cmdline option. */
 342static int __init early_fadump_param(char *p)
 343{
 344        if (!p)
 345                return 1;
 346
 347        if (strncmp(p, "on", 2) == 0)
 348                fw_dump.fadump_enabled = 1;
 349        else if (strncmp(p, "off", 3) == 0)
 350                fw_dump.fadump_enabled = 0;
 351
 352        return 0;
 353}
 354early_param("fadump", early_fadump_param);
 355
 356/* Look for fadump_reserve_mem= cmdline option */
 357static int __init early_fadump_reserve_mem(char *p)
 358{
 359        if (p)
 360                fw_dump.reserve_bootvar = memparse(p, &p);
 361        return 0;
 362}
 363early_param("fadump_reserve_mem", early_fadump_reserve_mem);
 364
 365static void register_fw_dump(struct fadump_mem_struct *fdm)
 366{
 367        int rc;
 368        unsigned int wait_time;
 369
 370        pr_debug("Registering for firmware-assisted kernel dump...\n");
 371
 372        /* TODO: Add upper time limit for the delay */
 373        do {
 374                rc = rtas_call(fw_dump.ibm_configure_kernel_dump, 3, 1, NULL,
 375                        FADUMP_REGISTER, fdm,
 376                        sizeof(struct fadump_mem_struct));
 377
 378                wait_time = rtas_busy_delay_time(rc);
 379                if (wait_time)
 380                        mdelay(wait_time);
 381
 382        } while (wait_time);
 383
 384        switch (rc) {
 385        case -1:
 386                printk(KERN_ERR "Failed to register firmware-assisted kernel"
 387                        " dump. Hardware Error(%d).\n", rc);
 388                break;
 389        case -3:
 390                printk(KERN_ERR "Failed to register firmware-assisted kernel"
 391                        " dump. Parameter Error(%d).\n", rc);
 392                break;
 393        case -9:
 394                printk(KERN_ERR "firmware-assisted kernel dump is already "
 395                        " registered.");
 396                fw_dump.dump_registered = 1;
 397                break;
 398        case 0:
 399                printk(KERN_INFO "firmware-assisted kernel dump registration"
 400                        " is successful\n");
 401                fw_dump.dump_registered = 1;
 402                break;
 403        }
 404}
 405
 406void crash_fadump(struct pt_regs *regs, const char *str)
 407{
 408        struct fadump_crash_info_header *fdh = NULL;
 409
 410        if (!fw_dump.dump_registered || !fw_dump.fadumphdr_addr)
 411                return;
 412
 413        fdh = __va(fw_dump.fadumphdr_addr);
 414        crashing_cpu = smp_processor_id();
 415        fdh->crashing_cpu = crashing_cpu;
 416        crash_save_vmcoreinfo();
 417
 418        if (regs)
 419                fdh->regs = *regs;
 420        else
 421                ppc_save_regs(&fdh->regs);
 422
 423        fdh->online_mask = *cpu_online_mask;
 424
 425        /* Call ibm,os-term rtas call to trigger firmware assisted dump */
 426        rtas_os_term((char *)str);
 427}
 428
 429#define GPR_MASK        0xffffff0000000000
 430static inline int fadump_gpr_index(u64 id)
 431{
 432        int i = -1;
 433        char str[3];
 434
 435        if ((id & GPR_MASK) == REG_ID("GPR")) {
 436                /* get the digits at the end */
 437                id &= ~GPR_MASK;
 438                id >>= 24;
 439                str[2] = '\0';
 440                str[1] = id & 0xff;
 441                str[0] = (id >> 8) & 0xff;
 442                sscanf(str, "%d", &i);
 443                if (i > 31)
 444                        i = -1;
 445        }
 446        return i;
 447}
 448
 449static inline void fadump_set_regval(struct pt_regs *regs, u64 reg_id,
 450                                                                u64 reg_val)
 451{
 452        int i;
 453
 454        i = fadump_gpr_index(reg_id);
 455        if (i >= 0)
 456                regs->gpr[i] = (unsigned long)reg_val;
 457        else if (reg_id == REG_ID("NIA"))
 458                regs->nip = (unsigned long)reg_val;
 459        else if (reg_id == REG_ID("MSR"))
 460                regs->msr = (unsigned long)reg_val;
 461        else if (reg_id == REG_ID("CTR"))
 462                regs->ctr = (unsigned long)reg_val;
 463        else if (reg_id == REG_ID("LR"))
 464                regs->link = (unsigned long)reg_val;
 465        else if (reg_id == REG_ID("XER"))
 466                regs->xer = (unsigned long)reg_val;
 467        else if (reg_id == REG_ID("CR"))
 468                regs->ccr = (unsigned long)reg_val;
 469        else if (reg_id == REG_ID("DAR"))
 470                regs->dar = (unsigned long)reg_val;
 471        else if (reg_id == REG_ID("DSISR"))
 472                regs->dsisr = (unsigned long)reg_val;
 473}
 474
 475static struct fadump_reg_entry*
 476fadump_read_registers(struct fadump_reg_entry *reg_entry, struct pt_regs *regs)
 477{
 478        memset(regs, 0, sizeof(struct pt_regs));
 479
 480        while (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUEND")) {
 481                fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
 482                                        be64_to_cpu(reg_entry->reg_value));
 483                reg_entry++;
 484        }
 485        reg_entry++;
 486        return reg_entry;
 487}
 488
 489static u32 *fadump_append_elf_note(u32 *buf, char *name, unsigned type,
 490                                                void *data, size_t data_len)
 491{
 492        struct elf_note note;
 493
 494        note.n_namesz = strlen(name) + 1;
 495        note.n_descsz = data_len;
 496        note.n_type   = type;
 497        memcpy(buf, &note, sizeof(note));
 498        buf += (sizeof(note) + 3)/4;
 499        memcpy(buf, name, note.n_namesz);
 500        buf += (note.n_namesz + 3)/4;
 501        memcpy(buf, data, note.n_descsz);
 502        buf += (note.n_descsz + 3)/4;
 503
 504        return buf;
 505}
 506
 507static void fadump_final_note(u32 *buf)
 508{
 509        struct elf_note note;
 510
 511        note.n_namesz = 0;
 512        note.n_descsz = 0;
 513        note.n_type   = 0;
 514        memcpy(buf, &note, sizeof(note));
 515}
 516
 517static u32 *fadump_regs_to_elf_notes(u32 *buf, struct pt_regs *regs)
 518{
 519        struct elf_prstatus prstatus;
 520
 521        memset(&prstatus, 0, sizeof(prstatus));
 522        /*
 523         * FIXME: How do i get PID? Do I really need it?
 524         * prstatus.pr_pid = ????
 525         */
 526        elf_core_copy_kernel_regs(&prstatus.pr_reg, regs);
 527        buf = fadump_append_elf_note(buf, KEXEC_CORE_NOTE_NAME, NT_PRSTATUS,
 528                                &prstatus, sizeof(prstatus));
 529        return buf;
 530}
 531
 532static void fadump_update_elfcore_header(char *bufp)
 533{
 534        struct elfhdr *elf;
 535        struct elf_phdr *phdr;
 536
 537        elf = (struct elfhdr *)bufp;
 538        bufp += sizeof(struct elfhdr);
 539
 540        /* First note is a place holder for cpu notes info. */
 541        phdr = (struct elf_phdr *)bufp;
 542
 543        if (phdr->p_type == PT_NOTE) {
 544                phdr->p_paddr = fw_dump.cpu_notes_buf;
 545                phdr->p_offset  = phdr->p_paddr;
 546                phdr->p_filesz  = fw_dump.cpu_notes_buf_size;
 547                phdr->p_memsz = fw_dump.cpu_notes_buf_size;
 548        }
 549        return;
 550}
 551
 552static void *fadump_cpu_notes_buf_alloc(unsigned long size)
 553{
 554        void *vaddr;
 555        struct page *page;
 556        unsigned long order, count, i;
 557
 558        order = get_order(size);
 559        vaddr = (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
 560        if (!vaddr)
 561                return NULL;
 562
 563        count = 1 << order;
 564        page = virt_to_page(vaddr);
 565        for (i = 0; i < count; i++)
 566                SetPageReserved(page + i);
 567        return vaddr;
 568}
 569
 570static void fadump_cpu_notes_buf_free(unsigned long vaddr, unsigned long size)
 571{
 572        struct page *page;
 573        unsigned long order, count, i;
 574
 575        order = get_order(size);
 576        count = 1 << order;
 577        page = virt_to_page(vaddr);
 578        for (i = 0; i < count; i++)
 579                ClearPageReserved(page + i);
 580        __free_pages(page, order);
 581}
 582
 583/*
 584 * Read CPU state dump data and convert it into ELF notes.
 585 * The CPU dump starts with magic number "REGSAVE". NumCpusOffset should be
 586 * used to access the data to allow for additional fields to be added without
 587 * affecting compatibility. Each list of registers for a CPU starts with
 588 * "CPUSTRT" and ends with "CPUEND". Each register entry is of 16 bytes,
 589 * 8 Byte ASCII identifier and 8 Byte register value. The register entry
 590 * with identifier "CPUSTRT" and "CPUEND" contains 4 byte cpu id as part
 591 * of register value. For more details refer to PAPR document.
 592 *
 593 * Only for the crashing cpu we ignore the CPU dump data and get exact
 594 * state from fadump crash info structure populated by first kernel at the
 595 * time of crash.
 596 */
 597static int __init fadump_build_cpu_notes(const struct fadump_mem_struct *fdm)
 598{
 599        struct fadump_reg_save_area_header *reg_header;
 600        struct fadump_reg_entry *reg_entry;
 601        struct fadump_crash_info_header *fdh = NULL;
 602        void *vaddr;
 603        unsigned long addr;
 604        u32 num_cpus, *note_buf;
 605        struct pt_regs regs;
 606        int i, rc = 0, cpu = 0;
 607
 608        if (!fdm->cpu_state_data.bytes_dumped)
 609                return -EINVAL;
 610
 611        addr = be64_to_cpu(fdm->cpu_state_data.destination_address);
 612        vaddr = __va(addr);
 613
 614        reg_header = vaddr;
 615        if (be64_to_cpu(reg_header->magic_number) != REGSAVE_AREA_MAGIC) {
 616                printk(KERN_ERR "Unable to read register save area.\n");
 617                return -ENOENT;
 618        }
 619        pr_debug("--------CPU State Data------------\n");
 620        pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
 621        pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
 622
 623        vaddr += be32_to_cpu(reg_header->num_cpu_offset);
 624        num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
 625        pr_debug("NumCpus     : %u\n", num_cpus);
 626        vaddr += sizeof(u32);
 627        reg_entry = (struct fadump_reg_entry *)vaddr;
 628
 629        /* Allocate buffer to hold cpu crash notes. */
 630        fw_dump.cpu_notes_buf_size = num_cpus * sizeof(note_buf_t);
 631        fw_dump.cpu_notes_buf_size = PAGE_ALIGN(fw_dump.cpu_notes_buf_size);
 632        note_buf = fadump_cpu_notes_buf_alloc(fw_dump.cpu_notes_buf_size);
 633        if (!note_buf) {
 634                printk(KERN_ERR "Failed to allocate 0x%lx bytes for "
 635                        "cpu notes buffer\n", fw_dump.cpu_notes_buf_size);
 636                return -ENOMEM;
 637        }
 638        fw_dump.cpu_notes_buf = __pa(note_buf);
 639
 640        pr_debug("Allocated buffer for cpu notes of size %ld at %p\n",
 641                        (num_cpus * sizeof(note_buf_t)), note_buf);
 642
 643        if (fw_dump.fadumphdr_addr)
 644                fdh = __va(fw_dump.fadumphdr_addr);
 645
 646        for (i = 0; i < num_cpus; i++) {
 647                if (be64_to_cpu(reg_entry->reg_id) != REG_ID("CPUSTRT")) {
 648                        printk(KERN_ERR "Unable to read CPU state data\n");
 649                        rc = -ENOENT;
 650                        goto error_out;
 651                }
 652                /* Lower 4 bytes of reg_value contains logical cpu id */
 653                cpu = be64_to_cpu(reg_entry->reg_value) & FADUMP_CPU_ID_MASK;
 654                if (fdh && !cpumask_test_cpu(cpu, &fdh->online_mask)) {
 655                        SKIP_TO_NEXT_CPU(reg_entry);
 656                        continue;
 657                }
 658                pr_debug("Reading register data for cpu %d...\n", cpu);
 659                if (fdh && fdh->crashing_cpu == cpu) {
 660                        regs = fdh->regs;
 661                        note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
 662                        SKIP_TO_NEXT_CPU(reg_entry);
 663                } else {
 664                        reg_entry++;
 665                        reg_entry = fadump_read_registers(reg_entry, &regs);
 666                        note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
 667                }
 668        }
 669        fadump_final_note(note_buf);
 670
 671        if (fdh) {
 672                pr_debug("Updating elfcore header (%llx) with cpu notes\n",
 673                                                        fdh->elfcorehdr_addr);
 674                fadump_update_elfcore_header((char *)__va(fdh->elfcorehdr_addr));
 675        }
 676        return 0;
 677
 678error_out:
 679        fadump_cpu_notes_buf_free((unsigned long)__va(fw_dump.cpu_notes_buf),
 680                                        fw_dump.cpu_notes_buf_size);
 681        fw_dump.cpu_notes_buf = 0;
 682        fw_dump.cpu_notes_buf_size = 0;
 683        return rc;
 684
 685}
 686
 687/*
 688 * Validate and process the dump data stored by firmware before exporting
 689 * it through '/proc/vmcore'.
 690 */
 691static int __init process_fadump(const struct fadump_mem_struct *fdm_active)
 692{
 693        struct fadump_crash_info_header *fdh;
 694        int rc = 0;
 695
 696        if (!fdm_active || !fw_dump.fadumphdr_addr)
 697                return -EINVAL;
 698
 699        /* Check if the dump data is valid. */
 700        if ((be16_to_cpu(fdm_active->header.dump_status_flag) == FADUMP_ERROR_FLAG) ||
 701                        (fdm_active->cpu_state_data.error_flags != 0) ||
 702                        (fdm_active->rmr_region.error_flags != 0)) {
 703                printk(KERN_ERR "Dump taken by platform is not valid\n");
 704                return -EINVAL;
 705        }
 706        if ((fdm_active->rmr_region.bytes_dumped !=
 707                        fdm_active->rmr_region.source_len) ||
 708                        !fdm_active->cpu_state_data.bytes_dumped) {
 709                printk(KERN_ERR "Dump taken by platform is incomplete\n");
 710                return -EINVAL;
 711        }
 712
 713        /* Validate the fadump crash info header */
 714        fdh = __va(fw_dump.fadumphdr_addr);
 715        if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
 716                printk(KERN_ERR "Crash info header is not valid.\n");
 717                return -EINVAL;
 718        }
 719
 720        rc = fadump_build_cpu_notes(fdm_active);
 721        if (rc)
 722                return rc;
 723
 724        /*
 725         * We are done validating dump info and elfcore header is now ready
 726         * to be exported. set elfcorehdr_addr so that vmcore module will
 727         * export the elfcore header through '/proc/vmcore'.
 728         */
 729        elfcorehdr_addr = fdh->elfcorehdr_addr;
 730
 731        return 0;
 732}
 733
 734static inline void fadump_add_crash_memory(unsigned long long base,
 735                                        unsigned long long end)
 736{
 737        if (base == end)
 738                return;
 739
 740        pr_debug("crash_memory_range[%d] [%#016llx-%#016llx], %#llx bytes\n",
 741                crash_mem_ranges, base, end - 1, (end - base));
 742        crash_memory_ranges[crash_mem_ranges].base = base;
 743        crash_memory_ranges[crash_mem_ranges].size = end - base;
 744        crash_mem_ranges++;
 745}
 746
 747static void fadump_exclude_reserved_area(unsigned long long start,
 748                                        unsigned long long end)
 749{
 750        unsigned long long ra_start, ra_end;
 751
 752        ra_start = fw_dump.reserve_dump_area_start;
 753        ra_end = ra_start + fw_dump.reserve_dump_area_size;
 754
 755        if ((ra_start < end) && (ra_end > start)) {
 756                if ((start < ra_start) && (end > ra_end)) {
 757                        fadump_add_crash_memory(start, ra_start);
 758                        fadump_add_crash_memory(ra_end, end);
 759                } else if (start < ra_start) {
 760                        fadump_add_crash_memory(start, ra_start);
 761                } else if (ra_end < end) {
 762                        fadump_add_crash_memory(ra_end, end);
 763                }
 764        } else
 765                fadump_add_crash_memory(start, end);
 766}
 767
 768static int fadump_init_elfcore_header(char *bufp)
 769{
 770        struct elfhdr *elf;
 771
 772        elf = (struct elfhdr *) bufp;
 773        bufp += sizeof(struct elfhdr);
 774        memcpy(elf->e_ident, ELFMAG, SELFMAG);
 775        elf->e_ident[EI_CLASS] = ELF_CLASS;
 776        elf->e_ident[EI_DATA] = ELF_DATA;
 777        elf->e_ident[EI_VERSION] = EV_CURRENT;
 778        elf->e_ident[EI_OSABI] = ELF_OSABI;
 779        memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
 780        elf->e_type = ET_CORE;
 781        elf->e_machine = ELF_ARCH;
 782        elf->e_version = EV_CURRENT;
 783        elf->e_entry = 0;
 784        elf->e_phoff = sizeof(struct elfhdr);
 785        elf->e_shoff = 0;
 786#if defined(_CALL_ELF)
 787        elf->e_flags = _CALL_ELF;
 788#else
 789        elf->e_flags = 0;
 790#endif
 791        elf->e_ehsize = sizeof(struct elfhdr);
 792        elf->e_phentsize = sizeof(struct elf_phdr);
 793        elf->e_phnum = 0;
 794        elf->e_shentsize = 0;
 795        elf->e_shnum = 0;
 796        elf->e_shstrndx = 0;
 797
 798        return 0;
 799}
 800
 801/*
 802 * Traverse through memblock structure and setup crash memory ranges. These
 803 * ranges will be used create PT_LOAD program headers in elfcore header.
 804 */
 805static void fadump_setup_crash_memory_ranges(void)
 806{
 807        struct memblock_region *reg;
 808        unsigned long long start, end;
 809
 810        pr_debug("Setup crash memory ranges.\n");
 811        crash_mem_ranges = 0;
 812        /*
 813         * add the first memory chunk (RMA_START through boot_memory_size) as
 814         * a separate memory chunk. The reason is, at the time crash firmware
 815         * will move the content of this memory chunk to different location
 816         * specified during fadump registration. We need to create a separate
 817         * program header for this chunk with the correct offset.
 818         */
 819        fadump_add_crash_memory(RMA_START, fw_dump.boot_memory_size);
 820
 821        for_each_memblock(memory, reg) {
 822                start = (unsigned long long)reg->base;
 823                end = start + (unsigned long long)reg->size;
 824                if (start == RMA_START && end >= fw_dump.boot_memory_size)
 825                        start = fw_dump.boot_memory_size;
 826
 827                /* add this range excluding the reserved dump area. */
 828                fadump_exclude_reserved_area(start, end);
 829        }
 830}
 831
 832/*
 833 * If the given physical address falls within the boot memory region then
 834 * return the relocated address that points to the dump region reserved
 835 * for saving initial boot memory contents.
 836 */
 837static inline unsigned long fadump_relocate(unsigned long paddr)
 838{
 839        if (paddr > RMA_START && paddr < fw_dump.boot_memory_size)
 840                return be64_to_cpu(fdm.rmr_region.destination_address) + paddr;
 841        else
 842                return paddr;
 843}
 844
 845static int fadump_create_elfcore_headers(char *bufp)
 846{
 847        struct elfhdr *elf;
 848        struct elf_phdr *phdr;
 849        int i;
 850
 851        fadump_init_elfcore_header(bufp);
 852        elf = (struct elfhdr *)bufp;
 853        bufp += sizeof(struct elfhdr);
 854
 855        /*
 856         * setup ELF PT_NOTE, place holder for cpu notes info. The notes info
 857         * will be populated during second kernel boot after crash. Hence
 858         * this PT_NOTE will always be the first elf note.
 859         *
 860         * NOTE: Any new ELF note addition should be placed after this note.
 861         */
 862        phdr = (struct elf_phdr *)bufp;
 863        bufp += sizeof(struct elf_phdr);
 864        phdr->p_type = PT_NOTE;
 865        phdr->p_flags = 0;
 866        phdr->p_vaddr = 0;
 867        phdr->p_align = 0;
 868
 869        phdr->p_offset = 0;
 870        phdr->p_paddr = 0;
 871        phdr->p_filesz = 0;
 872        phdr->p_memsz = 0;
 873
 874        (elf->e_phnum)++;
 875
 876        /* setup ELF PT_NOTE for vmcoreinfo */
 877        phdr = (struct elf_phdr *)bufp;
 878        bufp += sizeof(struct elf_phdr);
 879        phdr->p_type    = PT_NOTE;
 880        phdr->p_flags   = 0;
 881        phdr->p_vaddr   = 0;
 882        phdr->p_align   = 0;
 883
 884        phdr->p_paddr   = fadump_relocate(paddr_vmcoreinfo_note());
 885        phdr->p_offset  = phdr->p_paddr;
 886        phdr->p_memsz   = vmcoreinfo_max_size;
 887        phdr->p_filesz  = vmcoreinfo_max_size;
 888
 889        /* Increment number of program headers. */
 890        (elf->e_phnum)++;
 891
 892        /* setup PT_LOAD sections. */
 893
 894        for (i = 0; i < crash_mem_ranges; i++) {
 895                unsigned long long mbase, msize;
 896                mbase = crash_memory_ranges[i].base;
 897                msize = crash_memory_ranges[i].size;
 898
 899                if (!msize)
 900                        continue;
 901
 902                phdr = (struct elf_phdr *)bufp;
 903                bufp += sizeof(struct elf_phdr);
 904                phdr->p_type    = PT_LOAD;
 905                phdr->p_flags   = PF_R|PF_W|PF_X;
 906                phdr->p_offset  = mbase;
 907
 908                if (mbase == RMA_START) {
 909                        /*
 910                         * The entire RMA region will be moved by firmware
 911                         * to the specified destination_address. Hence set
 912                         * the correct offset.
 913                         */
 914                        phdr->p_offset = be64_to_cpu(fdm.rmr_region.destination_address);
 915                }
 916
 917                phdr->p_paddr = mbase;
 918                phdr->p_vaddr = (unsigned long)__va(mbase);
 919                phdr->p_filesz = msize;
 920                phdr->p_memsz = msize;
 921                phdr->p_align = 0;
 922
 923                /* Increment number of program headers. */
 924                (elf->e_phnum)++;
 925        }
 926        return 0;
 927}
 928
 929static unsigned long init_fadump_header(unsigned long addr)
 930{
 931        struct fadump_crash_info_header *fdh;
 932
 933        if (!addr)
 934                return 0;
 935
 936        fw_dump.fadumphdr_addr = addr;
 937        fdh = __va(addr);
 938        addr += sizeof(struct fadump_crash_info_header);
 939
 940        memset(fdh, 0, sizeof(struct fadump_crash_info_header));
 941        fdh->magic_number = FADUMP_CRASH_INFO_MAGIC;
 942        fdh->elfcorehdr_addr = addr;
 943        /* We will set the crashing cpu id in crash_fadump() during crash. */
 944        fdh->crashing_cpu = CPU_UNKNOWN;
 945
 946        return addr;
 947}
 948
 949static void register_fadump(void)
 950{
 951        unsigned long addr;
 952        void *vaddr;
 953
 954        /*
 955         * If no memory is reserved then we can not register for firmware-
 956         * assisted dump.
 957         */
 958        if (!fw_dump.reserve_dump_area_size)
 959                return;
 960
 961        fadump_setup_crash_memory_ranges();
 962
 963        addr = be64_to_cpu(fdm.rmr_region.destination_address) + be64_to_cpu(fdm.rmr_region.source_len);
 964        /* Initialize fadump crash info header. */
 965        addr = init_fadump_header(addr);
 966        vaddr = __va(addr);
 967
 968        pr_debug("Creating ELF core headers at %#016lx\n", addr);
 969        fadump_create_elfcore_headers(vaddr);
 970
 971        /* register the future kernel dump with firmware. */
 972        register_fw_dump(&fdm);
 973}
 974
 975static int fadump_unregister_dump(struct fadump_mem_struct *fdm)
 976{
 977        int rc = 0;
 978        unsigned int wait_time;
 979
 980        pr_debug("Un-register firmware-assisted dump\n");
 981
 982        /* TODO: Add upper time limit for the delay */
 983        do {
 984                rc = rtas_call(fw_dump.ibm_configure_kernel_dump, 3, 1, NULL,
 985                        FADUMP_UNREGISTER, fdm,
 986                        sizeof(struct fadump_mem_struct));
 987
 988                wait_time = rtas_busy_delay_time(rc);
 989                if (wait_time)
 990                        mdelay(wait_time);
 991        } while (wait_time);
 992
 993        if (rc) {
 994                printk(KERN_ERR "Failed to un-register firmware-assisted dump."
 995                        " unexpected error(%d).\n", rc);
 996                return rc;
 997        }
 998        fw_dump.dump_registered = 0;
 999        return 0;
1000}
1001
1002static int fadump_invalidate_dump(struct fadump_mem_struct *fdm)
1003{
1004        int rc = 0;
1005        unsigned int wait_time;
1006
1007        pr_debug("Invalidating firmware-assisted dump registration\n");
1008
1009        /* TODO: Add upper time limit for the delay */
1010        do {
1011                rc = rtas_call(fw_dump.ibm_configure_kernel_dump, 3, 1, NULL,
1012                        FADUMP_INVALIDATE, fdm,
1013                        sizeof(struct fadump_mem_struct));
1014
1015                wait_time = rtas_busy_delay_time(rc);
1016                if (wait_time)
1017                        mdelay(wait_time);
1018        } while (wait_time);
1019
1020        if (rc) {
1021                pr_err("Failed to invalidate firmware-assisted dump registration. Unexpected error (%d).\n", rc);
1022                return rc;
1023        }
1024        fw_dump.dump_active = 0;
1025        fdm_active = NULL;
1026        return 0;
1027}
1028
1029void fadump_cleanup(void)
1030{
1031        /* Invalidate the registration only if dump is active. */
1032        if (fw_dump.dump_active) {
1033                init_fadump_mem_struct(&fdm,
1034                        be64_to_cpu(fdm_active->cpu_state_data.destination_address));
1035                fadump_invalidate_dump(&fdm);
1036        }
1037}
1038
1039/*
1040 * Release the memory that was reserved in early boot to preserve the memory
1041 * contents. The released memory will be available for general use.
1042 */
1043static void fadump_release_memory(unsigned long begin, unsigned long end)
1044{
1045        unsigned long addr;
1046        unsigned long ra_start, ra_end;
1047
1048        ra_start = fw_dump.reserve_dump_area_start;
1049        ra_end = ra_start + fw_dump.reserve_dump_area_size;
1050
1051        for (addr = begin; addr < end; addr += PAGE_SIZE) {
1052                /*
1053                 * exclude the dump reserve area. Will reuse it for next
1054                 * fadump registration.
1055                 */
1056                if (addr <= ra_end && ((addr + PAGE_SIZE) > ra_start))
1057                        continue;
1058
1059                free_reserved_page(pfn_to_page(addr >> PAGE_SHIFT));
1060        }
1061}
1062
1063static void fadump_invalidate_release_mem(void)
1064{
1065        unsigned long reserved_area_start, reserved_area_end;
1066        unsigned long destination_address;
1067
1068        mutex_lock(&fadump_mutex);
1069        if (!fw_dump.dump_active) {
1070                mutex_unlock(&fadump_mutex);
1071                return;
1072        }
1073
1074        destination_address = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
1075        fadump_cleanup();
1076        mutex_unlock(&fadump_mutex);
1077
1078        /*
1079         * Save the current reserved memory bounds we will require them
1080         * later for releasing the memory for general use.
1081         */
1082        reserved_area_start = fw_dump.reserve_dump_area_start;
1083        reserved_area_end = reserved_area_start +
1084                        fw_dump.reserve_dump_area_size;
1085        /*
1086         * Setup reserve_dump_area_start and its size so that we can
1087         * reuse this reserved memory for Re-registration.
1088         */
1089        fw_dump.reserve_dump_area_start = destination_address;
1090        fw_dump.reserve_dump_area_size = get_fadump_area_size();
1091
1092        fadump_release_memory(reserved_area_start, reserved_area_end);
1093        if (fw_dump.cpu_notes_buf) {
1094                fadump_cpu_notes_buf_free(
1095                                (unsigned long)__va(fw_dump.cpu_notes_buf),
1096                                fw_dump.cpu_notes_buf_size);
1097                fw_dump.cpu_notes_buf = 0;
1098                fw_dump.cpu_notes_buf_size = 0;
1099        }
1100        /* Initialize the kernel dump memory structure for FAD registration. */
1101        init_fadump_mem_struct(&fdm, fw_dump.reserve_dump_area_start);
1102}
1103
1104static ssize_t fadump_release_memory_store(struct kobject *kobj,
1105                                        struct kobj_attribute *attr,
1106                                        const char *buf, size_t count)
1107{
1108        if (!fw_dump.dump_active)
1109                return -EPERM;
1110
1111        if (buf[0] == '1') {
1112                /*
1113                 * Take away the '/proc/vmcore'. We are releasing the dump
1114                 * memory, hence it will not be valid anymore.
1115                 */
1116#ifdef CONFIG_PROC_VMCORE
1117                vmcore_cleanup();
1118#endif
1119                fadump_invalidate_release_mem();
1120
1121        } else
1122                return -EINVAL;
1123        return count;
1124}
1125
1126static ssize_t fadump_enabled_show(struct kobject *kobj,
1127                                        struct kobj_attribute *attr,
1128                                        char *buf)
1129{
1130        return sprintf(buf, "%d\n", fw_dump.fadump_enabled);
1131}
1132
1133static ssize_t fadump_register_show(struct kobject *kobj,
1134                                        struct kobj_attribute *attr,
1135                                        char *buf)
1136{
1137        return sprintf(buf, "%d\n", fw_dump.dump_registered);
1138}
1139
1140static ssize_t fadump_register_store(struct kobject *kobj,
1141                                        struct kobj_attribute *attr,
1142                                        const char *buf, size_t count)
1143{
1144        int ret = 0;
1145
1146        if (!fw_dump.fadump_enabled || fdm_active)
1147                return -EPERM;
1148
1149        mutex_lock(&fadump_mutex);
1150
1151        switch (buf[0]) {
1152        case '0':
1153                if (fw_dump.dump_registered == 0) {
1154                        ret = -EINVAL;
1155                        goto unlock_out;
1156                }
1157                /* Un-register Firmware-assisted dump */
1158                fadump_unregister_dump(&fdm);
1159                break;
1160        case '1':
1161                if (fw_dump.dump_registered == 1) {
1162                        ret = -EINVAL;
1163                        goto unlock_out;
1164                }
1165                /* Register Firmware-assisted dump */
1166                register_fadump();
1167                break;
1168        default:
1169                ret = -EINVAL;
1170                break;
1171        }
1172
1173unlock_out:
1174        mutex_unlock(&fadump_mutex);
1175        return ret < 0 ? ret : count;
1176}
1177
1178static int fadump_region_show(struct seq_file *m, void *private)
1179{
1180        const struct fadump_mem_struct *fdm_ptr;
1181
1182        if (!fw_dump.fadump_enabled)
1183                return 0;
1184
1185        mutex_lock(&fadump_mutex);
1186        if (fdm_active)
1187                fdm_ptr = fdm_active;
1188        else {
1189                mutex_unlock(&fadump_mutex);
1190                fdm_ptr = &fdm;
1191        }
1192
1193        seq_printf(m,
1194                        "CPU : [%#016llx-%#016llx] %#llx bytes, "
1195                        "Dumped: %#llx\n",
1196                        be64_to_cpu(fdm_ptr->cpu_state_data.destination_address),
1197                        be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) +
1198                        be64_to_cpu(fdm_ptr->cpu_state_data.source_len) - 1,
1199                        be64_to_cpu(fdm_ptr->cpu_state_data.source_len),
1200                        be64_to_cpu(fdm_ptr->cpu_state_data.bytes_dumped));
1201        seq_printf(m,
1202                        "HPTE: [%#016llx-%#016llx] %#llx bytes, "
1203                        "Dumped: %#llx\n",
1204                        be64_to_cpu(fdm_ptr->hpte_region.destination_address),
1205                        be64_to_cpu(fdm_ptr->hpte_region.destination_address) +
1206                        be64_to_cpu(fdm_ptr->hpte_region.source_len) - 1,
1207                        be64_to_cpu(fdm_ptr->hpte_region.source_len),
1208                        be64_to_cpu(fdm_ptr->hpte_region.bytes_dumped));
1209        seq_printf(m,
1210                        "DUMP: [%#016llx-%#016llx] %#llx bytes, "
1211                        "Dumped: %#llx\n",
1212                        be64_to_cpu(fdm_ptr->rmr_region.destination_address),
1213                        be64_to_cpu(fdm_ptr->rmr_region.destination_address) +
1214                        be64_to_cpu(fdm_ptr->rmr_region.source_len) - 1,
1215                        be64_to_cpu(fdm_ptr->rmr_region.source_len),
1216                        be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
1217
1218        if (!fdm_active ||
1219                (fw_dump.reserve_dump_area_start ==
1220                be64_to_cpu(fdm_ptr->cpu_state_data.destination_address)))
1221                goto out;
1222
1223        /* Dump is active. Show reserved memory region. */
1224        seq_printf(m,
1225                        "    : [%#016llx-%#016llx] %#llx bytes, "
1226                        "Dumped: %#llx\n",
1227                        (unsigned long long)fw_dump.reserve_dump_area_start,
1228                        be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) - 1,
1229                        be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
1230                        fw_dump.reserve_dump_area_start,
1231                        be64_to_cpu(fdm_ptr->cpu_state_data.destination_address) -
1232                        fw_dump.reserve_dump_area_start);
1233out:
1234        if (fdm_active)
1235                mutex_unlock(&fadump_mutex);
1236        return 0;
1237}
1238
1239static struct kobj_attribute fadump_release_attr = __ATTR(fadump_release_mem,
1240                                                0200, NULL,
1241                                                fadump_release_memory_store);
1242static struct kobj_attribute fadump_attr = __ATTR(fadump_enabled,
1243                                                0444, fadump_enabled_show,
1244                                                NULL);
1245static struct kobj_attribute fadump_register_attr = __ATTR(fadump_registered,
1246                                                0644, fadump_register_show,
1247                                                fadump_register_store);
1248
1249static int fadump_region_open(struct inode *inode, struct file *file)
1250{
1251        return single_open(file, fadump_region_show, inode->i_private);
1252}
1253
1254static const struct file_operations fadump_region_fops = {
1255        .open    = fadump_region_open,
1256        .read    = seq_read,
1257        .llseek  = seq_lseek,
1258        .release = single_release,
1259};
1260
1261static void fadump_init_files(void)
1262{
1263        struct dentry *debugfs_file;
1264        int rc = 0;
1265
1266        rc = sysfs_create_file(kernel_kobj, &fadump_attr.attr);
1267        if (rc)
1268                printk(KERN_ERR "fadump: unable to create sysfs file"
1269                        " fadump_enabled (%d)\n", rc);
1270
1271        rc = sysfs_create_file(kernel_kobj, &fadump_register_attr.attr);
1272        if (rc)
1273                printk(KERN_ERR "fadump: unable to create sysfs file"
1274                        " fadump_registered (%d)\n", rc);
1275
1276        debugfs_file = debugfs_create_file("fadump_region", 0444,
1277                                        powerpc_debugfs_root, NULL,
1278                                        &fadump_region_fops);
1279        if (!debugfs_file)
1280                printk(KERN_ERR "fadump: unable to create debugfs file"
1281                                " fadump_region\n");
1282
1283        if (fw_dump.dump_active) {
1284                rc = sysfs_create_file(kernel_kobj, &fadump_release_attr.attr);
1285                if (rc)
1286                        printk(KERN_ERR "fadump: unable to create sysfs file"
1287                                " fadump_release_mem (%d)\n", rc);
1288        }
1289        return;
1290}
1291
1292/*
1293 * Prepare for firmware-assisted dump.
1294 */
1295int __init setup_fadump(void)
1296{
1297        if (!fw_dump.fadump_enabled)
1298                return 0;
1299
1300        if (!fw_dump.fadump_supported) {
1301                printk(KERN_ERR "Firmware-assisted dump is not supported on"
1302                        " this hardware\n");
1303                return 0;
1304        }
1305
1306        fadump_show_config();
1307        /*
1308         * If dump data is available then see if it is valid and prepare for
1309         * saving it to the disk.
1310         */
1311        if (fw_dump.dump_active) {
1312                /*
1313                 * if dump process fails then invalidate the registration
1314                 * and release memory before proceeding for re-registration.
1315                 */
1316                if (process_fadump(fdm_active) < 0)
1317                        fadump_invalidate_release_mem();
1318        }
1319        /* Initialize the kernel dump memory structure for FAD registration. */
1320        else if (fw_dump.reserve_dump_area_size)
1321                init_fadump_mem_struct(&fdm, fw_dump.reserve_dump_area_start);
1322        fadump_init_files();
1323
1324        return 1;
1325}
1326subsys_initcall(setup_fadump);
1327