Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/ipl: add eckd dump support

This adds support to use ECKD disks as dump device
to linux. The new dump type is called 'eckd_dump', parameters
are the same as for eckd ipl.

Signed-off-by: Sven Schnelle <svens@linux.ibm.com>
Reviewed-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>

authored by

Sven Schnelle and committed by
Alexander Gordeev
e2d2a296 87fd22e0

+81 -1
+3
arch/s390/boot/ipl_parm.c
··· 77 77 if (ipl_block.pb0_hdr.pbt == IPL_PBT_NVME && 78 78 ipl_block.nvme.opt == IPL_PB0_NVME_OPT_DUMP) 79 79 return true; 80 + if (ipl_block.pb0_hdr.pbt == IPL_PBT_ECKD && 81 + ipl_block.eckd.opt == IPL_PB0_ECKD_OPT_DUMP) 82 + return true; 80 83 return false; 81 84 } 82 85
+2
arch/s390/include/asm/ipl.h
··· 74 74 IPL_TYPE_NVME = 32, 75 75 IPL_TYPE_NVME_DUMP = 64, 76 76 IPL_TYPE_ECKD = 128, 77 + IPL_TYPE_ECKD_DUMP = 256, 77 78 }; 78 79 79 80 struct ipl_info ··· 109 108 static inline bool is_ipl_type_dump(void) 110 109 { 111 110 return (ipl_info.type == IPL_TYPE_FCP_DUMP) || 111 + (ipl_info.type == IPL_TYPE_ECKD_DUMP) || 112 112 (ipl_info.type == IPL_TYPE_NVME_DUMP); 113 113 } 114 114
+1
arch/s390/include/uapi/asm/ipl.h
··· 138 138 } __packed; 139 139 140 140 #define IPL_PB0_ECKD_OPT_IPL 0x10 141 + #define IPL_PB0_ECKD_OPT_DUMP 0x20 141 142 142 143 #define IPL_PB0_CCW_VM_FLAG_NSS 0x80 143 144 #define IPL_PB0_CCW_VM_FLAG_VP 0x40
+71 -1
arch/s390/kernel/ipl.c
··· 41 41 #define IPL_UNKNOWN_STR "unknown" 42 42 #define IPL_CCW_STR "ccw" 43 43 #define IPL_ECKD_STR "eckd" 44 + #define IPL_ECKD_DUMP_STR "eckd_dump" 44 45 #define IPL_FCP_STR "fcp" 45 46 #define IPL_FCP_DUMP_STR "fcp_dump" 46 47 #define IPL_NVME_STR "nvme" ··· 49 48 #define IPL_NSS_STR "nss" 50 49 51 50 #define DUMP_CCW_STR "ccw" 51 + #define DUMP_ECKD_STR "eckd" 52 52 #define DUMP_FCP_STR "fcp" 53 53 #define DUMP_NVME_STR "nvme" 54 54 #define DUMP_NONE_STR "none" ··· 98 96 return IPL_CCW_STR; 99 97 case IPL_TYPE_ECKD: 100 98 return IPL_ECKD_STR; 99 + case IPL_TYPE_ECKD_DUMP: 100 + return IPL_ECKD_DUMP_STR; 101 101 case IPL_TYPE_FCP: 102 102 return IPL_FCP_STR; 103 103 case IPL_TYPE_FCP_DUMP: ··· 121 117 DUMP_TYPE_CCW = 2, 122 118 DUMP_TYPE_FCP = 4, 123 119 DUMP_TYPE_NVME = 8, 120 + DUMP_TYPE_ECKD = 16, 124 121 }; 125 122 126 123 static char *dump_type_str(enum dump_type type) ··· 131 126 return DUMP_NONE_STR; 132 127 case DUMP_TYPE_CCW: 133 128 return DUMP_CCW_STR; 129 + case DUMP_TYPE_ECKD: 130 + return DUMP_ECKD_STR; 134 131 case DUMP_TYPE_FCP: 135 132 return DUMP_FCP_STR; 136 133 case DUMP_TYPE_NVME: ··· 167 160 static struct ipl_parameter_block *dump_block_fcp; 168 161 static struct ipl_parameter_block *dump_block_nvme; 169 162 static struct ipl_parameter_block *dump_block_ccw; 163 + static struct ipl_parameter_block *dump_block_eckd; 170 164 171 165 static struct sclp_ipl_info sclp_ipl_info; 172 166 ··· 296 288 else 297 289 return IPL_TYPE_NVME; 298 290 case IPL_PBT_ECKD: 299 - return IPL_TYPE_ECKD; 291 + if (ipl_block.eckd.opt == IPL_PB0_ECKD_OPT_DUMP) 292 + return IPL_TYPE_ECKD_DUMP; 293 + else 294 + return IPL_TYPE_ECKD; 300 295 } 301 296 return IPL_TYPE_UNKNOWN; 302 297 } ··· 354 343 return sprintf(page, "0.%x.%04x\n", ipl_block.ccw.ssid, 355 344 ipl_block.ccw.devno); 356 345 case IPL_TYPE_ECKD: 346 + case IPL_TYPE_ECKD_DUMP: 357 347 return sprintf(page, "0.%x.%04x\n", ipl_block.eckd.ssid, 358 348 ipl_block.eckd.devno); 359 349 case IPL_TYPE_FCP: ··· 1380 1368 break; 1381 1369 case IPL_TYPE_FCP_DUMP: 1382 1370 case IPL_TYPE_NVME_DUMP: 1371 + case IPL_TYPE_ECKD_DUMP: 1383 1372 break; 1384 1373 } 1385 1374 disabled_wait(); ··· 1749 1736 .attrs = dump_nvme_attrs, 1750 1737 }; 1751 1738 1739 + /* ECKD dump device attributes */ 1740 + DEFINE_IPL_CCW_ATTR_RW(dump_eckd, device, dump_block_eckd->eckd); 1741 + DEFINE_IPL_ATTR_RW(dump_eckd, bootprog, "%lld\n", "%llx\n", 1742 + dump_block_eckd->eckd.bootprog); 1743 + 1744 + IPL_ATTR_BR_CHR_SHOW_FN(dump, dump_block_eckd->eckd); 1745 + IPL_ATTR_BR_CHR_STORE_FN(dump, dump_block_eckd->eckd); 1746 + 1747 + static struct kobj_attribute sys_dump_eckd_br_chr_attr = 1748 + __ATTR(br_chr, (S_IRUGO | S_IWUSR), 1749 + eckd_dump_br_chr_show, 1750 + eckd_dump_br_chr_store); 1751 + 1752 + static struct attribute *dump_eckd_attrs[] = { 1753 + &sys_dump_eckd_device_attr.attr, 1754 + &sys_dump_eckd_bootprog_attr.attr, 1755 + &sys_dump_eckd_br_chr_attr.attr, 1756 + NULL, 1757 + }; 1758 + 1759 + static struct attribute_group dump_eckd_attr_group = { 1760 + .name = IPL_ECKD_STR, 1761 + .attrs = dump_eckd_attrs, 1762 + }; 1763 + 1752 1764 /* CCW dump device attributes */ 1753 1765 DEFINE_IPL_CCW_ATTR_RW(dump_ccw, device, dump_block_ccw->ccw); 1754 1766 ··· 1813 1775 rc = dump_set_type(DUMP_TYPE_NONE); 1814 1776 else if (strncmp(buf, DUMP_CCW_STR, strlen(DUMP_CCW_STR)) == 0) 1815 1777 rc = dump_set_type(DUMP_TYPE_CCW); 1778 + else if (strncmp(buf, DUMP_ECKD_STR, strlen(DUMP_ECKD_STR)) == 0) 1779 + rc = dump_set_type(DUMP_TYPE_ECKD); 1816 1780 else if (strncmp(buf, DUMP_FCP_STR, strlen(DUMP_FCP_STR)) == 0) 1817 1781 rc = dump_set_type(DUMP_TYPE_FCP); 1818 1782 else if (strncmp(buf, DUMP_NVME_STR, strlen(DUMP_NVME_STR)) == 0) ··· 1842 1802 switch (dump_type) { 1843 1803 case DUMP_TYPE_CCW: 1844 1804 diag308_dump(dump_block_ccw); 1805 + break; 1806 + case DUMP_TYPE_ECKD: 1807 + diag308_dump(dump_block_eckd); 1845 1808 break; 1846 1809 case DUMP_TYPE_FCP: 1847 1810 diag308_dump(dump_block_fcp); ··· 1931 1888 return 0; 1932 1889 } 1933 1890 1891 + static int __init dump_eckd_init(void) 1892 + { 1893 + int rc; 1894 + 1895 + if (!sclp_ipl_info.has_dump || !sclp.has_sipl_eckd) 1896 + return 0; /* LDIPL DUMP is not installed */ 1897 + dump_block_eckd = (void *)get_zeroed_page(GFP_KERNEL); 1898 + if (!dump_block_eckd) 1899 + return -ENOMEM; 1900 + rc = sysfs_create_group(&dump_kset->kobj, &dump_eckd_attr_group); 1901 + if (rc) { 1902 + free_page((unsigned long)dump_block_eckd); 1903 + return rc; 1904 + } 1905 + dump_block_eckd->hdr.len = IPL_BP_ECKD_LEN; 1906 + dump_block_eckd->hdr.version = IPL_PARM_BLOCK_VERSION; 1907 + dump_block_eckd->eckd.len = IPL_BP0_ECKD_LEN; 1908 + dump_block_eckd->eckd.pbt = IPL_PBT_ECKD; 1909 + dump_block_eckd->eckd.opt = IPL_PB0_ECKD_OPT_DUMP; 1910 + dump_capabilities |= DUMP_TYPE_ECKD; 1911 + return 0; 1912 + } 1913 + 1934 1914 static int __init dump_init(void) 1935 1915 { 1936 1916 int rc; ··· 1967 1901 return rc; 1968 1902 } 1969 1903 rc = dump_ccw_init(); 1904 + if (rc) 1905 + return rc; 1906 + rc = dump_eckd_init(); 1970 1907 if (rc) 1971 1908 return rc; 1972 1909 rc = dump_fcp_init(); ··· 2406 2337 ipl_info.data.ccw.dev_id.devno = ipl_block.ccw.devno; 2407 2338 break; 2408 2339 case IPL_TYPE_ECKD: 2340 + case IPL_TYPE_ECKD_DUMP: 2409 2341 ipl_info.data.eckd.dev_id.ssid = ipl_block.eckd.ssid; 2410 2342 ipl_info.data.eckd.dev_id.devno = ipl_block.eckd.devno; 2411 2343 break;
+4
drivers/s390/char/zcore.c
··· 282 282 TRACE("type: nvme\n"); 283 283 TRACE("fid: %x\n", ipl_info.data.nvme.fid); 284 284 TRACE("nsid: %x\n", ipl_info.data.nvme.nsid); 285 + } else if (ipl_info.type == IPL_TYPE_ECKD_DUMP) { 286 + TRACE("type: eckd\n"); 287 + TRACE("devno: %x\n", ipl_info.data.eckd.dev_id.devno); 288 + TRACE("ssid: %x\n", ipl_info.data.eckd.dev_id.ssid); 285 289 } 286 290 287 291 rc = sclp_sdias_init();