Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/arch/s390/kernel/ipl.c
26424 views
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 <[email protected]>
7
* Volker Sameske <[email protected]>
8
*/
9
10
#include <linux/types.h>
11
#include <linux/export.h>
12
#include <linux/init.h>
13
#include <linux/device.h>
14
#include <linux/delay.h>
15
#include <linux/kstrtox.h>
16
#include <linux/panic_notifier.h>
17
#include <linux/reboot.h>
18
#include <linux/ctype.h>
19
#include <linux/fs.h>
20
#include <linux/gfp.h>
21
#include <linux/crash_dump.h>
22
#include <linux/debug_locks.h>
23
#include <linux/vmalloc.h>
24
#include <asm/asm-extable.h>
25
#include <asm/machine.h>
26
#include <asm/diag.h>
27
#include <asm/ipl.h>
28
#include <asm/smp.h>
29
#include <asm/setup.h>
30
#include <asm/cpcmd.h>
31
#include <asm/ebcdic.h>
32
#include <asm/sclp.h>
33
#include <asm/checksum.h>
34
#include <asm/debug.h>
35
#include <asm/abs_lowcore.h>
36
#include <asm/os_info.h>
37
#include <asm/sections.h>
38
#include <asm/boot_data.h>
39
#include "entry.h"
40
41
#define IPL_PARM_BLOCK_VERSION 0
42
43
#define IPL_UNKNOWN_STR "unknown"
44
#define IPL_CCW_STR "ccw"
45
#define IPL_ECKD_STR "eckd"
46
#define IPL_ECKD_DUMP_STR "eckd_dump"
47
#define IPL_FCP_STR "fcp"
48
#define IPL_FCP_DUMP_STR "fcp_dump"
49
#define IPL_NVME_STR "nvme"
50
#define IPL_NVME_DUMP_STR "nvme_dump"
51
#define IPL_NSS_STR "nss"
52
53
#define DUMP_CCW_STR "ccw"
54
#define DUMP_ECKD_STR "eckd"
55
#define DUMP_FCP_STR "fcp"
56
#define DUMP_NVME_STR "nvme"
57
#define DUMP_NONE_STR "none"
58
59
/*
60
* Four shutdown trigger types are supported:
61
* - panic
62
* - halt
63
* - power off
64
* - reipl
65
* - restart
66
*/
67
#define ON_PANIC_STR "on_panic"
68
#define ON_HALT_STR "on_halt"
69
#define ON_POFF_STR "on_poff"
70
#define ON_REIPL_STR "on_reboot"
71
#define ON_RESTART_STR "on_restart"
72
73
struct shutdown_action;
74
struct shutdown_trigger {
75
char *name;
76
struct shutdown_action *action;
77
};
78
79
/*
80
* The following shutdown action types are supported:
81
*/
82
#define SHUTDOWN_ACTION_IPL_STR "ipl"
83
#define SHUTDOWN_ACTION_REIPL_STR "reipl"
84
#define SHUTDOWN_ACTION_DUMP_STR "dump"
85
#define SHUTDOWN_ACTION_VMCMD_STR "vmcmd"
86
#define SHUTDOWN_ACTION_STOP_STR "stop"
87
#define SHUTDOWN_ACTION_DUMP_REIPL_STR "dump_reipl"
88
89
struct shutdown_action {
90
char *name;
91
void (*fn) (struct shutdown_trigger *trigger);
92
int (*init) (void);
93
int init_rc;
94
};
95
96
static char *ipl_type_str(enum ipl_type type)
97
{
98
switch (type) {
99
case IPL_TYPE_CCW:
100
return IPL_CCW_STR;
101
case IPL_TYPE_ECKD:
102
return IPL_ECKD_STR;
103
case IPL_TYPE_ECKD_DUMP:
104
return IPL_ECKD_DUMP_STR;
105
case IPL_TYPE_FCP:
106
return IPL_FCP_STR;
107
case IPL_TYPE_FCP_DUMP:
108
return IPL_FCP_DUMP_STR;
109
case IPL_TYPE_NSS:
110
return IPL_NSS_STR;
111
case IPL_TYPE_NVME:
112
return IPL_NVME_STR;
113
case IPL_TYPE_NVME_DUMP:
114
return IPL_NVME_DUMP_STR;
115
case IPL_TYPE_UNKNOWN:
116
default:
117
return IPL_UNKNOWN_STR;
118
}
119
}
120
121
enum dump_type {
122
DUMP_TYPE_NONE = 1,
123
DUMP_TYPE_CCW = 2,
124
DUMP_TYPE_FCP = 4,
125
DUMP_TYPE_NVME = 8,
126
DUMP_TYPE_ECKD = 16,
127
};
128
129
static char *dump_type_str(enum dump_type type)
130
{
131
switch (type) {
132
case DUMP_TYPE_NONE:
133
return DUMP_NONE_STR;
134
case DUMP_TYPE_CCW:
135
return DUMP_CCW_STR;
136
case DUMP_TYPE_ECKD:
137
return DUMP_ECKD_STR;
138
case DUMP_TYPE_FCP:
139
return DUMP_FCP_STR;
140
case DUMP_TYPE_NVME:
141
return DUMP_NVME_STR;
142
default:
143
return NULL;
144
}
145
}
146
147
int __bootdata_preserved(ipl_block_valid);
148
struct ipl_parameter_block __bootdata_preserved(ipl_block);
149
int __bootdata_preserved(ipl_secure_flag);
150
151
unsigned long __bootdata_preserved(ipl_cert_list_addr);
152
unsigned long __bootdata_preserved(ipl_cert_list_size);
153
154
unsigned long __bootdata(early_ipl_comp_list_addr);
155
unsigned long __bootdata(early_ipl_comp_list_size);
156
157
static int reipl_capabilities = IPL_TYPE_UNKNOWN;
158
159
static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
160
static struct ipl_parameter_block *reipl_block_fcp;
161
static struct ipl_parameter_block *reipl_block_nvme;
162
static struct ipl_parameter_block *reipl_block_ccw;
163
static struct ipl_parameter_block *reipl_block_eckd;
164
static struct ipl_parameter_block *reipl_block_nss;
165
static struct ipl_parameter_block *reipl_block_actual;
166
167
static int dump_capabilities = DUMP_TYPE_NONE;
168
static enum dump_type dump_type = DUMP_TYPE_NONE;
169
static struct ipl_parameter_block *dump_block_fcp;
170
static struct ipl_parameter_block *dump_block_nvme;
171
static struct ipl_parameter_block *dump_block_ccw;
172
static struct ipl_parameter_block *dump_block_eckd;
173
174
static struct sclp_ipl_info sclp_ipl_info;
175
176
static bool reipl_nvme_clear;
177
static bool reipl_fcp_clear;
178
static bool reipl_ccw_clear;
179
static bool reipl_eckd_clear;
180
181
static unsigned long os_info_flags;
182
183
static inline int __diag308(unsigned long subcode, unsigned long addr)
184
{
185
union register_pair r1;
186
187
r1.even = addr;
188
r1.odd = 0;
189
asm_inline volatile(
190
" diag %[r1],%[subcode],0x308\n"
191
"0: nopr %%r7\n"
192
EX_TABLE(0b,0b)
193
: [r1] "+&d" (r1.pair)
194
: [subcode] "d" (subcode)
195
: "cc", "memory");
196
return r1.odd;
197
}
198
199
int diag308(unsigned long subcode, void *addr)
200
{
201
diag_stat_inc(DIAG_STAT_X308);
202
return __diag308(subcode, addr ? virt_to_phys(addr) : 0);
203
}
204
EXPORT_SYMBOL_GPL(diag308);
205
206
/* SYSFS */
207
208
#define IPL_ATTR_SHOW_FN(_prefix, _name, _format, args...) \
209
static ssize_t sys_##_prefix##_##_name##_show(struct kobject *kobj, \
210
struct kobj_attribute *attr, \
211
char *page) \
212
{ \
213
return sysfs_emit(page, _format, ##args); \
214
}
215
216
#define IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk) \
217
static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
218
struct kobj_attribute *attr, \
219
const char *buf, size_t len) \
220
{ \
221
unsigned long long ssid, devno; \
222
\
223
if (sscanf(buf, "0.%llx.%llx\n", &ssid, &devno) != 2) \
224
return -EINVAL; \
225
\
226
if (ssid > __MAX_SSID || devno > __MAX_SUBCHANNEL) \
227
return -EINVAL; \
228
\
229
_ipl_blk.ssid = ssid; \
230
_ipl_blk.devno = devno; \
231
return len; \
232
}
233
234
#define DEFINE_IPL_CCW_ATTR_RW(_prefix, _name, _ipl_blk) \
235
IPL_ATTR_SHOW_FN(_prefix, _name, "0.%x.%04x\n", \
236
_ipl_blk.ssid, _ipl_blk.devno); \
237
IPL_ATTR_CCW_STORE_FN(_prefix, _name, _ipl_blk); \
238
static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
239
__ATTR(_name, 0644, \
240
sys_##_prefix##_##_name##_show, \
241
sys_##_prefix##_##_name##_store) \
242
243
#define DEFINE_IPL_ATTR_RO(_prefix, _name, _format, _value) \
244
IPL_ATTR_SHOW_FN(_prefix, _name, _format, _value) \
245
static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
246
__ATTR(_name, 0444, sys_##_prefix##_##_name##_show, NULL)
247
248
#define DEFINE_IPL_ATTR_RW(_prefix, _name, _fmt_out, _fmt_in, _value) \
249
IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, (unsigned long long) _value) \
250
static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
251
struct kobj_attribute *attr, \
252
const char *buf, size_t len) \
253
{ \
254
unsigned long long value; \
255
if (sscanf(buf, _fmt_in, &value) != 1) \
256
return -EINVAL; \
257
_value = value; \
258
return len; \
259
} \
260
static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
261
__ATTR(_name, 0644, \
262
sys_##_prefix##_##_name##_show, \
263
sys_##_prefix##_##_name##_store)
264
265
#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
266
IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, _value) \
267
static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
268
struct kobj_attribute *attr, \
269
const char *buf, size_t len) \
270
{ \
271
if (len >= sizeof(_value)) \
272
return -E2BIG; \
273
len = strscpy(_value, buf); \
274
if ((ssize_t)len < 0) \
275
return len; \
276
strim(_value); \
277
return len; \
278
} \
279
static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
280
__ATTR(_name, 0644, \
281
sys_##_prefix##_##_name##_show, \
282
sys_##_prefix##_##_name##_store)
283
284
#define IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \
285
static ssize_t sys_##_prefix##_scp_data_show(struct file *filp, \
286
struct kobject *kobj, \
287
const struct bin_attribute *attr, \
288
char *buf, loff_t off, \
289
size_t count) \
290
{ \
291
size_t size = _ipl_block.scp_data_len; \
292
void *scp_data = _ipl_block.scp_data; \
293
\
294
return memory_read_from_buffer(buf, count, &off, \
295
scp_data, size); \
296
}
297
298
#define IPL_ATTR_SCP_DATA_STORE_FN(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len)\
299
static ssize_t sys_##_prefix##_scp_data_store(struct file *filp, \
300
struct kobject *kobj, \
301
const struct bin_attribute *attr, \
302
char *buf, loff_t off, \
303
size_t count) \
304
{ \
305
size_t scpdata_len = count; \
306
size_t padding; \
307
\
308
if (off) \
309
return -EINVAL; \
310
\
311
memcpy(_ipl_block.scp_data, buf, count); \
312
if (scpdata_len % 8) { \
313
padding = 8 - (scpdata_len % 8); \
314
memset(_ipl_block.scp_data + scpdata_len, \
315
0, padding); \
316
scpdata_len += padding; \
317
} \
318
\
319
_ipl_block_hdr.len = _ipl_bp_len + scpdata_len; \
320
_ipl_block.len = _ipl_bp0_len + scpdata_len; \
321
_ipl_block.scp_data_len = scpdata_len; \
322
\
323
return count; \
324
}
325
326
#define DEFINE_IPL_ATTR_SCP_DATA_RO(_prefix, _ipl_block, _size) \
327
IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \
328
static const struct bin_attribute sys_##_prefix##_scp_data_attr = \
329
__BIN_ATTR(scp_data, 0444, sys_##_prefix##_scp_data_show, \
330
NULL, _size)
331
332
#define DEFINE_IPL_ATTR_SCP_DATA_RW(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len, _size)\
333
IPL_ATTR_SCP_DATA_SHOW_FN(_prefix, _ipl_block) \
334
IPL_ATTR_SCP_DATA_STORE_FN(_prefix, _ipl_block_hdr, _ipl_block, _ipl_bp_len, _ipl_bp0_len)\
335
static const struct bin_attribute sys_##_prefix##_scp_data_attr = \
336
__BIN_ATTR(scp_data, 0644, sys_##_prefix##_scp_data_show, \
337
sys_##_prefix##_scp_data_store, _size)
338
339
/*
340
* ipl section
341
*/
342
343
static __init enum ipl_type get_ipl_type(void)
344
{
345
if (!ipl_block_valid)
346
return IPL_TYPE_UNKNOWN;
347
348
switch (ipl_block.pb0_hdr.pbt) {
349
case IPL_PBT_CCW:
350
return IPL_TYPE_CCW;
351
case IPL_PBT_FCP:
352
if (ipl_block.fcp.opt == IPL_PB0_FCP_OPT_DUMP)
353
return IPL_TYPE_FCP_DUMP;
354
else
355
return IPL_TYPE_FCP;
356
case IPL_PBT_NVME:
357
if (ipl_block.nvme.opt == IPL_PB0_NVME_OPT_DUMP)
358
return IPL_TYPE_NVME_DUMP;
359
else
360
return IPL_TYPE_NVME;
361
case IPL_PBT_ECKD:
362
if (ipl_block.eckd.opt == IPL_PB0_ECKD_OPT_DUMP)
363
return IPL_TYPE_ECKD_DUMP;
364
else
365
return IPL_TYPE_ECKD;
366
}
367
return IPL_TYPE_UNKNOWN;
368
}
369
370
struct ipl_info ipl_info;
371
EXPORT_SYMBOL_GPL(ipl_info);
372
373
static ssize_t ipl_type_show(struct kobject *kobj, struct kobj_attribute *attr,
374
char *page)
375
{
376
return sysfs_emit(page, "%s\n", ipl_type_str(ipl_info.type));
377
}
378
379
static struct kobj_attribute sys_ipl_type_attr = __ATTR_RO(ipl_type);
380
381
static ssize_t ipl_secure_show(struct kobject *kobj,
382
struct kobj_attribute *attr, char *page)
383
{
384
return sysfs_emit(page, "%i\n", !!ipl_secure_flag);
385
}
386
387
static struct kobj_attribute sys_ipl_secure_attr =
388
__ATTR(secure, 0444, ipl_secure_show, NULL);
389
390
static ssize_t ipl_has_secure_show(struct kobject *kobj,
391
struct kobj_attribute *attr, char *page)
392
{
393
return sysfs_emit(page, "%i\n", !!sclp.has_sipl);
394
}
395
396
static struct kobj_attribute sys_ipl_has_secure_attr =
397
__ATTR(has_secure, 0444, ipl_has_secure_show, NULL);
398
399
static ssize_t ipl_vm_parm_show(struct kobject *kobj,
400
struct kobj_attribute *attr, char *page)
401
{
402
char parm[DIAG308_VMPARM_SIZE + 1] = {};
403
404
if (ipl_block_valid && (ipl_block.pb0_hdr.pbt == IPL_PBT_CCW))
405
ipl_block_get_ascii_vmparm(parm, sizeof(parm), &ipl_block);
406
return sysfs_emit(page, "%s\n", parm);
407
}
408
409
static struct kobj_attribute sys_ipl_vm_parm_attr =
410
__ATTR(parm, 0444, ipl_vm_parm_show, NULL);
411
412
static ssize_t sys_ipl_device_show(struct kobject *kobj,
413
struct kobj_attribute *attr, char *page)
414
{
415
switch (ipl_info.type) {
416
case IPL_TYPE_CCW:
417
return sysfs_emit(page, "0.%x.%04x\n", ipl_block.ccw.ssid,
418
ipl_block.ccw.devno);
419
case IPL_TYPE_ECKD:
420
case IPL_TYPE_ECKD_DUMP:
421
return sysfs_emit(page, "0.%x.%04x\n", ipl_block.eckd.ssid,
422
ipl_block.eckd.devno);
423
case IPL_TYPE_FCP:
424
case IPL_TYPE_FCP_DUMP:
425
return sysfs_emit(page, "0.0.%04x\n", ipl_block.fcp.devno);
426
case IPL_TYPE_NVME:
427
case IPL_TYPE_NVME_DUMP:
428
return sysfs_emit(page, "%08ux\n", ipl_block.nvme.fid);
429
default:
430
return 0;
431
}
432
}
433
434
static struct kobj_attribute sys_ipl_device_attr =
435
__ATTR(device, 0444, sys_ipl_device_show, NULL);
436
437
static ssize_t sys_ipl_parameter_read(struct file *filp, struct kobject *kobj,
438
const struct bin_attribute *attr, char *buf,
439
loff_t off, size_t count)
440
{
441
return memory_read_from_buffer(buf, count, &off, &ipl_block,
442
ipl_block.hdr.len);
443
}
444
static const struct bin_attribute sys_ipl_parameter_attr =
445
__BIN_ATTR(binary_parameter, 0444, sys_ipl_parameter_read, NULL,
446
PAGE_SIZE);
447
448
DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_fcp, ipl_block.fcp, PAGE_SIZE);
449
450
static const struct bin_attribute *const ipl_fcp_bin_attrs[] = {
451
&sys_ipl_parameter_attr,
452
&sys_ipl_fcp_scp_data_attr,
453
NULL,
454
};
455
456
DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_nvme, ipl_block.nvme, PAGE_SIZE);
457
458
static const struct bin_attribute *const ipl_nvme_bin_attrs[] = {
459
&sys_ipl_parameter_attr,
460
&sys_ipl_nvme_scp_data_attr,
461
NULL,
462
};
463
464
DEFINE_IPL_ATTR_SCP_DATA_RO(ipl_eckd, ipl_block.eckd, PAGE_SIZE);
465
466
static const struct bin_attribute *const ipl_eckd_bin_attrs[] = {
467
&sys_ipl_parameter_attr,
468
&sys_ipl_eckd_scp_data_attr,
469
NULL,
470
};
471
472
/* FCP ipl device attributes */
473
474
DEFINE_IPL_ATTR_RO(ipl_fcp, wwpn, "0x%016llx\n",
475
(unsigned long long)ipl_block.fcp.wwpn);
476
DEFINE_IPL_ATTR_RO(ipl_fcp, lun, "0x%016llx\n",
477
(unsigned long long)ipl_block.fcp.lun);
478
DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n",
479
(unsigned long long)ipl_block.fcp.bootprog);
480
DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n",
481
(unsigned long long)ipl_block.fcp.br_lba);
482
483
/* NVMe ipl device attributes */
484
DEFINE_IPL_ATTR_RO(ipl_nvme, fid, "0x%08llx\n",
485
(unsigned long long)ipl_block.nvme.fid);
486
DEFINE_IPL_ATTR_RO(ipl_nvme, nsid, "0x%08llx\n",
487
(unsigned long long)ipl_block.nvme.nsid);
488
DEFINE_IPL_ATTR_RO(ipl_nvme, bootprog, "%lld\n",
489
(unsigned long long)ipl_block.nvme.bootprog);
490
DEFINE_IPL_ATTR_RO(ipl_nvme, br_lba, "%lld\n",
491
(unsigned long long)ipl_block.nvme.br_lba);
492
493
/* ECKD ipl device attributes */
494
DEFINE_IPL_ATTR_RO(ipl_eckd, bootprog, "%lld\n",
495
(unsigned long long)ipl_block.eckd.bootprog);
496
497
#define IPL_ATTR_BR_CHR_SHOW_FN(_name, _ipb) \
498
static ssize_t eckd_##_name##_br_chr_show(struct kobject *kobj, \
499
struct kobj_attribute *attr, \
500
char *buf) \
501
{ \
502
struct ipl_pb0_eckd *ipb = &(_ipb); \
503
\
504
if (!ipb->br_chr.cyl && \
505
!ipb->br_chr.head && \
506
!ipb->br_chr.record) \
507
return sysfs_emit(buf, "auto\n"); \
508
\
509
return sysfs_emit(buf, "0x%x,0x%x,0x%x\n", \
510
ipb->br_chr.cyl, \
511
ipb->br_chr.head, \
512
ipb->br_chr.record); \
513
}
514
515
#define IPL_ATTR_BR_CHR_STORE_FN(_name, _ipb) \
516
static ssize_t eckd_##_name##_br_chr_store(struct kobject *kobj, \
517
struct kobj_attribute *attr, \
518
const char *buf, size_t len) \
519
{ \
520
struct ipl_pb0_eckd *ipb = &(_ipb); \
521
unsigned long args[3] = { 0 }; \
522
char *p, *p1, *tmp = NULL; \
523
int i, rc; \
524
\
525
if (!strncmp(buf, "auto", 4)) \
526
goto out; \
527
\
528
tmp = kstrdup(buf, GFP_KERNEL); \
529
p = tmp; \
530
for (i = 0; i < 3; i++) { \
531
p1 = strsep(&p, ", "); \
532
if (!p1) { \
533
rc = -EINVAL; \
534
goto err; \
535
} \
536
rc = kstrtoul(p1, 0, args + i); \
537
if (rc) \
538
goto err; \
539
} \
540
\
541
rc = -EINVAL; \
542
if (i != 3) \
543
goto err; \
544
\
545
if ((args[0] || args[1]) && !args[2]) \
546
goto err; \
547
\
548
if (args[0] > UINT_MAX || args[1] > 255 || args[2] > 255) \
549
goto err; \
550
\
551
out: \
552
ipb->br_chr.cyl = args[0]; \
553
ipb->br_chr.head = args[1]; \
554
ipb->br_chr.record = args[2]; \
555
rc = len; \
556
err: \
557
kfree(tmp); \
558
return rc; \
559
}
560
561
IPL_ATTR_BR_CHR_SHOW_FN(ipl, ipl_block.eckd);
562
static struct kobj_attribute sys_ipl_eckd_br_chr_attr =
563
__ATTR(br_chr, 0644, eckd_ipl_br_chr_show, NULL);
564
565
IPL_ATTR_BR_CHR_SHOW_FN(reipl, reipl_block_eckd->eckd);
566
IPL_ATTR_BR_CHR_STORE_FN(reipl, reipl_block_eckd->eckd);
567
568
static struct kobj_attribute sys_reipl_eckd_br_chr_attr =
569
__ATTR(br_chr, 0644, eckd_reipl_br_chr_show, eckd_reipl_br_chr_store);
570
571
static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
572
struct kobj_attribute *attr, char *page)
573
{
574
char loadparm[LOADPARM_LEN + 1] = {};
575
576
if (!sclp_ipl_info.is_valid)
577
return sysfs_emit(page, "#unknown#\n");
578
memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
579
EBCASC(loadparm, LOADPARM_LEN);
580
strim(loadparm);
581
return sysfs_emit(page, "%s\n", loadparm);
582
}
583
584
static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
585
__ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
586
587
static struct attribute *ipl_fcp_attrs[] = {
588
&sys_ipl_device_attr.attr,
589
&sys_ipl_fcp_wwpn_attr.attr,
590
&sys_ipl_fcp_lun_attr.attr,
591
&sys_ipl_fcp_bootprog_attr.attr,
592
&sys_ipl_fcp_br_lba_attr.attr,
593
&sys_ipl_ccw_loadparm_attr.attr,
594
NULL,
595
};
596
597
static const struct attribute_group ipl_fcp_attr_group = {
598
.attrs = ipl_fcp_attrs,
599
.bin_attrs = ipl_fcp_bin_attrs,
600
};
601
602
static struct attribute *ipl_nvme_attrs[] = {
603
&sys_ipl_nvme_fid_attr.attr,
604
&sys_ipl_nvme_nsid_attr.attr,
605
&sys_ipl_nvme_bootprog_attr.attr,
606
&sys_ipl_nvme_br_lba_attr.attr,
607
&sys_ipl_ccw_loadparm_attr.attr,
608
NULL,
609
};
610
611
static const struct attribute_group ipl_nvme_attr_group = {
612
.attrs = ipl_nvme_attrs,
613
.bin_attrs = ipl_nvme_bin_attrs,
614
};
615
616
static struct attribute *ipl_eckd_attrs[] = {
617
&sys_ipl_eckd_bootprog_attr.attr,
618
&sys_ipl_eckd_br_chr_attr.attr,
619
&sys_ipl_ccw_loadparm_attr.attr,
620
&sys_ipl_device_attr.attr,
621
NULL,
622
};
623
624
static const struct attribute_group ipl_eckd_attr_group = {
625
.attrs = ipl_eckd_attrs,
626
.bin_attrs = ipl_eckd_bin_attrs,
627
};
628
629
/* CCW ipl device attributes */
630
631
static struct attribute *ipl_ccw_attrs_vm[] = {
632
&sys_ipl_device_attr.attr,
633
&sys_ipl_ccw_loadparm_attr.attr,
634
&sys_ipl_vm_parm_attr.attr,
635
NULL,
636
};
637
638
static struct attribute *ipl_ccw_attrs_lpar[] = {
639
&sys_ipl_device_attr.attr,
640
&sys_ipl_ccw_loadparm_attr.attr,
641
NULL,
642
};
643
644
static const struct attribute_group ipl_ccw_attr_group_vm = {
645
.attrs = ipl_ccw_attrs_vm,
646
};
647
648
static const struct attribute_group ipl_ccw_attr_group_lpar = {
649
.attrs = ipl_ccw_attrs_lpar
650
};
651
652
static struct attribute *ipl_common_attrs[] = {
653
&sys_ipl_type_attr.attr,
654
&sys_ipl_secure_attr.attr,
655
&sys_ipl_has_secure_attr.attr,
656
NULL,
657
};
658
659
static const struct attribute_group ipl_common_attr_group = {
660
.attrs = ipl_common_attrs,
661
};
662
663
static struct kset *ipl_kset;
664
665
static void __ipl_run(void *unused)
666
{
667
diag308(DIAG308_LOAD_CLEAR, NULL);
668
}
669
670
static void ipl_run(struct shutdown_trigger *trigger)
671
{
672
smp_call_ipl_cpu(__ipl_run, NULL);
673
}
674
675
static int __init ipl_init(void)
676
{
677
int rc;
678
679
ipl_kset = kset_create_and_add("ipl", NULL, firmware_kobj);
680
if (!ipl_kset) {
681
rc = -ENOMEM;
682
goto out;
683
}
684
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_common_attr_group);
685
if (rc)
686
goto out;
687
switch (ipl_info.type) {
688
case IPL_TYPE_CCW:
689
if (machine_is_vm())
690
rc = sysfs_create_group(&ipl_kset->kobj,
691
&ipl_ccw_attr_group_vm);
692
else
693
rc = sysfs_create_group(&ipl_kset->kobj,
694
&ipl_ccw_attr_group_lpar);
695
break;
696
case IPL_TYPE_ECKD:
697
case IPL_TYPE_ECKD_DUMP:
698
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_eckd_attr_group);
699
break;
700
case IPL_TYPE_FCP:
701
case IPL_TYPE_FCP_DUMP:
702
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_fcp_attr_group);
703
break;
704
case IPL_TYPE_NVME:
705
case IPL_TYPE_NVME_DUMP:
706
rc = sysfs_create_group(&ipl_kset->kobj, &ipl_nvme_attr_group);
707
break;
708
default:
709
break;
710
}
711
out:
712
if (rc)
713
panic("ipl_init failed: rc = %i\n", rc);
714
715
return 0;
716
}
717
718
static struct shutdown_action __refdata ipl_action = {
719
.name = SHUTDOWN_ACTION_IPL_STR,
720
.fn = ipl_run,
721
.init = ipl_init,
722
};
723
724
/*
725
* reipl shutdown action: Reboot Linux on shutdown.
726
*/
727
728
/* VM IPL PARM attributes */
729
static ssize_t reipl_generic_vmparm_show(struct ipl_parameter_block *ipb,
730
char *page)
731
{
732
char vmparm[DIAG308_VMPARM_SIZE + 1] = {};
733
734
ipl_block_get_ascii_vmparm(vmparm, sizeof(vmparm), ipb);
735
return sysfs_emit(page, "%s\n", vmparm);
736
}
737
738
static ssize_t reipl_generic_vmparm_store(struct ipl_parameter_block *ipb,
739
size_t vmparm_max,
740
const char *buf, size_t len)
741
{
742
int i, ip_len;
743
744
/* ignore trailing newline */
745
ip_len = len;
746
if ((len > 0) && (buf[len - 1] == '\n'))
747
ip_len--;
748
749
if (ip_len > vmparm_max)
750
return -EINVAL;
751
752
/* parm is used to store kernel options, check for common chars */
753
for (i = 0; i < ip_len; i++)
754
if (!(isalnum(buf[i]) || isascii(buf[i]) || isprint(buf[i])))
755
return -EINVAL;
756
757
memset(ipb->ccw.vm_parm, 0, DIAG308_VMPARM_SIZE);
758
ipb->ccw.vm_parm_len = ip_len;
759
if (ip_len > 0) {
760
ipb->ccw.vm_flags |= IPL_PB0_CCW_VM_FLAG_VP;
761
memcpy(ipb->ccw.vm_parm, buf, ip_len);
762
ASCEBC(ipb->ccw.vm_parm, ip_len);
763
} else {
764
ipb->ccw.vm_flags &= ~IPL_PB0_CCW_VM_FLAG_VP;
765
}
766
767
return len;
768
}
769
770
/* NSS wrapper */
771
static ssize_t reipl_nss_vmparm_show(struct kobject *kobj,
772
struct kobj_attribute *attr, char *page)
773
{
774
return reipl_generic_vmparm_show(reipl_block_nss, page);
775
}
776
777
static ssize_t reipl_nss_vmparm_store(struct kobject *kobj,
778
struct kobj_attribute *attr,
779
const char *buf, size_t len)
780
{
781
return reipl_generic_vmparm_store(reipl_block_nss, 56, buf, len);
782
}
783
784
/* CCW wrapper */
785
static ssize_t reipl_ccw_vmparm_show(struct kobject *kobj,
786
struct kobj_attribute *attr, char *page)
787
{
788
return reipl_generic_vmparm_show(reipl_block_ccw, page);
789
}
790
791
static ssize_t reipl_ccw_vmparm_store(struct kobject *kobj,
792
struct kobj_attribute *attr,
793
const char *buf, size_t len)
794
{
795
return reipl_generic_vmparm_store(reipl_block_ccw, 64, buf, len);
796
}
797
798
static struct kobj_attribute sys_reipl_nss_vmparm_attr =
799
__ATTR(parm, 0644, reipl_nss_vmparm_show,
800
reipl_nss_vmparm_store);
801
static struct kobj_attribute sys_reipl_ccw_vmparm_attr =
802
__ATTR(parm, 0644, reipl_ccw_vmparm_show,
803
reipl_ccw_vmparm_store);
804
805
/* FCP reipl device attributes */
806
807
DEFINE_IPL_ATTR_SCP_DATA_RW(reipl_fcp, reipl_block_fcp->hdr,
808
reipl_block_fcp->fcp,
809
IPL_BP_FCP_LEN, IPL_BP0_FCP_LEN,
810
DIAG308_SCPDATA_SIZE);
811
812
static const struct bin_attribute *const reipl_fcp_bin_attrs[] = {
813
&sys_reipl_fcp_scp_data_attr,
814
NULL,
815
};
816
817
DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n",
818
reipl_block_fcp->fcp.wwpn);
819
DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n",
820
reipl_block_fcp->fcp.lun);
821
DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
822
reipl_block_fcp->fcp.bootprog);
823
DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
824
reipl_block_fcp->fcp.br_lba);
825
DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
826
reipl_block_fcp->fcp.devno);
827
828
static void reipl_get_ascii_loadparm(char *loadparm,
829
struct ipl_parameter_block *ibp)
830
{
831
memcpy(loadparm, ibp->common.loadparm, LOADPARM_LEN);
832
EBCASC(loadparm, LOADPARM_LEN);
833
loadparm[LOADPARM_LEN] = 0;
834
strim(loadparm);
835
}
836
837
static ssize_t reipl_generic_loadparm_show(struct ipl_parameter_block *ipb,
838
char *page)
839
{
840
char buf[LOADPARM_LEN + 1];
841
842
reipl_get_ascii_loadparm(buf, ipb);
843
return sysfs_emit(page, "%s\n", buf);
844
}
845
846
static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb,
847
const char *buf, size_t len)
848
{
849
int i, lp_len;
850
851
/* ignore trailing newline */
852
lp_len = len;
853
if ((len > 0) && (buf[len - 1] == '\n'))
854
lp_len--;
855
/* loadparm can have max 8 characters and must not start with a blank */
856
if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' ')))
857
return -EINVAL;
858
/* loadparm can only contain "a-z,A-Z,0-9,SP,." */
859
for (i = 0; i < lp_len; i++) {
860
if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') ||
861
(buf[i] == '.'))
862
continue;
863
return -EINVAL;
864
}
865
/* initialize loadparm with blanks */
866
memset(ipb->common.loadparm, ' ', LOADPARM_LEN);
867
/* copy and convert to ebcdic */
868
memcpy(ipb->common.loadparm, buf, lp_len);
869
ASCEBC(ipb->common.loadparm, LOADPARM_LEN);
870
ipb->common.flags |= IPL_PB0_FLAG_LOADPARM;
871
return len;
872
}
873
874
#define DEFINE_GENERIC_LOADPARM(name) \
875
static ssize_t reipl_##name##_loadparm_show(struct kobject *kobj, \
876
struct kobj_attribute *attr, char *page) \
877
{ \
878
return reipl_generic_loadparm_show(reipl_block_##name, page); \
879
} \
880
static ssize_t reipl_##name##_loadparm_store(struct kobject *kobj, \
881
struct kobj_attribute *attr, \
882
const char *buf, size_t len) \
883
{ \
884
return reipl_generic_loadparm_store(reipl_block_##name, buf, len); \
885
} \
886
static struct kobj_attribute sys_reipl_##name##_loadparm_attr = \
887
__ATTR(loadparm, 0644, reipl_##name##_loadparm_show, \
888
reipl_##name##_loadparm_store)
889
890
DEFINE_GENERIC_LOADPARM(fcp);
891
DEFINE_GENERIC_LOADPARM(nvme);
892
DEFINE_GENERIC_LOADPARM(ccw);
893
DEFINE_GENERIC_LOADPARM(nss);
894
DEFINE_GENERIC_LOADPARM(eckd);
895
896
static ssize_t reipl_fcp_clear_show(struct kobject *kobj,
897
struct kobj_attribute *attr, char *page)
898
{
899
return sysfs_emit(page, "%u\n", reipl_fcp_clear);
900
}
901
902
static ssize_t reipl_fcp_clear_store(struct kobject *kobj,
903
struct kobj_attribute *attr,
904
const char *buf, size_t len)
905
{
906
if (kstrtobool(buf, &reipl_fcp_clear) < 0)
907
return -EINVAL;
908
return len;
909
}
910
911
static struct attribute *reipl_fcp_attrs[] = {
912
&sys_reipl_fcp_device_attr.attr,
913
&sys_reipl_fcp_wwpn_attr.attr,
914
&sys_reipl_fcp_lun_attr.attr,
915
&sys_reipl_fcp_bootprog_attr.attr,
916
&sys_reipl_fcp_br_lba_attr.attr,
917
&sys_reipl_fcp_loadparm_attr.attr,
918
NULL,
919
};
920
921
static const struct attribute_group reipl_fcp_attr_group = {
922
.attrs = reipl_fcp_attrs,
923
.bin_attrs = reipl_fcp_bin_attrs,
924
};
925
926
static struct kobj_attribute sys_reipl_fcp_clear_attr =
927
__ATTR(clear, 0644, reipl_fcp_clear_show, reipl_fcp_clear_store);
928
929
/* NVME reipl device attributes */
930
931
DEFINE_IPL_ATTR_SCP_DATA_RW(reipl_nvme, reipl_block_nvme->hdr,
932
reipl_block_nvme->nvme,
933
IPL_BP_NVME_LEN, IPL_BP0_NVME_LEN,
934
DIAG308_SCPDATA_SIZE);
935
936
static const struct bin_attribute *const reipl_nvme_bin_attrs[] = {
937
&sys_reipl_nvme_scp_data_attr,
938
NULL,
939
};
940
941
DEFINE_IPL_ATTR_RW(reipl_nvme, fid, "0x%08llx\n", "%llx\n",
942
reipl_block_nvme->nvme.fid);
943
DEFINE_IPL_ATTR_RW(reipl_nvme, nsid, "0x%08llx\n", "%llx\n",
944
reipl_block_nvme->nvme.nsid);
945
DEFINE_IPL_ATTR_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n",
946
reipl_block_nvme->nvme.bootprog);
947
DEFINE_IPL_ATTR_RW(reipl_nvme, br_lba, "%lld\n", "%lld\n",
948
reipl_block_nvme->nvme.br_lba);
949
950
static struct attribute *reipl_nvme_attrs[] = {
951
&sys_reipl_nvme_fid_attr.attr,
952
&sys_reipl_nvme_nsid_attr.attr,
953
&sys_reipl_nvme_bootprog_attr.attr,
954
&sys_reipl_nvme_br_lba_attr.attr,
955
&sys_reipl_nvme_loadparm_attr.attr,
956
NULL,
957
};
958
959
static const struct attribute_group reipl_nvme_attr_group = {
960
.attrs = reipl_nvme_attrs,
961
.bin_attrs = reipl_nvme_bin_attrs
962
};
963
964
static ssize_t reipl_nvme_clear_show(struct kobject *kobj,
965
struct kobj_attribute *attr, char *page)
966
{
967
return sysfs_emit(page, "%u\n", reipl_nvme_clear);
968
}
969
970
static ssize_t reipl_nvme_clear_store(struct kobject *kobj,
971
struct kobj_attribute *attr,
972
const char *buf, size_t len)
973
{
974
if (kstrtobool(buf, &reipl_nvme_clear) < 0)
975
return -EINVAL;
976
return len;
977
}
978
979
static struct kobj_attribute sys_reipl_nvme_clear_attr =
980
__ATTR(clear, 0644, reipl_nvme_clear_show, reipl_nvme_clear_store);
981
982
/* CCW reipl device attributes */
983
DEFINE_IPL_CCW_ATTR_RW(reipl_ccw, device, reipl_block_ccw->ccw);
984
985
static ssize_t reipl_ccw_clear_show(struct kobject *kobj,
986
struct kobj_attribute *attr, char *page)
987
{
988
return sysfs_emit(page, "%u\n", reipl_ccw_clear);
989
}
990
991
static ssize_t reipl_ccw_clear_store(struct kobject *kobj,
992
struct kobj_attribute *attr,
993
const char *buf, size_t len)
994
{
995
if (kstrtobool(buf, &reipl_ccw_clear) < 0)
996
return -EINVAL;
997
return len;
998
}
999
1000
static struct kobj_attribute sys_reipl_ccw_clear_attr =
1001
__ATTR(clear, 0644, reipl_ccw_clear_show, reipl_ccw_clear_store);
1002
1003
static struct attribute *reipl_ccw_attrs_vm[] = {
1004
&sys_reipl_ccw_device_attr.attr,
1005
&sys_reipl_ccw_loadparm_attr.attr,
1006
&sys_reipl_ccw_vmparm_attr.attr,
1007
&sys_reipl_ccw_clear_attr.attr,
1008
NULL,
1009
};
1010
1011
static struct attribute *reipl_ccw_attrs_lpar[] = {
1012
&sys_reipl_ccw_device_attr.attr,
1013
&sys_reipl_ccw_loadparm_attr.attr,
1014
&sys_reipl_ccw_clear_attr.attr,
1015
NULL,
1016
};
1017
1018
static struct attribute_group reipl_ccw_attr_group_vm = {
1019
.name = IPL_CCW_STR,
1020
.attrs = reipl_ccw_attrs_vm,
1021
};
1022
1023
static struct attribute_group reipl_ccw_attr_group_lpar = {
1024
.name = IPL_CCW_STR,
1025
.attrs = reipl_ccw_attrs_lpar,
1026
};
1027
1028
/* ECKD reipl device attributes */
1029
1030
DEFINE_IPL_ATTR_SCP_DATA_RW(reipl_eckd, reipl_block_eckd->hdr,
1031
reipl_block_eckd->eckd,
1032
IPL_BP_ECKD_LEN, IPL_BP0_ECKD_LEN,
1033
DIAG308_SCPDATA_SIZE);
1034
1035
static const struct bin_attribute *const reipl_eckd_bin_attrs[] = {
1036
&sys_reipl_eckd_scp_data_attr,
1037
NULL,
1038
};
1039
1040
DEFINE_IPL_CCW_ATTR_RW(reipl_eckd, device, reipl_block_eckd->eckd);
1041
DEFINE_IPL_ATTR_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n",
1042
reipl_block_eckd->eckd.bootprog);
1043
1044
static struct attribute *reipl_eckd_attrs[] = {
1045
&sys_reipl_eckd_device_attr.attr,
1046
&sys_reipl_eckd_bootprog_attr.attr,
1047
&sys_reipl_eckd_br_chr_attr.attr,
1048
&sys_reipl_eckd_loadparm_attr.attr,
1049
NULL,
1050
};
1051
1052
static const struct attribute_group reipl_eckd_attr_group = {
1053
.attrs = reipl_eckd_attrs,
1054
.bin_attrs = reipl_eckd_bin_attrs
1055
};
1056
1057
static ssize_t reipl_eckd_clear_show(struct kobject *kobj,
1058
struct kobj_attribute *attr, char *page)
1059
{
1060
return sysfs_emit(page, "%u\n", reipl_eckd_clear);
1061
}
1062
1063
static ssize_t reipl_eckd_clear_store(struct kobject *kobj,
1064
struct kobj_attribute *attr,
1065
const char *buf, size_t len)
1066
{
1067
if (kstrtobool(buf, &reipl_eckd_clear) < 0)
1068
return -EINVAL;
1069
return len;
1070
}
1071
1072
static struct kobj_attribute sys_reipl_eckd_clear_attr =
1073
__ATTR(clear, 0644, reipl_eckd_clear_show, reipl_eckd_clear_store);
1074
1075
/* NSS reipl device attributes */
1076
static void reipl_get_ascii_nss_name(char *dst,
1077
struct ipl_parameter_block *ipb)
1078
{
1079
memcpy(dst, ipb->ccw.nss_name, NSS_NAME_SIZE);
1080
EBCASC(dst, NSS_NAME_SIZE);
1081
dst[NSS_NAME_SIZE] = 0;
1082
}
1083
1084
static ssize_t reipl_nss_name_show(struct kobject *kobj,
1085
struct kobj_attribute *attr, char *page)
1086
{
1087
char nss_name[NSS_NAME_SIZE + 1] = {};
1088
1089
reipl_get_ascii_nss_name(nss_name, reipl_block_nss);
1090
return sysfs_emit(page, "%s\n", nss_name);
1091
}
1092
1093
static ssize_t reipl_nss_name_store(struct kobject *kobj,
1094
struct kobj_attribute *attr,
1095
const char *buf, size_t len)
1096
{
1097
int nss_len;
1098
1099
/* ignore trailing newline */
1100
nss_len = len;
1101
if ((len > 0) && (buf[len - 1] == '\n'))
1102
nss_len--;
1103
1104
if (nss_len > NSS_NAME_SIZE)
1105
return -EINVAL;
1106
1107
memset(reipl_block_nss->ccw.nss_name, 0x40, NSS_NAME_SIZE);
1108
if (nss_len > 0) {
1109
reipl_block_nss->ccw.vm_flags |= IPL_PB0_CCW_VM_FLAG_NSS;
1110
memcpy(reipl_block_nss->ccw.nss_name, buf, nss_len);
1111
ASCEBC(reipl_block_nss->ccw.nss_name, nss_len);
1112
EBC_TOUPPER(reipl_block_nss->ccw.nss_name, nss_len);
1113
} else {
1114
reipl_block_nss->ccw.vm_flags &= ~IPL_PB0_CCW_VM_FLAG_NSS;
1115
}
1116
1117
return len;
1118
}
1119
1120
static struct kobj_attribute sys_reipl_nss_name_attr =
1121
__ATTR(name, 0644, reipl_nss_name_show,
1122
reipl_nss_name_store);
1123
1124
static struct attribute *reipl_nss_attrs[] = {
1125
&sys_reipl_nss_name_attr.attr,
1126
&sys_reipl_nss_loadparm_attr.attr,
1127
&sys_reipl_nss_vmparm_attr.attr,
1128
NULL,
1129
};
1130
1131
static struct attribute_group reipl_nss_attr_group = {
1132
.name = IPL_NSS_STR,
1133
.attrs = reipl_nss_attrs,
1134
};
1135
1136
void set_os_info_reipl_block(void)
1137
{
1138
os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
1139
reipl_block_actual->hdr.len);
1140
}
1141
1142
/* reipl type */
1143
1144
static int reipl_set_type(enum ipl_type type)
1145
{
1146
if (!(reipl_capabilities & type))
1147
return -EINVAL;
1148
1149
switch(type) {
1150
case IPL_TYPE_CCW:
1151
reipl_block_actual = reipl_block_ccw;
1152
break;
1153
case IPL_TYPE_ECKD:
1154
reipl_block_actual = reipl_block_eckd;
1155
break;
1156
case IPL_TYPE_FCP:
1157
reipl_block_actual = reipl_block_fcp;
1158
break;
1159
case IPL_TYPE_NVME:
1160
reipl_block_actual = reipl_block_nvme;
1161
break;
1162
case IPL_TYPE_NSS:
1163
reipl_block_actual = reipl_block_nss;
1164
break;
1165
default:
1166
break;
1167
}
1168
reipl_type = type;
1169
return 0;
1170
}
1171
1172
static ssize_t reipl_type_show(struct kobject *kobj,
1173
struct kobj_attribute *attr, char *page)
1174
{
1175
return sysfs_emit(page, "%s\n", ipl_type_str(reipl_type));
1176
}
1177
1178
static ssize_t reipl_type_store(struct kobject *kobj,
1179
struct kobj_attribute *attr,
1180
const char *buf, size_t len)
1181
{
1182
int rc = -EINVAL;
1183
1184
if (strncmp(buf, IPL_CCW_STR, strlen(IPL_CCW_STR)) == 0)
1185
rc = reipl_set_type(IPL_TYPE_CCW);
1186
else if (strncmp(buf, IPL_ECKD_STR, strlen(IPL_ECKD_STR)) == 0)
1187
rc = reipl_set_type(IPL_TYPE_ECKD);
1188
else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
1189
rc = reipl_set_type(IPL_TYPE_FCP);
1190
else if (strncmp(buf, IPL_NVME_STR, strlen(IPL_NVME_STR)) == 0)
1191
rc = reipl_set_type(IPL_TYPE_NVME);
1192
else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0)
1193
rc = reipl_set_type(IPL_TYPE_NSS);
1194
return (rc != 0) ? rc : len;
1195
}
1196
1197
static struct kobj_attribute reipl_type_attr =
1198
__ATTR(reipl_type, 0644, reipl_type_show, reipl_type_store);
1199
1200
static struct kset *reipl_kset;
1201
static struct kset *reipl_fcp_kset;
1202
static struct kset *reipl_nvme_kset;
1203
static struct kset *reipl_eckd_kset;
1204
1205
static void __reipl_run(void *unused)
1206
{
1207
switch (reipl_type) {
1208
case IPL_TYPE_CCW:
1209
diag308(DIAG308_SET, reipl_block_ccw);
1210
if (reipl_ccw_clear)
1211
diag308(DIAG308_LOAD_CLEAR, NULL);
1212
else
1213
diag308(DIAG308_LOAD_NORMAL_DUMP, NULL);
1214
break;
1215
case IPL_TYPE_ECKD:
1216
diag308(DIAG308_SET, reipl_block_eckd);
1217
if (reipl_eckd_clear)
1218
diag308(DIAG308_LOAD_CLEAR, NULL);
1219
else
1220
diag308(DIAG308_LOAD_NORMAL, NULL);
1221
break;
1222
case IPL_TYPE_FCP:
1223
diag308(DIAG308_SET, reipl_block_fcp);
1224
if (reipl_fcp_clear)
1225
diag308(DIAG308_LOAD_CLEAR, NULL);
1226
else
1227
diag308(DIAG308_LOAD_NORMAL, NULL);
1228
break;
1229
case IPL_TYPE_NVME:
1230
diag308(DIAG308_SET, reipl_block_nvme);
1231
if (reipl_nvme_clear)
1232
diag308(DIAG308_LOAD_CLEAR, NULL);
1233
else
1234
diag308(DIAG308_LOAD_NORMAL, NULL);
1235
break;
1236
case IPL_TYPE_NSS:
1237
diag308(DIAG308_SET, reipl_block_nss);
1238
diag308(DIAG308_LOAD_CLEAR, NULL);
1239
break;
1240
case IPL_TYPE_UNKNOWN:
1241
diag308(DIAG308_LOAD_CLEAR, NULL);
1242
break;
1243
case IPL_TYPE_FCP_DUMP:
1244
case IPL_TYPE_NVME_DUMP:
1245
case IPL_TYPE_ECKD_DUMP:
1246
break;
1247
}
1248
disabled_wait();
1249
}
1250
1251
static void reipl_run(struct shutdown_trigger *trigger)
1252
{
1253
smp_call_ipl_cpu(__reipl_run, NULL);
1254
}
1255
1256
static void reipl_block_ccw_init(struct ipl_parameter_block *ipb)
1257
{
1258
ipb->hdr.len = IPL_BP_CCW_LEN;
1259
ipb->hdr.version = IPL_PARM_BLOCK_VERSION;
1260
ipb->pb0_hdr.len = IPL_BP0_CCW_LEN;
1261
ipb->pb0_hdr.pbt = IPL_PBT_CCW;
1262
}
1263
1264
static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb)
1265
{
1266
/* LOADPARM */
1267
/* check if read scp info worked and set loadparm */
1268
if (sclp_ipl_info.is_valid)
1269
memcpy(ipb->ccw.loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
1270
else
1271
/* read scp info failed: set empty loadparm (EBCDIC blanks) */
1272
memset(ipb->ccw.loadparm, 0x40, LOADPARM_LEN);
1273
ipb->ccw.flags = IPL_PB0_FLAG_LOADPARM;
1274
1275
/* VM PARM */
1276
if (machine_is_vm() && ipl_block_valid &&
1277
(ipl_block.ccw.vm_flags & IPL_PB0_CCW_VM_FLAG_VP)) {
1278
1279
ipb->ccw.vm_flags |= IPL_PB0_CCW_VM_FLAG_VP;
1280
ipb->ccw.vm_parm_len = ipl_block.ccw.vm_parm_len;
1281
memcpy(ipb->ccw.vm_parm,
1282
ipl_block.ccw.vm_parm, DIAG308_VMPARM_SIZE);
1283
}
1284
}
1285
1286
static int __init reipl_nss_init(void)
1287
{
1288
int rc;
1289
1290
if (!machine_is_vm())
1291
return 0;
1292
1293
reipl_block_nss = (void *) get_zeroed_page(GFP_KERNEL);
1294
if (!reipl_block_nss)
1295
return -ENOMEM;
1296
1297
rc = sysfs_create_group(&reipl_kset->kobj, &reipl_nss_attr_group);
1298
if (rc)
1299
return rc;
1300
1301
reipl_block_ccw_init(reipl_block_nss);
1302
reipl_capabilities |= IPL_TYPE_NSS;
1303
return 0;
1304
}
1305
1306
static int __init reipl_ccw_init(void)
1307
{
1308
int rc;
1309
1310
reipl_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
1311
if (!reipl_block_ccw)
1312
return -ENOMEM;
1313
1314
rc = sysfs_create_group(&reipl_kset->kobj,
1315
machine_is_vm() ? &reipl_ccw_attr_group_vm
1316
: &reipl_ccw_attr_group_lpar);
1317
if (rc)
1318
return rc;
1319
1320
reipl_block_ccw_init(reipl_block_ccw);
1321
if (ipl_info.type == IPL_TYPE_CCW) {
1322
reipl_block_ccw->ccw.ssid = ipl_block.ccw.ssid;
1323
reipl_block_ccw->ccw.devno = ipl_block.ccw.devno;
1324
reipl_block_ccw_fill_parms(reipl_block_ccw);
1325
}
1326
1327
reipl_capabilities |= IPL_TYPE_CCW;
1328
return 0;
1329
}
1330
1331
static int __init reipl_fcp_init(void)
1332
{
1333
int rc;
1334
1335
reipl_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1336
if (!reipl_block_fcp)
1337
return -ENOMEM;
1338
1339
/* sysfs: create fcp kset for mixing attr group and bin attrs */
1340
reipl_fcp_kset = kset_create_and_add(IPL_FCP_STR, NULL,
1341
&reipl_kset->kobj);
1342
if (!reipl_fcp_kset) {
1343
free_page((unsigned long) reipl_block_fcp);
1344
return -ENOMEM;
1345
}
1346
1347
rc = sysfs_create_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1348
if (rc)
1349
goto out1;
1350
1351
if (test_facility(141)) {
1352
rc = sysfs_create_file(&reipl_fcp_kset->kobj,
1353
&sys_reipl_fcp_clear_attr.attr);
1354
if (rc)
1355
goto out2;
1356
} else {
1357
reipl_fcp_clear = true;
1358
}
1359
1360
if (ipl_info.type == IPL_TYPE_FCP) {
1361
memcpy(reipl_block_fcp, &ipl_block, sizeof(ipl_block));
1362
/*
1363
* Fix loadparm: There are systems where the (SCSI) LOADPARM
1364
* is invalid in the SCSI IPL parameter block, so take it
1365
* always from sclp_ipl_info.
1366
*/
1367
memcpy(reipl_block_fcp->fcp.loadparm, sclp_ipl_info.loadparm,
1368
LOADPARM_LEN);
1369
} else {
1370
reipl_block_fcp->hdr.len = IPL_BP_FCP_LEN;
1371
reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1372
reipl_block_fcp->fcp.len = IPL_BP0_FCP_LEN;
1373
reipl_block_fcp->fcp.pbt = IPL_PBT_FCP;
1374
reipl_block_fcp->fcp.opt = IPL_PB0_FCP_OPT_IPL;
1375
}
1376
reipl_capabilities |= IPL_TYPE_FCP;
1377
return 0;
1378
1379
out2:
1380
sysfs_remove_group(&reipl_fcp_kset->kobj, &reipl_fcp_attr_group);
1381
out1:
1382
kset_unregister(reipl_fcp_kset);
1383
free_page((unsigned long) reipl_block_fcp);
1384
return rc;
1385
}
1386
1387
static int __init reipl_nvme_init(void)
1388
{
1389
int rc;
1390
1391
reipl_block_nvme = (void *) get_zeroed_page(GFP_KERNEL);
1392
if (!reipl_block_nvme)
1393
return -ENOMEM;
1394
1395
/* sysfs: create kset for mixing attr group and bin attrs */
1396
reipl_nvme_kset = kset_create_and_add(IPL_NVME_STR, NULL,
1397
&reipl_kset->kobj);
1398
if (!reipl_nvme_kset) {
1399
free_page((unsigned long) reipl_block_nvme);
1400
return -ENOMEM;
1401
}
1402
1403
rc = sysfs_create_group(&reipl_nvme_kset->kobj, &reipl_nvme_attr_group);
1404
if (rc)
1405
goto out1;
1406
1407
if (test_facility(141)) {
1408
rc = sysfs_create_file(&reipl_nvme_kset->kobj,
1409
&sys_reipl_nvme_clear_attr.attr);
1410
if (rc)
1411
goto out2;
1412
} else {
1413
reipl_nvme_clear = true;
1414
}
1415
1416
if (ipl_info.type == IPL_TYPE_NVME) {
1417
memcpy(reipl_block_nvme, &ipl_block, sizeof(ipl_block));
1418
/*
1419
* Fix loadparm: There are systems where the (SCSI) LOADPARM
1420
* is invalid in the IPL parameter block, so take it
1421
* always from sclp_ipl_info.
1422
*/
1423
memcpy(reipl_block_nvme->nvme.loadparm, sclp_ipl_info.loadparm,
1424
LOADPARM_LEN);
1425
} else {
1426
reipl_block_nvme->hdr.len = IPL_BP_NVME_LEN;
1427
reipl_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION;
1428
reipl_block_nvme->nvme.len = IPL_BP0_NVME_LEN;
1429
reipl_block_nvme->nvme.pbt = IPL_PBT_NVME;
1430
reipl_block_nvme->nvme.opt = IPL_PB0_NVME_OPT_IPL;
1431
}
1432
reipl_capabilities |= IPL_TYPE_NVME;
1433
return 0;
1434
1435
out2:
1436
sysfs_remove_group(&reipl_nvme_kset->kobj, &reipl_nvme_attr_group);
1437
out1:
1438
kset_unregister(reipl_nvme_kset);
1439
free_page((unsigned long) reipl_block_nvme);
1440
return rc;
1441
}
1442
1443
static int __init reipl_eckd_init(void)
1444
{
1445
int rc;
1446
1447
if (!sclp.has_sipl_eckd)
1448
return 0;
1449
1450
reipl_block_eckd = (void *)get_zeroed_page(GFP_KERNEL);
1451
if (!reipl_block_eckd)
1452
return -ENOMEM;
1453
1454
/* sysfs: create kset for mixing attr group and bin attrs */
1455
reipl_eckd_kset = kset_create_and_add(IPL_ECKD_STR, NULL,
1456
&reipl_kset->kobj);
1457
if (!reipl_eckd_kset) {
1458
free_page((unsigned long)reipl_block_eckd);
1459
return -ENOMEM;
1460
}
1461
1462
rc = sysfs_create_group(&reipl_eckd_kset->kobj, &reipl_eckd_attr_group);
1463
if (rc)
1464
goto out1;
1465
1466
if (test_facility(141)) {
1467
rc = sysfs_create_file(&reipl_eckd_kset->kobj,
1468
&sys_reipl_eckd_clear_attr.attr);
1469
if (rc)
1470
goto out2;
1471
} else {
1472
reipl_eckd_clear = true;
1473
}
1474
1475
if (ipl_info.type == IPL_TYPE_ECKD) {
1476
memcpy(reipl_block_eckd, &ipl_block, sizeof(ipl_block));
1477
} else {
1478
reipl_block_eckd->hdr.len = IPL_BP_ECKD_LEN;
1479
reipl_block_eckd->hdr.version = IPL_PARM_BLOCK_VERSION;
1480
reipl_block_eckd->eckd.len = IPL_BP0_ECKD_LEN;
1481
reipl_block_eckd->eckd.pbt = IPL_PBT_ECKD;
1482
reipl_block_eckd->eckd.opt = IPL_PB0_ECKD_OPT_IPL;
1483
}
1484
reipl_capabilities |= IPL_TYPE_ECKD;
1485
return 0;
1486
1487
out2:
1488
sysfs_remove_group(&reipl_eckd_kset->kobj, &reipl_eckd_attr_group);
1489
out1:
1490
kset_unregister(reipl_eckd_kset);
1491
free_page((unsigned long)reipl_block_eckd);
1492
return rc;
1493
}
1494
1495
static int __init reipl_type_init(void)
1496
{
1497
enum ipl_type reipl_type = ipl_info.type;
1498
struct ipl_parameter_block *reipl_block;
1499
unsigned long size;
1500
1501
reipl_block = os_info_old_entry(OS_INFO_REIPL_BLOCK, &size);
1502
if (!reipl_block)
1503
goto out;
1504
/*
1505
* If we have an OS info reipl block, this will be used
1506
*/
1507
if (reipl_block->pb0_hdr.pbt == IPL_PBT_FCP) {
1508
memcpy(reipl_block_fcp, reipl_block, size);
1509
reipl_type = IPL_TYPE_FCP;
1510
} else if (reipl_block->pb0_hdr.pbt == IPL_PBT_NVME) {
1511
memcpy(reipl_block_nvme, reipl_block, size);
1512
reipl_type = IPL_TYPE_NVME;
1513
} else if (reipl_block->pb0_hdr.pbt == IPL_PBT_CCW) {
1514
memcpy(reipl_block_ccw, reipl_block, size);
1515
reipl_type = IPL_TYPE_CCW;
1516
} else if (reipl_block->pb0_hdr.pbt == IPL_PBT_ECKD) {
1517
memcpy(reipl_block_eckd, reipl_block, size);
1518
reipl_type = IPL_TYPE_ECKD;
1519
}
1520
out:
1521
return reipl_set_type(reipl_type);
1522
}
1523
1524
static int __init reipl_init(void)
1525
{
1526
int rc;
1527
1528
reipl_kset = kset_create_and_add("reipl", NULL, firmware_kobj);
1529
if (!reipl_kset)
1530
return -ENOMEM;
1531
rc = sysfs_create_file(&reipl_kset->kobj, &reipl_type_attr.attr);
1532
if (rc) {
1533
kset_unregister(reipl_kset);
1534
return rc;
1535
}
1536
rc = reipl_ccw_init();
1537
if (rc)
1538
return rc;
1539
rc = reipl_eckd_init();
1540
if (rc)
1541
return rc;
1542
rc = reipl_fcp_init();
1543
if (rc)
1544
return rc;
1545
rc = reipl_nvme_init();
1546
if (rc)
1547
return rc;
1548
rc = reipl_nss_init();
1549
if (rc)
1550
return rc;
1551
return reipl_type_init();
1552
}
1553
1554
static struct shutdown_action __refdata reipl_action = {
1555
.name = SHUTDOWN_ACTION_REIPL_STR,
1556
.fn = reipl_run,
1557
.init = reipl_init,
1558
};
1559
1560
/*
1561
* dump shutdown action: Dump Linux on shutdown.
1562
*/
1563
1564
/* FCP dump device attributes */
1565
1566
DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n",
1567
dump_block_fcp->fcp.wwpn);
1568
DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n",
1569
dump_block_fcp->fcp.lun);
1570
DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
1571
dump_block_fcp->fcp.bootprog);
1572
DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
1573
dump_block_fcp->fcp.br_lba);
1574
DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
1575
dump_block_fcp->fcp.devno);
1576
1577
DEFINE_IPL_ATTR_SCP_DATA_RW(dump_fcp, dump_block_fcp->hdr,
1578
dump_block_fcp->fcp,
1579
IPL_BP_FCP_LEN, IPL_BP0_FCP_LEN,
1580
DIAG308_SCPDATA_SIZE);
1581
1582
static struct attribute *dump_fcp_attrs[] = {
1583
&sys_dump_fcp_device_attr.attr,
1584
&sys_dump_fcp_wwpn_attr.attr,
1585
&sys_dump_fcp_lun_attr.attr,
1586
&sys_dump_fcp_bootprog_attr.attr,
1587
&sys_dump_fcp_br_lba_attr.attr,
1588
NULL,
1589
};
1590
1591
static const struct bin_attribute *const dump_fcp_bin_attrs[] = {
1592
&sys_dump_fcp_scp_data_attr,
1593
NULL,
1594
};
1595
1596
static const struct attribute_group dump_fcp_attr_group = {
1597
.name = IPL_FCP_STR,
1598
.attrs = dump_fcp_attrs,
1599
.bin_attrs = dump_fcp_bin_attrs,
1600
};
1601
1602
/* NVME dump device attributes */
1603
DEFINE_IPL_ATTR_RW(dump_nvme, fid, "0x%08llx\n", "%llx\n",
1604
dump_block_nvme->nvme.fid);
1605
DEFINE_IPL_ATTR_RW(dump_nvme, nsid, "0x%08llx\n", "%llx\n",
1606
dump_block_nvme->nvme.nsid);
1607
DEFINE_IPL_ATTR_RW(dump_nvme, bootprog, "%lld\n", "%llx\n",
1608
dump_block_nvme->nvme.bootprog);
1609
DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n",
1610
dump_block_nvme->nvme.br_lba);
1611
1612
DEFINE_IPL_ATTR_SCP_DATA_RW(dump_nvme, dump_block_nvme->hdr,
1613
dump_block_nvme->nvme,
1614
IPL_BP_NVME_LEN, IPL_BP0_NVME_LEN,
1615
DIAG308_SCPDATA_SIZE);
1616
1617
static struct attribute *dump_nvme_attrs[] = {
1618
&sys_dump_nvme_fid_attr.attr,
1619
&sys_dump_nvme_nsid_attr.attr,
1620
&sys_dump_nvme_bootprog_attr.attr,
1621
&sys_dump_nvme_br_lba_attr.attr,
1622
NULL,
1623
};
1624
1625
static const struct bin_attribute *const dump_nvme_bin_attrs[] = {
1626
&sys_dump_nvme_scp_data_attr,
1627
NULL,
1628
};
1629
1630
static const struct attribute_group dump_nvme_attr_group = {
1631
.name = IPL_NVME_STR,
1632
.attrs = dump_nvme_attrs,
1633
.bin_attrs = dump_nvme_bin_attrs,
1634
};
1635
1636
/* ECKD dump device attributes */
1637
DEFINE_IPL_CCW_ATTR_RW(dump_eckd, device, dump_block_eckd->eckd);
1638
DEFINE_IPL_ATTR_RW(dump_eckd, bootprog, "%lld\n", "%llx\n",
1639
dump_block_eckd->eckd.bootprog);
1640
1641
IPL_ATTR_BR_CHR_SHOW_FN(dump, dump_block_eckd->eckd);
1642
IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd);
1643
1644
static struct kobj_attribute sys_dump_eckd_br_chr_attr =
1645
__ATTR(br_chr, 0644, eckd_dump_br_chr_show, eckd_dump_br_chr_store);
1646
1647
DEFINE_IPL_ATTR_SCP_DATA_RW(dump_eckd, dump_block_eckd->hdr,
1648
dump_block_eckd->eckd,
1649
IPL_BP_ECKD_LEN, IPL_BP0_ECKD_LEN,
1650
DIAG308_SCPDATA_SIZE);
1651
1652
static struct attribute *dump_eckd_attrs[] = {
1653
&sys_dump_eckd_device_attr.attr,
1654
&sys_dump_eckd_bootprog_attr.attr,
1655
&sys_dump_eckd_br_chr_attr.attr,
1656
NULL,
1657
};
1658
1659
static const struct bin_attribute *const dump_eckd_bin_attrs[] = {
1660
&sys_dump_eckd_scp_data_attr,
1661
NULL,
1662
};
1663
1664
static const struct attribute_group dump_eckd_attr_group = {
1665
.name = IPL_ECKD_STR,
1666
.attrs = dump_eckd_attrs,
1667
.bin_attrs = dump_eckd_bin_attrs,
1668
};
1669
1670
/* CCW dump device attributes */
1671
DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ccw);
1672
1673
static struct attribute *dump_ccw_attrs[] = {
1674
&sys_dump_ccw_device_attr.attr,
1675
NULL,
1676
};
1677
1678
static struct attribute_group dump_ccw_attr_group = {
1679
.name = IPL_CCW_STR,
1680
.attrs = dump_ccw_attrs,
1681
};
1682
1683
/* dump type */
1684
1685
static int dump_set_type(enum dump_type type)
1686
{
1687
if (!(dump_capabilities & type))
1688
return -EINVAL;
1689
dump_type = type;
1690
return 0;
1691
}
1692
1693
static ssize_t dump_type_show(struct kobject *kobj,
1694
struct kobj_attribute *attr, char *page)
1695
{
1696
return sysfs_emit(page, "%s\n", dump_type_str(dump_type));
1697
}
1698
1699
static ssize_t dump_type_store(struct kobject *kobj,
1700
struct kobj_attribute *attr,
1701
const char *buf, size_t len)
1702
{
1703
int rc = -EINVAL;
1704
1705
if (strncmp(buf, DUMP_NONE_STR, strlen(DUMP_NONE_STR)) == 0)
1706
rc = dump_set_type(DUMP_TYPE_NONE);
1707
else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0)
1708
rc = dump_set_type(DUMP_TYPE_CCW);
1709
else if (strncmp(buf, DUMP_ECKD_STR, strlen(DUMP_ECKD_STR)) == 0)
1710
rc = dump_set_type(DUMP_TYPE_ECKD);
1711
else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0)
1712
rc = dump_set_type(DUMP_TYPE_FCP);
1713
else if (strncmp(buf, DUMP_NVME_STR, strlen(DUMP_NVME_STR)) == 0)
1714
rc = dump_set_type(DUMP_TYPE_NVME);
1715
return (rc != 0) ? rc : len;
1716
}
1717
1718
static struct kobj_attribute dump_type_attr =
1719
__ATTR(dump_type, 0644, dump_type_show, dump_type_store);
1720
1721
static ssize_t dump_area_size_show(struct kobject *kobj,
1722
struct kobj_attribute *attr, char *page)
1723
{
1724
return sysfs_emit(page, "%lu\n", sclp.hsa_size);
1725
}
1726
1727
static struct kobj_attribute dump_area_size_attr = __ATTR_RO(dump_area_size);
1728
1729
static struct attribute *dump_attrs[] = {
1730
&dump_type_attr.attr,
1731
&dump_area_size_attr.attr,
1732
NULL,
1733
};
1734
1735
static struct attribute_group dump_attr_group = {
1736
.attrs = dump_attrs,
1737
};
1738
1739
static struct kset *dump_kset;
1740
1741
static void diag308_dump(void *dump_block)
1742
{
1743
diag308(DIAG308_SET, dump_block);
1744
while (1) {
1745
if (diag308(DIAG308_LOAD_NORMAL_DUMP, NULL) != 0x302)
1746
break;
1747
udelay(USEC_PER_SEC);
1748
}
1749
}
1750
1751
static void __dump_run(void *unused)
1752
{
1753
switch (dump_type) {
1754
case DUMP_TYPE_CCW:
1755
diag308_dump(dump_block_ccw);
1756
break;
1757
case DUMP_TYPE_ECKD:
1758
diag308_dump(dump_block_eckd);
1759
break;
1760
case DUMP_TYPE_FCP:
1761
diag308_dump(dump_block_fcp);
1762
break;
1763
case DUMP_TYPE_NVME:
1764
diag308_dump(dump_block_nvme);
1765
break;
1766
default:
1767
break;
1768
}
1769
}
1770
1771
static void dump_run(struct shutdown_trigger *trigger)
1772
{
1773
if (dump_type == DUMP_TYPE_NONE)
1774
return;
1775
smp_send_stop();
1776
smp_call_ipl_cpu(__dump_run, NULL);
1777
}
1778
1779
static int __init dump_ccw_init(void)
1780
{
1781
int rc;
1782
1783
dump_block_ccw = (void *) get_zeroed_page(GFP_KERNEL);
1784
if (!dump_block_ccw)
1785
return -ENOMEM;
1786
rc = sysfs_create_group(&dump_kset->kobj, &dump_ccw_attr_group);
1787
if (rc) {
1788
free_page((unsigned long)dump_block_ccw);
1789
return rc;
1790
}
1791
dump_block_ccw->hdr.len = IPL_BP_CCW_LEN;
1792
dump_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
1793
dump_block_ccw->ccw.len = IPL_BP0_CCW_LEN;
1794
dump_block_ccw->ccw.pbt = IPL_PBT_CCW;
1795
dump_capabilities |= DUMP_TYPE_CCW;
1796
return 0;
1797
}
1798
1799
static int __init dump_fcp_init(void)
1800
{
1801
int rc;
1802
1803
if (!sclp_ipl_info.has_dump)
1804
return 0; /* LDIPL DUMP is not installed */
1805
dump_block_fcp = (void *) get_zeroed_page(GFP_KERNEL);
1806
if (!dump_block_fcp)
1807
return -ENOMEM;
1808
rc = sysfs_create_group(&dump_kset->kobj, &dump_fcp_attr_group);
1809
if (rc) {
1810
free_page((unsigned long)dump_block_fcp);
1811
return rc;
1812
}
1813
dump_block_fcp->hdr.len = IPL_BP_FCP_LEN;
1814
dump_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
1815
dump_block_fcp->fcp.len = IPL_BP0_FCP_LEN;
1816
dump_block_fcp->fcp.pbt = IPL_PBT_FCP;
1817
dump_block_fcp->fcp.opt = IPL_PB0_FCP_OPT_DUMP;
1818
dump_capabilities |= DUMP_TYPE_FCP;
1819
return 0;
1820
}
1821
1822
static int __init dump_nvme_init(void)
1823
{
1824
int rc;
1825
1826
if (!sclp_ipl_info.has_dump)
1827
return 0; /* LDIPL DUMP is not installed */
1828
dump_block_nvme = (void *) get_zeroed_page(GFP_KERNEL);
1829
if (!dump_block_nvme)
1830
return -ENOMEM;
1831
rc = sysfs_create_group(&dump_kset->kobj, &dump_nvme_attr_group);
1832
if (rc) {
1833
free_page((unsigned long)dump_block_nvme);
1834
return rc;
1835
}
1836
dump_block_nvme->hdr.len = IPL_BP_NVME_LEN;
1837
dump_block_nvme->hdr.version = IPL_PARM_BLOCK_VERSION;
1838
dump_block_nvme->nvme.len = IPL_BP0_NVME_LEN;
1839
dump_block_nvme->nvme.pbt = IPL_PBT_NVME;
1840
dump_block_nvme->nvme.opt = IPL_PB0_NVME_OPT_DUMP;
1841
dump_capabilities |= DUMP_TYPE_NVME;
1842
return 0;
1843
}
1844
1845
static int __init dump_eckd_init(void)
1846
{
1847
int rc;
1848
1849
if (!sclp_ipl_info.has_dump || !sclp.has_sipl_eckd)
1850
return 0; /* LDIPL DUMP is not installed */
1851
dump_block_eckd = (void *)get_zeroed_page(GFP_KERNEL);
1852
if (!dump_block_eckd)
1853
return -ENOMEM;
1854
rc = sysfs_create_group(&dump_kset->kobj, &dump_eckd_attr_group);
1855
if (rc) {
1856
free_page((unsigned long)dump_block_eckd);
1857
return rc;
1858
}
1859
dump_block_eckd->hdr.len = IPL_BP_ECKD_LEN;
1860
dump_block_eckd->hdr.version = IPL_PARM_BLOCK_VERSION;
1861
dump_block_eckd->eckd.len = IPL_BP0_ECKD_LEN;
1862
dump_block_eckd->eckd.pbt = IPL_PBT_ECKD;
1863
dump_block_eckd->eckd.opt = IPL_PB0_ECKD_OPT_DUMP;
1864
dump_capabilities |= DUMP_TYPE_ECKD;
1865
return 0;
1866
}
1867
1868
static int __init dump_init(void)
1869
{
1870
int rc;
1871
1872
dump_kset = kset_create_and_add("dump", NULL, firmware_kobj);
1873
if (!dump_kset)
1874
return -ENOMEM;
1875
rc = sysfs_create_group(&dump_kset->kobj, &dump_attr_group);
1876
if (rc) {
1877
kset_unregister(dump_kset);
1878
return rc;
1879
}
1880
rc = dump_ccw_init();
1881
if (rc)
1882
return rc;
1883
rc = dump_eckd_init();
1884
if (rc)
1885
return rc;
1886
rc = dump_fcp_init();
1887
if (rc)
1888
return rc;
1889
rc = dump_nvme_init();
1890
if (rc)
1891
return rc;
1892
dump_set_type(DUMP_TYPE_NONE);
1893
return 0;
1894
}
1895
1896
static struct shutdown_action __refdata dump_action = {
1897
.name = SHUTDOWN_ACTION_DUMP_STR,
1898
.fn = dump_run,
1899
.init = dump_init,
1900
};
1901
1902
static void dump_reipl_run(struct shutdown_trigger *trigger)
1903
{
1904
struct lowcore *abs_lc;
1905
unsigned int csum;
1906
1907
/*
1908
* Set REIPL_CLEAR flag in os_info flags entry indicating
1909
* 'clear' sysfs attribute has been set on the panicked system
1910
* for specified reipl type.
1911
* Always set for IPL_TYPE_NSS and IPL_TYPE_UNKNOWN.
1912
*/
1913
if ((reipl_type == IPL_TYPE_CCW && reipl_ccw_clear) ||
1914
(reipl_type == IPL_TYPE_ECKD && reipl_eckd_clear) ||
1915
(reipl_type == IPL_TYPE_FCP && reipl_fcp_clear) ||
1916
(reipl_type == IPL_TYPE_NVME && reipl_nvme_clear) ||
1917
reipl_type == IPL_TYPE_NSS ||
1918
reipl_type == IPL_TYPE_UNKNOWN)
1919
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
1920
os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
1921
csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
1922
abs_lc = get_abs_lowcore();
1923
abs_lc->ipib = __pa(reipl_block_actual);
1924
abs_lc->ipib_checksum = csum;
1925
put_abs_lowcore(abs_lc);
1926
dump_run(trigger);
1927
}
1928
1929
static struct shutdown_action __refdata dump_reipl_action = {
1930
.name = SHUTDOWN_ACTION_DUMP_REIPL_STR,
1931
.fn = dump_reipl_run,
1932
};
1933
1934
/*
1935
* vmcmd shutdown action: Trigger vm command on shutdown.
1936
*/
1937
1938
#define VMCMD_MAX_SIZE 240
1939
1940
static char vmcmd_on_reboot[VMCMD_MAX_SIZE + 1];
1941
static char vmcmd_on_panic[VMCMD_MAX_SIZE + 1];
1942
static char vmcmd_on_halt[VMCMD_MAX_SIZE + 1];
1943
static char vmcmd_on_poff[VMCMD_MAX_SIZE + 1];
1944
static char vmcmd_on_restart[VMCMD_MAX_SIZE + 1];
1945
1946
DEFINE_IPL_ATTR_STR_RW(vmcmd, on_reboot, "%s\n", "%s\n", vmcmd_on_reboot);
1947
DEFINE_IPL_ATTR_STR_RW(vmcmd, on_panic, "%s\n", "%s\n", vmcmd_on_panic);
1948
DEFINE_IPL_ATTR_STR_RW(vmcmd, on_halt, "%s\n", "%s\n", vmcmd_on_halt);
1949
DEFINE_IPL_ATTR_STR_RW(vmcmd, on_poff, "%s\n", "%s\n", vmcmd_on_poff);
1950
DEFINE_IPL_ATTR_STR_RW(vmcmd, on_restart, "%s\n", "%s\n", vmcmd_on_restart);
1951
1952
static struct attribute *vmcmd_attrs[] = {
1953
&sys_vmcmd_on_reboot_attr.attr,
1954
&sys_vmcmd_on_panic_attr.attr,
1955
&sys_vmcmd_on_halt_attr.attr,
1956
&sys_vmcmd_on_poff_attr.attr,
1957
&sys_vmcmd_on_restart_attr.attr,
1958
NULL,
1959
};
1960
1961
static struct attribute_group vmcmd_attr_group = {
1962
.attrs = vmcmd_attrs,
1963
};
1964
1965
static struct kset *vmcmd_kset;
1966
1967
static void vmcmd_run(struct shutdown_trigger *trigger)
1968
{
1969
char *cmd;
1970
1971
if (strcmp(trigger->name, ON_REIPL_STR) == 0)
1972
cmd = vmcmd_on_reboot;
1973
else if (strcmp(trigger->name, ON_PANIC_STR) == 0)
1974
cmd = vmcmd_on_panic;
1975
else if (strcmp(trigger->name, ON_HALT_STR) == 0)
1976
cmd = vmcmd_on_halt;
1977
else if (strcmp(trigger->name, ON_POFF_STR) == 0)
1978
cmd = vmcmd_on_poff;
1979
else if (strcmp(trigger->name, ON_RESTART_STR) == 0)
1980
cmd = vmcmd_on_restart;
1981
else
1982
return;
1983
1984
if (strlen(cmd) == 0)
1985
return;
1986
__cpcmd(cmd, NULL, 0, NULL);
1987
}
1988
1989
static int vmcmd_init(void)
1990
{
1991
if (!machine_is_vm())
1992
return -EOPNOTSUPP;
1993
vmcmd_kset = kset_create_and_add("vmcmd", NULL, firmware_kobj);
1994
if (!vmcmd_kset)
1995
return -ENOMEM;
1996
return sysfs_create_group(&vmcmd_kset->kobj, &vmcmd_attr_group);
1997
}
1998
1999
static struct shutdown_action vmcmd_action = {SHUTDOWN_ACTION_VMCMD_STR,
2000
vmcmd_run, vmcmd_init};
2001
2002
/*
2003
* stop shutdown action: Stop Linux on shutdown.
2004
*/
2005
2006
static void stop_run(struct shutdown_trigger *trigger)
2007
{
2008
if (strcmp(trigger->name, ON_PANIC_STR) == 0 ||
2009
strcmp(trigger->name, ON_RESTART_STR) == 0)
2010
disabled_wait();
2011
smp_stop_cpu();
2012
}
2013
2014
static struct shutdown_action stop_action = {SHUTDOWN_ACTION_STOP_STR,
2015
stop_run, NULL};
2016
2017
/* action list */
2018
2019
static struct shutdown_action *shutdown_actions_list[] = {
2020
&ipl_action, &reipl_action, &dump_reipl_action, &dump_action,
2021
&vmcmd_action, &stop_action};
2022
#define SHUTDOWN_ACTIONS_COUNT (sizeof(shutdown_actions_list) / sizeof(void *))
2023
2024
/*
2025
* Trigger section
2026
*/
2027
2028
static struct kset *shutdown_actions_kset;
2029
2030
static int set_trigger(const char *buf, struct shutdown_trigger *trigger,
2031
size_t len)
2032
{
2033
int i;
2034
2035
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
2036
if (sysfs_streq(buf, shutdown_actions_list[i]->name)) {
2037
if (shutdown_actions_list[i]->init_rc) {
2038
return shutdown_actions_list[i]->init_rc;
2039
} else {
2040
trigger->action = shutdown_actions_list[i];
2041
return len;
2042
}
2043
}
2044
}
2045
return -EINVAL;
2046
}
2047
2048
/* on reipl */
2049
2050
static struct shutdown_trigger on_reboot_trigger = {ON_REIPL_STR,
2051
&reipl_action};
2052
2053
static ssize_t on_reboot_show(struct kobject *kobj,
2054
struct kobj_attribute *attr, char *page)
2055
{
2056
return sysfs_emit(page, "%s\n", on_reboot_trigger.action->name);
2057
}
2058
2059
static ssize_t on_reboot_store(struct kobject *kobj,
2060
struct kobj_attribute *attr,
2061
const char *buf, size_t len)
2062
{
2063
return set_trigger(buf, &on_reboot_trigger, len);
2064
}
2065
static struct kobj_attribute on_reboot_attr = __ATTR_RW(on_reboot);
2066
2067
static void do_machine_restart(char *__unused)
2068
{
2069
smp_send_stop();
2070
on_reboot_trigger.action->fn(&on_reboot_trigger);
2071
reipl_run(NULL);
2072
}
2073
void (*_machine_restart)(char *command) = do_machine_restart;
2074
2075
/* on panic */
2076
2077
static struct shutdown_trigger on_panic_trigger = {ON_PANIC_STR, &stop_action};
2078
2079
static ssize_t on_panic_show(struct kobject *kobj,
2080
struct kobj_attribute *attr, char *page)
2081
{
2082
return sysfs_emit(page, "%s\n", on_panic_trigger.action->name);
2083
}
2084
2085
static ssize_t on_panic_store(struct kobject *kobj,
2086
struct kobj_attribute *attr,
2087
const char *buf, size_t len)
2088
{
2089
return set_trigger(buf, &on_panic_trigger, len);
2090
}
2091
static struct kobj_attribute on_panic_attr = __ATTR_RW(on_panic);
2092
2093
static void do_panic(void)
2094
{
2095
lgr_info_log();
2096
on_panic_trigger.action->fn(&on_panic_trigger);
2097
stop_run(&on_panic_trigger);
2098
}
2099
2100
/* on restart */
2101
2102
static struct shutdown_trigger on_restart_trigger = {ON_RESTART_STR,
2103
&stop_action};
2104
2105
static ssize_t on_restart_show(struct kobject *kobj,
2106
struct kobj_attribute *attr, char *page)
2107
{
2108
return sysfs_emit(page, "%s\n", on_restart_trigger.action->name);
2109
}
2110
2111
static ssize_t on_restart_store(struct kobject *kobj,
2112
struct kobj_attribute *attr,
2113
const char *buf, size_t len)
2114
{
2115
return set_trigger(buf, &on_restart_trigger, len);
2116
}
2117
static struct kobj_attribute on_restart_attr = __ATTR_RW(on_restart);
2118
2119
static void __do_restart(void *ignore)
2120
{
2121
smp_send_stop();
2122
#ifdef CONFIG_CRASH_DUMP
2123
crash_kexec(NULL);
2124
#endif
2125
on_restart_trigger.action->fn(&on_restart_trigger);
2126
stop_run(&on_restart_trigger);
2127
}
2128
2129
void do_restart(void *arg)
2130
{
2131
tracing_off();
2132
debug_locks_off();
2133
lgr_info_log();
2134
smp_call_ipl_cpu(__do_restart, arg);
2135
}
2136
2137
/* on halt */
2138
2139
static struct shutdown_trigger on_halt_trigger = {ON_HALT_STR, &stop_action};
2140
2141
static ssize_t on_halt_show(struct kobject *kobj,
2142
struct kobj_attribute *attr, char *page)
2143
{
2144
return sysfs_emit(page, "%s\n", on_halt_trigger.action->name);
2145
}
2146
2147
static ssize_t on_halt_store(struct kobject *kobj,
2148
struct kobj_attribute *attr,
2149
const char *buf, size_t len)
2150
{
2151
return set_trigger(buf, &on_halt_trigger, len);
2152
}
2153
static struct kobj_attribute on_halt_attr = __ATTR_RW(on_halt);
2154
2155
static void do_machine_halt(void)
2156
{
2157
smp_send_stop();
2158
on_halt_trigger.action->fn(&on_halt_trigger);
2159
stop_run(&on_halt_trigger);
2160
}
2161
void (*_machine_halt)(void) = do_machine_halt;
2162
2163
/* on power off */
2164
2165
static struct shutdown_trigger on_poff_trigger = {ON_POFF_STR, &stop_action};
2166
2167
static ssize_t on_poff_show(struct kobject *kobj,
2168
struct kobj_attribute *attr, char *page)
2169
{
2170
return sysfs_emit(page, "%s\n", on_poff_trigger.action->name);
2171
}
2172
2173
static ssize_t on_poff_store(struct kobject *kobj,
2174
struct kobj_attribute *attr,
2175
const char *buf, size_t len)
2176
{
2177
return set_trigger(buf, &on_poff_trigger, len);
2178
}
2179
static struct kobj_attribute on_poff_attr = __ATTR_RW(on_poff);
2180
2181
static void do_machine_power_off(void)
2182
{
2183
smp_send_stop();
2184
on_poff_trigger.action->fn(&on_poff_trigger);
2185
stop_run(&on_poff_trigger);
2186
}
2187
void (*_machine_power_off)(void) = do_machine_power_off;
2188
2189
static struct attribute *shutdown_action_attrs[] = {
2190
&on_restart_attr.attr,
2191
&on_reboot_attr.attr,
2192
&on_panic_attr.attr,
2193
&on_halt_attr.attr,
2194
&on_poff_attr.attr,
2195
NULL,
2196
};
2197
2198
static struct attribute_group shutdown_action_attr_group = {
2199
.attrs = shutdown_action_attrs,
2200
};
2201
2202
static void __init shutdown_triggers_init(void)
2203
{
2204
shutdown_actions_kset = kset_create_and_add("shutdown_actions", NULL,
2205
firmware_kobj);
2206
if (!shutdown_actions_kset)
2207
goto fail;
2208
if (sysfs_create_group(&shutdown_actions_kset->kobj,
2209
&shutdown_action_attr_group))
2210
goto fail;
2211
return;
2212
fail:
2213
panic("shutdown_triggers_init failed\n");
2214
}
2215
2216
static void __init shutdown_actions_init(void)
2217
{
2218
int i;
2219
2220
for (i = 0; i < SHUTDOWN_ACTIONS_COUNT; i++) {
2221
if (!shutdown_actions_list[i]->init)
2222
continue;
2223
shutdown_actions_list[i]->init_rc =
2224
shutdown_actions_list[i]->init();
2225
}
2226
}
2227
2228
static int __init s390_ipl_init(void)
2229
{
2230
char str[8] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
2231
2232
sclp_early_get_ipl_info(&sclp_ipl_info);
2233
/*
2234
* Fix loadparm: There are systems where the (SCSI) LOADPARM
2235
* returned by read SCP info is invalid (contains EBCDIC blanks)
2236
* when the system has been booted via diag308. In that case we use
2237
* the value from diag308, if available.
2238
*
2239
* There are also systems where diag308 store does not work in
2240
* case the system is booted from HMC. Fortunately in this case
2241
* READ SCP info provides the correct value.
2242
*/
2243
if (memcmp(sclp_ipl_info.loadparm, str, sizeof(str)) == 0 && ipl_block_valid)
2244
memcpy(sclp_ipl_info.loadparm, ipl_block.ccw.loadparm, LOADPARM_LEN);
2245
shutdown_actions_init();
2246
shutdown_triggers_init();
2247
return 0;
2248
}
2249
2250
__initcall(s390_ipl_init);
2251
2252
static void __init strscpy_skip_quote(char *dst, char *src, int n)
2253
{
2254
int sx, dx;
2255
2256
if (!n)
2257
return;
2258
for (sx = 0, dx = 0; src[sx]; sx++) {
2259
if (src[sx] == '"')
2260
continue;
2261
dst[dx] = src[sx];
2262
if (dx + 1 == n)
2263
break;
2264
dx++;
2265
}
2266
dst[dx] = '\0';
2267
}
2268
2269
static int __init vmcmd_on_reboot_setup(char *str)
2270
{
2271
if (!machine_is_vm())
2272
return 1;
2273
strscpy_skip_quote(vmcmd_on_reboot, str, sizeof(vmcmd_on_reboot));
2274
on_reboot_trigger.action = &vmcmd_action;
2275
return 1;
2276
}
2277
__setup("vmreboot=", vmcmd_on_reboot_setup);
2278
2279
static int __init vmcmd_on_panic_setup(char *str)
2280
{
2281
if (!machine_is_vm())
2282
return 1;
2283
strscpy_skip_quote(vmcmd_on_panic, str, sizeof(vmcmd_on_panic));
2284
on_panic_trigger.action = &vmcmd_action;
2285
return 1;
2286
}
2287
__setup("vmpanic=", vmcmd_on_panic_setup);
2288
2289
static int __init vmcmd_on_halt_setup(char *str)
2290
{
2291
if (!machine_is_vm())
2292
return 1;
2293
strscpy_skip_quote(vmcmd_on_halt, str, sizeof(vmcmd_on_halt));
2294
on_halt_trigger.action = &vmcmd_action;
2295
return 1;
2296
}
2297
__setup("vmhalt=", vmcmd_on_halt_setup);
2298
2299
static int __init vmcmd_on_poff_setup(char *str)
2300
{
2301
if (!machine_is_vm())
2302
return 1;
2303
strscpy_skip_quote(vmcmd_on_poff, str, sizeof(vmcmd_on_poff));
2304
on_poff_trigger.action = &vmcmd_action;
2305
return 1;
2306
}
2307
__setup("vmpoff=", vmcmd_on_poff_setup);
2308
2309
static int on_panic_notify(struct notifier_block *self,
2310
unsigned long event, void *data)
2311
{
2312
do_panic();
2313
return NOTIFY_OK;
2314
}
2315
2316
static struct notifier_block on_panic_nb = {
2317
.notifier_call = on_panic_notify,
2318
.priority = INT_MIN,
2319
};
2320
2321
void __init setup_ipl(void)
2322
{
2323
BUILD_BUG_ON(sizeof(struct ipl_parameter_block) != PAGE_SIZE);
2324
2325
ipl_info.type = get_ipl_type();
2326
switch (ipl_info.type) {
2327
case IPL_TYPE_CCW:
2328
ipl_info.data.ccw.dev_id.ssid = ipl_block.ccw.ssid;
2329
ipl_info.data.ccw.dev_id.devno = ipl_block.ccw.devno;
2330
break;
2331
case IPL_TYPE_ECKD:
2332
case IPL_TYPE_ECKD_DUMP:
2333
ipl_info.data.eckd.dev_id.ssid = ipl_block.eckd.ssid;
2334
ipl_info.data.eckd.dev_id.devno = ipl_block.eckd.devno;
2335
break;
2336
case IPL_TYPE_FCP:
2337
case IPL_TYPE_FCP_DUMP:
2338
ipl_info.data.fcp.dev_id.ssid = 0;
2339
ipl_info.data.fcp.dev_id.devno = ipl_block.fcp.devno;
2340
ipl_info.data.fcp.wwpn = ipl_block.fcp.wwpn;
2341
ipl_info.data.fcp.lun = ipl_block.fcp.lun;
2342
break;
2343
case IPL_TYPE_NVME:
2344
case IPL_TYPE_NVME_DUMP:
2345
ipl_info.data.nvme.fid = ipl_block.nvme.fid;
2346
ipl_info.data.nvme.nsid = ipl_block.nvme.nsid;
2347
break;
2348
case IPL_TYPE_NSS:
2349
case IPL_TYPE_UNKNOWN:
2350
/* We have no info to copy */
2351
break;
2352
}
2353
atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb);
2354
}
2355
2356
void s390_reset_system(void)
2357
{
2358
/* Disable prefixing */
2359
set_prefix(0);
2360
2361
/* Disable lowcore protection */
2362
local_ctl_clear_bit(0, CR0_LOW_ADDRESS_PROTECTION_BIT);
2363
diag_amode31_ops.diag308_reset();
2364
}
2365
2366
#ifdef CONFIG_KEXEC_FILE
2367
2368
int ipl_report_add_component(struct ipl_report *report, struct kexec_buf *kbuf,
2369
unsigned char flags, unsigned short cert)
2370
{
2371
struct ipl_report_component *comp;
2372
2373
comp = vzalloc(sizeof(*comp));
2374
if (!comp)
2375
return -ENOMEM;
2376
list_add_tail(&comp->list, &report->components);
2377
2378
comp->entry.addr = kbuf->mem;
2379
comp->entry.len = kbuf->memsz;
2380
comp->entry.flags = flags;
2381
comp->entry.certificate_index = cert;
2382
2383
report->size += sizeof(comp->entry);
2384
2385
return 0;
2386
}
2387
2388
int ipl_report_add_certificate(struct ipl_report *report, void *key,
2389
unsigned long addr, unsigned long len)
2390
{
2391
struct ipl_report_certificate *cert;
2392
2393
cert = vzalloc(sizeof(*cert));
2394
if (!cert)
2395
return -ENOMEM;
2396
list_add_tail(&cert->list, &report->certificates);
2397
2398
cert->entry.addr = addr;
2399
cert->entry.len = len;
2400
cert->key = key;
2401
2402
report->size += sizeof(cert->entry);
2403
report->size += cert->entry.len;
2404
2405
return 0;
2406
}
2407
2408
struct ipl_report *ipl_report_init(struct ipl_parameter_block *ipib)
2409
{
2410
struct ipl_report *report;
2411
2412
report = vzalloc(sizeof(*report));
2413
if (!report)
2414
return ERR_PTR(-ENOMEM);
2415
2416
report->ipib = ipib;
2417
INIT_LIST_HEAD(&report->components);
2418
INIT_LIST_HEAD(&report->certificates);
2419
2420
report->size = ALIGN(ipib->hdr.len, 8);
2421
report->size += sizeof(struct ipl_rl_hdr);
2422
report->size += sizeof(struct ipl_rb_components);
2423
report->size += sizeof(struct ipl_rb_certificates);
2424
2425
return report;
2426
}
2427
2428
void *ipl_report_finish(struct ipl_report *report)
2429
{
2430
struct ipl_report_certificate *cert;
2431
struct ipl_report_component *comp;
2432
struct ipl_rb_certificates *certs;
2433
struct ipl_parameter_block *ipib;
2434
struct ipl_rb_components *comps;
2435
struct ipl_rl_hdr *rl_hdr;
2436
void *buf, *ptr;
2437
2438
buf = vzalloc(report->size);
2439
if (!buf)
2440
goto out;
2441
ptr = buf;
2442
2443
memcpy(ptr, report->ipib, report->ipib->hdr.len);
2444
ipib = ptr;
2445
if (ipl_secure_flag)
2446
ipib->hdr.flags |= IPL_PL_FLAG_SIPL;
2447
ipib->hdr.flags |= IPL_PL_FLAG_IPLSR;
2448
ptr += report->ipib->hdr.len;
2449
ptr = PTR_ALIGN(ptr, 8);
2450
2451
rl_hdr = ptr;
2452
ptr += sizeof(*rl_hdr);
2453
2454
comps = ptr;
2455
comps->rbt = IPL_RBT_COMPONENTS;
2456
ptr += sizeof(*comps);
2457
list_for_each_entry(comp, &report->components, list) {
2458
memcpy(ptr, &comp->entry, sizeof(comp->entry));
2459
ptr += sizeof(comp->entry);
2460
}
2461
comps->len = ptr - (void *)comps;
2462
2463
certs = ptr;
2464
certs->rbt = IPL_RBT_CERTIFICATES;
2465
ptr += sizeof(*certs);
2466
list_for_each_entry(cert, &report->certificates, list) {
2467
memcpy(ptr, &cert->entry, sizeof(cert->entry));
2468
ptr += sizeof(cert->entry);
2469
}
2470
certs->len = ptr - (void *)certs;
2471
rl_hdr->len = ptr - (void *)rl_hdr;
2472
2473
list_for_each_entry(cert, &report->certificates, list) {
2474
memcpy(ptr, cert->key, cert->entry.len);
2475
ptr += cert->entry.len;
2476
}
2477
2478
BUG_ON(ptr > buf + report->size);
2479
out:
2480
return buf;
2481
}
2482
2483
int ipl_report_free(struct ipl_report *report)
2484
{
2485
struct ipl_report_component *comp, *ncomp;
2486
struct ipl_report_certificate *cert, *ncert;
2487
2488
list_for_each_entry_safe(comp, ncomp, &report->components, list)
2489
vfree(comp);
2490
2491
list_for_each_entry_safe(cert, ncert, &report->certificates, list)
2492
vfree(cert);
2493
2494
vfree(report);
2495
2496
return 0;
2497
}
2498
2499
#endif
2500
2501