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