xref: /openbmc/linux/arch/powerpc/platforms/powernv/opal-core.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
1  // SPDX-License-Identifier: GPL-2.0-only
2  /*
3   * Interface for exporting the OPAL ELF core.
4   * Heavily inspired from fs/proc/vmcore.c
5   *
6   * Copyright 2019, Hari Bathini, IBM Corporation.
7   */
8  
9  #define pr_fmt(fmt) "opal core: " fmt
10  
11  #include <linux/memblock.h>
12  #include <linux/uaccess.h>
13  #include <linux/proc_fs.h>
14  #include <linux/elf.h>
15  #include <linux/elfcore.h>
16  #include <linux/kobject.h>
17  #include <linux/sysfs.h>
18  #include <linux/slab.h>
19  #include <linux/crash_core.h>
20  #include <linux/of.h>
21  
22  #include <asm/page.h>
23  #include <asm/opal.h>
24  #include <asm/fadump-internal.h>
25  
26  #include "opal-fadump.h"
27  
28  #define MAX_PT_LOAD_CNT		8
29  
30  /* NT_AUXV note related info */
31  #define AUXV_CNT		1
32  #define AUXV_DESC_SZ		(((2 * AUXV_CNT) + 1) * sizeof(Elf64_Off))
33  
34  struct opalcore_config {
35  	u32			num_cpus;
36  	/* PIR value of crashing CPU */
37  	u32			crashing_cpu;
38  
39  	/* CPU state data info from F/W */
40  	u64			cpu_state_destination_vaddr;
41  	u64			cpu_state_data_size;
42  	u64			cpu_state_entry_size;
43  
44  	/* OPAL memory to be exported as PT_LOAD segments */
45  	u64			ptload_addr[MAX_PT_LOAD_CNT];
46  	u64			ptload_size[MAX_PT_LOAD_CNT];
47  	u64			ptload_cnt;
48  
49  	/* Pointer to the first PT_LOAD in the ELF core file */
50  	Elf64_Phdr		*ptload_phdr;
51  
52  	/* Total size of opalcore file. */
53  	size_t			opalcore_size;
54  
55  	/* Buffer for all the ELF core headers and the PT_NOTE */
56  	size_t			opalcorebuf_sz;
57  	char			*opalcorebuf;
58  
59  	/* NT_AUXV buffer */
60  	char			auxv_buf[AUXV_DESC_SZ];
61  };
62  
63  struct opalcore {
64  	struct list_head	list;
65  	u64			paddr;
66  	size_t			size;
67  	loff_t			offset;
68  };
69  
70  static LIST_HEAD(opalcore_list);
71  static struct opalcore_config *oc_conf;
72  static const struct opal_mpipl_fadump *opalc_metadata;
73  static const struct opal_mpipl_fadump *opalc_cpu_metadata;
74  static struct kobject *mpipl_kobj;
75  
76  /*
77   * Set crashing CPU's signal to SIGUSR1. if the kernel is triggered
78   * by kernel, SIGTERM otherwise.
79   */
80  bool kernel_initiated;
81  
get_new_element(void)82  static struct opalcore * __init get_new_element(void)
83  {
84  	return kzalloc(sizeof(struct opalcore), GFP_KERNEL);
85  }
86  
is_opalcore_usable(void)87  static inline int is_opalcore_usable(void)
88  {
89  	return (oc_conf && oc_conf->opalcorebuf != NULL) ? 1 : 0;
90  }
91  
append_elf64_note(Elf64_Word * buf,char * name,u32 type,void * data,size_t data_len)92  static Elf64_Word *__init append_elf64_note(Elf64_Word *buf, char *name,
93  				     u32 type, void *data,
94  				     size_t data_len)
95  {
96  	Elf64_Nhdr *note = (Elf64_Nhdr *)buf;
97  	Elf64_Word namesz = strlen(name) + 1;
98  
99  	note->n_namesz = cpu_to_be32(namesz);
100  	note->n_descsz = cpu_to_be32(data_len);
101  	note->n_type   = cpu_to_be32(type);
102  	buf += DIV_ROUND_UP(sizeof(*note), sizeof(Elf64_Word));
103  	memcpy(buf, name, namesz);
104  	buf += DIV_ROUND_UP(namesz, sizeof(Elf64_Word));
105  	memcpy(buf, data, data_len);
106  	buf += DIV_ROUND_UP(data_len, sizeof(Elf64_Word));
107  
108  	return buf;
109  }
110  
fill_prstatus(struct elf_prstatus * prstatus,int pir,struct pt_regs * regs)111  static void __init fill_prstatus(struct elf_prstatus *prstatus, int pir,
112  			  struct pt_regs *regs)
113  {
114  	memset(prstatus, 0, sizeof(struct elf_prstatus));
115  	elf_core_copy_regs(&(prstatus->pr_reg), regs);
116  
117  	/*
118  	 * Overload PID with PIR value.
119  	 * As a PIR value could also be '0', add an offset of '100'
120  	 * to every PIR to avoid misinterpretations in GDB.
121  	 */
122  	prstatus->common.pr_pid  = cpu_to_be32(100 + pir);
123  	prstatus->common.pr_ppid = cpu_to_be32(1);
124  
125  	/*
126  	 * Indicate SIGUSR1 for crash initiated from kernel.
127  	 * SIGTERM otherwise.
128  	 */
129  	if (pir == oc_conf->crashing_cpu) {
130  		short sig;
131  
132  		sig = kernel_initiated ? SIGUSR1 : SIGTERM;
133  		prstatus->common.pr_cursig = cpu_to_be16(sig);
134  	}
135  }
136  
auxv_to_elf64_notes(Elf64_Word * buf,u64 opal_boot_entry)137  static Elf64_Word *__init auxv_to_elf64_notes(Elf64_Word *buf,
138  				       u64 opal_boot_entry)
139  {
140  	Elf64_Off *bufp = (Elf64_Off *)oc_conf->auxv_buf;
141  	int idx = 0;
142  
143  	memset(bufp, 0, AUXV_DESC_SZ);
144  
145  	/* Entry point of OPAL */
146  	bufp[idx++] = cpu_to_be64(AT_ENTRY);
147  	bufp[idx++] = cpu_to_be64(opal_boot_entry);
148  
149  	/* end of vector */
150  	bufp[idx++] = cpu_to_be64(AT_NULL);
151  
152  	buf = append_elf64_note(buf, CRASH_CORE_NOTE_NAME, NT_AUXV,
153  				oc_conf->auxv_buf, AUXV_DESC_SZ);
154  	return buf;
155  }
156  
157  /*
158   * Read from the ELF header and then the crash dump.
159   * Returns number of bytes read on success, -errno on failure.
160   */
read_opalcore(struct file * file,struct kobject * kobj,struct bin_attribute * bin_attr,char * to,loff_t pos,size_t count)161  static ssize_t read_opalcore(struct file *file, struct kobject *kobj,
162  			     struct bin_attribute *bin_attr, char *to,
163  			     loff_t pos, size_t count)
164  {
165  	struct opalcore *m;
166  	ssize_t tsz, avail;
167  	loff_t tpos = pos;
168  
169  	if (pos >= oc_conf->opalcore_size)
170  		return 0;
171  
172  	/* Adjust count if it goes beyond opalcore size */
173  	avail = oc_conf->opalcore_size - pos;
174  	if (count > avail)
175  		count = avail;
176  
177  	if (count == 0)
178  		return 0;
179  
180  	/* Read ELF core header and/or PT_NOTE segment */
181  	if (tpos < oc_conf->opalcorebuf_sz) {
182  		tsz = min_t(size_t, oc_conf->opalcorebuf_sz - tpos, count);
183  		memcpy(to, oc_conf->opalcorebuf + tpos, tsz);
184  		to += tsz;
185  		tpos += tsz;
186  		count -= tsz;
187  	}
188  
189  	list_for_each_entry(m, &opalcore_list, list) {
190  		/* nothing more to read here */
191  		if (count == 0)
192  			break;
193  
194  		if (tpos < m->offset + m->size) {
195  			void *addr;
196  
197  			tsz = min_t(size_t, m->offset + m->size - tpos, count);
198  			addr = (void *)(m->paddr + tpos - m->offset);
199  			memcpy(to, __va(addr), tsz);
200  			to += tsz;
201  			tpos += tsz;
202  			count -= tsz;
203  		}
204  	}
205  
206  	return (tpos - pos);
207  }
208  
209  static struct bin_attribute opal_core_attr = {
210  	.attr = {.name = "core", .mode = 0400},
211  	.read = read_opalcore
212  };
213  
214  /*
215   * Read CPU state dump data and convert it into ELF notes.
216   *
217   * Each register entry is of 16 bytes, A numerical identifier along with
218   * a GPR/SPR flag in the first 8 bytes and the register value in the next
219   * 8 bytes. For more details refer to F/W documentation.
220   */
opalcore_append_cpu_notes(Elf64_Word * buf)221  static Elf64_Word * __init opalcore_append_cpu_notes(Elf64_Word *buf)
222  {
223  	u32 thread_pir, size_per_thread, regs_offset, regs_cnt, reg_esize;
224  	struct hdat_fadump_thread_hdr *thdr;
225  	struct elf_prstatus prstatus;
226  	Elf64_Word *first_cpu_note;
227  	struct pt_regs regs;
228  	char *bufp;
229  	int i;
230  
231  	size_per_thread = oc_conf->cpu_state_entry_size;
232  	bufp = __va(oc_conf->cpu_state_destination_vaddr);
233  
234  	/*
235  	 * Offset for register entries, entry size and registers count is
236  	 * duplicated in every thread header in keeping with HDAT format.
237  	 * Use these values from the first thread header.
238  	 */
239  	thdr = (struct hdat_fadump_thread_hdr *)bufp;
240  	regs_offset = (offsetof(struct hdat_fadump_thread_hdr, offset) +
241  		       be32_to_cpu(thdr->offset));
242  	reg_esize = be32_to_cpu(thdr->esize);
243  	regs_cnt  = be32_to_cpu(thdr->ecnt);
244  
245  	pr_debug("--------CPU State Data------------\n");
246  	pr_debug("NumCpus     : %u\n", oc_conf->num_cpus);
247  	pr_debug("\tOffset: %u, Entry size: %u, Cnt: %u\n",
248  		 regs_offset, reg_esize, regs_cnt);
249  
250  	/*
251  	 * Skip past the first CPU note. Fill this note with the
252  	 * crashing CPU's prstatus.
253  	 */
254  	first_cpu_note = buf;
255  	buf = append_elf64_note(buf, CRASH_CORE_NOTE_NAME, NT_PRSTATUS,
256  				&prstatus, sizeof(prstatus));
257  
258  	for (i = 0; i < oc_conf->num_cpus; i++, bufp += size_per_thread) {
259  		thdr = (struct hdat_fadump_thread_hdr *)bufp;
260  		thread_pir = be32_to_cpu(thdr->pir);
261  
262  		pr_debug("[%04d] PIR: 0x%x, core state: 0x%02x\n",
263  			 i, thread_pir, thdr->core_state);
264  
265  		/*
266  		 * Register state data of MAX cores is provided by firmware,
267  		 * but some of this cores may not be active. So, while
268  		 * processing register state data, check core state and
269  		 * skip threads that belong to inactive cores.
270  		 */
271  		if (thdr->core_state == HDAT_FADUMP_CORE_INACTIVE)
272  			continue;
273  
274  		opal_fadump_read_regs((bufp + regs_offset), regs_cnt,
275  				      reg_esize, false, &regs);
276  
277  		pr_debug("PIR 0x%x - R1 : 0x%llx, NIP : 0x%llx\n", thread_pir,
278  			 be64_to_cpu(regs.gpr[1]), be64_to_cpu(regs.nip));
279  		fill_prstatus(&prstatus, thread_pir, &regs);
280  
281  		if (thread_pir != oc_conf->crashing_cpu) {
282  			buf = append_elf64_note(buf, CRASH_CORE_NOTE_NAME,
283  						NT_PRSTATUS, &prstatus,
284  						sizeof(prstatus));
285  		} else {
286  			/*
287  			 * Add crashing CPU as the first NT_PRSTATUS note for
288  			 * GDB to process the core file appropriately.
289  			 */
290  			append_elf64_note(first_cpu_note, CRASH_CORE_NOTE_NAME,
291  					  NT_PRSTATUS, &prstatus,
292  					  sizeof(prstatus));
293  		}
294  	}
295  
296  	return buf;
297  }
298  
create_opalcore(void)299  static int __init create_opalcore(void)
300  {
301  	u64 opal_boot_entry, opal_base_addr, paddr;
302  	u32 hdr_size, cpu_notes_size, count;
303  	struct device_node *dn;
304  	struct opalcore *new;
305  	loff_t opalcore_off;
306  	struct page *page;
307  	Elf64_Phdr *phdr;
308  	Elf64_Ehdr *elf;
309  	int i, ret;
310  	char *bufp;
311  
312  	/* Get size of header & CPU notes for OPAL core */
313  	hdr_size = (sizeof(Elf64_Ehdr) +
314  		    ((oc_conf->ptload_cnt + 1) * sizeof(Elf64_Phdr)));
315  	cpu_notes_size = ((oc_conf->num_cpus * (CRASH_CORE_NOTE_HEAD_BYTES +
316  			  CRASH_CORE_NOTE_NAME_BYTES +
317  			  CRASH_CORE_NOTE_DESC_BYTES)) +
318  			  (CRASH_CORE_NOTE_HEAD_BYTES +
319  			  CRASH_CORE_NOTE_NAME_BYTES + AUXV_DESC_SZ));
320  
321  	/* Allocate buffer to setup OPAL core */
322  	oc_conf->opalcorebuf_sz = PAGE_ALIGN(hdr_size + cpu_notes_size);
323  	oc_conf->opalcorebuf = alloc_pages_exact(oc_conf->opalcorebuf_sz,
324  						 GFP_KERNEL | __GFP_ZERO);
325  	if (!oc_conf->opalcorebuf) {
326  		pr_err("Not enough memory to setup OPAL core (size: %lu)\n",
327  		       oc_conf->opalcorebuf_sz);
328  		oc_conf->opalcorebuf_sz = 0;
329  		return -ENOMEM;
330  	}
331  	count = oc_conf->opalcorebuf_sz / PAGE_SIZE;
332  	page = virt_to_page(oc_conf->opalcorebuf);
333  	for (i = 0; i < count; i++)
334  		mark_page_reserved(page + i);
335  
336  	pr_debug("opalcorebuf = 0x%llx\n", (u64)oc_conf->opalcorebuf);
337  
338  	/* Read OPAL related device-tree entries */
339  	dn = of_find_node_by_name(NULL, "ibm,opal");
340  	if (dn) {
341  		ret = of_property_read_u64(dn, "opal-base-address",
342  					   &opal_base_addr);
343  		pr_debug("opal-base-address: %llx\n", opal_base_addr);
344  		ret |= of_property_read_u64(dn, "opal-boot-address",
345  					    &opal_boot_entry);
346  		pr_debug("opal-boot-address: %llx\n", opal_boot_entry);
347  	}
348  	if (!dn || ret)
349  		pr_warn("WARNING: Failed to read OPAL base & entry values\n");
350  
351  	of_node_put(dn);
352  
353  	/* Use count to keep track of the program headers */
354  	count = 0;
355  
356  	bufp = oc_conf->opalcorebuf;
357  	elf = (Elf64_Ehdr *)bufp;
358  	bufp += sizeof(Elf64_Ehdr);
359  	memcpy(elf->e_ident, ELFMAG, SELFMAG);
360  	elf->e_ident[EI_CLASS] = ELF_CLASS;
361  	elf->e_ident[EI_DATA] = ELFDATA2MSB;
362  	elf->e_ident[EI_VERSION] = EV_CURRENT;
363  	elf->e_ident[EI_OSABI] = ELF_OSABI;
364  	memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
365  	elf->e_type = cpu_to_be16(ET_CORE);
366  	elf->e_machine = cpu_to_be16(ELF_ARCH);
367  	elf->e_version = cpu_to_be32(EV_CURRENT);
368  	elf->e_entry = 0;
369  	elf->e_phoff = cpu_to_be64(sizeof(Elf64_Ehdr));
370  	elf->e_shoff = 0;
371  	elf->e_flags = 0;
372  
373  	elf->e_ehsize = cpu_to_be16(sizeof(Elf64_Ehdr));
374  	elf->e_phentsize = cpu_to_be16(sizeof(Elf64_Phdr));
375  	elf->e_phnum = 0;
376  	elf->e_shentsize = 0;
377  	elf->e_shnum = 0;
378  	elf->e_shstrndx = 0;
379  
380  	phdr = (Elf64_Phdr *)bufp;
381  	bufp += sizeof(Elf64_Phdr);
382  	phdr->p_type	= cpu_to_be32(PT_NOTE);
383  	phdr->p_flags	= 0;
384  	phdr->p_align	= 0;
385  	phdr->p_paddr	= phdr->p_vaddr = 0;
386  	phdr->p_offset	= cpu_to_be64(hdr_size);
387  	phdr->p_filesz	= phdr->p_memsz = cpu_to_be64(cpu_notes_size);
388  	count++;
389  
390  	opalcore_off = oc_conf->opalcorebuf_sz;
391  	oc_conf->ptload_phdr  = (Elf64_Phdr *)bufp;
392  	paddr = 0;
393  	for (i = 0; i < oc_conf->ptload_cnt; i++) {
394  		phdr = (Elf64_Phdr *)bufp;
395  		bufp += sizeof(Elf64_Phdr);
396  		phdr->p_type	= cpu_to_be32(PT_LOAD);
397  		phdr->p_flags	= cpu_to_be32(PF_R|PF_W|PF_X);
398  		phdr->p_align	= 0;
399  
400  		new = get_new_element();
401  		if (!new)
402  			return -ENOMEM;
403  		new->paddr  = oc_conf->ptload_addr[i];
404  		new->size   = oc_conf->ptload_size[i];
405  		new->offset = opalcore_off;
406  		list_add_tail(&new->list, &opalcore_list);
407  
408  		phdr->p_paddr	= cpu_to_be64(paddr);
409  		phdr->p_vaddr	= cpu_to_be64(opal_base_addr + paddr);
410  		phdr->p_filesz	= phdr->p_memsz  =
411  			cpu_to_be64(oc_conf->ptload_size[i]);
412  		phdr->p_offset	= cpu_to_be64(opalcore_off);
413  
414  		count++;
415  		opalcore_off += oc_conf->ptload_size[i];
416  		paddr += oc_conf->ptload_size[i];
417  	}
418  
419  	elf->e_phnum = cpu_to_be16(count);
420  
421  	bufp = (char *)opalcore_append_cpu_notes((Elf64_Word *)bufp);
422  	bufp = (char *)auxv_to_elf64_notes((Elf64_Word *)bufp, opal_boot_entry);
423  
424  	oc_conf->opalcore_size = opalcore_off;
425  	return 0;
426  }
427  
opalcore_cleanup(void)428  static void opalcore_cleanup(void)
429  {
430  	if (oc_conf == NULL)
431  		return;
432  
433  	/* Remove OPAL core sysfs file */
434  	sysfs_remove_bin_file(mpipl_kobj, &opal_core_attr);
435  	oc_conf->ptload_phdr = NULL;
436  	oc_conf->ptload_cnt = 0;
437  
438  	/* free the buffer used for setting up OPAL core */
439  	if (oc_conf->opalcorebuf) {
440  		void *end = (void *)((u64)oc_conf->opalcorebuf +
441  				     oc_conf->opalcorebuf_sz);
442  
443  		free_reserved_area(oc_conf->opalcorebuf, end, -1, NULL);
444  		oc_conf->opalcorebuf = NULL;
445  		oc_conf->opalcorebuf_sz = 0;
446  	}
447  
448  	kfree(oc_conf);
449  	oc_conf = NULL;
450  }
451  __exitcall(opalcore_cleanup);
452  
opalcore_config_init(void)453  static void __init opalcore_config_init(void)
454  {
455  	u32 idx, cpu_data_version;
456  	struct device_node *np;
457  	const __be32 *prop;
458  	u64 addr = 0;
459  	int i, ret;
460  
461  	np = of_find_node_by_path("/ibm,opal/dump");
462  	if (np == NULL)
463  		return;
464  
465  	if (!of_device_is_compatible(np, "ibm,opal-dump")) {
466  		pr_warn("Support missing for this f/w version!\n");
467  		return;
468  	}
469  
470  	/* Check if dump has been initiated on last reboot */
471  	prop = of_get_property(np, "mpipl-boot", NULL);
472  	if (!prop) {
473  		of_node_put(np);
474  		return;
475  	}
476  
477  	/* Get OPAL metadata */
478  	ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_OPAL, &addr);
479  	if ((ret != OPAL_SUCCESS) || !addr) {
480  		pr_err("Failed to get OPAL metadata (%d)\n", ret);
481  		goto error_out;
482  	}
483  
484  	addr = be64_to_cpu(addr);
485  	pr_debug("OPAL metadata addr: %llx\n", addr);
486  	opalc_metadata = __va(addr);
487  
488  	/* Get OPAL CPU metadata */
489  	ret = opal_mpipl_query_tag(OPAL_MPIPL_TAG_CPU, &addr);
490  	if ((ret != OPAL_SUCCESS) || !addr) {
491  		pr_err("Failed to get OPAL CPU metadata (%d)\n", ret);
492  		goto error_out;
493  	}
494  
495  	addr = be64_to_cpu(addr);
496  	pr_debug("CPU metadata addr: %llx\n", addr);
497  	opalc_cpu_metadata = __va(addr);
498  
499  	/* Allocate memory for config buffer */
500  	oc_conf = kzalloc(sizeof(struct opalcore_config), GFP_KERNEL);
501  	if (oc_conf == NULL)
502  		goto error_out;
503  
504  	/* Parse OPAL metadata */
505  	if (opalc_metadata->version != OPAL_MPIPL_VERSION) {
506  		pr_warn("Supported OPAL metadata version: %u, found: %u!\n",
507  			OPAL_MPIPL_VERSION, opalc_metadata->version);
508  		pr_warn("WARNING: F/W using newer OPAL metadata format!!\n");
509  	}
510  
511  	oc_conf->ptload_cnt = 0;
512  	idx = be32_to_cpu(opalc_metadata->region_cnt);
513  	if (idx > MAX_PT_LOAD_CNT) {
514  		pr_warn("WARNING: OPAL regions count (%d) adjusted to limit (%d)",
515  			idx, MAX_PT_LOAD_CNT);
516  		idx = MAX_PT_LOAD_CNT;
517  	}
518  	for (i = 0; i < idx; i++) {
519  		oc_conf->ptload_addr[oc_conf->ptload_cnt] =
520  				be64_to_cpu(opalc_metadata->region[i].dest);
521  		oc_conf->ptload_size[oc_conf->ptload_cnt++] =
522  				be64_to_cpu(opalc_metadata->region[i].size);
523  	}
524  	oc_conf->ptload_cnt = i;
525  	oc_conf->crashing_cpu = be32_to_cpu(opalc_metadata->crashing_pir);
526  
527  	if (!oc_conf->ptload_cnt) {
528  		pr_err("OPAL memory regions not found\n");
529  		goto error_out;
530  	}
531  
532  	/* Parse OPAL CPU metadata */
533  	cpu_data_version = be32_to_cpu(opalc_cpu_metadata->cpu_data_version);
534  	if (cpu_data_version != HDAT_FADUMP_CPU_DATA_VER) {
535  		pr_warn("Supported CPU data version: %u, found: %u!\n",
536  			HDAT_FADUMP_CPU_DATA_VER, cpu_data_version);
537  		pr_warn("WARNING: F/W using newer CPU state data format!!\n");
538  	}
539  
540  	addr = be64_to_cpu(opalc_cpu_metadata->region[0].dest);
541  	if (!addr) {
542  		pr_err("CPU state data not found!\n");
543  		goto error_out;
544  	}
545  	oc_conf->cpu_state_destination_vaddr = (u64)__va(addr);
546  
547  	oc_conf->cpu_state_data_size =
548  			be64_to_cpu(opalc_cpu_metadata->region[0].size);
549  	oc_conf->cpu_state_entry_size =
550  			be32_to_cpu(opalc_cpu_metadata->cpu_data_size);
551  
552  	if ((oc_conf->cpu_state_entry_size == 0) ||
553  	    (oc_conf->cpu_state_entry_size > oc_conf->cpu_state_data_size)) {
554  		pr_err("CPU state data is invalid.\n");
555  		goto error_out;
556  	}
557  	oc_conf->num_cpus = (oc_conf->cpu_state_data_size /
558  			     oc_conf->cpu_state_entry_size);
559  
560  	of_node_put(np);
561  	return;
562  
563  error_out:
564  	pr_err("Could not export /sys/firmware/opal/core\n");
565  	opalcore_cleanup();
566  	of_node_put(np);
567  }
568  
release_core_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)569  static ssize_t release_core_store(struct kobject *kobj,
570  				  struct kobj_attribute *attr,
571  				  const char *buf, size_t count)
572  {
573  	int input = -1;
574  
575  	if (kstrtoint(buf, 0, &input))
576  		return -EINVAL;
577  
578  	if (input == 1) {
579  		if (oc_conf == NULL) {
580  			pr_err("'/sys/firmware/opal/core' file not accessible!\n");
581  			return -EPERM;
582  		}
583  
584  		/*
585  		 * Take away '/sys/firmware/opal/core' and release all memory
586  		 * used for exporting this file.
587  		 */
588  		opalcore_cleanup();
589  	} else
590  		return -EINVAL;
591  
592  	return count;
593  }
594  
595  static struct kobj_attribute opalcore_rel_attr = __ATTR_WO(release_core);
596  
597  static struct attribute *mpipl_attr[] = {
598  	&opalcore_rel_attr.attr,
599  	NULL,
600  };
601  
602  static struct bin_attribute *mpipl_bin_attr[] = {
603  	&opal_core_attr,
604  	NULL,
605  
606  };
607  
608  static const struct attribute_group mpipl_group = {
609  	.attrs = mpipl_attr,
610  	.bin_attrs =  mpipl_bin_attr,
611  };
612  
opalcore_init(void)613  static int __init opalcore_init(void)
614  {
615  	int rc = -1;
616  
617  	opalcore_config_init();
618  
619  	if (oc_conf == NULL)
620  		return rc;
621  
622  	create_opalcore();
623  
624  	/*
625  	 * If oc_conf->opalcorebuf= is set in the 2nd kernel,
626  	 * then capture the dump.
627  	 */
628  	if (!(is_opalcore_usable())) {
629  		pr_err("Failed to export /sys/firmware/opal/mpipl/core\n");
630  		opalcore_cleanup();
631  		return rc;
632  	}
633  
634  	/* Set OPAL core file size */
635  	opal_core_attr.size = oc_conf->opalcore_size;
636  
637  	mpipl_kobj = kobject_create_and_add("mpipl", opal_kobj);
638  	if (!mpipl_kobj) {
639  		pr_err("unable to create mpipl kobject\n");
640  		return -ENOMEM;
641  	}
642  
643  	/* Export OPAL core sysfs file */
644  	rc = sysfs_create_group(mpipl_kobj, &mpipl_group);
645  	if (rc) {
646  		pr_err("mpipl sysfs group creation failed (%d)", rc);
647  		opalcore_cleanup();
648  		return rc;
649  	}
650  	/* The /sys/firmware/opal/core is moved to /sys/firmware/opal/mpipl/
651  	 * directory, need to create symlink at old location to maintain
652  	 * backward compatibility.
653  	 */
654  	rc = compat_only_sysfs_link_entry_to_kobj(opal_kobj, mpipl_kobj,
655  						  "core", NULL);
656  	if (rc) {
657  		pr_err("unable to create core symlink (%d)\n", rc);
658  		return rc;
659  	}
660  
661  	return 0;
662  }
663  fs_initcall(opalcore_init);
664