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