1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Firmware-Assisted Dump support on POWERVM platform.
4  *
5  * Copyright 2011, Mahesh Salgaonkar, IBM Corporation.
6  * Copyright 2019, Hari Bathini, IBM Corporation.
7  */
8 
9 #define pr_fmt(fmt) "rtas fadump: " fmt
10 
11 #include <linux/string.h>
12 #include <linux/memblock.h>
13 #include <linux/delay.h>
14 #include <linux/seq_file.h>
15 #include <linux/crash_dump.h>
16 
17 #include <asm/page.h>
18 #include <asm/prom.h>
19 #include <asm/rtas.h>
20 #include <asm/fadump.h>
21 #include <asm/fadump-internal.h>
22 
23 #include "rtas-fadump.h"
24 
25 static struct rtas_fadump_mem_struct fdm;
26 static const struct rtas_fadump_mem_struct *fdm_active;
27 
28 static void rtas_fadump_update_config(struct fw_dump *fadump_conf,
29 				      const struct rtas_fadump_mem_struct *fdm)
30 {
31 	fadump_conf->boot_mem_dest_addr =
32 		be64_to_cpu(fdm->rmr_region.destination_address);
33 
34 	fadump_conf->fadumphdr_addr = (fadump_conf->boot_mem_dest_addr +
35 				       fadump_conf->boot_memory_size);
36 }
37 
38 /*
39  * This function is called in the capture kernel to get configuration details
40  * setup in the first kernel and passed to the f/w.
41  */
42 static void __init rtas_fadump_get_config(struct fw_dump *fadump_conf,
43 				   const struct rtas_fadump_mem_struct *fdm)
44 {
45 	fadump_conf->boot_mem_addr[0] =
46 		be64_to_cpu(fdm->rmr_region.source_address);
47 	fadump_conf->boot_mem_sz[0] = be64_to_cpu(fdm->rmr_region.source_len);
48 	fadump_conf->boot_memory_size = fadump_conf->boot_mem_sz[0];
49 
50 	fadump_conf->boot_mem_top = fadump_conf->boot_memory_size;
51 	fadump_conf->boot_mem_regs_cnt = 1;
52 
53 	/*
54 	 * Start address of reserve dump area (permanent reservation) for
55 	 * re-registering FADump after dump capture.
56 	 */
57 	fadump_conf->reserve_dump_area_start =
58 		be64_to_cpu(fdm->cpu_state_data.destination_address);
59 
60 	rtas_fadump_update_config(fadump_conf, fdm);
61 }
62 
63 static u64 rtas_fadump_init_mem_struct(struct fw_dump *fadump_conf)
64 {
65 	u64 addr = fadump_conf->reserve_dump_area_start;
66 
67 	memset(&fdm, 0, sizeof(struct rtas_fadump_mem_struct));
68 	addr = addr & PAGE_MASK;
69 
70 	fdm.header.dump_format_version = cpu_to_be32(0x00000001);
71 	fdm.header.dump_num_sections = cpu_to_be16(3);
72 	fdm.header.dump_status_flag = 0;
73 	fdm.header.offset_first_dump_section =
74 		cpu_to_be32((u32)offsetof(struct rtas_fadump_mem_struct,
75 					  cpu_state_data));
76 
77 	/*
78 	 * Fields for disk dump option.
79 	 * We are not using disk dump option, hence set these fields to 0.
80 	 */
81 	fdm.header.dd_block_size = 0;
82 	fdm.header.dd_block_offset = 0;
83 	fdm.header.dd_num_blocks = 0;
84 	fdm.header.dd_offset_disk_path = 0;
85 
86 	/* set 0 to disable an automatic dump-reboot. */
87 	fdm.header.max_time_auto = 0;
88 
89 	/* Kernel dump sections */
90 	/* cpu state data section. */
91 	fdm.cpu_state_data.request_flag =
92 		cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
93 	fdm.cpu_state_data.source_data_type =
94 		cpu_to_be16(RTAS_FADUMP_CPU_STATE_DATA);
95 	fdm.cpu_state_data.source_address = 0;
96 	fdm.cpu_state_data.source_len =
97 		cpu_to_be64(fadump_conf->cpu_state_data_size);
98 	fdm.cpu_state_data.destination_address = cpu_to_be64(addr);
99 	addr += fadump_conf->cpu_state_data_size;
100 
101 	/* hpte region section */
102 	fdm.hpte_region.request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
103 	fdm.hpte_region.source_data_type =
104 		cpu_to_be16(RTAS_FADUMP_HPTE_REGION);
105 	fdm.hpte_region.source_address = 0;
106 	fdm.hpte_region.source_len =
107 		cpu_to_be64(fadump_conf->hpte_region_size);
108 	fdm.hpte_region.destination_address = cpu_to_be64(addr);
109 	addr += fadump_conf->hpte_region_size;
110 
111 	/*
112 	 * Align boot memory area destination address to page boundary to
113 	 * be able to mmap read this area in the vmcore.
114 	 */
115 	addr = PAGE_ALIGN(addr);
116 
117 	/* RMA region section */
118 	fdm.rmr_region.request_flag = cpu_to_be32(RTAS_FADUMP_REQUEST_FLAG);
119 	fdm.rmr_region.source_data_type =
120 		cpu_to_be16(RTAS_FADUMP_REAL_MODE_REGION);
121 	fdm.rmr_region.source_address = cpu_to_be64(0);
122 	fdm.rmr_region.source_len = cpu_to_be64(fadump_conf->boot_memory_size);
123 	fdm.rmr_region.destination_address = cpu_to_be64(addr);
124 	addr += fadump_conf->boot_memory_size;
125 
126 	rtas_fadump_update_config(fadump_conf, &fdm);
127 
128 	return addr;
129 }
130 
131 static u64 rtas_fadump_get_bootmem_min(void)
132 {
133 	return RTAS_FADUMP_MIN_BOOT_MEM;
134 }
135 
136 static int rtas_fadump_register(struct fw_dump *fadump_conf)
137 {
138 	unsigned int wait_time;
139 	int rc, err = -EIO;
140 
141 	/* TODO: Add upper time limit for the delay */
142 	do {
143 		rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
144 				NULL, FADUMP_REGISTER, &fdm,
145 				sizeof(struct rtas_fadump_mem_struct));
146 
147 		wait_time = rtas_busy_delay_time(rc);
148 		if (wait_time)
149 			mdelay(wait_time);
150 
151 	} while (wait_time);
152 
153 	switch (rc) {
154 	case 0:
155 		pr_info("Registration is successful!\n");
156 		fadump_conf->dump_registered = 1;
157 		err = 0;
158 		break;
159 	case -1:
160 		pr_err("Failed to register. Hardware Error(%d).\n", rc);
161 		break;
162 	case -3:
163 		if (!is_fadump_boot_mem_contiguous())
164 			pr_err("Can't have holes in boot memory area.\n");
165 		else if (!is_fadump_reserved_mem_contiguous())
166 			pr_err("Can't have holes in reserved memory area.\n");
167 
168 		pr_err("Failed to register. Parameter Error(%d).\n", rc);
169 		err = -EINVAL;
170 		break;
171 	case -9:
172 		pr_err("Already registered!\n");
173 		fadump_conf->dump_registered = 1;
174 		err = -EEXIST;
175 		break;
176 	default:
177 		pr_err("Failed to register. Unknown Error(%d).\n", rc);
178 		break;
179 	}
180 
181 	return err;
182 }
183 
184 static int rtas_fadump_unregister(struct fw_dump *fadump_conf)
185 {
186 	unsigned int wait_time;
187 	int rc;
188 
189 	/* TODO: Add upper time limit for the delay */
190 	do {
191 		rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
192 				NULL, FADUMP_UNREGISTER, &fdm,
193 				sizeof(struct rtas_fadump_mem_struct));
194 
195 		wait_time = rtas_busy_delay_time(rc);
196 		if (wait_time)
197 			mdelay(wait_time);
198 	} while (wait_time);
199 
200 	if (rc) {
201 		pr_err("Failed to un-register - unexpected error(%d).\n", rc);
202 		return -EIO;
203 	}
204 
205 	fadump_conf->dump_registered = 0;
206 	return 0;
207 }
208 
209 static int rtas_fadump_invalidate(struct fw_dump *fadump_conf)
210 {
211 	unsigned int wait_time;
212 	int rc;
213 
214 	/* TODO: Add upper time limit for the delay */
215 	do {
216 		rc =  rtas_call(fadump_conf->ibm_configure_kernel_dump, 3, 1,
217 				NULL, FADUMP_INVALIDATE, fdm_active,
218 				sizeof(struct rtas_fadump_mem_struct));
219 
220 		wait_time = rtas_busy_delay_time(rc);
221 		if (wait_time)
222 			mdelay(wait_time);
223 	} while (wait_time);
224 
225 	if (rc) {
226 		pr_err("Failed to invalidate - unexpected error (%d).\n", rc);
227 		return -EIO;
228 	}
229 
230 	fadump_conf->dump_active = 0;
231 	fdm_active = NULL;
232 	return 0;
233 }
234 
235 #define RTAS_FADUMP_GPR_MASK		0xffffff0000000000
236 static inline int rtas_fadump_gpr_index(u64 id)
237 {
238 	char str[3];
239 	int i = -1;
240 
241 	if ((id & RTAS_FADUMP_GPR_MASK) == fadump_str_to_u64("GPR")) {
242 		/* get the digits at the end */
243 		id &= ~RTAS_FADUMP_GPR_MASK;
244 		id >>= 24;
245 		str[2] = '\0';
246 		str[1] = id & 0xff;
247 		str[0] = (id >> 8) & 0xff;
248 		if (kstrtoint(str, 10, &i))
249 			i = -EINVAL;
250 		if (i > 31)
251 			i = -1;
252 	}
253 	return i;
254 }
255 
256 static void __init rtas_fadump_set_regval(struct pt_regs *regs, u64 reg_id, u64 reg_val)
257 {
258 	int i;
259 
260 	i = rtas_fadump_gpr_index(reg_id);
261 	if (i >= 0)
262 		regs->gpr[i] = (unsigned long)reg_val;
263 	else if (reg_id == fadump_str_to_u64("NIA"))
264 		regs->nip = (unsigned long)reg_val;
265 	else if (reg_id == fadump_str_to_u64("MSR"))
266 		regs->msr = (unsigned long)reg_val;
267 	else if (reg_id == fadump_str_to_u64("CTR"))
268 		regs->ctr = (unsigned long)reg_val;
269 	else if (reg_id == fadump_str_to_u64("LR"))
270 		regs->link = (unsigned long)reg_val;
271 	else if (reg_id == fadump_str_to_u64("XER"))
272 		regs->xer = (unsigned long)reg_val;
273 	else if (reg_id == fadump_str_to_u64("CR"))
274 		regs->ccr = (unsigned long)reg_val;
275 	else if (reg_id == fadump_str_to_u64("DAR"))
276 		regs->dar = (unsigned long)reg_val;
277 	else if (reg_id == fadump_str_to_u64("DSISR"))
278 		regs->dsisr = (unsigned long)reg_val;
279 }
280 
281 static struct rtas_fadump_reg_entry* __init
282 rtas_fadump_read_regs(struct rtas_fadump_reg_entry *reg_entry,
283 		      struct pt_regs *regs)
284 {
285 	memset(regs, 0, sizeof(struct pt_regs));
286 
287 	while (be64_to_cpu(reg_entry->reg_id) != fadump_str_to_u64("CPUEND")) {
288 		rtas_fadump_set_regval(regs, be64_to_cpu(reg_entry->reg_id),
289 				       be64_to_cpu(reg_entry->reg_value));
290 		reg_entry++;
291 	}
292 	reg_entry++;
293 	return reg_entry;
294 }
295 
296 /*
297  * Read CPU state dump data and convert it into ELF notes.
298  * The CPU dump starts with magic number "REGSAVE". NumCpusOffset should be
299  * used to access the data to allow for additional fields to be added without
300  * affecting compatibility. Each list of registers for a CPU starts with
301  * "CPUSTRT" and ends with "CPUEND". Each register entry is of 16 bytes,
302  * 8 Byte ASCII identifier and 8 Byte register value. The register entry
303  * with identifier "CPUSTRT" and "CPUEND" contains 4 byte cpu id as part
304  * of register value. For more details refer to PAPR document.
305  *
306  * Only for the crashing cpu we ignore the CPU dump data and get exact
307  * state from fadump crash info structure populated by first kernel at the
308  * time of crash.
309  */
310 static int __init rtas_fadump_build_cpu_notes(struct fw_dump *fadump_conf)
311 {
312 	struct rtas_fadump_reg_save_area_header *reg_header;
313 	struct fadump_crash_info_header *fdh = NULL;
314 	struct rtas_fadump_reg_entry *reg_entry;
315 	u32 num_cpus, *note_buf;
316 	int i, rc = 0, cpu = 0;
317 	struct pt_regs regs;
318 	unsigned long addr;
319 	void *vaddr;
320 
321 	addr = be64_to_cpu(fdm_active->cpu_state_data.destination_address);
322 	vaddr = __va(addr);
323 
324 	reg_header = vaddr;
325 	if (be64_to_cpu(reg_header->magic_number) !=
326 	    fadump_str_to_u64("REGSAVE")) {
327 		pr_err("Unable to read register save area.\n");
328 		return -ENOENT;
329 	}
330 
331 	pr_debug("--------CPU State Data------------\n");
332 	pr_debug("Magic Number: %llx\n", be64_to_cpu(reg_header->magic_number));
333 	pr_debug("NumCpuOffset: %x\n", be32_to_cpu(reg_header->num_cpu_offset));
334 
335 	vaddr += be32_to_cpu(reg_header->num_cpu_offset);
336 	num_cpus = be32_to_cpu(*((__be32 *)(vaddr)));
337 	pr_debug("NumCpus     : %u\n", num_cpus);
338 	vaddr += sizeof(u32);
339 	reg_entry = (struct rtas_fadump_reg_entry *)vaddr;
340 
341 	rc = fadump_setup_cpu_notes_buf(num_cpus);
342 	if (rc != 0)
343 		return rc;
344 
345 	note_buf = (u32 *)fadump_conf->cpu_notes_buf_vaddr;
346 
347 	if (fadump_conf->fadumphdr_addr)
348 		fdh = __va(fadump_conf->fadumphdr_addr);
349 
350 	for (i = 0; i < num_cpus; i++) {
351 		if (be64_to_cpu(reg_entry->reg_id) !=
352 		    fadump_str_to_u64("CPUSTRT")) {
353 			pr_err("Unable to read CPU state data\n");
354 			rc = -ENOENT;
355 			goto error_out;
356 		}
357 		/* Lower 4 bytes of reg_value contains logical cpu id */
358 		cpu = (be64_to_cpu(reg_entry->reg_value) &
359 		       RTAS_FADUMP_CPU_ID_MASK);
360 		if (fdh && !cpumask_test_cpu(cpu, &fdh->cpu_mask)) {
361 			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
362 			continue;
363 		}
364 		pr_debug("Reading register data for cpu %d...\n", cpu);
365 		if (fdh && fdh->crashing_cpu == cpu) {
366 			regs = fdh->regs;
367 			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
368 			RTAS_FADUMP_SKIP_TO_NEXT_CPU(reg_entry);
369 		} else {
370 			reg_entry++;
371 			reg_entry = rtas_fadump_read_regs(reg_entry, &regs);
372 			note_buf = fadump_regs_to_elf_notes(note_buf, &regs);
373 		}
374 	}
375 	final_note(note_buf);
376 
377 	if (fdh) {
378 		pr_debug("Updating elfcore header (%llx) with cpu notes\n",
379 			 fdh->elfcorehdr_addr);
380 		fadump_update_elfcore_header(__va(fdh->elfcorehdr_addr));
381 	}
382 	return 0;
383 
384 error_out:
385 	fadump_free_cpu_notes_buf();
386 	return rc;
387 
388 }
389 
390 /*
391  * Validate and process the dump data stored by firmware before exporting
392  * it through '/proc/vmcore'.
393  */
394 static int __init rtas_fadump_process(struct fw_dump *fadump_conf)
395 {
396 	struct fadump_crash_info_header *fdh;
397 	int rc = 0;
398 
399 	if (!fdm_active || !fadump_conf->fadumphdr_addr)
400 		return -EINVAL;
401 
402 	/* Check if the dump data is valid. */
403 	if ((be16_to_cpu(fdm_active->header.dump_status_flag) ==
404 			RTAS_FADUMP_ERROR_FLAG) ||
405 			(fdm_active->cpu_state_data.error_flags != 0) ||
406 			(fdm_active->rmr_region.error_flags != 0)) {
407 		pr_err("Dump taken by platform is not valid\n");
408 		return -EINVAL;
409 	}
410 	if ((fdm_active->rmr_region.bytes_dumped !=
411 			fdm_active->rmr_region.source_len) ||
412 			!fdm_active->cpu_state_data.bytes_dumped) {
413 		pr_err("Dump taken by platform is incomplete\n");
414 		return -EINVAL;
415 	}
416 
417 	/* Validate the fadump crash info header */
418 	fdh = __va(fadump_conf->fadumphdr_addr);
419 	if (fdh->magic_number != FADUMP_CRASH_INFO_MAGIC) {
420 		pr_err("Crash info header is not valid.\n");
421 		return -EINVAL;
422 	}
423 
424 	rc = rtas_fadump_build_cpu_notes(fadump_conf);
425 	if (rc)
426 		return rc;
427 
428 	/*
429 	 * We are done validating dump info and elfcore header is now ready
430 	 * to be exported. set elfcorehdr_addr so that vmcore module will
431 	 * export the elfcore header through '/proc/vmcore'.
432 	 */
433 	elfcorehdr_addr = fdh->elfcorehdr_addr;
434 
435 	return 0;
436 }
437 
438 static void rtas_fadump_region_show(struct fw_dump *fadump_conf,
439 				    struct seq_file *m)
440 {
441 	const struct rtas_fadump_section *cpu_data_section;
442 	const struct rtas_fadump_mem_struct *fdm_ptr;
443 
444 	if (fdm_active)
445 		fdm_ptr = fdm_active;
446 	else
447 		fdm_ptr = &fdm;
448 
449 	cpu_data_section = &(fdm_ptr->cpu_state_data);
450 	seq_printf(m, "CPU :[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
451 		   be64_to_cpu(cpu_data_section->destination_address),
452 		   be64_to_cpu(cpu_data_section->destination_address) +
453 		   be64_to_cpu(cpu_data_section->source_len) - 1,
454 		   be64_to_cpu(cpu_data_section->source_len),
455 		   be64_to_cpu(cpu_data_section->bytes_dumped));
456 
457 	seq_printf(m, "HPTE:[%#016llx-%#016llx] %#llx bytes, Dumped: %#llx\n",
458 		   be64_to_cpu(fdm_ptr->hpte_region.destination_address),
459 		   be64_to_cpu(fdm_ptr->hpte_region.destination_address) +
460 		   be64_to_cpu(fdm_ptr->hpte_region.source_len) - 1,
461 		   be64_to_cpu(fdm_ptr->hpte_region.source_len),
462 		   be64_to_cpu(fdm_ptr->hpte_region.bytes_dumped));
463 
464 	seq_printf(m, "DUMP: Src: %#016llx, Dest: %#016llx, ",
465 		   be64_to_cpu(fdm_ptr->rmr_region.source_address),
466 		   be64_to_cpu(fdm_ptr->rmr_region.destination_address));
467 	seq_printf(m, "Size: %#llx, Dumped: %#llx bytes\n",
468 		   be64_to_cpu(fdm_ptr->rmr_region.source_len),
469 		   be64_to_cpu(fdm_ptr->rmr_region.bytes_dumped));
470 
471 	/* Dump is active. Show preserved area start address. */
472 	if (fdm_active) {
473 		seq_printf(m, "\nMemory above %#016llx is reserved for saving crash dump\n",
474 			   fadump_conf->boot_mem_top);
475 	}
476 }
477 
478 static void rtas_fadump_trigger(struct fadump_crash_info_header *fdh,
479 				const char *msg)
480 {
481 	/* Call ibm,os-term rtas call to trigger firmware assisted dump */
482 	rtas_os_term((char *)msg);
483 }
484 
485 static struct fadump_ops rtas_fadump_ops = {
486 	.fadump_init_mem_struct		= rtas_fadump_init_mem_struct,
487 	.fadump_get_bootmem_min		= rtas_fadump_get_bootmem_min,
488 	.fadump_register		= rtas_fadump_register,
489 	.fadump_unregister		= rtas_fadump_unregister,
490 	.fadump_invalidate		= rtas_fadump_invalidate,
491 	.fadump_process			= rtas_fadump_process,
492 	.fadump_region_show		= rtas_fadump_region_show,
493 	.fadump_trigger			= rtas_fadump_trigger,
494 };
495 
496 void __init rtas_fadump_dt_scan(struct fw_dump *fadump_conf, u64 node)
497 {
498 	int i, size, num_sections;
499 	const __be32 *sections;
500 	const __be32 *token;
501 
502 	/*
503 	 * Check if Firmware Assisted dump is supported. if yes, check
504 	 * if dump has been initiated on last reboot.
505 	 */
506 	token = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump", NULL);
507 	if (!token)
508 		return;
509 
510 	fadump_conf->ibm_configure_kernel_dump = be32_to_cpu(*token);
511 	fadump_conf->ops		= &rtas_fadump_ops;
512 	fadump_conf->fadump_supported	= 1;
513 
514 	/* Firmware supports 64-bit value for size, align it to pagesize. */
515 	fadump_conf->max_copy_size = ALIGN_DOWN(U64_MAX, PAGE_SIZE);
516 
517 	/*
518 	 * The 'ibm,kernel-dump' rtas node is present only if there is
519 	 * dump data waiting for us.
520 	 */
521 	fdm_active = of_get_flat_dt_prop(node, "ibm,kernel-dump", NULL);
522 	if (fdm_active) {
523 		pr_info("Firmware-assisted dump is active.\n");
524 		fadump_conf->dump_active = 1;
525 		rtas_fadump_get_config(fadump_conf, (void *)__pa(fdm_active));
526 	}
527 
528 	/* Get the sizes required to store dump data for the firmware provided
529 	 * dump sections.
530 	 * For each dump section type supported, a 32bit cell which defines
531 	 * the ID of a supported section followed by two 32 bit cells which
532 	 * gives the size of the section in bytes.
533 	 */
534 	sections = of_get_flat_dt_prop(node, "ibm,configure-kernel-dump-sizes",
535 					&size);
536 
537 	if (!sections)
538 		return;
539 
540 	num_sections = size / (3 * sizeof(u32));
541 
542 	for (i = 0; i < num_sections; i++, sections += 3) {
543 		u32 type = (u32)of_read_number(sections, 1);
544 
545 		switch (type) {
546 		case RTAS_FADUMP_CPU_STATE_DATA:
547 			fadump_conf->cpu_state_data_size =
548 					of_read_ulong(&sections[1], 2);
549 			break;
550 		case RTAS_FADUMP_HPTE_REGION:
551 			fadump_conf->hpte_region_size =
552 					of_read_ulong(&sections[1], 2);
553 			break;
554 		}
555 	}
556 }
557