s390/ipl: Clear SBP flag when bootprog is set
With z16 a new flag 'search boot program' was introduced for list-directed IPL (SCSI, NVMe, ECKD DASD). If this flag is set, e.g. via selecting the "Automatic" value for the "Boot program selector" control on an HMC load panel, it is copied to the reipl structure from the initial ipl structure. When a user now sets a boot prog via sysfs, the flag is not cleared and the bootloader will again automatically select the boot program, ignoring user configuration. To avoid that, clear the SBP flag when a bootprog sysfs file is written. Cc: stable@vger.kernel.org Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Sven Schnelle <svens@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>master
parent
8f0b4cce44
commit
b1aa01d312
|
|
@ -15,6 +15,7 @@ struct ipl_pl_hdr {
|
||||||
#define IPL_PL_FLAG_IPLPS 0x80
|
#define IPL_PL_FLAG_IPLPS 0x80
|
||||||
#define IPL_PL_FLAG_SIPL 0x40
|
#define IPL_PL_FLAG_SIPL 0x40
|
||||||
#define IPL_PL_FLAG_IPLSR 0x20
|
#define IPL_PL_FLAG_IPLSR 0x20
|
||||||
|
#define IPL_PL_FLAG_SBP 0x10
|
||||||
|
|
||||||
/* IPL Parameter Block header */
|
/* IPL Parameter Block header */
|
||||||
struct ipl_pb_hdr {
|
struct ipl_pb_hdr {
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,24 @@ static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
|
||||||
sys_##_prefix##_##_name##_show, \
|
sys_##_prefix##_##_name##_show, \
|
||||||
sys_##_prefix##_##_name##_store)
|
sys_##_prefix##_##_name##_store)
|
||||||
|
|
||||||
|
#define DEFINE_IPL_ATTR_BOOTPROG_RW(_prefix, _name, _fmt_out, _fmt_in, _hdr, _value) \
|
||||||
|
IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, (unsigned long long) _value) \
|
||||||
|
static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
|
||||||
|
struct kobj_attribute *attr, \
|
||||||
|
const char *buf, size_t len) \
|
||||||
|
{ \
|
||||||
|
unsigned long long value; \
|
||||||
|
if (sscanf(buf, _fmt_in, &value) != 1) \
|
||||||
|
return -EINVAL; \
|
||||||
|
(_value) = value; \
|
||||||
|
(_hdr).flags &= ~IPL_PL_FLAG_SBP; \
|
||||||
|
return len; \
|
||||||
|
} \
|
||||||
|
static struct kobj_attribute sys_##_prefix##_##_name##_attr = \
|
||||||
|
__ATTR(_name, 0644, \
|
||||||
|
sys_##_prefix##_##_name##_show, \
|
||||||
|
sys_##_prefix##_##_name##_store)
|
||||||
|
|
||||||
#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
|
#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
|
||||||
IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, _value) \
|
IPL_ATTR_SHOW_FN(_prefix, _name, _fmt_out, _value) \
|
||||||
static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
|
static ssize_t sys_##_prefix##_##_name##_store(struct kobject *kobj, \
|
||||||
|
|
@ -818,12 +836,13 @@ DEFINE_IPL_ATTR_RW(reipl_fcp, wwpn, "0x%016llx\n", "%llx\n",
|
||||||
reipl_block_fcp->fcp.wwpn);
|
reipl_block_fcp->fcp.wwpn);
|
||||||
DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n",
|
DEFINE_IPL_ATTR_RW(reipl_fcp, lun, "0x%016llx\n", "%llx\n",
|
||||||
reipl_block_fcp->fcp.lun);
|
reipl_block_fcp->fcp.lun);
|
||||||
DEFINE_IPL_ATTR_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
|
|
||||||
reipl_block_fcp->fcp.bootprog);
|
|
||||||
DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
|
DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
|
||||||
reipl_block_fcp->fcp.br_lba);
|
reipl_block_fcp->fcp.br_lba);
|
||||||
DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
|
DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
|
||||||
reipl_block_fcp->fcp.devno);
|
reipl_block_fcp->fcp.devno);
|
||||||
|
DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_fcp, bootprog, "%lld\n", "%lld\n",
|
||||||
|
reipl_block_fcp->hdr,
|
||||||
|
reipl_block_fcp->fcp.bootprog);
|
||||||
|
|
||||||
static void reipl_get_ascii_loadparm(char *loadparm,
|
static void reipl_get_ascii_loadparm(char *loadparm,
|
||||||
struct ipl_parameter_block *ibp)
|
struct ipl_parameter_block *ibp)
|
||||||
|
|
@ -942,10 +961,11 @@ DEFINE_IPL_ATTR_RW(reipl_nvme, fid, "0x%08llx\n", "%llx\n",
|
||||||
reipl_block_nvme->nvme.fid);
|
reipl_block_nvme->nvme.fid);
|
||||||
DEFINE_IPL_ATTR_RW(reipl_nvme, nsid, "0x%08llx\n", "%llx\n",
|
DEFINE_IPL_ATTR_RW(reipl_nvme, nsid, "0x%08llx\n", "%llx\n",
|
||||||
reipl_block_nvme->nvme.nsid);
|
reipl_block_nvme->nvme.nsid);
|
||||||
DEFINE_IPL_ATTR_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n",
|
|
||||||
reipl_block_nvme->nvme.bootprog);
|
|
||||||
DEFINE_IPL_ATTR_RW(reipl_nvme, br_lba, "%lld\n", "%lld\n",
|
DEFINE_IPL_ATTR_RW(reipl_nvme, br_lba, "%lld\n", "%lld\n",
|
||||||
reipl_block_nvme->nvme.br_lba);
|
reipl_block_nvme->nvme.br_lba);
|
||||||
|
DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_nvme, bootprog, "%lld\n", "%lld\n",
|
||||||
|
reipl_block_nvme->hdr,
|
||||||
|
reipl_block_nvme->nvme.bootprog);
|
||||||
|
|
||||||
static struct attribute *reipl_nvme_attrs[] = {
|
static struct attribute *reipl_nvme_attrs[] = {
|
||||||
&sys_reipl_nvme_fid_attr.attr,
|
&sys_reipl_nvme_fid_attr.attr,
|
||||||
|
|
@ -1038,8 +1058,9 @@ static const struct bin_attribute *const reipl_eckd_bin_attrs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_IPL_CCW_ATTR_RW(reipl_eckd, device, reipl_block_eckd->eckd);
|
DEFINE_IPL_CCW_ATTR_RW(reipl_eckd, device, reipl_block_eckd->eckd);
|
||||||
DEFINE_IPL_ATTR_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n",
|
DEFINE_IPL_ATTR_BOOTPROG_RW(reipl_eckd, bootprog, "%lld\n", "%lld\n",
|
||||||
reipl_block_eckd->eckd.bootprog);
|
reipl_block_eckd->hdr,
|
||||||
|
reipl_block_eckd->eckd.bootprog);
|
||||||
|
|
||||||
static struct attribute *reipl_eckd_attrs[] = {
|
static struct attribute *reipl_eckd_attrs[] = {
|
||||||
&sys_reipl_eckd_device_attr.attr,
|
&sys_reipl_eckd_device_attr.attr,
|
||||||
|
|
@ -1567,12 +1588,13 @@ DEFINE_IPL_ATTR_RW(dump_fcp, wwpn, "0x%016llx\n", "%llx\n",
|
||||||
dump_block_fcp->fcp.wwpn);
|
dump_block_fcp->fcp.wwpn);
|
||||||
DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n",
|
DEFINE_IPL_ATTR_RW(dump_fcp, lun, "0x%016llx\n", "%llx\n",
|
||||||
dump_block_fcp->fcp.lun);
|
dump_block_fcp->fcp.lun);
|
||||||
DEFINE_IPL_ATTR_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
|
|
||||||
dump_block_fcp->fcp.bootprog);
|
|
||||||
DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
|
DEFINE_IPL_ATTR_RW(dump_fcp, br_lba, "%lld\n", "%lld\n",
|
||||||
dump_block_fcp->fcp.br_lba);
|
dump_block_fcp->fcp.br_lba);
|
||||||
DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
|
DEFINE_IPL_ATTR_RW(dump_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
|
||||||
dump_block_fcp->fcp.devno);
|
dump_block_fcp->fcp.devno);
|
||||||
|
DEFINE_IPL_ATTR_BOOTPROG_RW(dump_fcp, bootprog, "%lld\n", "%lld\n",
|
||||||
|
dump_block_fcp->hdr,
|
||||||
|
dump_block_fcp->fcp.bootprog);
|
||||||
|
|
||||||
DEFINE_IPL_ATTR_SCP_DATA_RW(dump_fcp, dump_block_fcp->hdr,
|
DEFINE_IPL_ATTR_SCP_DATA_RW(dump_fcp, dump_block_fcp->hdr,
|
||||||
dump_block_fcp->fcp,
|
dump_block_fcp->fcp,
|
||||||
|
|
@ -1604,10 +1626,11 @@ DEFINE_IPL_ATTR_RW(dump_nvme, fid, "0x%08llx\n", "%llx\n",
|
||||||
dump_block_nvme->nvme.fid);
|
dump_block_nvme->nvme.fid);
|
||||||
DEFINE_IPL_ATTR_RW(dump_nvme, nsid, "0x%08llx\n", "%llx\n",
|
DEFINE_IPL_ATTR_RW(dump_nvme, nsid, "0x%08llx\n", "%llx\n",
|
||||||
dump_block_nvme->nvme.nsid);
|
dump_block_nvme->nvme.nsid);
|
||||||
DEFINE_IPL_ATTR_RW(dump_nvme, bootprog, "%lld\n", "%llx\n",
|
|
||||||
dump_block_nvme->nvme.bootprog);
|
|
||||||
DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n",
|
DEFINE_IPL_ATTR_RW(dump_nvme, br_lba, "%lld\n", "%llx\n",
|
||||||
dump_block_nvme->nvme.br_lba);
|
dump_block_nvme->nvme.br_lba);
|
||||||
|
DEFINE_IPL_ATTR_BOOTPROG_RW(dump_nvme, bootprog, "%lld\n", "%llx\n",
|
||||||
|
dump_block_nvme->hdr,
|
||||||
|
dump_block_nvme->nvme.bootprog);
|
||||||
|
|
||||||
DEFINE_IPL_ATTR_SCP_DATA_RW(dump_nvme, dump_block_nvme->hdr,
|
DEFINE_IPL_ATTR_SCP_DATA_RW(dump_nvme, dump_block_nvme->hdr,
|
||||||
dump_block_nvme->nvme,
|
dump_block_nvme->nvme,
|
||||||
|
|
@ -1635,8 +1658,9 @@ static const struct attribute_group dump_nvme_attr_group = {
|
||||||
|
|
||||||
/* ECKD dump device attributes */
|
/* ECKD dump device attributes */
|
||||||
DEFINE_IPL_CCW_ATTR_RW(dump_eckd, device, dump_block_eckd->eckd);
|
DEFINE_IPL_CCW_ATTR_RW(dump_eckd, device, dump_block_eckd->eckd);
|
||||||
DEFINE_IPL_ATTR_RW(dump_eckd, bootprog, "%lld\n", "%llx\n",
|
DEFINE_IPL_ATTR_BOOTPROG_RW(dump_eckd, bootprog, "%lld\n", "%llx\n",
|
||||||
dump_block_eckd->eckd.bootprog);
|
dump_block_eckd->hdr,
|
||||||
|
dump_block_eckd->eckd.bootprog);
|
||||||
|
|
||||||
IPL_ATTR_BR_CHR_SHOW_FN(dump, dump_block_eckd->eckd);
|
IPL_ATTR_BR_CHR_SHOW_FN(dump, dump_block_eckd->eckd);
|
||||||
IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd);
|
IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue