aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/early.c45
-rw-r--r--arch/s390/kernel/entry.S7
-rw-r--r--arch/s390/kernel/entry64.S7
-rw-r--r--arch/s390/kernel/ipl.c17
-rw-r--r--arch/s390/kernel/process.c6
-rw-r--r--arch/s390/kernel/smp.c63
-rw-r--r--arch/s390/kernel/time.c4
-rw-r--r--arch/s390/kernel/vtime.c4
8 files changed, 60 insertions, 93 deletions
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index 50538e545618..e6289ee74ecd 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -171,37 +171,6 @@ static inline int memory_fast_detect(void)
171} 171}
172#endif 172#endif
173 173
174#define ADDR2G (1UL << 31)
175
176static noinline __init unsigned long sclp_memory_detect(void)
177{
178 struct sclp_readinfo_sccb *sccb;
179 unsigned long long memsize;
180
181 sccb = &s390_readinfo_sccb;
182
183 if (sccb->header.response_code != 0x10)
184 return 0;
185
186 if (sccb->rnsize)
187 memsize = sccb->rnsize << 20;
188 else
189 memsize = sccb->rnsize2 << 20;
190 if (sccb->rnmax)
191 memsize *= sccb->rnmax;
192 else
193 memsize *= sccb->rnmax2;
194#ifndef CONFIG_64BIT
195 /*
196 * Can't deal with more than 2G in 31 bit addressing mode, so
197 * limit the value in order to avoid strange side effects.
198 */
199 if (memsize > ADDR2G)
200 memsize = ADDR2G;
201#endif
202 return (unsigned long) memsize;
203}
204
205static inline __init unsigned long __tprot(unsigned long addr) 174static inline __init unsigned long __tprot(unsigned long addr)
206{ 175{
207 int cc = -1; 176 int cc = -1;
@@ -218,6 +187,7 @@ static inline __init unsigned long __tprot(unsigned long addr)
218 187
219/* Checking memory in 128KB increments. */ 188/* Checking memory in 128KB increments. */
220#define CHUNK_INCR (1UL << 17) 189#define CHUNK_INCR (1UL << 17)
190#define ADDR2G (1UL << 31)
221 191
222static noinline __init void find_memory_chunks(unsigned long memsize) 192static noinline __init void find_memory_chunks(unsigned long memsize)
223{ 193{
@@ -293,7 +263,7 @@ static noinline __init void setup_lowcore_early(void)
293 */ 263 */
294void __init startup_init(void) 264void __init startup_init(void)
295{ 265{
296 unsigned long memsize; 266 unsigned long long memsize;
297 267
298 ipl_save_parameters(); 268 ipl_save_parameters();
299 clear_bss_section(); 269 clear_bss_section();
@@ -305,8 +275,17 @@ void __init startup_init(void)
305 sort_main_extable(); 275 sort_main_extable();
306 setup_lowcore_early(); 276 setup_lowcore_early();
307 sclp_readinfo_early(); 277 sclp_readinfo_early();
278 sclp_facilities_detect();
308 memsize = sclp_memory_detect(); 279 memsize = sclp_memory_detect();
280#ifndef CONFIG_64BIT
281 /*
282 * Can't deal with more than 2G in 31 bit addressing mode, so
283 * limit the value in order to avoid strange side effects.
284 */
285 if (memsize > ADDR2G)
286 memsize = ADDR2G;
287#endif
309 if (memory_fast_detect() < 0) 288 if (memory_fast_detect() < 0)
310 find_memory_chunks(memsize); 289 find_memory_chunks((unsigned long) memsize);
311 lockdep_on(); 290 lockdep_on();
312} 291}
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index 6234c6978a1f..bc7ff3658c3d 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -107,6 +107,11 @@ STACK_SIZE = 1 << STACK_SHIFT
107 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 107 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
108 .endm 108 .endm
109 109
110 .macro SAVE_ALL_SVC psworg,savearea
111 la %r12,\psworg
112 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
113 .endm
114
110 .macro SAVE_ALL_SYNC psworg,savearea 115 .macro SAVE_ALL_SYNC psworg,savearea
111 la %r12,\psworg 116 la %r12,\psworg
112 tm \psworg+1,0x01 # test problem state bit 117 tm \psworg+1,0x01 # test problem state bit
@@ -218,7 +223,7 @@ system_call:
218 STORE_TIMER __LC_SYNC_ENTER_TIMER 223 STORE_TIMER __LC_SYNC_ENTER_TIMER
219sysc_saveall: 224sysc_saveall:
220 SAVE_ALL_BASE __LC_SAVE_AREA 225 SAVE_ALL_BASE __LC_SAVE_AREA
221 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 226 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
222 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 227 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
223 lh %r7,0x8a # get svc number from lowcore 228 lh %r7,0x8a # get svc number from lowcore
224#ifdef CONFIG_VIRT_CPU_ACCOUNTING 229#ifdef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 685f11faa4bc..2a7b1304418b 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -99,6 +99,11 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \
99 larl %r13,system_call 99 larl %r13,system_call
100 .endm 100 .endm
101 101
102 .macro SAVE_ALL_SVC psworg,savearea
103 la %r12,\psworg
104 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
105 .endm
106
102 .macro SAVE_ALL_SYNC psworg,savearea 107 .macro SAVE_ALL_SYNC psworg,savearea
103 la %r12,\psworg 108 la %r12,\psworg
104 tm \psworg+1,0x01 # test problem state bit 109 tm \psworg+1,0x01 # test problem state bit
@@ -207,7 +212,7 @@ system_call:
207 STORE_TIMER __LC_SYNC_ENTER_TIMER 212 STORE_TIMER __LC_SYNC_ENTER_TIMER
208sysc_saveall: 213sysc_saveall:
209 SAVE_ALL_BASE __LC_SAVE_AREA 214 SAVE_ALL_BASE __LC_SAVE_AREA
210 SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 215 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA
211 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA 216 CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA
212 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore 217 llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore
213#ifdef CONFIG_VIRT_CPU_ACCOUNTING 218#ifdef CONFIG_VIRT_CPU_ACCOUNTING
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 367caf92ea78..82b131ddd7ff 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -25,10 +25,6 @@
25 25
26#define IPL_PARM_BLOCK_VERSION 0 26#define IPL_PARM_BLOCK_VERSION 0
27 27
28#define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10)
29#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm)
30#define SCCB_FLAG (s390_readinfo_sccb.flags)
31
32#define IPL_UNKNOWN_STR "unknown" 28#define IPL_UNKNOWN_STR "unknown"
33#define IPL_CCW_STR "ccw" 29#define IPL_CCW_STR "ccw"
34#define IPL_FCP_STR "fcp" 30#define IPL_FCP_STR "fcp"
@@ -146,6 +142,8 @@ static struct ipl_parameter_block *dump_block_ccw;
146 142
147static enum shutdown_action on_panic_action = SHUTDOWN_STOP; 143static enum shutdown_action on_panic_action = SHUTDOWN_STOP;
148 144
145static struct sclp_ipl_info sclp_ipl_info;
146
149int diag308(unsigned long subcode, void *addr) 147int diag308(unsigned long subcode, void *addr)
150{ 148{
151 register unsigned long _addr asm("0") = (unsigned long) addr; 149 register unsigned long _addr asm("0") = (unsigned long) addr;
@@ -375,9 +373,9 @@ static ssize_t ipl_ccw_loadparm_show(struct kset *kset, char *page)
375{ 373{
376 char loadparm[LOADPARM_LEN + 1] = {}; 374 char loadparm[LOADPARM_LEN + 1] = {};
377 375
378 if (!SCCB_VALID) 376 if (!sclp_ipl_info.is_valid)
379 return sprintf(page, "#unknown#\n"); 377 return sprintf(page, "#unknown#\n");
380 memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN); 378 memcpy(loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
381 EBCASC(loadparm, LOADPARM_LEN); 379 EBCASC(loadparm, LOADPARM_LEN);
382 strstrip(loadparm); 380 strstrip(loadparm);
383 return sprintf(page, "%s\n", loadparm); 381 return sprintf(page, "%s\n", loadparm);
@@ -910,9 +908,9 @@ static int __init reipl_ccw_init(void)
910 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN; 908 reipl_block_ccw->hdr.blk0_len = IPL_PARM_BLK0_CCW_LEN;
911 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 909 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
912 /* check if read scp info worked and set loadparm */ 910 /* check if read scp info worked and set loadparm */
913 if (SCCB_VALID) 911 if (sclp_ipl_info.is_valid)
914 memcpy(reipl_block_ccw->ipl_info.ccw.load_param, 912 memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
915 SCCB_LOADPARM, LOADPARM_LEN); 913 &sclp_ipl_info.loadparm, LOADPARM_LEN);
916 else 914 else
917 /* read scp info failed: set empty loadparm (EBCDIC blanks) */ 915 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
918 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40, 916 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
@@ -1007,7 +1005,7 @@ static int __init dump_fcp_init(void)
1007{ 1005{
1008 int rc; 1006 int rc;
1009 1007
1010 if(!(SCCB_FLAG & 0x2) || !SCCB_VALID) 1008 if (!sclp_ipl_info.has_dump)
1011 return 0; /* LDIPL DUMP is not installed */ 1009 return 0; /* LDIPL DUMP is not installed */
1012 if (!diag308_set_works) 1010 if (!diag308_set_works)
1013 return 0; 1011 return 0;
@@ -1088,6 +1086,7 @@ static int __init s390_ipl_init(void)
1088{ 1086{
1089 int rc; 1087 int rc;
1090 1088
1089 sclp_get_ipl_info(&sclp_ipl_info);
1091 reipl_probe(); 1090 reipl_probe();
1092 rc = ipl_init(); 1091 rc = ipl_init();
1093 if (rc) 1092 if (rc)
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index eb43c3b31269..441975b796fb 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -93,8 +93,8 @@ void do_monitor_call(struct pt_regs *regs, long interruption_code)
93 /* disable monitor call class 0 */ 93 /* disable monitor call class 0 */
94 __ctl_clear_bit(8, 15); 94 __ctl_clear_bit(8, 15);
95 95
96 atomic_notifier_call_chain(&idle_chain, CPU_NOT_IDLE, 96 atomic_notifier_call_chain(&idle_chain, S390_CPU_NOT_IDLE,
97 (void *)(long) smp_processor_id()); 97 (void *)(long) smp_processor_id());
98} 98}
99 99
100extern void s390_handle_mcck(void); 100extern void s390_handle_mcck(void);
@@ -115,7 +115,7 @@ static void default_idle(void)
115 } 115 }
116 116
117 rc = atomic_notifier_call_chain(&idle_chain, 117 rc = atomic_notifier_call_chain(&idle_chain,
118 CPU_IDLE, (void *)(long) cpu); 118 S390_CPU_IDLE, (void *)(long) cpu);
119 if (rc != NOTIFY_OK && rc != NOTIFY_DONE) 119 if (rc != NOTIFY_OK && rc != NOTIFY_DONE)
120 BUG(); 120 BUG();
121 if (rc != NOTIFY_OK) { 121 if (rc != NOTIFY_OK) {
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 8ff2feaf9b00..182c085ae4dd 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -410,58 +410,40 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
410unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \ 410unsigned int zfcpdump_prefix_array[NR_CPUS + 1] \
411 __attribute__((__section__(".data"))); 411 __attribute__((__section__(".data")));
412 412
413static void __init smp_get_save_areas(void) 413static void __init smp_get_save_area(unsigned int cpu, unsigned int phy_cpu)
414{ 414{
415 unsigned int cpu, cpu_num, rc;
416 __u16 boot_cpu_addr;
417
418 if (ipl_info.type != IPL_TYPE_FCP_DUMP) 415 if (ipl_info.type != IPL_TYPE_FCP_DUMP)
419 return; 416 return;
420 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; 417 if (cpu >= NR_CPUS) {
421 cpu_num = 1; 418 printk(KERN_WARNING "Registers for cpu %i not saved since dump "
422 for (cpu = 0; cpu <= 65535; cpu++) { 419 "kernel was compiled with NR_CPUS=%i\n", cpu, NR_CPUS);
423 if ((u16) cpu == boot_cpu_addr) 420 return;
424 continue;
425 __cpu_logical_map[1] = (__u16) cpu;
426 if (signal_processor(1, sigp_sense) == sigp_not_operational)
427 continue;
428 if (cpu_num >= NR_CPUS) {
429 printk("WARNING: Registers for cpu %i are not "
430 "saved, since dump kernel was compiled with"
431 "NR_CPUS=%i!\n", cpu_num, NR_CPUS);
432 continue;
433 }
434 zfcpdump_save_areas[cpu_num] =
435 alloc_bootmem(sizeof(union save_area));
436 while (1) {
437 rc = signal_processor(1, sigp_stop_and_store_status);
438 if (rc != sigp_busy)
439 break;
440 cpu_relax();
441 }
442 memcpy(zfcpdump_save_areas[cpu_num],
443 (void *)(unsigned long) store_prefix() +
444 SAVE_AREA_BASE, SAVE_AREA_SIZE);
445#ifdef __s390x__
446 /* copy original prefix register */
447 zfcpdump_save_areas[cpu_num]->s390x.pref_reg =
448 zfcpdump_prefix_array[cpu_num];
449#endif
450 cpu_num++;
451 } 421 }
422 zfcpdump_save_areas[cpu] = alloc_bootmem(sizeof(union save_area));
423 __cpu_logical_map[1] = (__u16) phy_cpu;
424 while (signal_processor(1, sigp_stop_and_store_status) == sigp_busy)
425 cpu_relax();
426 memcpy(zfcpdump_save_areas[cpu],
427 (void *)(unsigned long) store_prefix() + SAVE_AREA_BASE,
428 SAVE_AREA_SIZE);
429#ifdef CONFIG_64BIT
430 /* copy original prefix register */
431 zfcpdump_save_areas[cpu]->s390x.pref_reg = zfcpdump_prefix_array[cpu];
432#endif
452} 433}
453 434
454union save_area *zfcpdump_save_areas[NR_CPUS + 1]; 435union save_area *zfcpdump_save_areas[NR_CPUS + 1];
455EXPORT_SYMBOL_GPL(zfcpdump_save_areas); 436EXPORT_SYMBOL_GPL(zfcpdump_save_areas);
456 437
457#else 438#else
458#define smp_get_save_areas() do { } while (0) 439
459#endif 440static inline void smp_get_save_area(unsigned int cpu, unsigned int phy_cpu) { }
441
442#endif /* CONFIG_ZFCPDUMP || CONFIG_ZFCPDUMP_MODULE */
460 443
461/* 444/*
462 * Lets check how many CPUs we have. 445 * Lets check how many CPUs we have.
463 */ 446 */
464
465static unsigned int __init smp_count_cpus(void) 447static unsigned int __init smp_count_cpus(void)
466{ 448{
467 unsigned int cpu, num_cpus; 449 unsigned int cpu, num_cpus;
@@ -470,7 +452,6 @@ static unsigned int __init smp_count_cpus(void)
470 /* 452 /*
471 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu. 453 * cpu 0 is the boot cpu. See smp_prepare_boot_cpu.
472 */ 454 */
473
474 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr; 455 boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
475 current_thread_info()->cpu = 0; 456 current_thread_info()->cpu = 0;
476 num_cpus = 1; 457 num_cpus = 1;
@@ -480,12 +461,11 @@ static unsigned int __init smp_count_cpus(void)
480 __cpu_logical_map[1] = (__u16) cpu; 461 __cpu_logical_map[1] = (__u16) cpu;
481 if (signal_processor(1, sigp_sense) == sigp_not_operational) 462 if (signal_processor(1, sigp_sense) == sigp_not_operational)
482 continue; 463 continue;
464 smp_get_save_area(num_cpus, cpu);
483 num_cpus++; 465 num_cpus++;
484 } 466 }
485
486 printk("Detected %d CPU's\n", (int) num_cpus); 467 printk("Detected %d CPU's\n", (int) num_cpus);
487 printk("Boot cpu address %2X\n", boot_cpu_addr); 468 printk("Boot cpu address %2X\n", boot_cpu_addr);
488
489 return num_cpus; 469 return num_cpus;
490} 470}
491 471
@@ -606,7 +586,6 @@ void __init smp_setup_cpu_possible_map(void)
606{ 586{
607 unsigned int phy_cpus, pos_cpus, cpu; 587 unsigned int phy_cpus, pos_cpus, cpu;
608 588
609 smp_get_save_areas();
610 phy_cpus = smp_count_cpus(); 589 phy_cpus = smp_count_cpus();
611 pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS); 590 pos_cpus = min(phy_cpus + additional_cpus, (unsigned int) NR_CPUS);
612 591
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 9c2872a7cca7..48dae49bc1ec 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -226,10 +226,10 @@ static int nohz_idle_notify(struct notifier_block *self,
226 unsigned long action, void *hcpu) 226 unsigned long action, void *hcpu)
227{ 227{
228 switch (action) { 228 switch (action) {
229 case CPU_IDLE: 229 case S390_CPU_IDLE:
230 stop_hz_timer(); 230 stop_hz_timer();
231 break; 231 break;
232 case CPU_NOT_IDLE: 232 case S390_CPU_NOT_IDLE:
233 start_hz_timer(); 233 start_hz_timer();
234 break; 234 break;
235 } 235 }
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 1e1a6ee2cac1..b6ed143e8597 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -545,10 +545,10 @@ static int vtimer_idle_notify(struct notifier_block *self,
545 unsigned long action, void *hcpu) 545 unsigned long action, void *hcpu)
546{ 546{
547 switch (action) { 547 switch (action) {
548 case CPU_IDLE: 548 case S390_CPU_IDLE:
549 stop_cpu_timer(); 549 stop_cpu_timer();
550 break; 550 break;
551 case CPU_NOT_IDLE: 551 case S390_CPU_NOT_IDLE:
552 start_cpu_timer(); 552 start_cpu_timer();
553 break; 553 break;
554 } 554 }