0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #define KMSG_COMPONENT "zdump"
0013 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
0014
0015 #include <linux/init.h>
0016 #include <linux/slab.h>
0017 #include <linux/debugfs.h>
0018 #include <linux/panic_notifier.h>
0019 #include <linux/reboot.h>
0020 #include <linux/uio.h>
0021
0022 #include <asm/asm-offsets.h>
0023 #include <asm/ipl.h>
0024 #include <asm/sclp.h>
0025 #include <asm/setup.h>
0026 #include <linux/uaccess.h>
0027 #include <asm/debug.h>
0028 #include <asm/processor.h>
0029 #include <asm/irqflags.h>
0030 #include <asm/checksum.h>
0031 #include <asm/os_info.h>
0032 #include <asm/switch_to.h>
0033 #include "sclp.h"
0034
0035 #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
0036
0037 enum arch_id {
0038 ARCH_S390 = 0,
0039 ARCH_S390X = 1,
0040 };
0041
0042 struct ipib_info {
0043 unsigned long ipib;
0044 u32 checksum;
0045 } __attribute__((packed));
0046
0047 static struct debug_info *zcore_dbf;
0048 static int hsa_available;
0049 static struct dentry *zcore_dir;
0050 static struct dentry *zcore_reipl_file;
0051 static struct dentry *zcore_hsa_file;
0052 static struct ipl_parameter_block *zcore_ipl_block;
0053
0054 static DEFINE_MUTEX(hsa_buf_mutex);
0055 static char hsa_buf[PAGE_SIZE] __aligned(PAGE_SIZE);
0056
0057
0058
0059
0060
0061
0062
0063
0064 size_t memcpy_hsa_iter(struct iov_iter *iter, unsigned long src, size_t count)
0065 {
0066 size_t bytes, copied, res = 0;
0067 unsigned long offset;
0068
0069 if (!hsa_available)
0070 return 0;
0071
0072 mutex_lock(&hsa_buf_mutex);
0073 while (count) {
0074 if (sclp_sdias_copy(hsa_buf, src / PAGE_SIZE + 2, 1)) {
0075 TRACE("sclp_sdias_copy() failed\n");
0076 break;
0077 }
0078 offset = src % PAGE_SIZE;
0079 bytes = min(PAGE_SIZE - offset, count);
0080 copied = copy_to_iter(hsa_buf + offset, bytes, iter);
0081 count -= copied;
0082 src += copied;
0083 res += copied;
0084 if (copied < bytes)
0085 break;
0086 }
0087 mutex_unlock(&hsa_buf_mutex);
0088 return res;
0089 }
0090
0091
0092
0093
0094
0095
0096
0097
0098 static inline int memcpy_hsa_kernel(void *dst, unsigned long src, size_t count)
0099 {
0100 struct iov_iter iter;
0101 struct kvec kvec;
0102
0103 kvec.iov_base = dst;
0104 kvec.iov_len = count;
0105 iov_iter_kvec(&iter, WRITE, &kvec, 1, count);
0106 if (memcpy_hsa_iter(&iter, src, count) < count)
0107 return -EIO;
0108 return 0;
0109 }
0110
0111 static int __init init_cpu_info(void)
0112 {
0113 struct save_area *sa;
0114
0115
0116 sa = save_area_boot_cpu();
0117 if (!sa)
0118 return -ENOMEM;
0119 if (memcpy_hsa_kernel(hsa_buf, __LC_FPREGS_SAVE_AREA, 512) < 0) {
0120 TRACE("could not copy from HSA\n");
0121 return -EIO;
0122 }
0123 save_area_add_regs(sa, hsa_buf);
0124 return 0;
0125 }
0126
0127
0128
0129
0130 static void release_hsa(void)
0131 {
0132 diag308(DIAG308_REL_HSA, NULL);
0133 hsa_available = 0;
0134 }
0135
0136 static ssize_t zcore_reipl_write(struct file *filp, const char __user *buf,
0137 size_t count, loff_t *ppos)
0138 {
0139 if (zcore_ipl_block) {
0140 diag308(DIAG308_SET, zcore_ipl_block);
0141 diag308(DIAG308_LOAD_CLEAR, NULL);
0142 }
0143 return count;
0144 }
0145
0146 static int zcore_reipl_open(struct inode *inode, struct file *filp)
0147 {
0148 return stream_open(inode, filp);
0149 }
0150
0151 static int zcore_reipl_release(struct inode *inode, struct file *filp)
0152 {
0153 return 0;
0154 }
0155
0156 static const struct file_operations zcore_reipl_fops = {
0157 .owner = THIS_MODULE,
0158 .write = zcore_reipl_write,
0159 .open = zcore_reipl_open,
0160 .release = zcore_reipl_release,
0161 .llseek = no_llseek,
0162 };
0163
0164 static ssize_t zcore_hsa_read(struct file *filp, char __user *buf,
0165 size_t count, loff_t *ppos)
0166 {
0167 static char str[18];
0168
0169 if (hsa_available)
0170 snprintf(str, sizeof(str), "%lx\n", sclp.hsa_size);
0171 else
0172 snprintf(str, sizeof(str), "0\n");
0173 return simple_read_from_buffer(buf, count, ppos, str, strlen(str));
0174 }
0175
0176 static ssize_t zcore_hsa_write(struct file *filp, const char __user *buf,
0177 size_t count, loff_t *ppos)
0178 {
0179 char value;
0180
0181 if (*ppos != 0)
0182 return -EPIPE;
0183 if (copy_from_user(&value, buf, 1))
0184 return -EFAULT;
0185 if (value != '0')
0186 return -EINVAL;
0187 release_hsa();
0188 return count;
0189 }
0190
0191 static const struct file_operations zcore_hsa_fops = {
0192 .owner = THIS_MODULE,
0193 .write = zcore_hsa_write,
0194 .read = zcore_hsa_read,
0195 .open = nonseekable_open,
0196 .llseek = no_llseek,
0197 };
0198
0199 static int __init check_sdias(void)
0200 {
0201 if (!sclp.hsa_size) {
0202 TRACE("Could not determine HSA size\n");
0203 return -ENODEV;
0204 }
0205 return 0;
0206 }
0207
0208
0209
0210
0211
0212 static int __init zcore_reipl_init(void)
0213 {
0214 struct ipib_info ipib_info;
0215 int rc;
0216
0217 rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
0218 if (rc)
0219 return rc;
0220 if (ipib_info.ipib == 0)
0221 return 0;
0222 zcore_ipl_block = (void *) __get_free_page(GFP_KERNEL);
0223 if (!zcore_ipl_block)
0224 return -ENOMEM;
0225 if (ipib_info.ipib < sclp.hsa_size)
0226 rc = memcpy_hsa_kernel(zcore_ipl_block, ipib_info.ipib,
0227 PAGE_SIZE);
0228 else
0229 rc = memcpy_real(zcore_ipl_block, ipib_info.ipib, PAGE_SIZE);
0230 if (rc || (__force u32)csum_partial(zcore_ipl_block, zcore_ipl_block->hdr.len, 0) !=
0231 ipib_info.checksum) {
0232 TRACE("Checksum does not match\n");
0233 free_page((unsigned long) zcore_ipl_block);
0234 zcore_ipl_block = NULL;
0235 }
0236 return 0;
0237 }
0238
0239 static int zcore_reboot_and_on_panic_handler(struct notifier_block *self,
0240 unsigned long event,
0241 void *data)
0242 {
0243 if (hsa_available)
0244 release_hsa();
0245
0246 return NOTIFY_OK;
0247 }
0248
0249 static struct notifier_block zcore_reboot_notifier = {
0250 .notifier_call = zcore_reboot_and_on_panic_handler,
0251
0252 .priority = INT_MAX,
0253 };
0254
0255 static struct notifier_block zcore_on_panic_notifier = {
0256 .notifier_call = zcore_reboot_and_on_panic_handler,
0257
0258 .priority = INT_MAX,
0259 };
0260
0261 static int __init zcore_init(void)
0262 {
0263 unsigned char arch;
0264 int rc;
0265
0266 if (!is_ipl_type_dump())
0267 return -ENODATA;
0268 if (oldmem_data.start)
0269 return -ENODATA;
0270
0271 zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long));
0272 debug_register_view(zcore_dbf, &debug_sprintf_view);
0273 debug_set_level(zcore_dbf, 6);
0274
0275 if (ipl_info.type == IPL_TYPE_FCP_DUMP) {
0276 TRACE("type: fcp\n");
0277 TRACE("devno: %x\n", ipl_info.data.fcp.dev_id.devno);
0278 TRACE("wwpn: %llx\n", (unsigned long long) ipl_info.data.fcp.wwpn);
0279 TRACE("lun: %llx\n", (unsigned long long) ipl_info.data.fcp.lun);
0280 } else if (ipl_info.type == IPL_TYPE_NVME_DUMP) {
0281 TRACE("type: nvme\n");
0282 TRACE("fid: %x\n", ipl_info.data.nvme.fid);
0283 TRACE("nsid: %x\n", ipl_info.data.nvme.nsid);
0284 }
0285
0286 rc = sclp_sdias_init();
0287 if (rc)
0288 goto fail;
0289
0290 rc = check_sdias();
0291 if (rc)
0292 goto fail;
0293 hsa_available = 1;
0294
0295 rc = memcpy_hsa_kernel(&arch, __LC_AR_MODE_ID, 1);
0296 if (rc)
0297 goto fail;
0298
0299 if (arch == ARCH_S390) {
0300 pr_alert("The 64-bit dump tool cannot be used for a "
0301 "32-bit system\n");
0302 rc = -EINVAL;
0303 goto fail;
0304 }
0305
0306 pr_alert("The dump process started for a 64-bit operating system\n");
0307 rc = init_cpu_info();
0308 if (rc)
0309 goto fail;
0310
0311 rc = zcore_reipl_init();
0312 if (rc)
0313 goto fail;
0314
0315 zcore_dir = debugfs_create_dir("zcore" , NULL);
0316 zcore_reipl_file = debugfs_create_file("reipl", S_IRUSR, zcore_dir,
0317 NULL, &zcore_reipl_fops);
0318 zcore_hsa_file = debugfs_create_file("hsa", S_IRUSR|S_IWUSR, zcore_dir,
0319 NULL, &zcore_hsa_fops);
0320
0321 register_reboot_notifier(&zcore_reboot_notifier);
0322 atomic_notifier_chain_register(&panic_notifier_list, &zcore_on_panic_notifier);
0323
0324 return 0;
0325 fail:
0326 diag308(DIAG308_REL_HSA, NULL);
0327 return rc;
0328 }
0329 subsys_initcall(zcore_init);