12 #define KMSG_COMPONENT "zdump"
13 #define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
16 #include <linux/slab.h>
19 #include <linux/module.h>
20 #include <asm/asm-offsets.h>
23 #include <asm/setup.h>
24 #include <asm/uaccess.h>
25 #include <asm/debug.h>
26 #include <asm/processor.h>
27 #include <asm/irqflags.h>
28 #include <asm/checksum.h>
31 #define TRACE(x...) debug_sprintf_event(zcore_dbf, 1, x)
35 #define CHUNK_INFO_SIZE 34
60 static int hsa_available;
61 static struct dentry *zcore_dir;
62 static struct dentry *zcore_file;
63 static struct dentry *zcore_memmap_file;
64 static struct dentry *zcore_reipl_file;
86 blk_num = src / PAGE_SIZE + 2;
88 TRACE(
"sclp_sdias_copy() failed\n");
91 offs =
min((PAGE_SIZE - (src % PAGE_SIZE)), count);
94 buf + (src % PAGE_SIZE), offs))
97 memcpy(dest,
buf + (src % PAGE_SIZE), offs);
104 blk_num = (src +
offs) / PAGE_SIZE + 2;
106 TRACE(
"sclp_sdias_copy() failed\n");
120 blk_num = (src +
offs) / PAGE_SIZE + 2;
122 TRACE(
"sclp_sdias_copy() failed\n");
135 static int memcpy_hsa_user(
void __user *dest,
unsigned long src,
size_t count)
140 static int memcpy_hsa_kernel(
void *dest,
unsigned long src,
size_t count)
142 return memcpy_hsa(dest, src, count,
TO_KERNEL);
155 TRACE(
"could not copy from HSA\n");
159 zfcpdump_save_areas[0] =
sa;
165 #define DUMP_VERSION 0x5
166 #define DUMP_MAGIC 0xa8190173618f23fdULL
167 #define DUMP_ARCH_S390X 2
168 #define DUMP_ARCH_S390 1
169 #define HEADER_SIZE 4096
222 static int copy_lc(
void __user *
buf,
void *sa,
int sa_off,
int len)
227 for (i = 0; i < len; i++) {
228 if (!lc_mask[i + sa_off])
243 static int zcore_add_lc(
char __user *
buf,
unsigned long start,
size_t count)
252 while (zfcpdump_save_areas[i]) {
253 unsigned long cp_start, cp_end;
254 unsigned long sa_start, sa_end;
256 unsigned long sa_off,
len, buf_off;
258 prefix = zfcpdump_save_areas[
i]->pref_reg;
262 if ((end < sa_start) || (start > sa_end))
264 cp_start =
max(start, sa_start);
265 cp_end =
min(end, sa_end);
267 buf_off = cp_start -
start;
268 sa_off = cp_start - sa_start;
269 len = cp_end - cp_start;
271 TRACE(
"copy_lc for: %lx\n", start);
272 if (copy_lc(buf + buf_off, zfcpdump_save_areas[i], sa_off, len))
286 static ssize_t zcore_read(
struct file *
file,
char __user *buf,
size_t count,
324 rc = memcpy_hsa_user(buf + hdr_count, mem_start, size);
332 size = count - mem_offs - hdr_count;
334 (
void *) mem_start + mem_offs, size);
346 if (zcore_add_lc(buf + hdr_count, mem_start, count - hdr_count)) {
353 return (rc < 0) ? rc :
count;
356 static int zcore_open(
struct inode *
inode,
struct file *filp)
364 static int zcore_release(
struct inode *inode,
struct file *filep)
371 static loff_t zcore_lseek(
struct file *file, loff_t
offset,
int orig)
394 .llseek = zcore_lseek,
397 .release = zcore_release,
400 static ssize_t zcore_memmap_read(
struct file *filp,
char __user *buf,
401 size_t count, loff_t *ppos)
407 static int zcore_memmap_open(
struct inode *inode,
struct file *filp)
425 (
unsigned long long) chunk_array[i].
addr,
426 (
unsigned long long) chunk_array[i].size);
427 if (chunk_array[i].size == 0)
435 static int zcore_memmap_release(
struct inode *inode,
struct file *filp)
443 .read = zcore_memmap_read,
444 .open = zcore_memmap_open,
445 .release = zcore_memmap_release,
449 static ssize_t zcore_reipl_write(
struct file *filp,
const char __user *buf,
450 size_t count, loff_t *ppos)
459 static int zcore_reipl_open(
struct inode *inode,
struct file *filp)
464 static int zcore_reipl_release(
struct inode *inode,
struct file *filp)
471 .write = zcore_reipl_write,
472 .open = zcore_reipl_open,
473 .release = zcore_reipl_release,
481 memset(&map->ext_save, 0xff,
sizeof(map->ext_save));
519 pr_alert(
"DETECTED 'S390X (64 bit) OS'\n");
522 pr_alert(
"DETECTED 'S390 (32 bit) OS'\n");
525 pr_alert(
"0x%x is an unknown architecture.\n",arch);
532 rc = init_cpu_info(arch);
540 static int __init check_sdias(
void)
542 int rc, act_hsa_size;
546 TRACE(
"Could not determine HSA size\n");
549 act_hsa_size = (rc - 1) * PAGE_SIZE;
551 TRACE(
"HSA size too small: %i\n", act_hsa_size);
557 static int __init get_mem_size(
unsigned long *
mem)
562 chunk_array = kzalloc(MEMORY_CHUNKS *
sizeof(
struct mem_chunk),
568 if (chunk_array[i].size == 0)
570 *mem += chunk_array[
i].
size;
576 static int __init zcore_header_init(
int arch,
struct zcore_header *
hdr)
586 rc = get_mem_size(&memory);
595 for (i = 0; zfcpdump_save_areas[
i]; i++) {
596 prefix = zfcpdump_save_areas[
i]->pref_reg;
610 static int __init zcore_reipl_init(
void)
624 rc = memcpy_hsa_kernel(ipl_block,
ipib_info.
ipib, PAGE_SIZE);
629 TRACE(
"Checksum does not match\n");
636 static int __init zcore_init(
void)
662 rc = memcpy_hsa_kernel(&arch, __LC_AR_MODE_ID, 1);
668 pr_alert(
"The 64-bit dump tool cannot be used for a "
675 pr_alert(
"The 32-bit dump tool cannot be used for a "
682 rc = sys_info_init(arch);
686 rc = zcore_header_init(arch, &zcore_header);
690 rc = zcore_reipl_init();
706 NULL, &zcore_memmap_fops);
707 if (!zcore_memmap_file) {
712 NULL, &zcore_reipl_fops);
713 if (!zcore_reipl_file) {
715 goto fail_memmap_file;
731 static void __exit zcore_exit(
void)