aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/zcore.c140
1 files changed, 47 insertions, 93 deletions
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index 82daa3c1dc9c..1d935b2c9bf4 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -40,12 +40,12 @@ enum arch_id {
40/* dump system info */ 40/* dump system info */
41 41
42struct sys_info { 42struct sys_info {
43 enum arch_id arch; 43 enum arch_id arch;
44 unsigned long sa_base; 44 unsigned long sa_base;
45 u32 sa_size; 45 u32 sa_size;
46 int cpu_map[NR_CPUS]; 46 int cpu_map[NR_CPUS];
47 unsigned long mem_size; 47 unsigned long mem_size;
48 union save_area lc_mask; 48 struct save_area lc_mask;
49}; 49};
50 50
51struct ipib_info { 51struct ipib_info {
@@ -183,52 +183,9 @@ static int memcpy_real_user(void __user *dest, unsigned long src, size_t count)
183 return 0; 183 return 0;
184} 184}
185 185
186#ifdef __s390x__
187/*
188 * Convert s390x (64 bit) cpu info to s390 (32 bit) cpu info
189 */
190static void __init s390x_to_s390_regs(union save_area *out, union save_area *in,
191 int cpu)
192{
193 int i;
194
195 for (i = 0; i < 16; i++) {
196 out->s390.gp_regs[i] = in->s390x.gp_regs[i] & 0x00000000ffffffff;
197 out->s390.acc_regs[i] = in->s390x.acc_regs[i];
198 out->s390.ctrl_regs[i] =
199 in->s390x.ctrl_regs[i] & 0x00000000ffffffff;
200 }
201 /* locore for 31 bit has only space for fpregs 0,2,4,6 */
202 out->s390.fp_regs[0] = in->s390x.fp_regs[0];
203 out->s390.fp_regs[1] = in->s390x.fp_regs[2];
204 out->s390.fp_regs[2] = in->s390x.fp_regs[4];
205 out->s390.fp_regs[3] = in->s390x.fp_regs[6];
206 memcpy(&(out->s390.psw[0]), &(in->s390x.psw[0]), 4);
207 out->s390.psw[1] |= 0x8; /* set bit 12 */
208 memcpy(&(out->s390.psw[4]),&(in->s390x.psw[12]), 4);
209 out->s390.psw[4] |= 0x80; /* set (31bit) addressing bit */
210 out->s390.pref_reg = in->s390x.pref_reg;
211 out->s390.timer = in->s390x.timer;
212 out->s390.clk_cmp = in->s390x.clk_cmp;
213}
214
215static void __init s390x_to_s390_save_areas(void)
216{
217 int i = 1;
218 static union save_area tmp;
219
220 while (zfcpdump_save_areas[i]) {
221 s390x_to_s390_regs(&tmp, zfcpdump_save_areas[i], i);
222 memcpy(zfcpdump_save_areas[i], &tmp, sizeof(tmp));
223 i++;
224 }
225}
226
227#endif /* __s390x__ */
228
229static int __init init_cpu_info(enum arch_id arch) 186static int __init init_cpu_info(enum arch_id arch)
230{ 187{
231 union save_area *sa; 188 struct save_area *sa;
232 189
233 /* get info for boot cpu from lowcore, stored in the HSA */ 190 /* get info for boot cpu from lowcore, stored in the HSA */
234 191
@@ -241,14 +198,6 @@ static int __init init_cpu_info(enum arch_id arch)
241 return -EIO; 198 return -EIO;
242 } 199 }
243 zfcpdump_save_areas[0] = sa; 200 zfcpdump_save_areas[0] = sa;
244
245#ifdef __s390x__
246 /* convert s390x regs to s390, if we are dumping an s390 Linux */
247
248 if (arch == ARCH_S390)
249 s390x_to_s390_save_areas();
250#endif
251
252 return 0; 201 return 0;
253} 202}
254 203
@@ -289,7 +238,7 @@ static struct zcore_header zcore_header = {
289 .dump_level = 0, 238 .dump_level = 0,
290 .page_size = PAGE_SIZE, 239 .page_size = PAGE_SIZE,
291 .mem_start = 0, 240 .mem_start = 0,
292#ifdef __s390x__ 241#ifdef CONFIG_64BIT
293 .build_arch = DUMP_ARCH_S390X, 242 .build_arch = DUMP_ARCH_S390X,
294#else 243#else
295 .build_arch = DUMP_ARCH_S390, 244 .build_arch = DUMP_ARCH_S390,
@@ -340,11 +289,7 @@ static int zcore_add_lc(char __user *buf, unsigned long start, size_t count)
340 unsigned long prefix; 289 unsigned long prefix;
341 unsigned long sa_off, len, buf_off; 290 unsigned long sa_off, len, buf_off;
342 291
343 if (sys_info.arch == ARCH_S390) 292 prefix = zfcpdump_save_areas[i]->pref_reg;
344 prefix = zfcpdump_save_areas[i]->s390.pref_reg;
345 else
346 prefix = zfcpdump_save_areas[i]->s390x.pref_reg;
347
348 sa_start = prefix + sys_info.sa_base; 293 sa_start = prefix + sys_info.sa_base;
349 sa_end = prefix + sys_info.sa_base + sys_info.sa_size; 294 sa_end = prefix + sys_info.sa_base + sys_info.sa_size;
350 295
@@ -561,34 +506,39 @@ static const struct file_operations zcore_reipl_fops = {
561 .release = zcore_reipl_release, 506 .release = zcore_reipl_release,
562}; 507};
563 508
509#ifdef CONFIG_32BIT
564 510
565static void __init set_s390_lc_mask(union save_area *map) 511static void __init set_lc_mask(struct save_area *map)
566{ 512{
567 memset(&map->s390.ext_save, 0xff, sizeof(map->s390.ext_save)); 513 memset(&map->ext_save, 0xff, sizeof(map->ext_save));
568 memset(&map->s390.timer, 0xff, sizeof(map->s390.timer)); 514 memset(&map->timer, 0xff, sizeof(map->timer));
569 memset(&map->s390.clk_cmp, 0xff, sizeof(map->s390.clk_cmp)); 515 memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
570 memset(&map->s390.psw, 0xff, sizeof(map->s390.psw)); 516 memset(&map->psw, 0xff, sizeof(map->psw));
571 memset(&map->s390.pref_reg, 0xff, sizeof(map->s390.pref_reg)); 517 memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
572 memset(&map->s390.acc_regs, 0xff, sizeof(map->s390.acc_regs)); 518 memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
573 memset(&map->s390.fp_regs, 0xff, sizeof(map->s390.fp_regs)); 519 memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
574 memset(&map->s390.gp_regs, 0xff, sizeof(map->s390.gp_regs)); 520 memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
575 memset(&map->s390.ctrl_regs, 0xff, sizeof(map->s390.ctrl_regs)); 521 memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
576} 522}
577 523
578static void __init set_s390x_lc_mask(union save_area *map) 524#else /* CONFIG_32BIT */
525
526static void __init set_lc_mask(struct save_area *map)
579{ 527{
580 memset(&map->s390x.fp_regs, 0xff, sizeof(map->s390x.fp_regs)); 528 memset(&map->fp_regs, 0xff, sizeof(map->fp_regs));
581 memset(&map->s390x.gp_regs, 0xff, sizeof(map->s390x.gp_regs)); 529 memset(&map->gp_regs, 0xff, sizeof(map->gp_regs));
582 memset(&map->s390x.psw, 0xff, sizeof(map->s390x.psw)); 530 memset(&map->psw, 0xff, sizeof(map->psw));
583 memset(&map->s390x.pref_reg, 0xff, sizeof(map->s390x.pref_reg)); 531 memset(&map->pref_reg, 0xff, sizeof(map->pref_reg));
584 memset(&map->s390x.fp_ctrl_reg, 0xff, sizeof(map->s390x.fp_ctrl_reg)); 532 memset(&map->fp_ctrl_reg, 0xff, sizeof(map->fp_ctrl_reg));
585 memset(&map->s390x.tod_reg, 0xff, sizeof(map->s390x.tod_reg)); 533 memset(&map->tod_reg, 0xff, sizeof(map->tod_reg));
586 memset(&map->s390x.timer, 0xff, sizeof(map->s390x.timer)); 534 memset(&map->timer, 0xff, sizeof(map->timer));
587 memset(&map->s390x.clk_cmp, 0xff, sizeof(map->s390x.clk_cmp)); 535 memset(&map->clk_cmp, 0xff, sizeof(map->clk_cmp));
588 memset(&map->s390x.acc_regs, 0xff, sizeof(map->s390x.acc_regs)); 536 memset(&map->acc_regs, 0xff, sizeof(map->acc_regs));
589 memset(&map->s390x.ctrl_regs, 0xff, sizeof(map->s390x.ctrl_regs)); 537 memset(&map->ctrl_regs, 0xff, sizeof(map->ctrl_regs));
590} 538}
591 539
540#endif /* CONFIG_32BIT */
541
592/* 542/*
593 * Initialize dump globals for a given architecture 543 * Initialize dump globals for a given architecture
594 */ 544 */
@@ -599,21 +549,18 @@ static int __init sys_info_init(enum arch_id arch)
599 switch (arch) { 549 switch (arch) {
600 case ARCH_S390X: 550 case ARCH_S390X:
601 pr_alert("DETECTED 'S390X (64 bit) OS'\n"); 551 pr_alert("DETECTED 'S390X (64 bit) OS'\n");
602 sys_info.sa_base = SAVE_AREA_BASE_S390X;
603 sys_info.sa_size = sizeof(struct save_area_s390x);
604 set_s390x_lc_mask(&sys_info.lc_mask);
605 break; 552 break;
606 case ARCH_S390: 553 case ARCH_S390:
607 pr_alert("DETECTED 'S390 (32 bit) OS'\n"); 554 pr_alert("DETECTED 'S390 (32 bit) OS'\n");
608 sys_info.sa_base = SAVE_AREA_BASE_S390;
609 sys_info.sa_size = sizeof(struct save_area_s390);
610 set_s390_lc_mask(&sys_info.lc_mask);
611 break; 555 break;
612 default: 556 default:
613 pr_alert("0x%x is an unknown architecture.\n",arch); 557 pr_alert("0x%x is an unknown architecture.\n",arch);
614 return -EINVAL; 558 return -EINVAL;
615 } 559 }
560 sys_info.sa_base = SAVE_AREA_BASE;
561 sys_info.sa_size = sizeof(struct save_area);
616 sys_info.arch = arch; 562 sys_info.arch = arch;
563 set_lc_mask(&sys_info.lc_mask);
617 rc = init_cpu_info(arch); 564 rc = init_cpu_info(arch);
618 if (rc) 565 if (rc)
619 return rc; 566 return rc;
@@ -741,14 +688,21 @@ static int __init zcore_init(void)
741 if (rc) 688 if (rc)
742 goto fail; 689 goto fail;
743 690
744#ifndef __s390x__ 691#ifdef CONFIG_64BIT
692 if (arch == ARCH_S390) {
693 pr_alert("The 64-bit dump tool cannot be used for a "
694 "32-bit system\n");
695 rc = -EINVAL;
696 goto fail;
697 }
698#else /* CONFIG_64BIT */
745 if (arch == ARCH_S390X) { 699 if (arch == ARCH_S390X) {
746 pr_alert("The 32-bit dump tool cannot be used for a " 700 pr_alert("The 32-bit dump tool cannot be used for a "
747 "64-bit system\n"); 701 "64-bit system\n");
748 rc = -EINVAL; 702 rc = -EINVAL;
749 goto fail; 703 goto fail;
750 } 704 }
751#endif 705#endif /* CONFIG_64BIT */
752 706
753 rc = sys_info_init(arch); 707 rc = sys_info_init(arch);
754 if (rc) 708 if (rc)