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