Path: blob/master/arch/powerpc/platforms/pseries/rtas-fadump.c
26481 views
// SPDX-License-Identifier: GPL-2.0-or-later1/*2* Firmware-Assisted Dump support on POWERVM platform.3*4* Copyright 2011, Mahesh Salgaonkar, IBM Corporation.5* Copyright 2019, Hari Bathini, IBM Corporation.6*/78#define pr_fmt(fmt) "rtas fadump: " fmt910#include <linux/string.h>11#include <linux/memblock.h>12#include <linux/delay.h>13#include <linux/seq_file.h>14#include <linux/crash_dump.h>15#include <linux/of.h>16#include <linux/of_fdt.h>1718#include <asm/page.h>19#include <asm/rtas.h>20#include <asm/setup.h>21#include <asm/fadump.h>22#include <asm/fadump-internal.h>2324#include "rtas-fadump.h"2526static struct rtas_fadump_mem_struct fdm;27static const struct rtas_fadump_mem_struct *fdm_active;2829static void rtas_fadump_update_config(struct fw_dump *fadump_conf,30const struct rtas_fadump_mem_struct *fdm)31{32fadump_conf->fadumphdr_addr = (fadump_conf->boot_mem_dest_addr +33fadump_conf->boot_memory_size);34}3536/*37* This function is called in the capture kernel to get configuration details38* setup in the first kernel and passed to the f/w.39*/40static void __init rtas_fadump_get_config(struct fw_dump *fadump_conf,41const struct rtas_fadump_mem_struct *fdm)42{43unsigned long base, size, last_end, hole_size;4445last_end = 0;46hole_size = 0;47fadump_conf->boot_memory_size = 0;48fadump_conf->boot_mem_regs_cnt = 0;49pr_debug("Boot memory regions:\n");50for (int i = 0; i < be16_to_cpu(fdm->header.dump_num_sections); i++) {51int type = be16_to_cpu(fdm->rgn[i].source_data_type);52u64 addr;5354switch (type) {55case RTAS_FADUMP_CPU_STATE_DATA:56addr = be64_to_cpu(fdm->rgn[i].destination_address);5758fadump_conf->cpu_state_dest_vaddr = (u64)__va(addr);59/*60* Start address of reserve dump area (permanent reservation) for61* re-registering FADump after dump capture.62*/63fadump_conf->reserve_dump_area_start = addr;64break;65case RTAS_FADUMP_HPTE_REGION:66/* Not processed currently. */67break;68case RTAS_FADUMP_REAL_MODE_REGION:69base = be64_to_cpu(fdm->rgn[i].source_address);70size = be64_to_cpu(fdm->rgn[i].source_len);71pr_debug("\t[%03d] base: 0x%lx, size: 0x%lx\n", i, base, size);72if (!base) {73fadump_conf->boot_mem_dest_addr =74be64_to_cpu(fdm->rgn[i].destination_address);75}7677fadump_conf->boot_mem_addr[fadump_conf->boot_mem_regs_cnt] = base;78fadump_conf->boot_mem_sz[fadump_conf->boot_mem_regs_cnt] = size;79fadump_conf->boot_memory_size += size;80hole_size += (base - last_end);81last_end = base + size;82fadump_conf->boot_mem_regs_cnt++;83break;84case RTAS_FADUMP_PARAM_AREA:85fadump_conf->param_area = be64_to_cpu(fdm->rgn[i].destination_address);86break;87default:88pr_warn("Section type %d unsupported on this kernel. Ignoring!\n", type);89break;90}91}92fadump_conf->boot_mem_top = fadump_conf->boot_memory_size + hole_size;9394rtas_fadump_update_config(fadump_conf, fdm);95}9697static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)98{99u64 addr = fadump_conf->reserve_dump_area_start;100u16 sec_cnt = 0;101102memset(&fdm, 0, sizeof(struct rtas_fadump_mem_struct));103addr = addr & PAGE_MASK;104105fdm.header.dump_format_version = cpu_to_be32(0x00000001);106fdm.header.dump_status_flag = 0;107fdm.header.offset_first_dump_section =108cpu_to_be32((u32)offsetof(struct rtas_fadump_mem_struct, rgn));109110/*111* Fields for disk dump option.112* We are not using disk dump option, hence set these fields to 0.113*/114fdm.header.dd_block_size = 0;115fdm.header.dd_block_offset = 0;116fdm.header.dd_num_blocks = 0;117fdm.header.dd_offset_disk_path = 0;118119/* set 0 to disable an automatic dump-reboot. */120fdm.header.max_time_auto = 0;121122/* Kernel dump sections */123/* cpu state data section. */124fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);125fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_CPU_STATE_DATA);126fdm.rgn[sec_cnt].source_address = 0;127fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->cpu_state_data_size);128fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);129addr += fadump_conf->cpu_state_data_size;130sec_cnt++;131132/* hpte region section */133fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);134fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_HPTE_REGION);135fdm.rgn[sec_cnt].source_address = 0;136fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->hpte_region_size);137fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);138addr += fadump_conf->hpte_region_size;139sec_cnt++;140141/*142* Align boot memory area destination address to page boundary to143* be able to mmap read this area in the vmcore.144*/145addr = PAGE_ALIGN(addr);146147/* First boot memory region destination address */148fadump_conf->boot_mem_dest_addr = addr;149for (int i = 0; i < fadump_conf->boot_mem_regs_cnt; i++) {150/* Boot memory regions */151fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);152fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_REAL_MODE_REGION);153fdm.rgn[sec_cnt].source_address = cpu_to_be64(fadump_conf->boot_mem_addr[i]);154fdm.rgn[sec_cnt].source_len = cpu_to_be64(fadump_conf->boot_mem_sz[i]);155fdm.rgn[sec_cnt].destination_address = cpu_to_be64(addr);156addr += fadump_conf->boot_mem_sz[i];157sec_cnt++;158}159160/* Parameters area */161if (fadump_conf->param_area) {162fdm.rgn[sec_cnt].request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);163fdm.rgn[sec_cnt].source_data_type = cpu_to_be16(RTAS_FADUMP_PARAM_AREA);164fdm.rgn[sec_cnt].source_address = cpu_to_be64(fadump_conf->param_area);165fdm.rgn[sec_cnt].source_len = cpu_to_be64(COMMAND_LINE_SIZE);166fdm.rgn[sec_cnt].destination_address = cpu_to_be64(fadump_conf->param_area);167sec_cnt++;168}169fdm.header.dump_num_sections = cpu_to_be16(sec_cnt);170171rtas_fadump_update_config(fadump_conf, &fdm);172173return addr;174}175176static u64 rtas_fadump_get_bootmem_min(void)177{178return RTAS_FADUMP_MIN_BOOT_MEM;179}180181static int rtas_fadump_register(struct fw_dump *fadump_conf)182{183unsigned int wait_time, fdm_size;184int rc, err = -EIO;185186/*187* Platform requires the exact size of the Dump Memory Structure.188* Avoid including any unused rgns in the calculation, as this189* could result in a parameter error (-3) from the platform.190*/191fdm_size = sizeof(struct rtas_fadump_section_header);192fdm_size += be16_to_cpu(fdm.header.dump_num_sections) * sizeof(struct rtas_fadump_section);193194/* TODO: Add upper time limit for the delay */195do {196rc = rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,197NULL, FADUMP_REGISTER, &fdm, fdm_size);198199wait_time = rtas_busy_delay_time(rc);200if (wait_time)201mdelay(wait_time);202203} while (wait_time);204205switch (rc) {206case 0:207pr_info("Registration is successful!\n");208fadump_conf->dump_registered = 1;209err = 0;210break;211case -1:212pr_err("Failed to register. Hardware Error(%d).\n", rc);213break;214case -3:215if (!is_fadump_reserved_mem_contiguous())216pr_err("Can't have holes in reserved memory area.\n");217218pr_err("Failed to register. Parameter Error(%d).\n", rc);219err = -EINVAL;220break;221case -9:222pr_err("Already registered!\n");223fadump_conf->dump_registered = 1;224err = -EEXIST;225break;226default:227pr_err("Failed to register. Unknown Error(%d).\n", rc);228break;229}230231return err;232}233234static int rtas_fadump_unregister(struct fw_dump *fadump_conf)235{236unsigned int wait_time;237int rc;238239/* TODO: Add upper time limit for the delay */240do {241rc = rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,242NULL, FADUMP_UNREGISTER, &fdm,243sizeof(struct rtas_fadump_mem_struct));244245wait_time = rtas_busy_delay_time(rc);246if (wait_time)247mdelay(wait_time);248} while (wait_time);249250if (rc) {251pr_err("Failed to un-register - unexpected error(%d).\n", rc);252return -EIO;253}254255fadump_conf->dump_registered = 0;256return 0;257}258259static int rtas_fadump_invalidate(struct fw_dump *fadump_conf)260{261unsigned int wait_time;262int rc;263264/* TODO: Add upper time limit for the delay */265do {266rc = rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,267NULL, FADUMP_INVALIDATE, fdm_active,268sizeof(struct rtas_fadump_mem_struct));269270wait_time = rtas_busy_delay_time(rc);271if (wait_time)272mdelay(wait_time);273} while (wait_time);274275if (rc) {276pr_err("Failed to invalidate - unexpected error (%d).\n", rc);277return -EIO;278}279280fadump_conf->dump_active = 0;281fdm_active = NULL;282return 0;283}284285#define RTAS_FADUMP_GPR_MASK 0xffffff0000000000286static inline int rtas_fadump_gpr_index(u64 id)287{288char str[3];289int i = -1;290291if ((id & RTAS_FADUMP_GPR_MASK) == fadump_str_to_u64("GPR")) {292/* get the digits at the end */293id &= ~RTAS_FADUMP_GPR_MASK;294id >>= 24;295str[2] = '\0';296str[1] = id & 0xff;297str[0] = (id >> 8) & 0xff;298if (kstrtoint(str, 10, &i))299i = -EINVAL;300if (i > 31)301i = -1;302}303return i;304}305306static void __init rtas_fadump_set_regval(struct pt_regs *regs, u64 reg_id, u64 reg_val)307{308int i;309310i = rtas_fadump_gpr_index(reg_id);311if (i >= 0)312regs->gpr[i] = (unsigned long)reg_val;313else if (reg_id == fadump_str_to_u64("NIA"))314regs->nip = (unsigned long)reg_val;315else if (reg_id == fadump_str_to_u64("MSR"))316regs->msr = (unsigned long)reg_val;317else if (reg_id == fadump_str_to_u64("CTR"))318regs->ctr = (unsigned long)reg_val;319else if (reg_id == fadump_str_to_u64("LR"))320regs->link = (unsigned long)reg_val;321else if (reg_id == fadump_str_to_u64("XER"))322regs->xer = (unsigned long)reg_val;323else if (reg_id == fadump_str_to_u64("CR"))324regs->ccr = (unsigned long)reg_val;325else if (reg_id == fadump_str_to_u64("DAR"))326regs->dar = (unsigned long)reg_val;327else if (reg_id == fadump_str_to_u64("DSISR"))328regs->dsisr = (unsigned long)reg_val;329}330331static struct rtas_fadump_reg_entry* __init332rtas_fadump_read_regs(struct rtas_fadump_reg_entry *reg_entry,333struct pt_regs *regs)334{335memset(regs, 0, sizeof(struct pt_regs));336337while (be64_to_cpu(reg_entry->reg_id) != fadump_str_to_u64("CPUEND")) {338rtas_fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),339be64_to_cpu(reg_entry->reg_value));340reg_entry++;341}342reg_entry++;343return reg_entry;344}345346/*347* Read CPU state dump data and convert it into ELF notes.348* The CPU dump starts with magic number "REGSAVE". NumCpusOffset should be349* used to access the data to allow for additional fields to be added without350* affecting compatibility. Each list of registers for a CPU starts with351* "CPUSTRT" and ends with "CPUEND". Each register entry is of 16 bytes,352* 8 Byte ASCII identifier and 8 Byte register value. The register entry353* with identifier "CPUSTRT" and "CPUEND" contains 4 byte cpu id as part354* of register value. For more details refer to PAPR document.355*356* Only for the crashing cpu we ignore the CPU dump data and get exact357* state from fadump crash info structure populated by first kernel at the358* time of crash.359*/360static int __init rtas_fadump_build_cpu_notes(struct fw_dump *fadump_conf)361{362struct rtas_fadump_reg_save_area_header *reg_header;363struct fadump_crash_info_header *fdh = NULL;364struct rtas_fadump_reg_entry *reg_entry;365u32 num_cpus, *note_buf;366int i, rc = 0, cpu = 0;367struct pt_regs regs;368void *vaddr;369370vaddr = (void *)fadump_conf->cpu_state_dest_vaddr;371372reg_header = vaddr;373if (be64_to_cpu(reg_header->magic_number) !=374fadump_str_to_u64("REGSAVE")) {375pr_err("Unable to read register save area.\n");376return -ENOENT;377}378379pr_debug("--------CPU State Data------------\n");380pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));381pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));382383vaddr += be32_to_cpu(reg_header->num_cpu_offset);384num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));385pr_debug("NumCpus : %u\n", num_cpus);386vaddr += sizeof(u32);387reg_entry = (struct rtas_fadump_reg_entry *)vaddr;388389rc = fadump_setup_cpu_notes_buf(num_cpus);390if (rc != 0)391return rc;392393note_buf = (u32 *)fadump_conf->cpu_notes_buf_vaddr;394395if (fadump_conf->fadumphdr_addr)396fdh = __va(fadump_conf->fadumphdr_addr);397398for (i = 0; i < num_cpus; i++) {399if (be64_to_cpu(reg_entry->reg_id) !=400fadump_str_to_u64("CPUSTRT")) {401pr_err("Unable to read CPU state data\n");402rc = -ENOENT;403goto error_out;404}405/* Lower 4 bytes of reg_value contains logical cpu id */406cpu = (be64_to_cpu(reg_entry->reg_value) &407RTAS_FADUMP_CPU_ID_MASK);408if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_mask)) {409RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);410continue;411}412pr_debug("Reading register data for cpu %d...\n", cpu);413if (fdh && fdh->crashing_cpu == cpu) {414regs = fdh->regs;415note_buf = fadump_regs_to_elf_notes(note_buf, ®s);416RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);417} else {418reg_entry++;419reg_entry = rtas_fadump_read_regs(reg_entry, ®s);420note_buf = fadump_regs_to_elf_notes(note_buf, ®s);421}422}423final_note(note_buf);424425pr_debug("Updating elfcore header (%llx) with cpu notes\n", fadump_conf->elfcorehdr_addr);426fadump_update_elfcore_header((char *)fadump_conf->elfcorehdr_addr);427return 0;428429error_out:430fadump_free_cpu_notes_buf();431return rc;432433}434435/*436* Validate and process the dump data stored by the firmware, and update437* the CPU notes of elfcorehdr.438*/439static int __init rtas_fadump_process(struct fw_dump *fadump_conf)440{441if (!fdm_active || !fadump_conf->fadumphdr_addr)442return -EINVAL;443444/* Check if the dump data is valid. */445for (int i = 0; i < be16_to_cpu(fdm_active->header.dump_num_sections); i++) {446int type = be16_to_cpu(fdm_active->rgn[i].source_data_type);447int rc = 0;448449switch (type) {450case RTAS_FADUMP_CPU_STATE_DATA:451case RTAS_FADUMP_HPTE_REGION:452case RTAS_FADUMP_REAL_MODE_REGION:453if (fdm_active->rgn[i].error_flags != 0) {454pr_err("Dump taken by platform is not valid (%d)\n", i);455rc = -EINVAL;456}457if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len) {458pr_err("Dump taken by platform is incomplete (%d)\n", i);459rc = -EINVAL;460}461if (rc) {462pr_warn("Region type: %u src addr: 0x%llx dest addr: 0x%llx\n",463be16_to_cpu(fdm_active->rgn[i].source_data_type),464be64_to_cpu(fdm_active->rgn[i].source_address),465be64_to_cpu(fdm_active->rgn[i].destination_address));466return rc;467}468break;469case RTAS_FADUMP_PARAM_AREA:470if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len ||471fdm_active->rgn[i].error_flags != 0) {472pr_warn("Failed to process additional parameters! Proceeding anyway..\n");473fadump_conf->param_area = 0;474}475break;476default:477/*478* If the first/crashed kernel added a new region type that the479* second/fadump kernel doesn't recognize, skip it and process480* assuming backward compatibility.481*/482pr_warn("Unknown region found: type: %u src addr: 0x%llx dest addr: 0x%llx\n",483be16_to_cpu(fdm_active->rgn[i].source_data_type),484be64_to_cpu(fdm_active->rgn[i].source_address),485be64_to_cpu(fdm_active->rgn[i].destination_address));486break;487}488}489490return rtas_fadump_build_cpu_notes(fadump_conf);491}492493static void rtas_fadump_region_show(struct fw_dump *fadump_conf,494struct seq_file *m)495{496const struct rtas_fadump_mem_struct *fdm_ptr;497498if (fdm_active)499fdm_ptr = fdm_active;500else501fdm_ptr = &fdm;502503504for (int i = 0; i < be16_to_cpu(fdm_ptr->header.dump_num_sections); i++) {505int type = be16_to_cpu(fdm_ptr->rgn[i].source_data_type);506507switch (type) {508case RTAS_FADUMP_CPU_STATE_DATA:509seq_printf(m, "CPU :[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",510be64_to_cpu(fdm_ptr->rgn[i].destination_address),511be64_to_cpu(fdm_ptr->rgn[i].destination_address) +512be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,513be64_to_cpu(fdm_ptr->rgn[i].source_len),514be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));515break;516case RTAS_FADUMP_HPTE_REGION:517seq_printf(m, "HPTE:[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",518be64_to_cpu(fdm_ptr->rgn[i].destination_address),519be64_to_cpu(fdm_ptr->rgn[i].destination_address) +520be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,521be64_to_cpu(fdm_ptr->rgn[i].source_len),522be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));523break;524case RTAS_FADUMP_REAL_MODE_REGION:525seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ",526be64_to_cpu(fdm_ptr->rgn[i].source_address),527be64_to_cpu(fdm_ptr->rgn[i].destination_address));528seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n",529be64_to_cpu(fdm_ptr->rgn[i].source_len),530be64_to_cpu(fdm_ptr->rgn[i].bytes_dumped));531break;532case RTAS_FADUMP_PARAM_AREA:533seq_printf(m, "\n[%#016llx-%#016llx]: cmdline append: '%s'\n",534be64_to_cpu(fdm_ptr->rgn[i].destination_address),535be64_to_cpu(fdm_ptr->rgn[i].destination_address) +536be64_to_cpu(fdm_ptr->rgn[i].source_len) - 1,537(char *)__va(be64_to_cpu(fdm_ptr->rgn[i].destination_address)));538break;539default:540seq_printf(m, "Unknown region type %d : Src: %#016llx, Dest: %#016llx, ",541type, be64_to_cpu(fdm_ptr->rgn[i].source_address),542be64_to_cpu(fdm_ptr->rgn[i].destination_address));543break;544}545}546547/* Dump is active. Show preserved area start address. */548if (fdm_active) {549seq_printf(m, "\nMemory above %#016llx is reserved for saving crash dump\n",550fadump_conf->boot_mem_top);551}552}553554static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh,555const char *msg)556{557/* Call ibm,os-term rtas call to trigger firmware assisted dump */558rtas_os_term((char *)msg);559}560561/* FADUMP_MAX_MEM_REGS or lower */562static int rtas_fadump_max_boot_mem_rgns(void)563{564/*565* Version 1 of Kernel Assisted Dump Memory Structure (PAPR) supports 10 sections.566* With one each section taken for CPU state data & HPTE respectively, 8 sections567* can be used for boot memory regions.568*569* If new region(s) is(are) defined, maximum boot memory regions will decrease570* proportionally.571*/572return RTAS_FADUMP_MAX_BOOT_MEM_REGS;573}574575static struct fadump_ops rtas_fadump_ops = {576.fadump_init_mem_struct = rtas_fadump_init_mem_struct,577.fadump_get_bootmem_min = rtas_fadump_get_bootmem_min,578.fadump_register = rtas_fadump_register,579.fadump_unregister = rtas_fadump_unregister,580.fadump_invalidate = rtas_fadump_invalidate,581.fadump_process = rtas_fadump_process,582.fadump_region_show = rtas_fadump_region_show,583.fadump_trigger = rtas_fadump_trigger,584.fadump_max_boot_mem_rgns = rtas_fadump_max_boot_mem_rgns,585};586587void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)588{589int i, size, num_sections;590const __be32 *sections;591const __be32 *token;592593/*594* Check if Firmware Assisted dump is supported. if yes, check595* if dump has been initiated on last reboot.596*/597token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL);598if (!token)599return;600601fadump_conf->ibm_configure_kernel_dump = be32_to_cpu(*token);602fadump_conf->ops = &rtas_fadump_ops;603fadump_conf->fadump_supported = 1;604fadump_conf->param_area_supported = 1;605606/* Firmware supports 64-bit value for size, align it to pagesize. */607fadump_conf->max_copy_size = ALIGN_DOWN(U64_MAX, PAGE_SIZE);608609/*610* The 'ibm,kernel-dump' rtas node is present only if there is611* dump data waiting for us.612*/613fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);614if (fdm_active) {615pr_info("Firmware-assisted dump is active.\n");616fadump_conf->dump_active = 1;617rtas_fadump_get_config(fadump_conf, (void *)__pa(fdm_active));618}619620/* Get the sizes required to store dump data for the firmware provided621* dump sections.622* For each dump section type supported, a 32bit cell which defines623* the ID of a supported section followed by two 32 bit cells which624* gives the size of the section in bytes.625*/626sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",627&size);628629if (!sections)630return;631632num_sections = size / (3 * sizeof(u32));633634for (i = 0; i < num_sections; i++, sections += 3) {635u32 type = (u32)of_read_number(sections, 1);636637switch (type) {638case RTAS_FADUMP_CPU_STATE_DATA:639fadump_conf->cpu_state_data_size =640of_read_ulong(§ions[1], 2);641break;642case RTAS_FADUMP_HPTE_REGION:643fadump_conf->hpte_region_size =644of_read_ulong(§ions[1], 2);645break;646}647}648}649650651