zcore.c (42249094f79422fbf5ed4b54eeb48ff096809b8f) zcore.c (e657d8fe2faf49ed5d35e2325bd0f1712b8058cd)
1/*
2 * zcore module to export memory content and register sets for creating system
3 * dumps on SCSI disks (zfcpdump). The "zcore/mem" debugfs file shows the same
4 * dump format as s390 standalone dumps.
5 *
6 * For more information please refer to Documentation/s390/zfcpdump.txt
7 *
8 * Copyright IBM Corp. 2003, 2008

--- 137 unchanged lines hidden (view full) ---

146}
147
148static int __init init_cpu_info(enum arch_id arch)
149{
150 struct save_area *sa;
151
152 /* get info for boot cpu from lowcore, stored in the HSA */
153
1/*
2 * zcore module to export memory content and register sets for creating system
3 * dumps on SCSI disks (zfcpdump). The "zcore/mem" debugfs file shows the same
4 * dump format as s390 standalone dumps.
5 *
6 * For more information please refer to Documentation/s390/zfcpdump.txt
7 *
8 * Copyright IBM Corp. 2003, 2008

--- 137 unchanged lines hidden (view full) ---

146}
147
148static int __init init_cpu_info(enum arch_id arch)
149{
150 struct save_area *sa;
151
152 /* get info for boot cpu from lowcore, stored in the HSA */
153
154 sa = kmalloc(sizeof(*sa), GFP_KERNEL);
154 sa = dump_save_area_create(0);
155 if (!sa)
156 return -ENOMEM;
157 if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) {
158 TRACE("could not copy from HSA\n");
159 kfree(sa);
160 return -EIO;
161 }
155 if (!sa)
156 return -ENOMEM;
157 if (memcpy_hsa_kernel(sa, sys_info.sa_base, sys_info.sa_size) < 0) {
158 TRACE("could not copy from HSA\n");
159 kfree(sa);
160 return -EIO;
161 }
162 zfcpdump_save_areas[0] = sa;
163 return 0;
164}
165
166static DEFINE_MUTEX(zcore_mutex);
167
168#define DUMP_VERSION 0x5
169#define DUMP_MAGIC 0xa8190173618f23fdULL
170#define DUMP_ARCH_S390X 2

--- 70 unchanged lines hidden (view full) ---

241 *
242 * @buf: User buffer
243 * @addr: Start address of buffer in dump memory
244 * @count: Size of buffer
245 */
246static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
247{
248 unsigned long end;
162 return 0;
163}
164
165static DEFINE_MUTEX(zcore_mutex);
166
167#define DUMP_VERSION 0x5
168#define DUMP_MAGIC 0xa8190173618f23fdULL
169#define DUMP_ARCH_S390X 2

--- 70 unchanged lines hidden (view full) ---

240 *
241 * @buf: User buffer
242 * @addr: Start address of buffer in dump memory
243 * @count: Size of buffer
244 */
245static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
246{
247 unsigned long end;
249 int i = 0;
248 int i;
250
251 if (count == 0)
252 return 0;
253
254 end = start + count;
249
250 if (count == 0)
251 return 0;
252
253 end = start + count;
255 while (zfcpdump_save_areas[i]) {
254 for (i = 0; i < dump_save_areas.count; i++) {
256 unsigned long cp_start, cp_end; /* copy range */
257 unsigned long sa_start, sa_end; /* save area range */
258 unsigned long prefix;
259 unsigned long sa_off, len, buf_off;
255 unsigned long cp_start, cp_end; /* copy range */
256 unsigned long sa_start, sa_end; /* save area range */
257 unsigned long prefix;
258 unsigned long sa_off, len, buf_off;
259 struct save_area *save_area = dump_save_areas.areas[i];
260
260
261 prefix = zfcpdump_save_areas[i]->pref_reg;
261 prefix = save_area->pref_reg;
262 sa_start = prefix + sys_info.sa_base;
263 sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
264
265 if ((end < sa_start) || (start > sa_end))
262 sa_start = prefix + sys_info.sa_base;
263 sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
264
265 if ((end < sa_start) || (start > sa_end))
266 goto next;
266 continue;
267 cp_start = max(start, sa_start);
268 cp_end = min(end, sa_end);
269
270 buf_off = cp_start - start;
271 sa_off = cp_start - sa_start;
272 len = cp_end - cp_start;
273
274 TRACE("copy_lc for: %lx\n", start);
267 cp_start = max(start, sa_start);
268 cp_end = min(end, sa_end);
269
270 buf_off = cp_start - start;
271 sa_off = cp_start - sa_start;
272 len = cp_end - cp_start;
273
274 TRACE("copy_lc for: %lx\n", start);
275 if (copy_lc(buf + buf_off, zfcpdump_save_areas[i], sa_off, len))
275 if (copy_lc(buf + buf_off, save_area, sa_off, len))
276 return -EFAULT;
276 return -EFAULT;
277next:
278 i++;
279 }
280 return 0;
281}
282
283/*
284 * Release the HSA
285 */
286static void release_hsa(void)

--- 38 unchanged lines hidden (view full) ---

325 } else {
326 hdr_count = 0;
327 mem_start = *ppos - HEADER_SIZE;
328 }
329
330 mem_offs = 0;
331
332 /* Copy from HSA data */
277 }
278 return 0;
279}
280
281/*
282 * Release the HSA
283 */
284static void release_hsa(void)

--- 38 unchanged lines hidden (view full) ---

323 } else {
324 hdr_count = 0;
325 mem_start = *ppos - HEADER_SIZE;
326 }
327
328 mem_offs = 0;
329
330 /* Copy from HSA data */
333 if (*ppos < (ZFCPDUMP_HSA_SIZE + HEADER_SIZE)) {
334 size = min((count - hdr_count), (size_t) (ZFCPDUMP_HSA_SIZE
335 - mem_start));
331 if (*ppos < sclp_get_hsa_size() + HEADER_SIZE) {
332 size = min((count - hdr_count),
333 (size_t) (sclp_get_hsa_size() - mem_start));
336 rc = memcpy_hsa_user(buf + hdr_count, mem_start, size);
337 if (rc)
338 goto fail;
339
340 mem_offs += size;
341 }
342
343 /* Copy from real mem */

--- 143 unchanged lines hidden (view full) ---

487};
488
489static ssize_t zcore_hsa_read(struct file *filp, char __user *buf,
490 size_t count, loff_t *ppos)
491{
492 static char str[18];
493
494 if (hsa_available)
334 rc = memcpy_hsa_user(buf + hdr_count, mem_start, size);
335 if (rc)
336 goto fail;
337
338 mem_offs += size;
339 }
340
341 /* Copy from real mem */

--- 143 unchanged lines hidden (view full) ---

485};
486
487static ssize_t zcore_hsa_read(struct file *filp, char __user *buf,
488 size_t count, loff_t *ppos)
489{
490 static char str[18];
491
492 if (hsa_available)
495 snprintf(str, sizeof(str), "%lx\n", ZFCPDUMP_HSA_SIZE);
493 snprintf(str, sizeof(str), "%lx\n", sclp_get_hsa_size());
496 else
497 snprintf(str, sizeof(str), "0\n");
498 return simple_read_from_buffer(buf, count, ppos, str, strlen(str));
499}
500
501static ssize_t zcore_hsa_write(struct file *filp, const char __user *buf,
502 size_t count, loff_t *ppos)
503{

--- 77 unchanged lines hidden (view full) ---

581 return rc;
582 sys_info.mem_size = mem_end;
583
584 return 0;
585}
586
587static int __init check_sdias(void)
588{
494 else
495 snprintf(str, sizeof(str), "0\n");
496 return simple_read_from_buffer(buf, count, ppos, str, strlen(str));
497}
498
499static ssize_t zcore_hsa_write(struct file *filp, const char __user *buf,
500 size_t count, loff_t *ppos)
501{

--- 77 unchanged lines hidden (view full) ---

579 return rc;
580 sys_info.mem_size = mem_end;
581
582 return 0;
583}
584
585static int __init check_sdias(void)
586{
589 int rc, act_hsa_size;
590
591 rc = sclp_sdias_blk_count();
592 if (rc < 0) {
587 if (!sclp_get_hsa_size()) {
593 TRACE("Could not determine HSA size\n");
588 TRACE("Could not determine HSA size\n");
594 return rc;
589 return -ENODEV;
595 }
590 }
596 act_hsa_size = (rc - 1) * PAGE_SIZE;
597 if (act_hsa_size < ZFCPDUMP_HSA_SIZE) {
598 TRACE("HSA size too small: %i\n", act_hsa_size);
599 return -EINVAL;
600 }
601 return 0;
602}
603
604static int __init get_mem_info(unsigned long *mem, unsigned long *end)
605{
606 int i;
607 struct mem_chunk *chunk_array;
608

--- 23 unchanged lines hidden (view full) ---

632 else
633 hdr->arch_id = DUMP_ARCH_S390;
634 hdr->mem_size = mem_size;
635 hdr->rmem_size = mem_size;
636 hdr->mem_end = sys_info.mem_size;
637 hdr->num_pages = mem_size / PAGE_SIZE;
638 hdr->tod = get_tod_clock();
639 get_cpu_id(&hdr->cpu_id);
591 return 0;
592}
593
594static int __init get_mem_info(unsigned long *mem, unsigned long *end)
595{
596 int i;
597 struct mem_chunk *chunk_array;
598

--- 23 unchanged lines hidden (view full) ---

622 else
623 hdr->arch_id = DUMP_ARCH_S390;
624 hdr->mem_size = mem_size;
625 hdr->rmem_size = mem_size;
626 hdr->mem_end = sys_info.mem_size;
627 hdr->num_pages = mem_size / PAGE_SIZE;
628 hdr->tod = get_tod_clock();
629 get_cpu_id(&hdr->cpu_id);
640 for (i = 0; zfcpdump_save_areas[i]; i++) {
641 prefix = zfcpdump_save_areas[i]->pref_reg;
630 for (i = 0; i < dump_save_areas.count; i++) {
631 prefix = dump_save_areas.areas[i]->pref_reg;
642 hdr->real_cpu_cnt++;
643 if (!prefix)
644 continue;
645 hdr->lc_vec[hdr->cpu_cnt] = prefix;
646 hdr->cpu_cnt++;
647 }
648}
649

--- 9 unchanged lines hidden (view full) ---

659 rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
660 if (rc)
661 return rc;
662 if (ipib_info.ipib == 0)
663 return 0;
664 ipl_block = (void *) __get_free_page(GFP_KERNEL);
665 if (!ipl_block)
666 return -ENOMEM;
632 hdr->real_cpu_cnt++;
633 if (!prefix)
634 continue;
635 hdr->lc_vec[hdr->cpu_cnt] = prefix;
636 hdr->cpu_cnt++;
637 }
638}
639

--- 9 unchanged lines hidden (view full) ---

649 rc = memcpy_hsa_kernel(&ipib_info, __LC_DUMP_REIPL, sizeof(ipib_info));
650 if (rc)
651 return rc;
652 if (ipib_info.ipib == 0)
653 return 0;
654 ipl_block = (void *) __get_free_page(GFP_KERNEL);
655 if (!ipl_block)
656 return -ENOMEM;
667 if (ipib_info.ipib < ZFCPDUMP_HSA_SIZE)
657 if (ipib_info.ipib < sclp_get_hsa_size())
668 rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
669 else
670 rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
671 if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
672 ipib_info.checksum) {
673 TRACE("Checksum does not match\n");
674 free_page((unsigned long) ipl_block);
675 ipl_block = NULL;

--- 129 unchanged lines hidden ---
658 rc = memcpy_hsa_kernel(ipl_block, ipib_info.ipib, PAGE_SIZE);
659 else
660 rc = memcpy_real(ipl_block, (void *) ipib_info.ipib, PAGE_SIZE);
661 if (rc || csum_partial(ipl_block, ipl_block->hdr.len, 0) !=
662 ipib_info.checksum) {
663 TRACE("Checksum does not match\n");
664 free_page((unsigned long) ipl_block);
665 ipl_block = NULL;

--- 129 unchanged lines hidden ---