xref: /openbmc/linux/arch/s390/kernel/ipl.c (revision 4fc4dca8)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *    ipl/reipl/dump support for Linux on s390.
4  *
5  *    Copyright IBM Corp. 2005, 2012
6  *    Author(s): Michael Holzheu <holzheu@de.ibm.com>
7  *		 Heiko Carstens <heiko.carstens@de.ibm.com>
8  *		 Volker Sameske <sameske@de.ibm.com>
9  */
10 
11 #include <linux/types.h>
12 #include <linux/export.h>
13 #include <linux/init.h>
14 #include <linux/device.h>
15 #include <linux/delay.h>
16 #include <linux/reboot.h>
17 #include <linux/ctype.h>
18 #include <linux/fs.h>
19 #include <linux/gfp.h>
20 #include <linux/crash_dump.h>
21 #include <linux/debug_locks.h>
22 #include <asm/diag.h>
23 #include <asm/ipl.h>
24 #include <asm/smp.h>
25 #include <asm/setup.h>
26 #include <asm/cpcmd.h>
27 #include <asm/ebcdic.h>
28 #include <asm/sclp.h>
29 #include <asm/checksum.h>
30 #include <asm/debug.h>
31 #include <asm/os_info.h>
32 #include <asm/sections.h>
33 #include <asm/boot_data.h>
34 #include <asm/uv.h>
35 #include "entry.h"
36 
37 #define IPL_PARM_BLOCK_VERSION 0
38 
39 #define IPL_UNKNOWN_STR		"unknown"
40 #define IPL_CCW_STR		"ccw"
41 #define IPL_FCP_STR		"fcp"
42 #define IPL_FCP_DUMP_STR	"fcp_dump"
43 #define IPL_NSS_STR		"nss"
44 
45 #define DUMP_CCW_STR		"ccw"
46 #define DUMP_FCP_STR		"fcp"
47 #define DUMP_NONE_STR		"none"
48 
49 /*
50  * Four shutdown trigger types are supported:
51  * - panic
52  * - halt
53  * - power off
54  * - reipl
55  * - restart
56  */
57 #define ON_PANIC_STR		"on_panic"
58 #define ON_HALT_STR		"on_halt"
59 #define ON_POFF_STR		"on_poff"
60 #define ON_REIPL_STR		"on_reboot"
61 #define ON_RESTART_STR		"on_restart"
62 
63 struct shutdown_action;
64 struct shutdown_trigger {
65 	char *name;
66 	struct shutdown_action *action;
67 };
68 
69 /*
70  * The following shutdown action types are supported:
71  */
72 #define SHUTDOWN_ACTION_IPL_STR		"ipl"
73 #define SHUTDOWN_ACTION_REIPL_STR	"reipl"
74 #define SHUTDOWN_ACTION_DUMP_STR	"dump"
75 #define SHUTDOWN_ACTION_VMCMD_STR	"vmcmd"
76 #define SHUTDOWN_ACTION_STOP_STR	"stop"
77 #define SHUTDOWN_ACTION_DUMP_REIPL_STR	"dump_reipl"
78 
79 struct shutdown_action {
80 	char *name;
81 	void (*fn) (struct shutdown_trigger *trigger);
82 	int (*init) (void);
83 	int init_rc;
84 };
85 
86 static char *ipl_type_str(enum ipl_type type)
87 {
88 	switch (type) {
89 	case IPL_TYPE_CCW:
90 		return IPL_CCW_STR;
91 	case IPL_TYPE_FCP:
92 		return IPL_FCP_STR;
93 	case IPL_TYPE_FCP_DUMP:
94 		return IPL_FCP_DUMP_STR;
95 	case IPL_TYPE_NSS:
96 		return IPL_NSS_STR;
97 	case IPL_TYPE_UNKNOWN:
98 	default:
99 		return IPL_UNKNOWN_STR;
100 	}
101 }
102 
103 enum dump_type {
104 	DUMP_TYPE_NONE	= 1,
105 	DUMP_TYPE_CCW	= 2,
106 	DUMP_TYPE_FCP	= 4,
107 };
108 
109 static char *dump_type_str(enum dump_type type)
110 {
111 	switch (type) {
112 	case DUMP_TYPE_NONE:
113 		return DUMP_NONE_STR;
114 	case DUMP_TYPE_CCW:
115 		return DUMP_CCW_STR;
116 	case DUMP_TYPE_FCP:
117 		return DUMP_FCP_STR;
118 	default:
119 		return NULL;
120 	}
121 }
122 
123 int __bootdata_preserved(ipl_block_valid);
124 struct ipl_parameter_block __bootdata_preserved(ipl_block);
125 int __bootdata_preserved(ipl_secure_flag);
126 
127 unsigned long __bootdata_preserved(ipl_cert_list_addr);
128 unsigned long __bootdata_preserved(ipl_cert_list_size);
129 
130 unsigned long __bootdata(early_ipl_comp_list_addr);
131 unsigned long __bootdata(early_ipl_comp_list_size);
132 
133 static int reipl_capabilities = IPL_TYPE_UNKNOWN;
134 
135 static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
136 static struct ipl_parameter_block *reipl_block_fcp;
137 static struct ipl_parameter_block *reipl_block_ccw;
138 static struct ipl_parameter_block *reipl_block_nss;
139 static struct ipl_parameter_block *reipl_block_actual;
140 
141 static int dump_capabilities = DUMP_TYPE_NONE;
142 static enum dump_type dump_type = DUMP_TYPE_NONE;
143 static struct ipl_parameter_block *dump_block_fcp;
144 static struct ipl_parameter_block *dump_block_ccw;
145 
146 static struct sclp_ipl_info sclp_ipl_info;
147 
148 static inline int __diag308(unsigned long subcode, void *addr)
149 {
150 	register unsigned long _addr asm("0") = (unsigned long) addr;
151 	register unsigned long _rc asm("1") = 0;
152 
153 	asm volatile(
154 		"	diag	%0,%2,0x308\n"
155 		"0:	nopr	%%r7\n"
156 		EX_TABLE(0b,0b)
157 		: "+d" (_addr), "+d" (_rc)
158 		: "d" (subcode) : "cc", "memory");
159 	return _rc;
160 }
161 
162 int diag308(unsigned long subcode, void *addr)
163 {
164 	if (IS_ENABLED(CONFIG_KASAN))
165 		__arch_local_irq_stosm(0x04); /* enable DAT */
166 	diag_stat_inc(DIAG_STAT_X308);
167 	return __diag308(subcode, addr);
168 }
169 EXPORT_SYMBOL_GPL(diag308);
170 
171 /* SYSFS */
172 
173 #define IPL_ATTR_SHOW_FN(_prefix, _name, _format, args...)		\
174 static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj,	\
175 		struct kobj_attribute *attr,				\
176 		char *page)						\
177 {									\
178 	return snprintf(page, PAGE_SIZE, _format, ##args);		\
179 }
180 
181 #define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk)			\
182 static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,	\
183 		struct kobj_attribute *attr,				\
184 		const char *buf, size_t len)				\
185 {									\
186 	unsigned long long ssid, devno;					\
187 									\
188 	if (sscanf(buf, "0.%llx.%llx\n", &ssid, &devno) != 2)		\
189 		return -EINVAL;						\
190 									\
191 	if (ssid > __MAX_SSID || devno > __MAX_SUBCHANNEL)		\
192 		return -EINVAL;						\
193 									\
194 	_ipl_blk.ssid = ssid;						\
195 	_ipl_blk.devno = devno;						\
196 	return len;							\
197 }
198 
199 #define DEFINE_IPL_CCW_ATTR_RW(_prefix, _name, _ipl_blk)		\
200 IPL_ATTR_SHOW_FN(_prefix, _name, "0.%x.%04x\n",				\
201 		 _ipl_blk.ssid, _ipl_blk.devno);			\
202 IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk);			\
203 static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
204 	__ATTR(_name, (S_IRUGO | S_IWUSR),				\
205 	       sys_##_prefix##_##_name##_show,				\
206 	       sys_##_prefix##_##_name##_store)				\
207 
208 #define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value)		\
209 IPL_ATTR_SHOW_FN(_prefix, _name, _format, _value)			\
210 static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
211 	__ATTR(_name, S_IRUGO, sys_##_prefix##_##_name##_show, NULL)
212 
213 #define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)	\
214 IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, (unsigned long long) _value)	\
215 static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,	\
216 		struct kobj_attribute *attr,				\
217 		const char *buf, size_t len)				\
218 {									\
219 	unsigned long long value;					\
220 	if (sscanf(buf, _fmt_in, &value) != 1)				\
221 		return -EINVAL;						\
222 	_value = value;							\
223 	return len;							\
224 }									\
225 static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
226 	__ATTR(_name,(S_IRUGO | S_IWUSR),				\
227 			sys_##_prefix##_##_name##_show,			\
228 			sys_##_prefix##_##_name##_store)
229 
230 #define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
231 IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, _value)			\
232 static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj,	\
233 		struct kobj_attribute *attr,				\
234 		const char *buf, size_t len)				\
235 {									\
236 	strncpy(_value, buf, sizeof(_value) - 1);			\
237 	strim(_value);							\
238 	return len;							\
239 }									\
240 static struct kobj_attribute sys_##_prefix##_##_name##_attr =		\
241 	__ATTR(_name,(S_IRUGO | S_IWUSR),				\
242 			sys_##_prefix##_##_name##_show,			\
243 			sys_##_prefix##_##_name##_store)
244 
245 /*
246  * ipl section
247  */
248 
249 static __init enum ipl_type get_ipl_type(void)
250 {
251 	if (!ipl_block_valid)
252 		return IPL_TYPE_UNKNOWN;
253 
254 	switch (ipl_block.pb0_hdr.pbt) {
255 	case IPL_PBT_CCW:
256 		return IPL_TYPE_CCW;
257 	case IPL_PBT_FCP:
258 		if (ipl_block.fcp.opt == IPL_PB0_FCP_OPT_DUMP)
259 			return IPL_TYPE_FCP_DUMP;
260 		else
261 			return IPL_TYPE_FCP;
262 	}
263 	return IPL_TYPE_UNKNOWN;
264 }
265 
266 struct ipl_info ipl_info;
267 EXPORT_SYMBOL_GPL(ipl_info);
268 
269 static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
270 			     char *page)
271 {
272 	return sprintf(page, "%s\n", ipl_type_str(ipl_info.type));
273 }
274 
275 static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
276 
277 static ssize_t ipl_secure_show(struct kobject *kobj,
278 			       struct kobj_attribute *attr, char *page)
279 {
280 	return sprintf(page, "%i\n", !!ipl_secure_flag);
281 }
282 
283 static struct kobj_attribute sys_ipl_secure_attr =
284 	__ATTR(secure, 0444, ipl_secure_show, NULL);
285 
286 static ssize_t ipl_has_secure_show(struct kobject *kobj,
287 				   struct kobj_attribute *attr, char *page)
288 {
289 	if (MACHINE_IS_LPAR)
290 		return sprintf(page, "%i\n", !!sclp.has_sipl);
291 	else if (MACHINE_IS_VM)
292 		return sprintf(page, "%i\n", !!sclp.has_sipl_g2);
293 	else
294 		return sprintf(page, "%i\n", 0);
295 }
296 
297 static struct kobj_attribute sys_ipl_has_secure_attr =
298 	__ATTR(has_secure, 0444, ipl_has_secure_show, NULL);
299 
300 static ssize_t ipl_vm_parm_show(struct kobject *kobj,
301 				struct kobj_attribute *attr, char *page)
302 {
303 	char parm[DIAG308_VMPARM_SIZE + 1] = {};
304 
305 	if (ipl_block_valid && (ipl_block.pb0_hdr.pbt == IPL_PBT_CCW))
306 		ipl_block_get_ascii_vmparm(parm, sizeof(parm), &ipl_block);
307 	return sprintf(page, "%s\n", parm);
308 }
309 
310 static struct kobj_attribute sys_ipl_vm_parm_attr =
311 	__ATTR(parm, S_IRUGO, ipl_vm_parm_show, NULL);
312 
313 static ssize_t sys_ipl_device_show(struct kobject *kobj,
314 				   struct kobj_attribute *attr, char *page)
315 {
316 	switch (ipl_info.type) {
317 	case IPL_TYPE_CCW:
318 		return sprintf(page, "0.%x.%04x\n", ipl_block.ccw.ssid,
319 			       ipl_block.ccw.devno);
320 	case IPL_TYPE_FCP:
321 	case IPL_TYPE_FCP_DUMP:
322 		return sprintf(page, "0.0.%04x\n", ipl_block.fcp.devno);
323 	default:
324 		return 0;
325 	}
326 }
327 
328 static struct kobj_attribute sys_ipl_device_attr =
329 	__ATTR(device, S_IRUGO, sys_ipl_device_show, NULL);
330 
331 static ssize_t ipl_parameter_read(struct file *filp, struct kobject *kobj,
332 				  struct bin_attribute *attr, char *buf,
333 				  loff_t off, size_t count)
334 {
335 	return memory_read_from_buffer(buf, count, &off, &ipl_block,
336 				       ipl_block.hdr.len);
337 }
338 static struct bin_attribute ipl_parameter_attr =
339 	__BIN_ATTR(binary_parameter, S_IRUGO, ipl_parameter_read, NULL,
340 		   PAGE_SIZE);
341 
342 static ssize_t ipl_scp_data_read(struct file *filp, struct kobject *kobj,
343 				 struct bin_attribute *attr, char *buf,
344 				 loff_t off, size_t count)
345 {
346 	unsigned int size = ipl_block.fcp.scp_data_len;
347 	void *scp_data = &ipl_block.fcp.scp_data;
348 
349 	return memory_read_from_buffer(buf, count, &off, scp_data, size);
350 }
351 static struct bin_attribute ipl_scp_data_attr =
352 	__BIN_ATTR(scp_data, S_IRUGO, ipl_scp_data_read, NULL, PAGE_SIZE);
353 
354 static struct bin_attribute *ipl_fcp_bin_attrs[] = {
355 	&ipl_parameter_attr,
356 	&ipl_scp_data_attr,
357 	NULL,
358 };
359 
360 /* FCP ipl device attributes */
361 
362 DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n",
363 		   (unsigned long long)ipl_block.fcp.wwpn);
364 DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n",
365 		   (unsigned long long)ipl_block.fcp.lun);
366 DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n",
367 		   (unsigned long long)ipl_block.fcp.bootprog);
368 DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n",
369 		   (unsigned long long)ipl_block.fcp.br_lba);
370 
371 static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
372 				     struct kobj_attribute *attr, char *page)
373 {
374 	char loadparm[LOADPARM_LEN + 1] = {};
375 
376 	if (!sclp_ipl_info.is_valid)
377 		return sprintf(page, "#unknown#\n");
378 	memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
379 	EBCASC(loadparm, LOADPARM_LEN);
380 	strim(loadparm);
381 	return sprintf(page, "%s\n", loadparm);
382 }
383 
384 static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
385 	__ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
386 
387 static struct attribute *ipl_fcp_attrs[] = {
388 	&sys_ipl_type_attr.attr,
389 	&sys_ipl_device_attr.attr,
390 	&sys_ipl_fcp_wwpn_attr.attr,
391 	&sys_ipl_fcp_lun_attr.attr,
392 	&sys_ipl_fcp_bootprog_attr.attr,
393 	&sys_ipl_fcp_br_lba_attr.attr,
394 	&sys_ipl_ccw_loadparm_attr.attr,
395 	&sys_ipl_secure_attr.attr,
396 	&sys_ipl_has_secure_attr.attr,
397 	NULL,
398 };
399 
400 static struct attribute_group ipl_fcp_attr_group = {
401 	.attrs = ipl_fcp_attrs,
402 	.bin_attrs = ipl_fcp_bin_attrs,
403 };
404 
405 /* CCW ipl device attributes */
406 
407 static struct attribute *ipl_ccw_attrs_vm[] = {
408 	&sys_ipl_type_attr.attr,
409 	&sys_ipl_device_attr.attr,
410 	&sys_ipl_ccw_loadparm_attr.attr,
411 	&sys_ipl_vm_parm_attr.attr,
412 	&sys_ipl_secure_attr.attr,
413 	&sys_ipl_has_secure_attr.attr,
414 	NULL,
415 };
416 
417 static struct attribute *ipl_ccw_attrs_lpar[] = {
418 	&sys_ipl_type_attr.attr,
419 	&sys_ipl_device_attr.attr,
420 	&sys_ipl_ccw_loadparm_attr.attr,
421 	&sys_ipl_secure_attr.attr,
422 	&sys_ipl_has_secure_attr.attr,
423 	NULL,
424 };
425 
426 static struct attribute_group ipl_ccw_attr_group_vm = {
427 	.attrs = ipl_ccw_attrs_vm,
428 };
429 
430 static struct attribute_group ipl_ccw_attr_group_lpar = {
431 	.attrs = ipl_ccw_attrs_lpar
432 };
433 
434 /* UNKNOWN ipl device attributes */
435 
436 static struct attribute *ipl_unknown_attrs[] = {
437 	&sys_ipl_type_attr.attr,
438 	NULL,
439 };
440 
441 static struct attribute_group ipl_unknown_attr_group = {
442 	.attrs = ipl_unknown_attrs,
443 };
444 
445 static struct kset *ipl_kset;
446 
447 static void __ipl_run(void *unused)
448 {
449 	__bpon();
450 	diag308(DIAG308_LOAD_CLEAR, NULL);
451 }
452 
453 static void ipl_run(struct shutdown_trigger *trigger)
454 {
455 	smp_call_ipl_cpu(__ipl_run, NULL);
456 }
457 
458 static int __init ipl_init(void)
459 {
460 	int rc;
461 
462 	ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
463 	if (!ipl_kset) {
464 		rc = -ENOMEM;
465 		goto out;
466 	}
467 	switch (ipl_info.type) {
468 	case IPL_TYPE_CCW:
469 		if (MACHINE_IS_VM)
470 			rc = sysfs_create_group(&ipl_kset->kobj,
471 						&ipl_ccw_attr_group_vm);
472 		else
473 			rc = sysfs_create_group(&ipl_kset->kobj,
474 						&ipl_ccw_attr_group_lpar);
475 		break;
476 	case IPL_TYPE_FCP:
477 	case IPL_TYPE_FCP_DUMP:
478 		rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
479 		break;
480 	default:
481 		rc = sysfs_create_group(&ipl_kset->kobj,
482 					&ipl_unknown_attr_group);
483 		break;
484 	}
485 out:
486 	if (rc)
487 		panic("ipl_init failed: rc = %i\n", rc);
488 
489 	return 0;
490 }
491 
492 static struct shutdown_action __refdata ipl_action = {
493 	.name	= SHUTDOWN_ACTION_IPL_STR,
494 	.fn	= ipl_run,
495 	.init	= ipl_init,
496 };
497 
498 /*
499  * reipl shutdown action: Reboot Linux on shutdown.
500  */
501 
502 /* VM IPL PARM attributes */
503 static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb,
504 					  char *page)
505 {
506 	char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
507 
508 	ipl_block_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
509 	return sprintf(page, "%s\n", vmparm);
510 }
511 
512 static ssize_t reipl_generic_vmparm_store(struct ipl_parameter_block *ipb,
513 					  size_t vmparm_max,
514 					  const char *buf, size_t len)
515 {
516 	int i, ip_len;
517 
518 	/* ignore trailing newline */
519 	ip_len = len;
520 	if ((len > 0) && (buf[len - 1] == '\n'))
521 		ip_len--;
522 
523 	if (ip_len > vmparm_max)
524 		return -EINVAL;
525 
526 	/* parm is used to store kernel options, check for common chars */
527 	for (i = 0; i < ip_len; i++)
528 		if (!(isalnum(buf[i]) || isascii(buf[i]) || isprint(buf[i])))
529 			return -EINVAL;
530 
531 	memset(ipb->ccw.vm_parm, 0, DIAG308_VMPARM_SIZE);
532 	ipb->ccw.vm_parm_len = ip_len;
533 	if (ip_len > 0) {
534 		ipb->ccw.vm_flags |= IPL_PB0_CCW_VM_FLAG_VP;
535 		memcpy(ipb->ccw.vm_parm, buf, ip_len);
536 		ASCEBC(ipb->ccw.vm_parm, ip_len);
537 	} else {
538 		ipb->ccw.vm_flags &= ~IPL_PB0_CCW_VM_FLAG_VP;
539 	}
540 
541 	return len;
542 }
543 
544 /* NSS wrapper */
545 static ssize_t reipl_nss_vmparm_show(struct kobject *kobj,
546 				     struct kobj_attribute *attr, char *page)
547 {
548 	return reipl_generic_vmparm_show(reipl_block_nss, page);
549 }
550 
551 static ssize_t reipl_nss_vmparm_store(struct kobject *kobj,
552 				      struct kobj_attribute *attr,
553 				      const char *buf, size_t len)
554 {
555 	return reipl_generic_vmparm_store(reipl_block_nss, 56, buf, len);
556 }
557 
558 /* CCW wrapper */
559 static ssize_t reipl_ccw_vmparm_show(struct kobject *kobj,
560 				     struct kobj_attribute *attr, char *page)
561 {
562 	return reipl_generic_vmparm_show(reipl_block_ccw, page);
563 }
564 
565 static ssize_t reipl_ccw_vmparm_store(struct kobject *kobj,
566 				      struct kobj_attribute *attr,
567 				      const char *buf, size_t len)
568 {
569 	return reipl_generic_vmparm_store(reipl_block_ccw, 64, buf, len);
570 }
571 
572 static struct kobj_attribute sys_reipl_nss_vmparm_attr =
573 	__ATTR(parm, S_IRUGO | S_IWUSR, reipl_nss_vmparm_show,
574 					reipl_nss_vmparm_store);
575 static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
576 	__ATTR(parm, S_IRUGO | S_IWUSR, reipl_ccw_vmparm_show,
577 					reipl_ccw_vmparm_store);
578 
579 /* FCP reipl device attributes */
580 
581 static ssize_t reipl_fcp_scpdata_read(struct file *filp, struct kobject *kobj,
582 				      struct bin_attribute *attr,
583 				      char *buf, loff_t off, size_t count)
584 {
585 	size_t size = reipl_block_fcp->fcp.scp_data_len;
586 	void *scp_data = reipl_block_fcp->fcp.scp_data;
587 
588 	return memory_read_from_buffer(buf, count, &off, scp_data, size);
589 }
590 
591 static ssize_t reipl_fcp_scpdata_write(struct file *filp, struct kobject *kobj,
592 				       struct bin_attribute *attr,
593 				       char *buf, loff_t off, size_t count)
594 {
595 	size_t scpdata_len = count;
596 	size_t padding;
597 
598 
599 	if (off)
600 		return -EINVAL;
601 
602 	memcpy(reipl_block_fcp->fcp.scp_data, buf, count);
603 	if (scpdata_len % 8) {
604 		padding = 8 - (scpdata_len % 8);
605 		memset(reipl_block_fcp->fcp.scp_data + scpdata_len,
606 		       0, padding);
607 		scpdata_len += padding;
608 	}
609 
610 	reipl_block_fcp->hdr.len = IPL_BP_FCP_LEN + scpdata_len;
611 	reipl_block_fcp->fcp.len = IPL_BP0_FCP_LEN + scpdata_len;
612 	reipl_block_fcp->fcp.scp_data_len = scpdata_len;
613 
614 	return count;
615 }
616 static struct bin_attribute sys_reipl_fcp_scp_data_attr =
617 	__BIN_ATTR(scp_data, (S_IRUGO | S_IWUSR), reipl_fcp_scpdata_read,
618 		   reipl_fcp_scpdata_write, DIAG308_SCPDATA_SIZE);
619 
620 static struct bin_attribute *reipl_fcp_bin_attrs[] = {
621 	&sys_reipl_fcp_scp_data_attr,
622 	NULL,
623 };
624 
625 DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n",
626 		   reipl_block_fcp->fcp.wwpn);
627 DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n",
628 		   reipl_block_fcp->fcp.lun);
629 DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
630 		   reipl_block_fcp->fcp.bootprog);
631 DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
632 		   reipl_block_fcp->fcp.br_lba);
633 DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
634 		   reipl_block_fcp->fcp.devno);
635 
636 static void reipl_get_ascii_loadparm(char *loadparm,
637 				     struct ipl_parameter_block *ibp)
638 {
639 	memcpy(loadparm, ibp->common.loadparm, LOADPARM_LEN);
640 	EBCASC(loadparm, LOADPARM_LEN);
641 	loadparm[LOADPARM_LEN] = 0;
642 	strim(loadparm);
643 }
644 
645 static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb,
646 					   char *page)
647 {
648 	char buf[LOADPARM_LEN + 1];
649 
650 	reipl_get_ascii_loadparm(buf, ipb);
651 	return sprintf(page, "%s\n", buf);
652 }
653 
654 static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb,
655 					    const char *buf, size_t len)
656 {
657 	int i, lp_len;
658 
659 	/* ignore trailing newline */
660 	lp_len = len;
661 	if ((len > 0) && (buf[len - 1] == '\n'))
662 		lp_len--;
663 	/* loadparm can have max 8 characters and must not start with a blank */
664 	if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' ')))
665 		return -EINVAL;
666 	/* loadparm can only contain "a-z,A-Z,0-9,SP,." */
667 	for (i = 0; i < lp_len; i++) {
668 		if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') ||
669 		    (buf[i] == '.'))
670 			continue;
671 		return -EINVAL;
672 	}
673 	/* initialize loadparm with blanks */
674 	memset(ipb->common.loadparm, ' ', LOADPARM_LEN);
675 	/* copy and convert to ebcdic */
676 	memcpy(ipb->common.loadparm, buf, lp_len);
677 	ASCEBC(ipb->common.loadparm, LOADPARM_LEN);
678 	ipb->common.flags |= IPL_PB0_FLAG_LOADPARM;
679 	return len;
680 }
681 
682 /* FCP wrapper */
683 static ssize_t reipl_fcp_loadparm_show(struct kobject *kobj,
684 				       struct kobj_attribute *attr, char *page)
685 {
686 	return reipl_generic_loadparm_show(reipl_block_fcp, page);
687 }
688 
689 static ssize_t reipl_fcp_loadparm_store(struct kobject *kobj,
690 					struct kobj_attribute *attr,
691 					const char *buf, size_t len)
692 {
693 	return reipl_generic_loadparm_store(reipl_block_fcp, buf, len);
694 }
695 
696 static struct kobj_attribute sys_reipl_fcp_loadparm_attr =
697 	__ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_fcp_loadparm_show,
698 					    reipl_fcp_loadparm_store);
699 
700 static struct attribute *reipl_fcp_attrs[] = {
701 	&sys_reipl_fcp_device_attr.attr,
702 	&sys_reipl_fcp_wwpn_attr.attr,
703 	&sys_reipl_fcp_lun_attr.attr,
704 	&sys_reipl_fcp_bootprog_attr.attr,
705 	&sys_reipl_fcp_br_lba_attr.attr,
706 	&sys_reipl_fcp_loadparm_attr.attr,
707 	NULL,
708 };
709 
710 static struct attribute_group reipl_fcp_attr_group = {
711 	.attrs = reipl_fcp_attrs,
712 	.bin_attrs = reipl_fcp_bin_attrs,
713 };
714 
715 /* CCW reipl device attributes */
716 DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ccw);
717 
718 /* NSS wrapper */
719 static ssize_t reipl_nss_loadparm_show(struct kobject *kobj,
720 				       struct kobj_attribute *attr, char *page)
721 {
722 	return reipl_generic_loadparm_show(reipl_block_nss, page);
723 }
724 
725 static ssize_t reipl_nss_loadparm_store(struct kobject *kobj,
726 					struct kobj_attribute *attr,
727 					const char *buf, size_t len)
728 {
729 	return reipl_generic_loadparm_store(reipl_block_nss, buf, len);
730 }
731 
732 /* CCW wrapper */
733 static ssize_t reipl_ccw_loadparm_show(struct kobject *kobj,
734 				       struct kobj_attribute *attr, char *page)
735 {
736 	return reipl_generic_loadparm_show(reipl_block_ccw, page);
737 }
738 
739 static ssize_t reipl_ccw_loadparm_store(struct kobject *kobj,
740 					struct kobj_attribute *attr,
741 					const char *buf, size_t len)
742 {
743 	return reipl_generic_loadparm_store(reipl_block_ccw, buf, len);
744 }
745 
746 static struct kobj_attribute sys_reipl_ccw_loadparm_attr =
747 	__ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_ccw_loadparm_show,
748 					    reipl_ccw_loadparm_store);
749 
750 static struct attribute *reipl_ccw_attrs_vm[] = {
751 	&sys_reipl_ccw_device_attr.attr,
752 	&sys_reipl_ccw_loadparm_attr.attr,
753 	&sys_reipl_ccw_vmparm_attr.attr,
754 	NULL,
755 };
756 
757 static struct attribute *reipl_ccw_attrs_lpar[] = {
758 	&sys_reipl_ccw_device_attr.attr,
759 	&sys_reipl_ccw_loadparm_attr.attr,
760 	NULL,
761 };
762 
763 static struct attribute_group reipl_ccw_attr_group_vm = {
764 	.name  = IPL_CCW_STR,
765 	.attrs = reipl_ccw_attrs_vm,
766 };
767 
768 static struct attribute_group reipl_ccw_attr_group_lpar = {
769 	.name  = IPL_CCW_STR,
770 	.attrs = reipl_ccw_attrs_lpar,
771 };
772 
773 
774 /* NSS reipl device attributes */
775 static void reipl_get_ascii_nss_name(char *dst,
776 				     struct ipl_parameter_block *ipb)
777 {
778 	memcpy(dst, ipb->ccw.nss_name, NSS_NAME_SIZE);
779 	EBCASC(dst, NSS_NAME_SIZE);
780 	dst[NSS_NAME_SIZE] = 0;
781 }
782 
783 static ssize_t reipl_nss_name_show(struct kobject *kobj,
784 				   struct kobj_attribute *attr, char *page)
785 {
786 	char nss_name[NSS_NAME_SIZE + 1] = {};
787 
788 	reipl_get_ascii_nss_name(nss_name, reipl_block_nss);
789 	return sprintf(page, "%s\n", nss_name);
790 }
791 
792 static ssize_t reipl_nss_name_store(struct kobject *kobj,
793 				    struct kobj_attribute *attr,
794 				    const char *buf, size_t len)
795 {
796 	int nss_len;
797 
798 	/* ignore trailing newline */
799 	nss_len = len;
800 	if ((len > 0) && (buf[len - 1] == '\n'))
801 		nss_len--;
802 
803 	if (nss_len > NSS_NAME_SIZE)
804 		return -EINVAL;
805 
806 	memset(reipl_block_nss->ccw.nss_name, 0x40, NSS_NAME_SIZE);
807 	if (nss_len > 0) {
808 		reipl_block_nss->ccw.vm_flags |= IPL_PB0_CCW_VM_FLAG_NSS;
809 		memcpy(reipl_block_nss->ccw.nss_name, buf, nss_len);
810 		ASCEBC(reipl_block_nss->ccw.nss_name, nss_len);
811 		EBC_TOUPPER(reipl_block_nss->ccw.nss_name, nss_len);
812 	} else {
813 		reipl_block_nss->ccw.vm_flags &= ~IPL_PB0_CCW_VM_FLAG_NSS;
814 	}
815 
816 	return len;
817 }
818 
819 static struct kobj_attribute sys_reipl_nss_name_attr =
820 	__ATTR(name, S_IRUGO | S_IWUSR, reipl_nss_name_show,
821 					reipl_nss_name_store);
822 
823 static struct kobj_attribute sys_reipl_nss_loadparm_attr =
824 	__ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_nss_loadparm_show,
825 					    reipl_nss_loadparm_store);
826 
827 static struct attribute *reipl_nss_attrs[] = {
828 	&sys_reipl_nss_name_attr.attr,
829 	&sys_reipl_nss_loadparm_attr.attr,
830 	&sys_reipl_nss_vmparm_attr.attr,
831 	NULL,
832 };
833 
834 static struct attribute_group reipl_nss_attr_group = {
835 	.name  = IPL_NSS_STR,
836 	.attrs = reipl_nss_attrs,
837 };
838 
839 void set_os_info_reipl_block(void)
840 {
841 	os_info_entry_add(OS_INFO_REIPL_BLOCK, reipl_block_actual,
842 			  reipl_block_actual->hdr.len);
843 }
844 
845 /* reipl type */
846 
847 static int reipl_set_type(enum ipl_type type)
848 {
849 	if (!(reipl_capabilities & type))
850 		return -EINVAL;
851 
852 	switch(type) {
853 	case IPL_TYPE_CCW:
854 		reipl_block_actual = reipl_block_ccw;
855 		break;
856 	case IPL_TYPE_FCP:
857 		reipl_block_actual = reipl_block_fcp;
858 		break;
859 	case IPL_TYPE_NSS:
860 		reipl_block_actual = reipl_block_nss;
861 		break;
862 	default:
863 		break;
864 	}
865 	reipl_type = type;
866 	return 0;
867 }
868 
869 static ssize_t reipl_type_show(struct kobject *kobj,
870 			       struct kobj_attribute *attr, char *page)
871 {
872 	return sprintf(page, "%s\n", ipl_type_str(reipl_type));
873 }
874 
875 static ssize_t reipl_type_store(struct kobject *kobj,
876 				struct kobj_attribute *attr,
877 				const char *buf, size_t len)
878 {
879 	int rc = -EINVAL;
880 
881 	if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
882 		rc = reipl_set_type(IPL_TYPE_CCW);
883 	else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
884 		rc = reipl_set_type(IPL_TYPE_FCP);
885 	else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0)
886 		rc = reipl_set_type(IPL_TYPE_NSS);
887 	return (rc != 0) ? rc : len;
888 }
889 
890 static struct kobj_attribute reipl_type_attr =
891 	__ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
892 
893 static struct kset *reipl_kset;
894 static struct kset *reipl_fcp_kset;
895 
896 static void __reipl_run(void *unused)
897 {
898 	switch (reipl_type) {
899 	case IPL_TYPE_CCW:
900 		uv_set_shared(__pa(reipl_block_ccw));
901 		diag308(DIAG308_SET, reipl_block_ccw);
902 		uv_remove_shared(__pa(reipl_block_ccw));
903 		diag308(DIAG308_LOAD_CLEAR, NULL);
904 		break;
905 	case IPL_TYPE_FCP:
906 		uv_set_shared(__pa(reipl_block_fcp));
907 		diag308(DIAG308_SET, reipl_block_fcp);
908 		uv_remove_shared(__pa(reipl_block_fcp));
909 		diag308(DIAG308_LOAD_CLEAR, NULL);
910 		break;
911 	case IPL_TYPE_NSS:
912 		uv_set_shared(__pa(reipl_block_nss));
913 		diag308(DIAG308_SET, reipl_block_nss);
914 		uv_remove_shared(__pa(reipl_block_nss));
915 		diag308(DIAG308_LOAD_CLEAR, NULL);
916 		break;
917 	case IPL_TYPE_UNKNOWN:
918 		diag308(DIAG308_LOAD_CLEAR, NULL);
919 		break;
920 	case IPL_TYPE_FCP_DUMP:
921 		break;
922 	}
923 	disabled_wait();
924 }
925 
926 static void reipl_run(struct shutdown_trigger *trigger)
927 {
928 	smp_call_ipl_cpu(__reipl_run, NULL);
929 }
930 
931 static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
932 {
933 	ipb->hdr.len = IPL_BP_CCW_LEN;
934 	ipb->hdr.version = IPL_PARM_BLOCK_VERSION;
935 	ipb->pb0_hdr.len = IPL_BP0_CCW_LEN;
936 	ipb->pb0_hdr.pbt = IPL_PBT_CCW;
937 }
938 
939 static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb)
940 {
941 	/* LOADPARM */
942 	/* check if read scp info worked and set loadparm */
943 	if (sclp_ipl_info.is_valid)
944 		memcpy(ipb->ccw.loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
945 	else
946 		/* read scp info failed: set empty loadparm (EBCDIC blanks) */
947 		memset(ipb->ccw.loadparm, 0x40, LOADPARM_LEN);
948 	ipb->ccw.flags = IPL_PB0_FLAG_LOADPARM;
949 
950 	/* VM PARM */
951 	if (MACHINE_IS_VM && ipl_block_valid &&
952 	    (ipl_block.ccw.vm_flags & IPL_PB0_CCW_VM_FLAG_VP)) {
953 
954 		ipb->ccw.vm_flags |= IPL_PB0_CCW_VM_FLAG_VP;
955 		ipb->ccw.vm_parm_len = ipl_block.ccw.vm_parm_len;
956 		memcpy(ipb->ccw.vm_parm,
957 		       ipl_block.ccw.vm_parm, DIAG308_VMPARM_SIZE);
958 	}
959 }
960 
961 static int __init reipl_nss_init(void)
962 {
963 	int rc;
964 
965 	if (!MACHINE_IS_VM)
966 		return 0;
967 
968 	reipl_block_nss = (void *) get_zeroed_page(GFP_KERNEL);
969 	if (!reipl_block_nss)
970 		return -ENOMEM;
971 
972 	rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
973 	if (rc)
974 		return rc;
975 
976 	reipl_block_ccw_init(reipl_block_nss);
977 	reipl_capabilities |= IPL_TYPE_NSS;
978 	return 0;
979 }
980 
981 static int __init reipl_ccw_init(void)
982 {
983 	int rc;
984 
985 	reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
986 	if (!reipl_block_ccw)
987 		return -ENOMEM;
988 
989 	rc = sysfs_create_group(&reipl_kset->kobj,
990 				MACHINE_IS_VM ? &reipl_ccw_attr_group_vm
991 					      : &reipl_ccw_attr_group_lpar);
992 	if (rc)
993 		return rc;
994 
995 	reipl_block_ccw_init(reipl_block_ccw);
996 	if (ipl_info.type == IPL_TYPE_CCW) {
997 		reipl_block_ccw->ccw.ssid = ipl_block.ccw.ssid;
998 		reipl_block_ccw->ccw.devno = ipl_block.ccw.devno;
999 		reipl_block_ccw_fill_parms(reipl_block_ccw);
1000 	}
1001 
1002 	reipl_capabilities |= IPL_TYPE_CCW;
1003 	return 0;
1004 }
1005 
1006 static int __init reipl_fcp_init(void)
1007 {
1008 	int rc;
1009 
1010 	reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1011 	if (!reipl_block_fcp)
1012 		return -ENOMEM;
1013 
1014 	/* sysfs: create fcp kset for mixing attr group and bin attrs */
1015 	reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
1016 					     &reipl_kset->kobj);
1017 	if (!reipl_fcp_kset) {
1018 		free_page((unsigned long) reipl_block_fcp);
1019 		return -ENOMEM;
1020 	}
1021 
1022 	rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1023 	if (rc) {
1024 		kset_unregister(reipl_fcp_kset);
1025 		free_page((unsigned long) reipl_block_fcp);
1026 		return rc;
1027 	}
1028 
1029 	if (ipl_info.type == IPL_TYPE_FCP) {
1030 		memcpy(reipl_block_fcp, &ipl_block, sizeof(ipl_block));
1031 		/*
1032 		 * Fix loadparm: There are systems where the (SCSI) LOADPARM
1033 		 * is invalid in the SCSI IPL parameter block, so take it
1034 		 * always from sclp_ipl_info.
1035 		 */
1036 		memcpy(reipl_block_fcp->fcp.loadparm, sclp_ipl_info.loadparm,
1037 		       LOADPARM_LEN);
1038 	} else {
1039 		reipl_block_fcp->hdr.len = IPL_BP_FCP_LEN;
1040 		reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1041 		reipl_block_fcp->fcp.len = IPL_BP0_FCP_LEN;
1042 		reipl_block_fcp->fcp.pbt = IPL_PBT_FCP;
1043 		reipl_block_fcp->fcp.opt = IPL_PB0_FCP_OPT_IPL;
1044 	}
1045 	reipl_capabilities |= IPL_TYPE_FCP;
1046 	return 0;
1047 }
1048 
1049 static int __init reipl_type_init(void)
1050 {
1051 	enum ipl_type reipl_type = ipl_info.type;
1052 	struct ipl_parameter_block *reipl_block;
1053 	unsigned long size;
1054 
1055 	reipl_block = os_info_old_entry(OS_INFO_REIPL_BLOCK, &size);
1056 	if (!reipl_block)
1057 		goto out;
1058 	/*
1059 	 * If we have an OS info reipl block, this will be used
1060 	 */
1061 	if (reipl_block->pb0_hdr.pbt == IPL_PBT_FCP) {
1062 		memcpy(reipl_block_fcp, reipl_block, size);
1063 		reipl_type = IPL_TYPE_FCP;
1064 	} else if (reipl_block->pb0_hdr.pbt == IPL_PBT_CCW) {
1065 		memcpy(reipl_block_ccw, reipl_block, size);
1066 		reipl_type = IPL_TYPE_CCW;
1067 	}
1068 out:
1069 	return reipl_set_type(reipl_type);
1070 }
1071 
1072 static int __init reipl_init(void)
1073 {
1074 	int rc;
1075 
1076 	reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
1077 	if (!reipl_kset)
1078 		return -ENOMEM;
1079 	rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
1080 	if (rc) {
1081 		kset_unregister(reipl_kset);
1082 		return rc;
1083 	}
1084 	rc = reipl_ccw_init();
1085 	if (rc)
1086 		return rc;
1087 	rc = reipl_fcp_init();
1088 	if (rc)
1089 		return rc;
1090 	rc = reipl_nss_init();
1091 	if (rc)
1092 		return rc;
1093 	return reipl_type_init();
1094 }
1095 
1096 static struct shutdown_action __refdata reipl_action = {
1097 	.name	= SHUTDOWN_ACTION_REIPL_STR,
1098 	.fn	= reipl_run,
1099 	.init	= reipl_init,
1100 };
1101 
1102 /*
1103  * dump shutdown action: Dump Linux on shutdown.
1104  */
1105 
1106 /* FCP dump device attributes */
1107 
1108 DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n",
1109 		   dump_block_fcp->fcp.wwpn);
1110 DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n",
1111 		   dump_block_fcp->fcp.lun);
1112 DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
1113 		   dump_block_fcp->fcp.bootprog);
1114 DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
1115 		   dump_block_fcp->fcp.br_lba);
1116 DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
1117 		   dump_block_fcp->fcp.devno);
1118 
1119 static struct attribute *dump_fcp_attrs[] = {
1120 	&sys_dump_fcp_device_attr.attr,
1121 	&sys_dump_fcp_wwpn_attr.attr,
1122 	&sys_dump_fcp_lun_attr.attr,
1123 	&sys_dump_fcp_bootprog_attr.attr,
1124 	&sys_dump_fcp_br_lba_attr.attr,
1125 	NULL,
1126 };
1127 
1128 static struct attribute_group dump_fcp_attr_group = {
1129 	.name  = IPL_FCP_STR,
1130 	.attrs = dump_fcp_attrs,
1131 };
1132 
1133 /* CCW dump device attributes */
1134 DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ccw);
1135 
1136 static struct attribute *dump_ccw_attrs[] = {
1137 	&sys_dump_ccw_device_attr.attr,
1138 	NULL,
1139 };
1140 
1141 static struct attribute_group dump_ccw_attr_group = {
1142 	.name  = IPL_CCW_STR,
1143 	.attrs = dump_ccw_attrs,
1144 };
1145 
1146 /* dump type */
1147 
1148 static int dump_set_type(enum dump_type type)
1149 {
1150 	if (!(dump_capabilities & type))
1151 		return -EINVAL;
1152 	dump_type = type;
1153 	return 0;
1154 }
1155 
1156 static ssize_t dump_type_show(struct kobject *kobj,
1157 			      struct kobj_attribute *attr, char *page)
1158 {
1159 	return sprintf(page, "%s\n", dump_type_str(dump_type));
1160 }
1161 
1162 static ssize_t dump_type_store(struct kobject *kobj,
1163 			       struct kobj_attribute *attr,
1164 			       const char *buf, size_t len)
1165 {
1166 	int rc = -EINVAL;
1167 
1168 	if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
1169 		rc = dump_set_type(DUMP_TYPE_NONE);
1170 	else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
1171 		rc = dump_set_type(DUMP_TYPE_CCW);
1172 	else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
1173 		rc = dump_set_type(DUMP_TYPE_FCP);
1174 	return (rc != 0) ? rc : len;
1175 }
1176 
1177 static struct kobj_attribute dump_type_attr =
1178 	__ATTR(dump_type, 0644, dump_type_show, dump_type_store);
1179 
1180 static struct kset *dump_kset;
1181 
1182 static void diag308_dump(void *dump_block)
1183 {
1184 	uv_set_shared(__pa(dump_block));
1185 	diag308(DIAG308_SET, dump_block);
1186 	uv_remove_shared(__pa(dump_block));
1187 	while (1) {
1188 		if (diag308(DIAG308_LOAD_NORMAL_DUMP, NULL) != 0x302)
1189 			break;
1190 		udelay_simple(USEC_PER_SEC);
1191 	}
1192 }
1193 
1194 static void __dump_run(void *unused)
1195 {
1196 	switch (dump_type) {
1197 	case DUMP_TYPE_CCW:
1198 		diag308_dump(dump_block_ccw);
1199 		break;
1200 	case DUMP_TYPE_FCP:
1201 		diag308_dump(dump_block_fcp);
1202 		break;
1203 	default:
1204 		break;
1205 	}
1206 }
1207 
1208 static void dump_run(struct shutdown_trigger *trigger)
1209 {
1210 	if (dump_type == DUMP_TYPE_NONE)
1211 		return;
1212 	smp_send_stop();
1213 	smp_call_ipl_cpu(__dump_run, NULL);
1214 }
1215 
1216 static int __init dump_ccw_init(void)
1217 {
1218 	int rc;
1219 
1220 	dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
1221 	if (!dump_block_ccw)
1222 		return -ENOMEM;
1223 	rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
1224 	if (rc) {
1225 		free_page((unsigned long)dump_block_ccw);
1226 		return rc;
1227 	}
1228 	dump_block_ccw->hdr.len = IPL_BP_CCW_LEN;
1229 	dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
1230 	dump_block_ccw->ccw.len = IPL_BP0_CCW_LEN;
1231 	dump_block_ccw->ccw.pbt = IPL_PBT_CCW;
1232 	dump_capabilities |= DUMP_TYPE_CCW;
1233 	return 0;
1234 }
1235 
1236 static int __init dump_fcp_init(void)
1237 {
1238 	int rc;
1239 
1240 	if (!sclp_ipl_info.has_dump)
1241 		return 0; /* LDIPL DUMP is not installed */
1242 	dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1243 	if (!dump_block_fcp)
1244 		return -ENOMEM;
1245 	rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
1246 	if (rc) {
1247 		free_page((unsigned long)dump_block_fcp);
1248 		return rc;
1249 	}
1250 	dump_block_fcp->hdr.len = IPL_BP_FCP_LEN;
1251 	dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1252 	dump_block_fcp->fcp.len = IPL_BP0_FCP_LEN;
1253 	dump_block_fcp->fcp.pbt = IPL_PBT_FCP;
1254 	dump_block_fcp->fcp.opt = IPL_PB0_FCP_OPT_DUMP;
1255 	dump_capabilities |= DUMP_TYPE_FCP;
1256 	return 0;
1257 }
1258 
1259 static int __init dump_init(void)
1260 {
1261 	int rc;
1262 
1263 	dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
1264 	if (!dump_kset)
1265 		return -ENOMEM;
1266 	rc = sysfs_create_file(&dump_kset->kobj, &dump_type_attr.attr);
1267 	if (rc) {
1268 		kset_unregister(dump_kset);
1269 		return rc;
1270 	}
1271 	rc = dump_ccw_init();
1272 	if (rc)
1273 		return rc;
1274 	rc = dump_fcp_init();
1275 	if (rc)
1276 		return rc;
1277 	dump_set_type(DUMP_TYPE_NONE);
1278 	return 0;
1279 }
1280 
1281 static struct shutdown_action __refdata dump_action = {
1282 	.name	= SHUTDOWN_ACTION_DUMP_STR,
1283 	.fn	= dump_run,
1284 	.init	= dump_init,
1285 };
1286 
1287 static void dump_reipl_run(struct shutdown_trigger *trigger)
1288 {
1289 	unsigned long ipib = (unsigned long) reipl_block_actual;
1290 	unsigned int csum;
1291 
1292 	csum = (__force unsigned int)
1293 	       csum_partial(reipl_block_actual, reipl_block_actual->hdr.len, 0);
1294 	mem_assign_absolute(S390_lowcore.ipib, ipib);
1295 	mem_assign_absolute(S390_lowcore.ipib_checksum, csum);
1296 	dump_run(trigger);
1297 }
1298 
1299 static struct shutdown_action __refdata dump_reipl_action = {
1300 	.name	= SHUTDOWN_ACTION_DUMP_REIPL_STR,
1301 	.fn	= dump_reipl_run,
1302 };
1303 
1304 /*
1305  * vmcmd shutdown action: Trigger vm command on shutdown.
1306  */
1307 
1308 static char vmcmd_on_reboot[128];
1309 static char vmcmd_on_panic[128];
1310 static char vmcmd_on_halt[128];
1311 static char vmcmd_on_poff[128];
1312 static char vmcmd_on_restart[128];
1313 
1314 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
1315 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
1316 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
1317 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
1318 DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
1319 
1320 static struct attribute *vmcmd_attrs[] = {
1321 	&sys_vmcmd_on_reboot_attr.attr,
1322 	&sys_vmcmd_on_panic_attr.attr,
1323 	&sys_vmcmd_on_halt_attr.attr,
1324 	&sys_vmcmd_on_poff_attr.attr,
1325 	&sys_vmcmd_on_restart_attr.attr,
1326 	NULL,
1327 };
1328 
1329 static struct attribute_group vmcmd_attr_group = {
1330 	.attrs = vmcmd_attrs,
1331 };
1332 
1333 static struct kset *vmcmd_kset;
1334 
1335 static void vmcmd_run(struct shutdown_trigger *trigger)
1336 {
1337 	char *cmd;
1338 
1339 	if (strcmp(trigger->name, ON_REIPL_STR) == 0)
1340 		cmd = vmcmd_on_reboot;
1341 	else if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1342 		cmd = vmcmd_on_panic;
1343 	else if (strcmp(trigger->name, ON_HALT_STR) == 0)
1344 		cmd = vmcmd_on_halt;
1345 	else if (strcmp(trigger->name, ON_POFF_STR) == 0)
1346 		cmd = vmcmd_on_poff;
1347 	else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
1348 		cmd = vmcmd_on_restart;
1349 	else
1350 		return;
1351 
1352 	if (strlen(cmd) == 0)
1353 		return;
1354 	__cpcmd(cmd, NULL, 0, NULL);
1355 }
1356 
1357 static int vmcmd_init(void)
1358 {
1359 	if (!MACHINE_IS_VM)
1360 		return -EOPNOTSUPP;
1361 	vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
1362 	if (!vmcmd_kset)
1363 		return -ENOMEM;
1364 	return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group);
1365 }
1366 
1367 static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
1368 					      vmcmd_run, vmcmd_init};
1369 
1370 /*
1371  * stop shutdown action: Stop Linux on shutdown.
1372  */
1373 
1374 static void stop_run(struct shutdown_trigger *trigger)
1375 {
1376 	if (strcmp(trigger->name, ON_PANIC_STR) == 0 ||
1377 	    strcmp(trigger->name, ON_RESTART_STR) == 0)
1378 		disabled_wait();
1379 	smp_stop_cpu();
1380 }
1381 
1382 static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
1383 					     stop_run, NULL};
1384 
1385 /* action list */
1386 
1387 static struct shutdown_action *shutdown_actions_list[] = {
1388 	&ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
1389 	&vmcmd_action, &stop_action};
1390 #define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
1391 
1392 /*
1393  * Trigger section
1394  */
1395 
1396 static struct kset *shutdown_actions_kset;
1397 
1398 static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
1399 		       size_t len)
1400 {
1401 	int i;
1402 
1403 	for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1404 		if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
1405 			if (shutdown_actions_list[i]->init_rc) {
1406 				return shutdown_actions_list[i]->init_rc;
1407 			} else {
1408 				trigger->action = shutdown_actions_list[i];
1409 				return len;
1410 			}
1411 		}
1412 	}
1413 	return -EINVAL;
1414 }
1415 
1416 /* on reipl */
1417 
1418 static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR,
1419 						    &reipl_action};
1420 
1421 static ssize_t on_reboot_show(struct kobject *kobj,
1422 			      struct kobj_attribute *attr, char *page)
1423 {
1424 	return sprintf(page, "%s\n", on_reboot_trigger.action->name);
1425 }
1426 
1427 static ssize_t on_reboot_store(struct kobject *kobj,
1428 			       struct kobj_attribute *attr,
1429 			       const char *buf, size_t len)
1430 {
1431 	return set_trigger(buf, &on_reboot_trigger, len);
1432 }
1433 static struct kobj_attribute on_reboot_attr = __ATTR_RW(on_reboot);
1434 
1435 static void do_machine_restart(char *__unused)
1436 {
1437 	smp_send_stop();
1438 	on_reboot_trigger.action->fn(&on_reboot_trigger);
1439 	reipl_run(NULL);
1440 }
1441 void (*_machine_restart)(char *command) = do_machine_restart;
1442 
1443 /* on panic */
1444 
1445 static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action};
1446 
1447 static ssize_t on_panic_show(struct kobject *kobj,
1448 			     struct kobj_attribute *attr, char *page)
1449 {
1450 	return sprintf(page, "%s\n", on_panic_trigger.action->name);
1451 }
1452 
1453 static ssize_t on_panic_store(struct kobject *kobj,
1454 			      struct kobj_attribute *attr,
1455 			      const char *buf, size_t len)
1456 {
1457 	return set_trigger(buf, &on_panic_trigger, len);
1458 }
1459 static struct kobj_attribute on_panic_attr = __ATTR_RW(on_panic);
1460 
1461 static void do_panic(void)
1462 {
1463 	lgr_info_log();
1464 	on_panic_trigger.action->fn(&on_panic_trigger);
1465 	stop_run(&on_panic_trigger);
1466 }
1467 
1468 /* on restart */
1469 
1470 static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
1471 	&stop_action};
1472 
1473 static ssize_t on_restart_show(struct kobject *kobj,
1474 			       struct kobj_attribute *attr, char *page)
1475 {
1476 	return sprintf(page, "%s\n", on_restart_trigger.action->name);
1477 }
1478 
1479 static ssize_t on_restart_store(struct kobject *kobj,
1480 				struct kobj_attribute *attr,
1481 				const char *buf, size_t len)
1482 {
1483 	return set_trigger(buf, &on_restart_trigger, len);
1484 }
1485 static struct kobj_attribute on_restart_attr = __ATTR_RW(on_restart);
1486 
1487 static void __do_restart(void *ignore)
1488 {
1489 	__arch_local_irq_stosm(0x04); /* enable DAT */
1490 	smp_send_stop();
1491 #ifdef CONFIG_CRASH_DUMP
1492 	crash_kexec(NULL);
1493 #endif
1494 	on_restart_trigger.action->fn(&on_restart_trigger);
1495 	stop_run(&on_restart_trigger);
1496 }
1497 
1498 void do_restart(void)
1499 {
1500 	tracing_off();
1501 	debug_locks_off();
1502 	lgr_info_log();
1503 	smp_call_online_cpu(__do_restart, NULL);
1504 }
1505 
1506 /* on halt */
1507 
1508 static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
1509 
1510 static ssize_t on_halt_show(struct kobject *kobj,
1511 			    struct kobj_attribute *attr, char *page)
1512 {
1513 	return sprintf(page, "%s\n", on_halt_trigger.action->name);
1514 }
1515 
1516 static ssize_t on_halt_store(struct kobject *kobj,
1517 			     struct kobj_attribute *attr,
1518 			     const char *buf, size_t len)
1519 {
1520 	return set_trigger(buf, &on_halt_trigger, len);
1521 }
1522 static struct kobj_attribute on_halt_attr = __ATTR_RW(on_halt);
1523 
1524 static void do_machine_halt(void)
1525 {
1526 	smp_send_stop();
1527 	on_halt_trigger.action->fn(&on_halt_trigger);
1528 	stop_run(&on_halt_trigger);
1529 }
1530 void (*_machine_halt)(void) = do_machine_halt;
1531 
1532 /* on power off */
1533 
1534 static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action};
1535 
1536 static ssize_t on_poff_show(struct kobject *kobj,
1537 			    struct kobj_attribute *attr, char *page)
1538 {
1539 	return sprintf(page, "%s\n", on_poff_trigger.action->name);
1540 }
1541 
1542 static ssize_t on_poff_store(struct kobject *kobj,
1543 			     struct kobj_attribute *attr,
1544 			     const char *buf, size_t len)
1545 {
1546 	return set_trigger(buf, &on_poff_trigger, len);
1547 }
1548 static struct kobj_attribute on_poff_attr = __ATTR_RW(on_poff);
1549 
1550 static void do_machine_power_off(void)
1551 {
1552 	smp_send_stop();
1553 	on_poff_trigger.action->fn(&on_poff_trigger);
1554 	stop_run(&on_poff_trigger);
1555 }
1556 void (*_machine_power_off)(void) = do_machine_power_off;
1557 
1558 static struct attribute *shutdown_action_attrs[] = {
1559 	&on_restart_attr.attr,
1560 	&on_reboot_attr.attr,
1561 	&on_panic_attr.attr,
1562 	&on_halt_attr.attr,
1563 	&on_poff_attr.attr,
1564 	NULL,
1565 };
1566 
1567 static struct attribute_group shutdown_action_attr_group = {
1568 	.attrs = shutdown_action_attrs,
1569 };
1570 
1571 static void __init shutdown_triggers_init(void)
1572 {
1573 	shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
1574 						    firmware_kobj);
1575 	if (!shutdown_actions_kset)
1576 		goto fail;
1577 	if (sysfs_create_group(&shutdown_actions_kset->kobj,
1578 			       &shutdown_action_attr_group))
1579 		goto fail;
1580 	return;
1581 fail:
1582 	panic("shutdown_triggers_init failed\n");
1583 }
1584 
1585 static void __init shutdown_actions_init(void)
1586 {
1587 	int i;
1588 
1589 	for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
1590 		if (!shutdown_actions_list[i]->init)
1591 			continue;
1592 		shutdown_actions_list[i]->init_rc =
1593 			shutdown_actions_list[i]->init();
1594 	}
1595 }
1596 
1597 static int __init s390_ipl_init(void)
1598 {
1599 	char str[8] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
1600 
1601 	sclp_early_get_ipl_info(&sclp_ipl_info);
1602 	/*
1603 	 * Fix loadparm: There are systems where the (SCSI) LOADPARM
1604 	 * returned by read SCP info is invalid (contains EBCDIC blanks)
1605 	 * when the system has been booted via diag308. In that case we use
1606 	 * the value from diag308, if available.
1607 	 *
1608 	 * There are also systems where diag308 store does not work in
1609 	 * case the system is booted from HMC. Fortunately in this case
1610 	 * READ SCP info provides the correct value.
1611 	 */
1612 	if (memcmp(sclp_ipl_info.loadparm, str, sizeof(str)) == 0 && ipl_block_valid)
1613 		memcpy(sclp_ipl_info.loadparm, ipl_block.ccw.loadparm, LOADPARM_LEN);
1614 	shutdown_actions_init();
1615 	shutdown_triggers_init();
1616 	return 0;
1617 }
1618 
1619 __initcall(s390_ipl_init);
1620 
1621 static void __init strncpy_skip_quote(char *dst, char *src, int n)
1622 {
1623 	int sx, dx;
1624 
1625 	dx = 0;
1626 	for (sx = 0; src[sx] != 0; sx++) {
1627 		if (src[sx] == '"')
1628 			continue;
1629 		dst[dx++] = src[sx];
1630 		if (dx >= n)
1631 			break;
1632 	}
1633 }
1634 
1635 static int __init vmcmd_on_reboot_setup(char *str)
1636 {
1637 	if (!MACHINE_IS_VM)
1638 		return 1;
1639 	strncpy_skip_quote(vmcmd_on_reboot, str, 127);
1640 	vmcmd_on_reboot[127] = 0;
1641 	on_reboot_trigger.action = &vmcmd_action;
1642 	return 1;
1643 }
1644 __setup("vmreboot=", vmcmd_on_reboot_setup);
1645 
1646 static int __init vmcmd_on_panic_setup(char *str)
1647 {
1648 	if (!MACHINE_IS_VM)
1649 		return 1;
1650 	strncpy_skip_quote(vmcmd_on_panic, str, 127);
1651 	vmcmd_on_panic[127] = 0;
1652 	on_panic_trigger.action = &vmcmd_action;
1653 	return 1;
1654 }
1655 __setup("vmpanic=", vmcmd_on_panic_setup);
1656 
1657 static int __init vmcmd_on_halt_setup(char *str)
1658 {
1659 	if (!MACHINE_IS_VM)
1660 		return 1;
1661 	strncpy_skip_quote(vmcmd_on_halt, str, 127);
1662 	vmcmd_on_halt[127] = 0;
1663 	on_halt_trigger.action = &vmcmd_action;
1664 	return 1;
1665 }
1666 __setup("vmhalt=", vmcmd_on_halt_setup);
1667 
1668 static int __init vmcmd_on_poff_setup(char *str)
1669 {
1670 	if (!MACHINE_IS_VM)
1671 		return 1;
1672 	strncpy_skip_quote(vmcmd_on_poff, str, 127);
1673 	vmcmd_on_poff[127] = 0;
1674 	on_poff_trigger.action = &vmcmd_action;
1675 	return 1;
1676 }
1677 __setup("vmpoff=", vmcmd_on_poff_setup);
1678 
1679 static int on_panic_notify(struct notifier_block *self,
1680 			   unsigned long event, void *data)
1681 {
1682 	do_panic();
1683 	return NOTIFY_OK;
1684 }
1685 
1686 static struct notifier_block on_panic_nb = {
1687 	.notifier_call = on_panic_notify,
1688 	.priority = INT_MIN,
1689 };
1690 
1691 void __init setup_ipl(void)
1692 {
1693 	BUILD_BUG_ON(sizeof(struct ipl_parameter_block) != PAGE_SIZE);
1694 
1695 	ipl_info.type = get_ipl_type();
1696 	switch (ipl_info.type) {
1697 	case IPL_TYPE_CCW:
1698 		ipl_info.data.ccw.dev_id.ssid = ipl_block.ccw.ssid;
1699 		ipl_info.data.ccw.dev_id.devno = ipl_block.ccw.devno;
1700 		break;
1701 	case IPL_TYPE_FCP:
1702 	case IPL_TYPE_FCP_DUMP:
1703 		ipl_info.data.fcp.dev_id.ssid = 0;
1704 		ipl_info.data.fcp.dev_id.devno = ipl_block.fcp.devno;
1705 		ipl_info.data.fcp.wwpn = ipl_block.fcp.wwpn;
1706 		ipl_info.data.fcp.lun = ipl_block.fcp.lun;
1707 		break;
1708 	case IPL_TYPE_NSS:
1709 	case IPL_TYPE_UNKNOWN:
1710 		/* We have no info to copy */
1711 		break;
1712 	}
1713 	atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
1714 }
1715 
1716 void s390_reset_system(void)
1717 {
1718 	/* Disable prefixing */
1719 	set_prefix(0);
1720 
1721 	/* Disable lowcore protection */
1722 	__ctl_clear_bit(0, 28);
1723 	diag_dma_ops.diag308_reset();
1724 }
1725 
1726 #ifdef CONFIG_KEXEC_FILE
1727 
1728 int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf,
1729 			     unsigned char flags, unsigned short cert)
1730 {
1731 	struct ipl_report_component *comp;
1732 
1733 	comp = vzalloc(sizeof(*comp));
1734 	if (!comp)
1735 		return -ENOMEM;
1736 	list_add_tail(&comp->list, &report->components);
1737 
1738 	comp->entry.addr = kbuf->mem;
1739 	comp->entry.len = kbuf->memsz;
1740 	comp->entry.flags = flags;
1741 	comp->entry.certificate_index = cert;
1742 
1743 	report->size += sizeof(comp->entry);
1744 
1745 	return 0;
1746 }
1747 
1748 int ipl_report_add_certificate(struct ipl_report *report, void *key,
1749 			       unsigned long addr, unsigned long len)
1750 {
1751 	struct ipl_report_certificate *cert;
1752 
1753 	cert = vzalloc(sizeof(*cert));
1754 	if (!cert)
1755 		return -ENOMEM;
1756 	list_add_tail(&cert->list, &report->certificates);
1757 
1758 	cert->entry.addr = addr;
1759 	cert->entry.len = len;
1760 	cert->key = key;
1761 
1762 	report->size += sizeof(cert->entry);
1763 	report->size += cert->entry.len;
1764 
1765 	return 0;
1766 }
1767 
1768 struct ipl_report *ipl_report_init(struct ipl_parameter_block *ipib)
1769 {
1770 	struct ipl_report *report;
1771 
1772 	report = vzalloc(sizeof(*report));
1773 	if (!report)
1774 		return ERR_PTR(-ENOMEM);
1775 
1776 	report->ipib = ipib;
1777 	INIT_LIST_HEAD(&report->components);
1778 	INIT_LIST_HEAD(&report->certificates);
1779 
1780 	report->size = ALIGN(ipib->hdr.len, 8);
1781 	report->size += sizeof(struct ipl_rl_hdr);
1782 	report->size += sizeof(struct ipl_rb_components);
1783 	report->size += sizeof(struct ipl_rb_certificates);
1784 
1785 	return report;
1786 }
1787 
1788 void *ipl_report_finish(struct ipl_report *report)
1789 {
1790 	struct ipl_report_certificate *cert;
1791 	struct ipl_report_component *comp;
1792 	struct ipl_rb_certificates *certs;
1793 	struct ipl_parameter_block *ipib;
1794 	struct ipl_rb_components *comps;
1795 	struct ipl_rl_hdr *rl_hdr;
1796 	void *buf, *ptr;
1797 
1798 	buf = vzalloc(report->size);
1799 	if (!buf)
1800 		return ERR_PTR(-ENOMEM);
1801 	ptr = buf;
1802 
1803 	memcpy(ptr, report->ipib, report->ipib->hdr.len);
1804 	ipib = ptr;
1805 	if (ipl_secure_flag)
1806 		ipib->hdr.flags |= IPL_PL_FLAG_SIPL;
1807 	ipib->hdr.flags |= IPL_PL_FLAG_IPLSR;
1808 	ptr += report->ipib->hdr.len;
1809 	ptr = PTR_ALIGN(ptr, 8);
1810 
1811 	rl_hdr = ptr;
1812 	ptr += sizeof(*rl_hdr);
1813 
1814 	comps = ptr;
1815 	comps->rbt = IPL_RBT_COMPONENTS;
1816 	ptr += sizeof(*comps);
1817 	list_for_each_entry(comp, &report->components, list) {
1818 		memcpy(ptr, &comp->entry, sizeof(comp->entry));
1819 		ptr += sizeof(comp->entry);
1820 	}
1821 	comps->len = ptr - (void *)comps;
1822 
1823 	certs = ptr;
1824 	certs->rbt = IPL_RBT_CERTIFICATES;
1825 	ptr += sizeof(*certs);
1826 	list_for_each_entry(cert, &report->certificates, list) {
1827 		memcpy(ptr, &cert->entry, sizeof(cert->entry));
1828 		ptr += sizeof(cert->entry);
1829 	}
1830 	certs->len = ptr - (void *)certs;
1831 	rl_hdr->len = ptr - (void *)rl_hdr;
1832 
1833 	list_for_each_entry(cert, &report->certificates, list) {
1834 		memcpy(ptr, cert->key, cert->entry.len);
1835 		ptr += cert->entry.len;
1836 	}
1837 
1838 	BUG_ON(ptr > buf + report->size);
1839 	return buf;
1840 }
1841 
1842 int ipl_report_free(struct ipl_report *report)
1843 {
1844 	struct ipl_report_component *comp, *ncomp;
1845 	struct ipl_report_certificate *cert, *ncert;
1846 
1847 	list_for_each_entry_safe(comp, ncomp, &report->components, list)
1848 		vfree(comp);
1849 
1850 	list_for_each_entry_safe(cert, ncert, &report->certificates, list)
1851 		vfree(cert);
1852 
1853 	vfree(report);
1854 
1855 	return 0;
1856 }
1857 
1858 #endif
1859