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 --- |