aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/Makefile4
-rw-r--r--arch/s390/kernel/base.S150
-rw-r--r--arch/s390/kernel/binfmt_elf32.c2
-rw-r--r--arch/s390/kernel/compat_exec_domain.c5
-rw-r--r--arch/s390/kernel/compat_linux.c24
-rw-r--r--arch/s390/kernel/compat_linux.h31
-rw-r--r--arch/s390/kernel/compat_signal.c8
-rw-r--r--arch/s390/kernel/cpcmd.c14
-rw-r--r--arch/s390/kernel/crash.c1
-rw-r--r--arch/s390/kernel/debug.c18
-rw-r--r--arch/s390/kernel/early.c306
-rw-r--r--arch/s390/kernel/ebcdic.c1
-rw-r--r--arch/s390/kernel/head31.S194
-rw-r--r--arch/s390/kernel/head64.S193
-rw-r--r--arch/s390/kernel/ipl.c106
-rw-r--r--arch/s390/kernel/irq.c15
-rw-r--r--arch/s390/kernel/kprobes.c32
-rw-r--r--arch/s390/kernel/machine_kexec.c1
-rw-r--r--arch/s390/kernel/module.c5
-rw-r--r--arch/s390/kernel/process.c4
-rw-r--r--arch/s390/kernel/profile.c20
-rw-r--r--arch/s390/kernel/ptrace.c46
-rw-r--r--arch/s390/kernel/reset.S90
-rw-r--r--arch/s390/kernel/s390_ext.c8
-rw-r--r--arch/s390/kernel/setup.c155
-rw-r--r--arch/s390/kernel/signal.c2
-rw-r--r--arch/s390/kernel/smp.c32
-rw-r--r--arch/s390/kernel/stacktrace.c10
-rw-r--r--arch/s390/kernel/time.c1185
-rw-r--r--arch/s390/kernel/traps.c24
-rw-r--r--arch/s390/kernel/vmlinux.lds.S13
-rw-r--r--arch/s390/kernel/vtime.c10
32 files changed, 1971 insertions, 738 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index a81881c9b297..5492d25d7d69 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -4,9 +4,9 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7obj-y := bitmap.o traps.o time.o process.o reset.o \ 7obj-y := bitmap.o traps.o time.o process.o base.o early.o \
8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ 8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
9 semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o 9 semaphore.o s390_ext.o debug.o irq.o ipl.o
10 10
11obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) 11obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o)
12obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) 12obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o)
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
new file mode 100644
index 000000000000..dc7e5259770f
--- /dev/null
+++ b/arch/s390/kernel/base.S
@@ -0,0 +1,150 @@
1/*
2 * arch/s390/kernel/base.S
3 *
4 * Copyright IBM Corp. 2006,2007
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 * Michael Holzheu <holzheu@de.ibm.com>
7 */
8
9#include <asm/ptrace.h>
10#include <asm/lowcore.h>
11
12#ifdef CONFIG_64BIT
13
14 .globl s390_base_mcck_handler
15s390_base_mcck_handler:
16 basr %r13,0
170: lg %r15,__LC_PANIC_STACK # load panic stack
18 aghi %r15,-STACK_FRAME_OVERHEAD
19 larl %r1,s390_base_mcck_handler_fn
20 lg %r1,0(%r1)
21 ltgr %r1,%r1
22 jz 1f
23 basr %r14,%r1
241: la %r1,4095
25 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
26 lpswe __LC_MCK_OLD_PSW
27
28 .section .bss
29 .globl s390_base_mcck_handler_fn
30s390_base_mcck_handler_fn:
31 .quad 0
32 .previous
33
34 .globl s390_base_ext_handler
35s390_base_ext_handler:
36 stmg %r0,%r15,__LC_SAVE_AREA
37 basr %r13,0
380: aghi %r15,-STACK_FRAME_OVERHEAD
39 larl %r1,s390_base_ext_handler_fn
40 lg %r1,0(%r1)
41 ltgr %r1,%r1
42 jz 1f
43 basr %r14,%r1
441: lmg %r0,%r15,__LC_SAVE_AREA
45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
46 lpswe __LC_EXT_OLD_PSW
47
48 .section .bss
49 .globl s390_base_ext_handler_fn
50s390_base_ext_handler_fn:
51 .quad 0
52 .previous
53
54 .globl s390_base_pgm_handler
55s390_base_pgm_handler:
56 stmg %r0,%r15,__LC_SAVE_AREA
57 basr %r13,0
580: aghi %r15,-STACK_FRAME_OVERHEAD
59 larl %r1,s390_base_pgm_handler_fn
60 lg %r1,0(%r1)
61 ltgr %r1,%r1
62 jz 1f
63 basr %r14,%r1
64 lmg %r0,%r15,__LC_SAVE_AREA
65 lpswe __LC_PGM_OLD_PSW
661: lpswe disabled_wait_psw-0b(%r13)
67
68 .align 8
69disabled_wait_psw:
70 .quad 0x0002000180000000,0x0000000000000000 + s390_base_pgm_handler
71
72 .section .bss
73 .globl s390_base_pgm_handler_fn
74s390_base_pgm_handler_fn:
75 .quad 0
76 .previous
77
78#else /* CONFIG_64BIT */
79
80 .globl s390_base_mcck_handler
81s390_base_mcck_handler:
82 basr %r13,0
830: l %r15,__LC_PANIC_STACK # load panic stack
84 ahi %r15,-STACK_FRAME_OVERHEAD
85 l %r1,2f-0b(%r13)
86 l %r1,0(%r1)
87 ltr %r1,%r1
88 jz 1f
89 basr %r14,%r1
901: lm %r0,%r15,__LC_GPREGS_SAVE_AREA
91 lpsw __LC_MCK_OLD_PSW
92
932: .long s390_base_mcck_handler_fn
94
95 .section .bss
96 .globl s390_base_mcck_handler_fn
97s390_base_mcck_handler_fn:
98 .long 0
99 .previous
100
101 .globl s390_base_ext_handler
102s390_base_ext_handler:
103 stm %r0,%r15,__LC_SAVE_AREA
104 basr %r13,0
1050: ahi %r15,-STACK_FRAME_OVERHEAD
106 l %r1,2f-0b(%r13)
107 l %r1,0(%r1)
108 ltr %r1,%r1
109 jz 1f
110 basr %r14,%r1
1111: lm %r0,%r15,__LC_SAVE_AREA
112 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
113 lpsw __LC_EXT_OLD_PSW
114
1152: .long s390_base_ext_handler_fn
116
117 .section .bss
118 .globl s390_base_ext_handler_fn
119s390_base_ext_handler_fn:
120 .long 0
121 .previous
122
123 .globl s390_base_pgm_handler
124s390_base_pgm_handler:
125 stm %r0,%r15,__LC_SAVE_AREA
126 basr %r13,0
1270: ahi %r15,-STACK_FRAME_OVERHEAD
128 l %r1,2f-0b(%r13)
129 l %r1,0(%r1)
130 ltr %r1,%r1
131 jz 1f
132 basr %r14,%r1
133 lm %r0,%r15,__LC_SAVE_AREA
134 lpsw __LC_PGM_OLD_PSW
135
1361: lpsw disabled_wait_psw-0b(%r13)
137
1382: .long s390_base_pgm_handler_fn
139
140disabled_wait_psw:
141 .align 8
142 .long 0x000a0000,0x00000000 + s390_base_pgm_handler
143
144 .section .bss
145 .globl s390_base_pgm_handler_fn
146s390_base_pgm_handler_fn:
147 .long 0
148 .previous
149
150#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/binfmt_elf32.c b/arch/s390/kernel/binfmt_elf32.c
index 5c46054195cb..f1e40ca00d8d 100644
--- a/arch/s390/kernel/binfmt_elf32.c
+++ b/arch/s390/kernel/binfmt_elf32.c
@@ -192,7 +192,7 @@ MODULE_AUTHOR("Gerhard Tonn <ton@de.ibm.com>");
192 192
193#undef cputime_to_timeval 193#undef cputime_to_timeval
194#define cputime_to_timeval cputime_to_compat_timeval 194#define cputime_to_timeval cputime_to_compat_timeval
195static __inline__ void 195static inline void
196cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value) 196cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
197{ 197{
198 value->tv_usec = cputime % 1000000; 198 value->tv_usec = cputime % 1000000;
diff --git a/arch/s390/kernel/compat_exec_domain.c b/arch/s390/kernel/compat_exec_domain.c
index 71d27c493568..914d49444f92 100644
--- a/arch/s390/kernel/compat_exec_domain.c
+++ b/arch/s390/kernel/compat_exec_domain.c
@@ -12,10 +12,9 @@
12#include <linux/personality.h> 12#include <linux/personality.h>
13#include <linux/sched.h> 13#include <linux/sched.h>
14 14
15struct exec_domain s390_exec_domain; 15static struct exec_domain s390_exec_domain;
16 16
17static int __init 17static int __init s390_init (void)
18s390_init (void)
19{ 18{
20 s390_exec_domain.name = "Linux/s390"; 19 s390_exec_domain.name = "Linux/s390";
21 s390_exec_domain.handler = NULL; 20 s390_exec_domain.handler = NULL;
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 5b33f823863a..666bb6daa148 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -69,6 +69,12 @@
69 69
70#include "compat_linux.h" 70#include "compat_linux.h"
71 71
72long psw_user32_bits = (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
73 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
74 PSW_MASK_PSTATE | PSW_DEFAULT_KEY);
75long psw32_user_bits = (PSW32_BASE_BITS | PSW32_MASK_DAT | PSW32_ASC_HOME |
76 PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK |
77 PSW32_MASK_PSTATE);
72 78
73/* For this source file, we want overflow handling. */ 79/* For this source file, we want overflow handling. */
74 80
@@ -416,7 +422,7 @@ asmlinkage long sys32_sysinfo(struct sysinfo32 __user *info)
416 mm_segment_t old_fs = get_fs (); 422 mm_segment_t old_fs = get_fs ();
417 423
418 set_fs (KERNEL_DS); 424 set_fs (KERNEL_DS);
419 ret = sys_sysinfo((struct sysinfo __user *) &s); 425 ret = sys_sysinfo((struct sysinfo __force __user *) &s);
420 set_fs (old_fs); 426 set_fs (old_fs);
421 err = put_user (s.uptime, &info->uptime); 427 err = put_user (s.uptime, &info->uptime);
422 err |= __put_user (s.loads[0], &info->loads[0]); 428 err |= __put_user (s.loads[0], &info->loads[0]);
@@ -445,7 +451,8 @@ asmlinkage long sys32_sched_rr_get_interval(compat_pid_t pid,
445 mm_segment_t old_fs = get_fs (); 451 mm_segment_t old_fs = get_fs ();
446 452
447 set_fs (KERNEL_DS); 453 set_fs (KERNEL_DS);
448 ret = sys_sched_rr_get_interval(pid, (struct timespec __user *) &t); 454 ret = sys_sched_rr_get_interval(pid,
455 (struct timespec __force __user *) &t);
449 set_fs (old_fs); 456 set_fs (old_fs);
450 if (put_compat_timespec(&t, interval)) 457 if (put_compat_timespec(&t, interval))
451 return -EFAULT; 458 return -EFAULT;
@@ -472,8 +479,8 @@ asmlinkage long sys32_rt_sigprocmask(int how, compat_sigset_t __user *set,
472 } 479 }
473 set_fs (KERNEL_DS); 480 set_fs (KERNEL_DS);
474 ret = sys_rt_sigprocmask(how, 481 ret = sys_rt_sigprocmask(how,
475 set ? (sigset_t __user *) &s : NULL, 482 set ? (sigset_t __force __user *) &s : NULL,
476 oset ? (sigset_t __user *) &s : NULL, 483 oset ? (sigset_t __force __user *) &s : NULL,
477 sigsetsize); 484 sigsetsize);
478 set_fs (old_fs); 485 set_fs (old_fs);
479 if (ret) return ret; 486 if (ret) return ret;
@@ -499,7 +506,7 @@ asmlinkage long sys32_rt_sigpending(compat_sigset_t __user *set,
499 mm_segment_t old_fs = get_fs(); 506 mm_segment_t old_fs = get_fs();
500 507
501 set_fs (KERNEL_DS); 508 set_fs (KERNEL_DS);
502 ret = sys_rt_sigpending((sigset_t __user *) &s, sigsetsize); 509 ret = sys_rt_sigpending((sigset_t __force __user *) &s, sigsetsize);
503 set_fs (old_fs); 510 set_fs (old_fs);
504 if (!ret) { 511 if (!ret) {
505 switch (_NSIG_WORDS) { 512 switch (_NSIG_WORDS) {
@@ -524,7 +531,7 @@ sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo)
524 if (copy_siginfo_from_user32(&info, uinfo)) 531 if (copy_siginfo_from_user32(&info, uinfo))
525 return -EFAULT; 532 return -EFAULT;
526 set_fs (KERNEL_DS); 533 set_fs (KERNEL_DS);
527 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info); 534 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __force __user *) &info);
528 set_fs (old_fs); 535 set_fs (old_fs);
529 return ret; 536 return ret;
530} 537}
@@ -682,7 +689,7 @@ asmlinkage long sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offse
682 689
683 set_fs(KERNEL_DS); 690 set_fs(KERNEL_DS);
684 ret = sys_sendfile(out_fd, in_fd, 691 ret = sys_sendfile(out_fd, in_fd,
685 offset ? (off_t __user *) &of : NULL, count); 692 offset ? (off_t __force __user *) &of : NULL, count);
686 set_fs(old_fs); 693 set_fs(old_fs);
687 694
688 if (offset && put_user(of, offset)) 695 if (offset && put_user(of, offset))
@@ -703,7 +710,8 @@ asmlinkage long sys32_sendfile64(int out_fd, int in_fd,
703 710
704 set_fs(KERNEL_DS); 711 set_fs(KERNEL_DS);
705 ret = sys_sendfile64(out_fd, in_fd, 712 ret = sys_sendfile64(out_fd, in_fd,
706 offset ? (loff_t __user *) &lof : NULL, count); 713 offset ? (loff_t __force __user *) &lof : NULL,
714 count);
707 set_fs(old_fs); 715 set_fs(old_fs);
708 716
709 if (offset && put_user(lof, offset)) 717 if (offset && put_user(lof, offset))
diff --git a/arch/s390/kernel/compat_linux.h b/arch/s390/kernel/compat_linux.h
index 1a18e29668ef..e89f8c0c42a0 100644
--- a/arch/s390/kernel/compat_linux.h
+++ b/arch/s390/kernel/compat_linux.h
@@ -115,37 +115,6 @@ typedef struct
115 __u32 addr; 115 __u32 addr;
116} _psw_t32 __attribute__ ((aligned(8))); 116} _psw_t32 __attribute__ ((aligned(8)));
117 117
118#define PSW32_MASK_PER 0x40000000UL
119#define PSW32_MASK_DAT 0x04000000UL
120#define PSW32_MASK_IO 0x02000000UL
121#define PSW32_MASK_EXT 0x01000000UL
122#define PSW32_MASK_KEY 0x00F00000UL
123#define PSW32_MASK_MCHECK 0x00040000UL
124#define PSW32_MASK_WAIT 0x00020000UL
125#define PSW32_MASK_PSTATE 0x00010000UL
126#define PSW32_MASK_ASC 0x0000C000UL
127#define PSW32_MASK_CC 0x00003000UL
128#define PSW32_MASK_PM 0x00000f00UL
129
130#define PSW32_ADDR_AMODE31 0x80000000UL
131#define PSW32_ADDR_INSN 0x7FFFFFFFUL
132
133#define PSW32_BASE_BITS 0x00080000UL
134
135#define PSW32_ASC_PRIMARY 0x00000000UL
136#define PSW32_ASC_ACCREG 0x00004000UL
137#define PSW32_ASC_SECONDARY 0x00008000UL
138#define PSW32_ASC_HOME 0x0000C000UL
139
140#define PSW32_USER_BITS (PSW32_BASE_BITS | PSW32_MASK_DAT | PSW32_ASC_HOME | \
141 PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK | \
142 PSW32_MASK_PSTATE)
143
144#define PSW32_MASK_MERGE(CURRENT,NEW) \
145 (((CURRENT) & ~(PSW32_MASK_CC|PSW32_MASK_PM)) | \
146 ((NEW) & (PSW32_MASK_CC|PSW32_MASK_PM)))
147
148
149typedef struct 118typedef struct
150{ 119{
151 _psw_t32 psw; 120 _psw_t32 psw;
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 861888ab8c13..887a9881d0d0 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -275,8 +275,8 @@ sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss,
275 } 275 }
276 276
277 set_fs (KERNEL_DS); 277 set_fs (KERNEL_DS);
278 ret = do_sigaltstack((stack_t __user *) (uss ? &kss : NULL), 278 ret = do_sigaltstack((stack_t __force __user *) (uss ? &kss : NULL),
279 (stack_t __user *) (uoss ? &koss : NULL), 279 (stack_t __force __user *) (uoss ? &koss : NULL),
280 regs->gprs[15]); 280 regs->gprs[15]);
281 set_fs (old_fs); 281 set_fs (old_fs);
282 282
@@ -298,7 +298,7 @@ static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
298 _s390_regs_common32 regs32; 298 _s390_regs_common32 regs32;
299 int err, i; 299 int err, i;
300 300
301 regs32.psw.mask = PSW32_MASK_MERGE(PSW32_USER_BITS, 301 regs32.psw.mask = PSW32_MASK_MERGE(psw32_user_bits,
302 (__u32)(regs->psw.mask >> 32)); 302 (__u32)(regs->psw.mask >> 32));
303 regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr; 303 regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
304 for (i = 0; i < NUM_GPRS; i++) 304 for (i = 0; i < NUM_GPRS; i++)
@@ -401,7 +401,7 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
401 goto badframe; 401 goto badframe;
402 402
403 set_fs (KERNEL_DS); 403 set_fs (KERNEL_DS);
404 do_sigaltstack((stack_t __user *)&st, NULL, regs->gprs[15]); 404 do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]);
405 set_fs (old_fs); 405 set_fs (old_fs);
406 406
407 return regs->gprs[2]; 407 return regs->gprs[2];
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index a5972f1541fe..6c89f30c8e31 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -16,6 +16,7 @@
16#include <asm/ebcdic.h> 16#include <asm/ebcdic.h>
17#include <asm/cpcmd.h> 17#include <asm/cpcmd.h>
18#include <asm/system.h> 18#include <asm/system.h>
19#include <asm/io.h>
19 20
20static DEFINE_SPINLOCK(cpcmd_lock); 21static DEFINE_SPINLOCK(cpcmd_lock);
21static char cpcmd_buf[241]; 22static char cpcmd_buf[241];
@@ -88,13 +89,8 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
88 int len; 89 int len;
89 unsigned long flags; 90 unsigned long flags;
90 91
91 if ((rlen == 0) || (response == NULL) 92 if ((virt_to_phys(response) != (unsigned long) response) ||
92 || !((unsigned long)response >> 31)) { 93 (((unsigned long)response + rlen) >> 31)) {
93 spin_lock_irqsave(&cpcmd_lock, flags);
94 len = __cpcmd(cmd, response, rlen, response_code);
95 spin_unlock_irqrestore(&cpcmd_lock, flags);
96 }
97 else {
98 lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); 94 lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
99 if (!lowbuf) { 95 if (!lowbuf) {
100 printk(KERN_WARNING 96 printk(KERN_WARNING
@@ -106,6 +102,10 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
106 spin_unlock_irqrestore(&cpcmd_lock, flags); 102 spin_unlock_irqrestore(&cpcmd_lock, flags);
107 memcpy(response, lowbuf, rlen); 103 memcpy(response, lowbuf, rlen);
108 kfree(lowbuf); 104 kfree(lowbuf);
105 } else {
106 spin_lock_irqsave(&cpcmd_lock, flags);
107 len = __cpcmd(cmd, response, rlen, response_code);
108 spin_unlock_irqrestore(&cpcmd_lock, flags);
109 } 109 }
110 return len; 110 return len;
111} 111}
diff --git a/arch/s390/kernel/crash.c b/arch/s390/kernel/crash.c
index 926cceeae0fa..8cc7c9fa64f5 100644
--- a/arch/s390/kernel/crash.c
+++ b/arch/s390/kernel/crash.c
@@ -9,6 +9,7 @@
9 9
10#include <linux/threads.h> 10#include <linux/threads.h>
11#include <linux/kexec.h> 11#include <linux/kexec.h>
12#include <linux/reboot.h>
12 13
13void machine_crash_shutdown(struct pt_regs *regs) 14void machine_crash_shutdown(struct pt_regs *regs)
14{ 15{
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index bb57bc0e3fc8..f4b62df02aa2 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -120,7 +120,7 @@ struct debug_view debug_hex_ascii_view = {
120 NULL 120 NULL
121}; 121};
122 122
123struct debug_view debug_level_view = { 123static struct debug_view debug_level_view = {
124 "level", 124 "level",
125 &debug_prolog_level_fn, 125 &debug_prolog_level_fn,
126 NULL, 126 NULL,
@@ -129,7 +129,7 @@ struct debug_view debug_level_view = {
129 NULL 129 NULL
130}; 130};
131 131
132struct debug_view debug_pages_view = { 132static struct debug_view debug_pages_view = {
133 "pages", 133 "pages",
134 &debug_prolog_pages_fn, 134 &debug_prolog_pages_fn,
135 NULL, 135 NULL,
@@ -138,7 +138,7 @@ struct debug_view debug_pages_view = {
138 NULL 138 NULL
139}; 139};
140 140
141struct debug_view debug_flush_view = { 141static struct debug_view debug_flush_view = {
142 "flush", 142 "flush",
143 NULL, 143 NULL,
144 NULL, 144 NULL,
@@ -156,14 +156,14 @@ struct debug_view debug_sprintf_view = {
156 NULL 156 NULL
157}; 157};
158 158
159 159/* used by dump analysis tools to determine version of debug feature */
160unsigned int debug_feature_version = __DEBUG_FEATURE_VERSION; 160unsigned int debug_feature_version = __DEBUG_FEATURE_VERSION;
161 161
162/* static globals */ 162/* static globals */
163 163
164static debug_info_t *debug_area_first = NULL; 164static debug_info_t *debug_area_first = NULL;
165static debug_info_t *debug_area_last = NULL; 165static debug_info_t *debug_area_last = NULL;
166DECLARE_MUTEX(debug_lock); 166static DECLARE_MUTEX(debug_lock);
167 167
168static int initialized; 168static int initialized;
169 169
@@ -905,7 +905,7 @@ static struct ctl_table s390dbf_dir_table[] = {
905 { .ctl_name = 0 } 905 { .ctl_name = 0 }
906}; 906};
907 907
908struct ctl_table_header *s390dbf_sysctl_header; 908static struct ctl_table_header *s390dbf_sysctl_header;
909 909
910void 910void
911debug_stop_all(void) 911debug_stop_all(void)
@@ -1300,8 +1300,7 @@ out:
1300 * flushes debug areas 1300 * flushes debug areas
1301 */ 1301 */
1302 1302
1303void 1303static void debug_flush(debug_info_t* id, int area)
1304debug_flush(debug_info_t* id, int area)
1305{ 1304{
1306 unsigned long flags; 1305 unsigned long flags;
1307 int i,j; 1306 int i,j;
@@ -1511,8 +1510,7 @@ out:
1511/* 1510/*
1512 * clean up module 1511 * clean up module
1513 */ 1512 */
1514void 1513static void __exit debug_exit(void)
1515__exit debug_exit(void)
1516{ 1514{
1517 debugfs_remove(debug_debugfs_root_entry); 1515 debugfs_remove(debug_debugfs_root_entry);
1518 unregister_sysctl_table(s390dbf_sysctl_header); 1516 unregister_sysctl_table(s390dbf_sysctl_header);
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
new file mode 100644
index 000000000000..e518dd53eff5
--- /dev/null
+++ b/arch/s390/kernel/early.c
@@ -0,0 +1,306 @@
1/*
2 * arch/s390/kernel/early.c
3 *
4 * Copyright IBM Corp. 2007
5 * Author(s): Hongjie Yang <hongjie@us.ibm.com>,
6 * Heiko Carstens <heiko.carstens@de.ibm.com>
7 */
8
9#include <linux/init.h>
10#include <linux/errno.h>
11#include <linux/string.h>
12#include <linux/ctype.h>
13#include <linux/lockdep.h>
14#include <linux/module.h>
15#include <linux/pfn.h>
16#include <linux/uaccess.h>
17#include <asm/lowcore.h>
18#include <asm/processor.h>
19#include <asm/sections.h>
20#include <asm/setup.h>
21#include <asm/cpcmd.h>
22#include <asm/sclp.h>
23
24/*
25 * Create a Kernel NSS if the SAVESYS= parameter is defined
26 */
27#define DEFSYS_CMD_SIZE 96
28#define SAVESYS_CMD_SIZE 32
29
30char kernel_nss_name[NSS_NAME_SIZE + 1];
31
32#ifdef CONFIG_SHARED_KERNEL
33static noinline __init void create_kernel_nss(void)
34{
35 unsigned int i, stext_pfn, eshared_pfn, end_pfn, min_size;
36#ifdef CONFIG_BLK_DEV_INITRD
37 unsigned int sinitrd_pfn, einitrd_pfn;
38#endif
39 int response;
40 char *savesys_ptr;
41 char upper_command_line[COMMAND_LINE_SIZE];
42 char defsys_cmd[DEFSYS_CMD_SIZE];
43 char savesys_cmd[SAVESYS_CMD_SIZE];
44
45 /* Do nothing if we are not running under VM */
46 if (!MACHINE_IS_VM)
47 return;
48
49 /* Convert COMMAND_LINE to upper case */
50 for (i = 0; i < strlen(COMMAND_LINE); i++)
51 upper_command_line[i] = toupper(COMMAND_LINE[i]);
52
53 savesys_ptr = strstr(upper_command_line, "SAVESYS=");
54
55 if (!savesys_ptr)
56 return;
57
58 savesys_ptr += 8; /* Point to the beginning of the NSS name */
59 for (i = 0; i < NSS_NAME_SIZE; i++) {
60 if (savesys_ptr[i] == ' ' || savesys_ptr[i] == '\0')
61 break;
62 kernel_nss_name[i] = savesys_ptr[i];
63 }
64
65 stext_pfn = PFN_DOWN(__pa(&_stext));
66 eshared_pfn = PFN_DOWN(__pa(&_eshared));
67 end_pfn = PFN_UP(__pa(&_end));
68 min_size = end_pfn << 2;
69
70 sprintf(defsys_cmd, "DEFSYS %s 00000-%.5X EW %.5X-%.5X SR %.5X-%.5X",
71 kernel_nss_name, stext_pfn - 1, stext_pfn, eshared_pfn - 1,
72 eshared_pfn, end_pfn);
73
74#ifdef CONFIG_BLK_DEV_INITRD
75 if (INITRD_START && INITRD_SIZE) {
76 sinitrd_pfn = PFN_DOWN(__pa(INITRD_START));
77 einitrd_pfn = PFN_UP(__pa(INITRD_START + INITRD_SIZE));
78 min_size = einitrd_pfn << 2;
79 sprintf(defsys_cmd, "%s EW %.5X-%.5X", defsys_cmd,
80 sinitrd_pfn, einitrd_pfn);
81 }
82#endif
83
84 sprintf(defsys_cmd, "%s EW MINSIZE=%.7iK", defsys_cmd, min_size);
85 sprintf(savesys_cmd, "SAVESYS %s \n IPL %s",
86 kernel_nss_name, kernel_nss_name);
87
88 __cpcmd(defsys_cmd, NULL, 0, &response);
89
90 if (response != 0)
91 return;
92
93 __cpcmd(savesys_cmd, NULL, 0, &response);
94
95 if (response != strlen(savesys_cmd))
96 return;
97
98 ipl_flags = IPL_NSS_VALID;
99}
100
101#else /* CONFIG_SHARED_KERNEL */
102
103static inline void create_kernel_nss(void) { }
104
105#endif /* CONFIG_SHARED_KERNEL */
106
107/*
108 * Clear bss memory
109 */
110static noinline __init void clear_bss_section(void)
111{
112 memset(__bss_start, 0, _end - __bss_start);
113}
114
115/*
116 * Initialize storage key for kernel pages
117 */
118static noinline __init void init_kernel_storage_key(void)
119{
120 unsigned long end_pfn, init_pfn;
121
122 end_pfn = PFN_UP(__pa(&_end));
123
124 for (init_pfn = 0 ; init_pfn < end_pfn; init_pfn++)
125 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
126}
127
128static noinline __init void detect_machine_type(void)
129{
130 struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;
131
132 asm volatile("stidp %0" : "=m" (S390_lowcore.cpu_data.cpu_id));
133
134 /* Running under z/VM ? */
135 if (cpuinfo->cpu_id.version == 0xff)
136 machine_flags |= 1;
137
138 /* Running on a P/390 ? */
139 if (cpuinfo->cpu_id.machine == 0x7490)
140 machine_flags |= 4;
141}
142
143static noinline __init int memory_fast_detect(void)
144{
145
146 unsigned long val0 = 0;
147 unsigned long val1 = 0xc;
148 int ret = -ENOSYS;
149
150 if (ipl_flags & IPL_NSS_VALID)
151 return -ENOSYS;
152
153 asm volatile(
154 " diag %1,%2,0x260\n"
155 "0: lhi %0,0\n"
156 "1:\n"
157 EX_TABLE(0b,1b)
158 : "+d" (ret), "+d" (val0), "+d" (val1) : : "cc");
159
160 if (ret || val0 != val1)
161 return -ENOSYS;
162
163 memory_chunk[0].size = val0;
164 return 0;
165}
166
167#define ADDR2G (1UL << 31)
168
169static noinline __init unsigned long sclp_memory_detect(void)
170{
171 struct sclp_readinfo_sccb *sccb;
172 unsigned long long memsize;
173
174 sccb = &s390_readinfo_sccb;
175
176 if (sccb->header.response_code != 0x10)
177 return 0;
178
179 if (sccb->rnsize)
180 memsize = sccb->rnsize << 20;
181 else
182 memsize = sccb->rnsize2 << 20;
183 if (sccb->rnmax)
184 memsize *= sccb->rnmax;
185 else
186 memsize *= sccb->rnmax2;
187#ifndef CONFIG_64BIT
188 /*
189 * Can't deal with more than 2G in 31 bit addressing mode, so
190 * limit the value in order to avoid strange side effects.
191 */
192 if (memsize > ADDR2G)
193 memsize = ADDR2G;
194#endif
195 return (unsigned long) memsize;
196}
197
198static inline __init unsigned long __tprot(unsigned long addr)
199{
200 int cc = -1;
201
202 asm volatile(
203 " tprot 0(%1),0\n"
204 "0: ipm %0\n"
205 " srl %0,28\n"
206 "1:\n"
207 EX_TABLE(0b,1b)
208 : "+d" (cc) : "a" (addr) : "cc");
209 return (unsigned long)cc;
210}
211
212/* Checking memory in 128KB increments. */
213#define CHUNK_INCR (1UL << 17)
214
215static noinline __init void find_memory_chunks(unsigned long memsize)
216{
217 unsigned long addr = 0, old_addr = 0;
218 unsigned long old_cc = CHUNK_READ_WRITE;
219 unsigned long cc;
220 int chunk = 0;
221
222 while (chunk < MEMORY_CHUNKS) {
223 cc = __tprot(addr);
224 while (cc == old_cc) {
225 addr += CHUNK_INCR;
226 cc = __tprot(addr);
227#ifndef CONFIG_64BIT
228 if (addr == ADDR2G)
229 break;
230#endif
231 }
232
233 if (old_addr != addr &&
234 (old_cc == CHUNK_READ_WRITE || old_cc == CHUNK_READ_ONLY)) {
235 memory_chunk[chunk].addr = old_addr;
236 memory_chunk[chunk].size = addr - old_addr;
237 memory_chunk[chunk].type = old_cc;
238 chunk++;
239 }
240
241 old_addr = addr;
242 old_cc = cc;
243
244#ifndef CONFIG_64BIT
245 if (addr == ADDR2G)
246 break;
247#endif
248 /*
249 * Finish memory detection at the first hole, unless
250 * - we reached the hsa -> skip it.
251 * - we know there must be more.
252 */
253 if (cc == -1UL && !memsize && old_addr != ADDR2G)
254 break;
255 if (memsize && addr >= memsize)
256 break;
257 }
258}
259
260static __init void early_pgm_check_handler(void)
261{
262 unsigned long addr;
263 const struct exception_table_entry *fixup;
264
265 addr = S390_lowcore.program_old_psw.addr;
266 fixup = search_exception_tables(addr & PSW_ADDR_INSN);
267 if (!fixup)
268 disabled_wait(0);
269 S390_lowcore.program_old_psw.addr = fixup->fixup | PSW_ADDR_AMODE;
270}
271
272static noinline __init void setup_lowcore_early(void)
273{
274 psw_t psw;
275
276 psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
277 psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_ext_handler;
278 S390_lowcore.external_new_psw = psw;
279 psw.addr = PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
280 S390_lowcore.program_new_psw = psw;
281 s390_base_pgm_handler_fn = early_pgm_check_handler;
282}
283
284/*
285 * Save ipl parameters, clear bss memory, initialize storage keys
286 * and create a kernel NSS at startup if the SAVESYS= parm is defined
287 */
288void __init startup_init(void)
289{
290 unsigned long memsize;
291
292 ipl_save_parameters();
293 clear_bss_section();
294 init_kernel_storage_key();
295 lockdep_init();
296 lockdep_off();
297 detect_machine_type();
298 create_kernel_nss();
299 sort_main_extable();
300 setup_lowcore_early();
301 sclp_readinfo_early();
302 memsize = sclp_memory_detect();
303 if (memory_fast_detect() < 0)
304 find_memory_chunks(memsize);
305 lockdep_on();
306}
diff --git a/arch/s390/kernel/ebcdic.c b/arch/s390/kernel/ebcdic.c
index bb0f973137f0..cc0dc609d738 100644
--- a/arch/s390/kernel/ebcdic.c
+++ b/arch/s390/kernel/ebcdic.c
@@ -11,6 +11,7 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <asm/types.h> 13#include <asm/types.h>
14#include <asm/ebcdic.h>
14 15
15/* 16/*
16 * ASCII (IBM PC 437) -> EBCDIC 037 17 * ASCII (IBM PC 437) -> EBCDIC 037
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index eca507050e47..453fd3b4edea 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -51,176 +51,15 @@ startup_continue:
51 st %r15,__LC_KERNEL_STACK # set end of kernel stack 51 st %r15,__LC_KERNEL_STACK # set end of kernel stack
52 ahi %r15,-96 52 ahi %r15,-96
53 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain 53 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
54
55 l %r14,.Lipl_save_parameters-.LPG1(%r13)
56 basr %r14,%r14
57# 54#
58# clear bss memory 55# Save ipl parameters, clear bss memory, initialize storage key for kernel pages,
56# and create a kernel NSS if the SAVESYS= parm is defined
59# 57#
60 l %r2,.Lbss_bgn-.LPG1(%r13) # start of bss 58 l %r14,.Lstartup_init-.LPG1(%r13)
61 l %r3,.Lbss_end-.LPG1(%r13) # end of bss 59 basr %r14,%r14
62 sr %r3,%r2 # length of bss
63 sr %r4,%r4
64 sr %r5,%r5 # set src,length and pad to zero
65 sr %r0,%r0
66 mvcle %r2,%r4,0 # clear mem
67 jo .-4 # branch back, if not finish
68
69 l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
70.Lservicecall:
71 stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
72
73 stctl %r0, %r0,.Lcr-.LPG1(%r13) # get cr0
74 la %r1,0x200 # set bit 22
75 o %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
76 st %r1,.Lcr-.LPG1(%r13)
77 lctl %r0, %r0,.Lcr-.LPG1(%r13) # load modified cr0
78
79 mvc __LC_EXT_NEW_PSW(8),.Lpcext-.LPG1(%r13) # set postcall psw
80 la %r1, .Lsclph-.LPG1(%r13)
81 a %r1,__LC_EXT_NEW_PSW+4 # set handler
82 st %r1,__LC_EXT_NEW_PSW+4
83
84 l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff
85 lr %r1,%r4 # our sccb
86 .insn rre,0xb2200000,%r2,%r1 # service call
87 ipm %r1
88 srl %r1,28 # get cc code
89 xr %r3, %r3
90 chi %r1,3
91 be .Lfchunk-.LPG1(%r13) # leave
92 chi %r1,2
93 be .Lservicecall-.LPG1(%r13)
94 lpsw .Lwaitsclp-.LPG1(%r13)
95.Lsclph:
96 lh %r1,.Lsccbr-.Lsccb(%r4)
97 chi %r1,0x10 # 0x0010 is the sucess code
98 je .Lprocsccb # let's process the sccb
99 chi %r1,0x1f0
100 bne .Lfchunk-.LPG1(%r13) # unhandled error code
101 c %r2, .Lrcp-.LPG1(%r13) # Did we try Read SCP forced
102 bne .Lfchunk-.LPG1(%r13) # if no, give up
103 l %r2, .Lrcp2-.LPG1(%r13) # try with Read SCP
104 b .Lservicecall-.LPG1(%r13)
105.Lprocsccb:
106 lhi %r1,0
107 icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
108 jnz .Lscnd
109 lhi %r1,0x800 # otherwise report 2GB
110.Lscnd:
111 lhi %r3,0x800 # limit reported memory size to 2GB
112 cr %r1,%r3
113 jl .Lno2gb
114 lr %r1,%r3
115.Lno2gb:
116 xr %r3,%r3 # same logic
117 ic %r3,.Lscpa1-.Lsccb(%r4)
118 chi %r3,0x00
119 jne .Lcompmem
120 l %r3,.Lscpa2-.Lsccb(%r4)
121.Lcompmem:
122 mr %r2,%r1 # mem in MB on 128-bit
123 l %r1,.Lonemb-.LPG1(%r13)
124 mr %r2,%r1 # mem size in bytes in %r3
125 b .Lfchunk-.LPG1(%r13)
126
127 .align 4
128.Lipl_save_parameters:
129 .long ipl_save_parameters
130.Linittu:
131 .long init_thread_union
132.Lpmask:
133 .byte 0
134 .align 8
135.Lpcext:.long 0x00080000,0x80000000
136.Lcr:
137 .long 0x00 # place holder for cr0
138 .align 8
139.Lwaitsclp:
140 .long 0x010a0000,0x80000000 + .Lsclph
141.Lrcp:
142 .int 0x00120001 # Read SCP forced code
143.Lrcp2:
144 .int 0x00020001 # Read SCP code
145.Lonemb:
146 .int 0x100000
147.Lfchunk:
148 60
149#
150# find memory chunks.
151#
152 lr %r9,%r3 # end of mem
153 mvc __LC_PGM_NEW_PSW(8),.Lpcmem-.LPG1(%r13)
154 la %r1,1 # test in increments of 128KB
155 sll %r1,17
156 l %r3,.Lmchunk-.LPG1(%r13) # get pointer to memory_chunk array
157 slr %r4,%r4 # set start of chunk to zero
158 slr %r5,%r5 # set end of chunk to zero
159 slr %r6,%r6 # set access code to zero
160 la %r10,MEMORY_CHUNKS # number of chunks
161.Lloop:
162 tprot 0(%r5),0 # test protection of first byte
163 ipm %r7
164 srl %r7,28
165 clr %r6,%r7 # compare cc with last access code
166 be .Lsame-.LPG1(%r13)
167 lhi %r8,0 # no program checks
168 b .Lsavchk-.LPG1(%r13)
169.Lsame:
170 ar %r5,%r1 # add 128KB to end of chunk
171 bno .Lloop-.LPG1(%r13) # r1 < 0x80000000 -> loop
172.Lchkmem: # > 2GB or tprot got a program check
173 lhi %r8,1 # set program check flag
174.Lsavchk:
175 clr %r4,%r5 # chunk size > 0?
176 be .Lchkloop-.LPG1(%r13)
177 st %r4,0(%r3) # store start address of chunk
178 lr %r0,%r5
179 slr %r0,%r4
180 st %r0,4(%r3) # store size of chunk
181 st %r6,8(%r3) # store type of chunk
182 la %r3,12(%r3)
183 ahi %r10,-1 # update chunk number
184.Lchkloop:
185 lr %r6,%r7 # set access code to last cc
186 # we got an exception or we're starting a new
187 # chunk , we must check if we should
188 # still try to find valid memory (if we detected
189 # the amount of available storage), and if we
190 # have chunks left
191 xr %r0,%r0
192 clr %r0,%r9 # did we detect memory?
193 je .Ldonemem # if not, leave
194 chi %r10,0 # do we have chunks left?
195 je .Ldonemem
196 chi %r8,1 # program check ?
197 je .Lpgmchk
198 lr %r4,%r5 # potential new chunk
199 alr %r5,%r1 # add 128KB to end of chunk
200 j .Llpcnt
201.Lpgmchk:
202 alr %r5,%r1 # add 128KB to end of chunk
203 lr %r4,%r5 # potential new chunk
204.Llpcnt:
205 clr %r5,%r9 # should we go on?
206 jl .Lloop
207.Ldonemem:
208 l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags 61 l %r12,.Lmflags-.LPG1(%r13) # get address of machine_flags
209# 62#
210# find out if we are running under VM
211#
212 stidp __LC_CPUID # store cpuid
213 tm __LC_CPUID,0xff # running under VM ?
214 bno .Lnovm-.LPG1(%r13)
215 oi 3(%r12),1 # set VM flag
216.Lnovm:
217 lh %r0,__LC_CPUID+4 # get cpu version
218 chi %r0,0x7490 # running on a P/390 ?
219 bne .Lnop390-.LPG1(%r13)
220 oi 3(%r12),4 # set P/390 flag
221.Lnop390:
222
223#
224# find out if we have an IEEE fpu 63# find out if we have an IEEE fpu
225# 64#
226 mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13) 65 mvc __LC_PGM_NEW_PSW(8),.Lpcfpu-.LPG1(%r13)
@@ -295,7 +134,6 @@ startup_continue:
295 .long 0 # cr15: linkage stack operations 134 .long 0 # cr15: linkage stack operations
296.Lduct: .long 0,0,0,0,0,0,0,0 135.Lduct: .long 0,0,0,0,0,0,0,0
297 .long 0,0,0,0,0,0,0,0 136 .long 0,0,0,0,0,0,0,0
298.Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem
299.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu 137.Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu
300.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp 138.Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp
301.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg 139.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
@@ -306,7 +144,9 @@ startup_continue:
306.Lbss_bgn: .long __bss_start 144.Lbss_bgn: .long __bss_start
307.Lbss_end: .long _end 145.Lbss_end: .long _end
308.Lparmaddr: .long PARMAREA 146.Lparmaddr: .long PARMAREA
309.Lsccbaddr: .long .Lsccb 147.Linittu: .long init_thread_union
148.Lstartup_init:
149 .long startup_init
310 150
311 .globl ipl_schib 151 .globl ipl_schib
312ipl_schib: 152ipl_schib:
@@ -322,26 +162,6 @@ ipl_devno:
322 .word 0 162 .word 0
323 163
324 .org 0x12000 164 .org 0x12000
325.globl s390_readinfo_sccb
326s390_readinfo_sccb:
327.Lsccb:
328 .hword 0x1000 # length, one page
329 .byte 0x00,0x00,0x00
330 .byte 0x80 # variable response bit set
331.Lsccbr:
332 .hword 0x00 # response code
333.Lscpincr1:
334 .hword 0x00
335.Lscpa1:
336 .byte 0x00
337 .fill 89,1,0
338.Lscpa2:
339 .int 0x00
340.Lscpincr2:
341 .quad 0x00
342 .fill 3984,1,0
343 .org 0x13000
344
345#ifdef CONFIG_SHARED_KERNEL 165#ifdef CONFIG_SHARED_KERNEL
346 .org 0x100000 166 .org 0x100000
347#endif 167#endif
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 6ba3f4512dd1..b8fec4e5c5d4 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -58,183 +58,15 @@ startup_continue:
58 stg %r15,__LC_KERNEL_STACK # set end of kernel stack 58 stg %r15,__LC_KERNEL_STACK # set end of kernel stack
59 aghi %r15,-160 59 aghi %r15,-160
60 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain 60 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear backchain
61
62 brasl %r14,ipl_save_parameters
63# 61#
64# clear bss memory 62# Save ipl parameters, clear bss memory, initialize storage key for kernel pages,
63# and create a kernel NSS if the SAVESYS= parm is defined
65# 64#
66 larl %r2,__bss_start # start of bss segment 65 brasl %r14,startup_init
67 larl %r3,_end # end of bss segment
68 sgr %r3,%r2 # length of bss
69 sgr %r4,%r4 #
70 sgr %r5,%r5 # set src,length and pad to zero
71 mvcle %r2,%r4,0 # clear mem
72 jo .-4 # branch back, if not finish
73 # set program check new psw mask 66 # set program check new psw mask
74 mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) 67 mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
75 larl %r1,.Lslowmemdetect # set program check address
76 stg %r1,__LC_PGM_NEW_PSW+8
77 lghi %r1,0xc
78 diag %r0,%r1,0x260 # get memory size of virtual machine
79 cgr %r0,%r1 # different? -> old detection routine
80 jne .Lslowmemdetect
81 aghi %r1,1 # size is one more than end
82 larl %r2,memory_chunk
83 stg %r1,8(%r2) # store size of chunk
84 j .Ldonemem
85
86.Lslowmemdetect:
87 l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
88.Lservicecall:
89 stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
90
91 stctg %r0,%r0,.Lcr-.LPG1(%r13) # get cr0
92 la %r1,0x200 # set bit 22
93 og %r1,.Lcr-.LPG1(%r13) # or old cr0 with r1
94 stg %r1,.Lcr-.LPG1(%r13)
95 lctlg %r0,%r0,.Lcr-.LPG1(%r13) # load modified cr0
96
97 mvc __LC_EXT_NEW_PSW(8),.Lpcmsk-.LPG1(%r13) # set postcall psw
98 larl %r1,.Lsclph
99 stg %r1,__LC_EXT_NEW_PSW+8 # set handler
100
101 larl %r4,.Lsccb # %r4 is our index for sccb stuff
102 lgr %r1,%r4 # our sccb
103 .insn rre,0xb2200000,%r2,%r1 # service call
104 ipm %r1
105 srl %r1,28 # get cc code
106 xr %r3,%r3
107 chi %r1,3
108 be .Lfchunk-.LPG1(%r13) # leave
109 chi %r1,2
110 be .Lservicecall-.LPG1(%r13)
111 lpswe .Lwaitsclp-.LPG1(%r13)
112.Lsclph:
113 lh %r1,.Lsccbr-.Lsccb(%r4)
114 chi %r1,0x10 # 0x0010 is the sucess code
115 je .Lprocsccb # let's process the sccb
116 chi %r1,0x1f0
117 bne .Lfchunk-.LPG1(%r13) # unhandled error code
118 c %r2,.Lrcp-.LPG1(%r13) # Did we try Read SCP forced
119 bne .Lfchunk-.LPG1(%r13) # if no, give up
120 l %r2,.Lrcp2-.LPG1(%r13) # try with Read SCP
121 b .Lservicecall-.LPG1(%r13)
122.Lprocsccb:
123 lghi %r1,0
124 icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0
125 jnz .Lscnd
126 lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one
127.Lscnd:
128 xr %r3,%r3 # same logic
129 ic %r3,.Lscpa1-.Lsccb(%r4)
130 chi %r3,0x00
131 jne .Lcompmem
132 l %r3,.Lscpa2-.Lsccb(%r4)
133.Lcompmem:
134 mlgr %r2,%r1 # mem in MB on 128-bit
135 l %r1,.Lonemb-.LPG1(%r13)
136 mlgr %r2,%r1 # mem size in bytes in %r3
137 b .Lfchunk-.LPG1(%r13)
138
139 .align 4
140.Lpmask:
141 .byte 0
142 .align 8
143.Lcr:
144 .quad 0x00 # place holder for cr0
145.Lwaitsclp:
146 .quad 0x0102000180000000,.Lsclph
147.Lrcp:
148 .int 0x00120001 # Read SCP forced code
149.Lrcp2:
150 .int 0x00020001 # Read SCP code
151.Lonemb:
152 .int 0x100000
153
154.Lfchunk:
155
156#
157# find memory chunks.
158#
159 lgr %r9,%r3 # end of mem
160 larl %r1,.Lchkmem # set program check address
161 stg %r1,__LC_PGM_NEW_PSW+8
162 la %r1,1 # test in increments of 128KB
163 sllg %r1,%r1,17
164 larl %r3,memory_chunk
165 slgr %r4,%r4 # set start of chunk to zero
166 slgr %r5,%r5 # set end of chunk to zero
167 slr %r6,%r6 # set access code to zero
168 la %r10,MEMORY_CHUNKS # number of chunks
169.Lloop:
170 tprot 0(%r5),0 # test protection of first byte
171 ipm %r7
172 srl %r7,28
173 clr %r6,%r7 # compare cc with last access code
174 je .Lsame
175 lghi %r8,0 # no program checks
176 j .Lsavchk
177.Lsame:
178 algr %r5,%r1 # add 128KB to end of chunk
179 # no need to check here,
180 brc 12,.Lloop # this is the same chunk
181.Lchkmem: # > 16EB or tprot got a program check
182 lghi %r8,1 # set program check flag
183.Lsavchk:
184 clgr %r4,%r5 # chunk size > 0?
185 je .Lchkloop
186 stg %r4,0(%r3) # store start address of chunk
187 lgr %r0,%r5
188 slgr %r0,%r4
189 stg %r0,8(%r3) # store size of chunk
190 st %r6,20(%r3) # store type of chunk
191 la %r3,24(%r3)
192 ahi %r10,-1 # update chunk number
193.Lchkloop:
194 lr %r6,%r7 # set access code to last cc
195 # we got an exception or we're starting a new
196 # chunk , we must check if we should
197 # still try to find valid memory (if we detected
198 # the amount of available storage), and if we
199 # have chunks left
200 lghi %r4,1
201 sllg %r4,%r4,31
202 clgr %r5,%r4
203 je .Lhsaskip
204 xr %r0, %r0
205 clgr %r0, %r9 # did we detect memory?
206 je .Ldonemem # if not, leave
207 chi %r10, 0 # do we have chunks left?
208 je .Ldonemem
209.Lhsaskip:
210 chi %r8,1 # program check ?
211 je .Lpgmchk
212 lgr %r4,%r5 # potential new chunk
213 algr %r5,%r1 # add 128KB to end of chunk
214 j .Llpcnt
215.Lpgmchk:
216 algr %r5,%r1 # add 128KB to end of chunk
217 lgr %r4,%r5 # potential new chunk
218.Llpcnt:
219 clgr %r5,%r9 # should we go on?
220 jl .Lloop
221.Ldonemem:
222
223 larl %r12,machine_flags 68 larl %r12,machine_flags
224# 69#
225# find out if we are running under VM
226#
227 stidp __LC_CPUID # store cpuid
228 tm __LC_CPUID,0xff # running under VM ?
229 bno 0f-.LPG1(%r13)
230 oi 7(%r12),1 # set VM flag
2310: lh %r0,__LC_CPUID+4 # get cpu version
232 chi %r0,0x7490 # running on a P/390 ?
233 bne 1f-.LPG1(%r13)
234 oi 7(%r12),4 # set P/390 flag
2351:
236
237#
238# find out if we have the MVPG instruction 70# find out if we have the MVPG instruction
239# 71#
240 la %r1,0f-.LPG1(%r13) # set program check address 72 la %r1,0f-.LPG1(%r13) # set program check address
@@ -336,25 +168,6 @@ ipl_devno:
336 .word 0 168 .word 0
337 169
338 .org 0x12000 170 .org 0x12000
339.globl s390_readinfo_sccb
340s390_readinfo_sccb:
341.Lsccb:
342 .hword 0x1000 # length, one page
343 .byte 0x00,0x00,0x00
344 .byte 0x80 # variable response bit set
345.Lsccbr:
346 .hword 0x00 # response code
347.Lscpincr1:
348 .hword 0x00
349.Lscpa1:
350 .byte 0x00
351 .fill 89,1,0
352.Lscpa2:
353 .int 0x00
354.Lscpincr2:
355 .quad 0x00
356 .fill 3984,1,0
357 .org 0x13000
358 171
359#ifdef CONFIG_SHARED_KERNEL 172#ifdef CONFIG_SHARED_KERNEL
360 .org 0x100000 173 .org 0x100000
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 9e9972e8a52b..052259530651 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -20,26 +20,27 @@
20#include <asm/cio.h> 20#include <asm/cio.h>
21#include <asm/ebcdic.h> 21#include <asm/ebcdic.h>
22#include <asm/reset.h> 22#include <asm/reset.h>
23#include <asm/sclp.h>
23 24
24#define IPL_PARM_BLOCK_VERSION 0 25#define IPL_PARM_BLOCK_VERSION 0
25#define LOADPARM_LEN 8
26 26
27extern char s390_readinfo_sccb[]; 27#define SCCB_VALID (s390_readinfo_sccb.header.response_code == 0x10)
28#define SCCB_VALID (*((__u16*)&s390_readinfo_sccb[6]) == 0x0010) 28#define SCCB_LOADPARM (&s390_readinfo_sccb.loadparm)
29#define SCCB_LOADPARM (&s390_readinfo_sccb[24]) 29#define SCCB_FLAG (s390_readinfo_sccb.flags)
30#define SCCB_FLAG (s390_readinfo_sccb[91])
31 30
32enum ipl_type { 31enum ipl_type {
33 IPL_TYPE_NONE = 1, 32 IPL_TYPE_NONE = 1,
34 IPL_TYPE_UNKNOWN = 2, 33 IPL_TYPE_UNKNOWN = 2,
35 IPL_TYPE_CCW = 4, 34 IPL_TYPE_CCW = 4,
36 IPL_TYPE_FCP = 8, 35 IPL_TYPE_FCP = 8,
36 IPL_TYPE_NSS = 16,
37}; 37};
38 38
39#define IPL_NONE_STR "none" 39#define IPL_NONE_STR "none"
40#define IPL_UNKNOWN_STR "unknown" 40#define IPL_UNKNOWN_STR "unknown"
41#define IPL_CCW_STR "ccw" 41#define IPL_CCW_STR "ccw"
42#define IPL_FCP_STR "fcp" 42#define IPL_FCP_STR "fcp"
43#define IPL_NSS_STR "nss"
43 44
44static char *ipl_type_str(enum ipl_type type) 45static char *ipl_type_str(enum ipl_type type)
45{ 46{
@@ -50,6 +51,8 @@ static char *ipl_type_str(enum ipl_type type)
50 return IPL_CCW_STR; 51 return IPL_CCW_STR;
51 case IPL_TYPE_FCP: 52 case IPL_TYPE_FCP:
52 return IPL_FCP_STR; 53 return IPL_FCP_STR;
54 case IPL_TYPE_NSS:
55 return IPL_NSS_STR;
53 case IPL_TYPE_UNKNOWN: 56 case IPL_TYPE_UNKNOWN:
54 default: 57 default:
55 return IPL_UNKNOWN_STR; 58 return IPL_UNKNOWN_STR;
@@ -64,6 +67,7 @@ enum ipl_method {
64 IPL_METHOD_FCP_RO_DIAG, 67 IPL_METHOD_FCP_RO_DIAG,
65 IPL_METHOD_FCP_RW_DIAG, 68 IPL_METHOD_FCP_RW_DIAG,
66 IPL_METHOD_FCP_RO_VM, 69 IPL_METHOD_FCP_RO_VM,
70 IPL_METHOD_NSS,
67}; 71};
68 72
69enum shutdown_action { 73enum shutdown_action {
@@ -114,11 +118,14 @@ enum diag308_rc {
114static int diag308_set_works = 0; 118static int diag308_set_works = 0;
115 119
116static int reipl_capabilities = IPL_TYPE_UNKNOWN; 120static int reipl_capabilities = IPL_TYPE_UNKNOWN;
121
117static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN; 122static enum ipl_type reipl_type = IPL_TYPE_UNKNOWN;
118static enum ipl_method reipl_method = IPL_METHOD_NONE; 123static enum ipl_method reipl_method = IPL_METHOD_NONE;
119static struct ipl_parameter_block *reipl_block_fcp; 124static struct ipl_parameter_block *reipl_block_fcp;
120static struct ipl_parameter_block *reipl_block_ccw; 125static struct ipl_parameter_block *reipl_block_ccw;
121 126
127static char reipl_nss_name[NSS_NAME_SIZE + 1];
128
122static int dump_capabilities = IPL_TYPE_NONE; 129static int dump_capabilities = IPL_TYPE_NONE;
123static enum ipl_type dump_type = IPL_TYPE_NONE; 130static enum ipl_type dump_type = IPL_TYPE_NONE;
124static enum ipl_method dump_method = IPL_METHOD_NONE; 131static enum ipl_method dump_method = IPL_METHOD_NONE;
@@ -173,6 +180,24 @@ static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
173 sys_##_prefix##_##_name##_show, \ 180 sys_##_prefix##_##_name##_show, \
174 sys_##_prefix##_##_name##_store); 181 sys_##_prefix##_##_name##_store);
175 182
183#define DEFINE_IPL_ATTR_STR_RW(_prefix, _name, _fmt_out, _fmt_in, _value)\
184static ssize_t sys_##_prefix##_##_name##_show(struct subsystem *subsys, \
185 char *page) \
186{ \
187 return sprintf(page, _fmt_out, _value); \
188} \
189static ssize_t sys_##_prefix##_##_name##_store(struct subsystem *subsys,\
190 const char *buf, size_t len) \
191{ \
192 if (sscanf(buf, _fmt_in, _value) != 1) \
193 return -EINVAL; \
194 return len; \
195} \
196static struct subsys_attribute sys_##_prefix##_##_name##_attr = \
197 __ATTR(_name,(S_IRUGO | S_IWUSR), \
198 sys_##_prefix##_##_name##_show, \
199 sys_##_prefix##_##_name##_store);
200
176static void make_attrs_ro(struct attribute **attrs) 201static void make_attrs_ro(struct attribute **attrs)
177{ 202{
178 while (*attrs) { 203 while (*attrs) {
@@ -189,6 +214,8 @@ static enum ipl_type ipl_get_type(void)
189{ 214{
190 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START; 215 struct ipl_parameter_block *ipl = IPL_PARMBLOCK_START;
191 216
217 if (ipl_flags & IPL_NSS_VALID)
218 return IPL_TYPE_NSS;
192 if (!(ipl_flags & IPL_DEVNO_VALID)) 219 if (!(ipl_flags & IPL_DEVNO_VALID))
193 return IPL_TYPE_UNKNOWN; 220 return IPL_TYPE_UNKNOWN;
194 if (!(ipl_flags & IPL_PARMBLOCK_VALID)) 221 if (!(ipl_flags & IPL_PARMBLOCK_VALID))
@@ -324,6 +351,20 @@ static struct attribute_group ipl_ccw_attr_group = {
324 .attrs = ipl_ccw_attrs, 351 .attrs = ipl_ccw_attrs,
325}; 352};
326 353
354/* NSS ipl device attributes */
355
356DEFINE_IPL_ATTR_RO(ipl_nss, name, "%s\n", kernel_nss_name);
357
358static struct attribute *ipl_nss_attrs[] = {
359 &sys_ipl_type_attr.attr,
360 &sys_ipl_nss_name_attr.attr,
361 NULL,
362};
363
364static struct attribute_group ipl_nss_attr_group = {
365 .attrs = ipl_nss_attrs,
366};
367
327/* UNKNOWN ipl device attributes */ 368/* UNKNOWN ipl device attributes */
328 369
329static struct attribute *ipl_unknown_attrs[] = { 370static struct attribute *ipl_unknown_attrs[] = {
@@ -432,6 +473,21 @@ static struct attribute_group reipl_ccw_attr_group = {
432 .attrs = reipl_ccw_attrs, 473 .attrs = reipl_ccw_attrs,
433}; 474};
434 475
476
477/* NSS reipl device attributes */
478
479DEFINE_IPL_ATTR_STR_RW(reipl_nss, name, "%s\n", "%s\n", reipl_nss_name);
480
481static struct attribute *reipl_nss_attrs[] = {
482 &sys_reipl_nss_name_attr.attr,
483 NULL,
484};
485
486static struct attribute_group reipl_nss_attr_group = {
487 .name = IPL_NSS_STR,
488 .attrs = reipl_nss_attrs,
489};
490
435/* reipl type */ 491/* reipl type */
436 492
437static int reipl_set_type(enum ipl_type type) 493static int reipl_set_type(enum ipl_type type)
@@ -454,6 +510,9 @@ static int reipl_set_type(enum ipl_type type)
454 else 510 else
455 reipl_method = IPL_METHOD_FCP_RO_DIAG; 511 reipl_method = IPL_METHOD_FCP_RO_DIAG;
456 break; 512 break;
513 case IPL_TYPE_NSS:
514 reipl_method = IPL_METHOD_NSS;
515 break;
457 default: 516 default:
458 reipl_method = IPL_METHOD_NONE; 517 reipl_method = IPL_METHOD_NONE;
459 } 518 }
@@ -475,6 +534,8 @@ static ssize_t reipl_type_store(struct subsystem *subsys, const char *buf,
475 rc = reipl_set_type(IPL_TYPE_CCW); 534 rc = reipl_set_type(IPL_TYPE_CCW);
476 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0) 535 else if (strncmp(buf, IPL_FCP_STR, strlen(IPL_FCP_STR)) == 0)
477 rc = reipl_set_type(IPL_TYPE_FCP); 536 rc = reipl_set_type(IPL_TYPE_FCP);
537 else if (strncmp(buf, IPL_NSS_STR, strlen(IPL_NSS_STR)) == 0)
538 rc = reipl_set_type(IPL_TYPE_NSS);
478 return (rc != 0) ? rc : len; 539 return (rc != 0) ? rc : len;
479} 540}
480 541
@@ -647,6 +708,10 @@ void do_reipl(void)
647 case IPL_METHOD_FCP_RO_VM: 708 case IPL_METHOD_FCP_RO_VM:
648 __cpcmd("IPL", NULL, 0, NULL); 709 __cpcmd("IPL", NULL, 0, NULL);
649 break; 710 break;
711 case IPL_METHOD_NSS:
712 sprintf(buf, "IPL %s", reipl_nss_name);
713 __cpcmd(buf, NULL, 0, NULL);
714 break;
650 case IPL_METHOD_NONE: 715 case IPL_METHOD_NONE:
651 default: 716 default:
652 if (MACHINE_IS_VM) 717 if (MACHINE_IS_VM)
@@ -733,6 +798,10 @@ static int __init ipl_init(void)
733 case IPL_TYPE_FCP: 798 case IPL_TYPE_FCP:
734 rc = ipl_register_fcp_files(); 799 rc = ipl_register_fcp_files();
735 break; 800 break;
801 case IPL_TYPE_NSS:
802 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
803 &ipl_nss_attr_group);
804 break;
736 default: 805 default:
737 rc = sysfs_create_group(&ipl_subsys.kset.kobj, 806 rc = sysfs_create_group(&ipl_subsys.kset.kobj,
738 &ipl_unknown_attr_group); 807 &ipl_unknown_attr_group);
@@ -755,6 +824,20 @@ static void __init reipl_probe(void)
755 free_page((unsigned long)buffer); 824 free_page((unsigned long)buffer);
756} 825}
757 826
827static int __init reipl_nss_init(void)
828{
829 int rc;
830
831 if (!MACHINE_IS_VM)
832 return 0;
833 rc = sysfs_create_group(&reipl_subsys.kset.kobj, &reipl_nss_attr_group);
834 if (rc)
835 return rc;
836 strncpy(reipl_nss_name, kernel_nss_name, NSS_NAME_SIZE + 1);
837 reipl_capabilities |= IPL_TYPE_NSS;
838 return 0;
839}
840
758static int __init reipl_ccw_init(void) 841static int __init reipl_ccw_init(void)
759{ 842{
760 int rc; 843 int rc;
@@ -837,6 +920,9 @@ static int __init reipl_init(void)
837 rc = reipl_fcp_init(); 920 rc = reipl_fcp_init();
838 if (rc) 921 if (rc)
839 return rc; 922 return rc;
923 rc = reipl_nss_init();
924 if (rc)
925 return rc;
840 rc = reipl_set_type(ipl_get_type()); 926 rc = reipl_set_type(ipl_get_type());
841 if (rc) 927 if (rc)
842 return rc; 928 return rc;
@@ -993,8 +1079,6 @@ static void do_reset_calls(void)
993 reset->fn(); 1079 reset->fn();
994} 1080}
995 1081
996extern void reset_mcck_handler(void);
997extern void reset_pgm_handler(void);
998extern __u32 dump_prefix_page; 1082extern __u32 dump_prefix_page;
999 1083
1000void s390_reset_system(void) 1084void s390_reset_system(void)
@@ -1016,14 +1100,14 @@ void s390_reset_system(void)
1016 __ctl_clear_bit(0,28); 1100 __ctl_clear_bit(0,28);
1017 1101
1018 /* Set new machine check handler */ 1102 /* Set new machine check handler */
1019 S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; 1103 S390_lowcore.mcck_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
1020 S390_lowcore.mcck_new_psw.addr = 1104 S390_lowcore.mcck_new_psw.addr =
1021 PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler; 1105 PSW_ADDR_AMODE | (unsigned long) s390_base_mcck_handler;
1022 1106
1023 /* Set new program check handler */ 1107 /* Set new program check handler */
1024 S390_lowcore.program_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK; 1108 S390_lowcore.program_new_psw.mask = psw_kernel_bits & ~PSW_MASK_MCHECK;
1025 S390_lowcore.program_new_psw.addr = 1109 S390_lowcore.program_new_psw.addr =
1026 PSW_ADDR_AMODE | (unsigned long) &reset_pgm_handler; 1110 PSW_ADDR_AMODE | (unsigned long) s390_base_pgm_handler;
1027 1111
1028 do_reset_calls(); 1112 do_reset_calls();
1029} 1113}
diff --git a/arch/s390/kernel/irq.c b/arch/s390/kernel/irq.c
index 1eef50918615..8f0cbca31203 100644
--- a/arch/s390/kernel/irq.c
+++ b/arch/s390/kernel/irq.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * arch/s390/kernel/irq.c 2 * arch/s390/kernel/irq.c
3 * 3 *
4 * S390 version 4 * Copyright IBM Corp. 2004,2007
5 * Copyright (C) 2004 IBM Deutschland Entwicklung GmbH, IBM Corporation
6 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), 5 * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
6 * Thomas Spatzier (tspat@de.ibm.com)
7 * 7 *
8 * This file contains interrupt related functions. 8 * This file contains interrupt related functions.
9 */ 9 */
@@ -14,6 +14,8 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/seq_file.h> 15#include <linux/seq_file.h>
16#include <linux/cpu.h> 16#include <linux/cpu.h>
17#include <linux/proc_fs.h>
18#include <linux/profile.h>
17 19
18/* 20/*
19 * show_interrupts is needed by /proc/interrupts. 21 * show_interrupts is needed by /proc/interrupts.
@@ -93,5 +95,12 @@ asmlinkage void do_softirq(void)
93 95
94 local_irq_restore(flags); 96 local_irq_restore(flags);
95} 97}
96
97EXPORT_SYMBOL(do_softirq); 98EXPORT_SYMBOL(do_softirq);
99
100void init_irq_proc(void)
101{
102 struct proc_dir_entry *root_irq_dir;
103
104 root_irq_dir = proc_mkdir("irq", NULL);
105 create_prof_cpu_mask(root_irq_dir);
106}
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index 576368c4f605..a466bab6677e 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -155,15 +155,34 @@ void __kprobes get_instruction_type(struct arch_specific_insn *ainsn)
155static int __kprobes swap_instruction(void *aref) 155static int __kprobes swap_instruction(void *aref)
156{ 156{
157 struct ins_replace_args *args = aref; 157 struct ins_replace_args *args = aref;
158 u32 *addr;
159 u32 instr;
158 int err = -EFAULT; 160 int err = -EFAULT;
159 161
162 /*
163 * Text segment is read-only, hence we use stura to bypass dynamic
164 * address translation to exchange the instruction. Since stura
165 * always operates on four bytes, but we only want to exchange two
166 * bytes do some calculations to get things right. In addition we
167 * shall not cross any page boundaries (vmalloc area!) when writing
168 * the new instruction.
169 */
170 addr = (u32 *)ALIGN((unsigned long)args->ptr, 4);
171 if ((unsigned long)args->ptr & 2)
172 instr = ((*addr) & 0xffff0000) | args->new;
173 else
174 instr = ((*addr) & 0x0000ffff) | args->new << 16;
175
160 asm volatile( 176 asm volatile(
161 "0: mvc 0(2,%2),0(%3)\n" 177 " lra %1,0(%1)\n"
162 "1: la %0,0\n" 178 "0: stura %2,%1\n"
179 "1: la %0,0\n"
163 "2:\n" 180 "2:\n"
164 EX_TABLE(0b,2b) 181 EX_TABLE(0b,2b)
165 : "+d" (err), "=m" (*args->ptr) 182 : "+d" (err)
166 : "a" (args->ptr), "a" (&args->new), "m" (args->new)); 183 : "a" (addr), "d" (instr)
184 : "memory", "cc");
185
167 return err; 186 return err;
168} 187}
169 188
@@ -356,7 +375,7 @@ no_kprobe:
356 * - When the probed function returns, this probe 375 * - When the probed function returns, this probe
357 * causes the handlers to fire 376 * causes the handlers to fire
358 */ 377 */
359void __kprobes kretprobe_trampoline_holder(void) 378void kretprobe_trampoline_holder(void)
360{ 379{
361 asm volatile(".global kretprobe_trampoline\n" 380 asm volatile(".global kretprobe_trampoline\n"
362 "kretprobe_trampoline: bcr 0,0\n"); 381 "kretprobe_trampoline: bcr 0,0\n");
@@ -365,7 +384,8 @@ void __kprobes kretprobe_trampoline_holder(void)
365/* 384/*
366 * Called when the probe at kretprobe trampoline is hit 385 * Called when the probe at kretprobe trampoline is hit
367 */ 386 */
368int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 387static int __kprobes trampoline_probe_handler(struct kprobe *p,
388 struct pt_regs *regs)
369{ 389{
370 struct kretprobe_instance *ri = NULL; 390 struct kretprobe_instance *ri = NULL;
371 struct hlist_head *head, empty_rp; 391 struct hlist_head *head, empty_rp;
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index f6d9bcc0f75b..52f57af252b4 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -11,6 +11,7 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/kexec.h> 12#include <linux/kexec.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/reboot.h>
14#include <asm/cio.h> 15#include <asm/cio.h>
15#include <asm/setup.h> 16#include <asm/setup.h>
16#include <asm/pgtable.h> 17#include <asm/pgtable.h>
diff --git a/arch/s390/kernel/module.c b/arch/s390/kernel/module.c
index d989ed45a7aa..39d1dd752529 100644
--- a/arch/s390/kernel/module.c
+++ b/arch/s390/kernel/module.c
@@ -30,6 +30,7 @@
30#include <linux/fs.h> 30#include <linux/fs.h>
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/kernel.h> 32#include <linux/kernel.h>
33#include <linux/moduleloader.h>
33 34
34#if 0 35#if 0
35#define DEBUGP printk 36#define DEBUGP printk
@@ -58,7 +59,7 @@ void module_free(struct module *mod, void *module_region)
58 table entries. */ 59 table entries. */
59} 60}
60 61
61static inline void 62static void
62check_rela(Elf_Rela *rela, struct module *me) 63check_rela(Elf_Rela *rela, struct module *me)
63{ 64{
64 struct mod_arch_syminfo *info; 65 struct mod_arch_syminfo *info;
@@ -181,7 +182,7 @@ apply_relocate(Elf_Shdr *sechdrs, const char *strtab, unsigned int symindex,
181 return -ENOEXEC; 182 return -ENOEXEC;
182} 183}
183 184
184static inline int 185static int
185apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab, 186apply_rela(Elf_Rela *rela, Elf_Addr base, Elf_Sym *symtab,
186 struct module *me) 187 struct module *me)
187{ 188{
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c
index 6603fbb41d07..5acfac654f9d 100644
--- a/arch/s390/kernel/process.c
+++ b/arch/s390/kernel/process.c
@@ -144,7 +144,7 @@ static void default_idle(void)
144 144
145 trace_hardirqs_on(); 145 trace_hardirqs_on();
146 /* Wait for external, I/O or machine check interrupt. */ 146 /* Wait for external, I/O or machine check interrupt. */
147 __load_psw_mask(PSW_KERNEL_BITS | PSW_MASK_WAIT | 147 __load_psw_mask(psw_kernel_bits | PSW_MASK_WAIT |
148 PSW_MASK_IO | PSW_MASK_EXT); 148 PSW_MASK_IO | PSW_MASK_EXT);
149} 149}
150 150
@@ -190,7 +190,7 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
190 struct pt_regs regs; 190 struct pt_regs regs;
191 191
192 memset(&regs, 0, sizeof(regs)); 192 memset(&regs, 0, sizeof(regs));
193 regs.psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT; 193 regs.psw.mask = psw_kernel_bits | PSW_MASK_IO | PSW_MASK_EXT;
194 regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE; 194 regs.psw.addr = (unsigned long) kernel_thread_starter | PSW_ADDR_AMODE;
195 regs.gprs[9] = (unsigned long) fn; 195 regs.gprs[9] = (unsigned long) fn;
196 regs.gprs[10] = (unsigned long) arg; 196 regs.gprs[10] = (unsigned long) arg;
diff --git a/arch/s390/kernel/profile.c b/arch/s390/kernel/profile.c
deleted file mode 100644
index b81aa1f569ca..000000000000
--- a/arch/s390/kernel/profile.c
+++ /dev/null
@@ -1,20 +0,0 @@
1/*
2 * arch/s390/kernel/profile.c
3 *
4 * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation
5 * Author(s): Thomas Spatzier (tspat@de.ibm.com)
6 *
7 */
8#include <linux/proc_fs.h>
9#include <linux/profile.h>
10
11static struct proc_dir_entry * root_irq_dir;
12
13void init_irq_proc(void)
14{
15 /* create /proc/irq */
16 root_irq_dir = proc_mkdir("irq", NULL);
17
18 /* create /proc/irq/prof_cpu_mask */
19 create_prof_cpu_mask(root_irq_dir);
20}
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 8f36504075ed..2a8f0872ea8b 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -86,15 +86,13 @@ FixPerRegisters(struct task_struct *task)
86 per_info->control_regs.bits.storage_alt_space_ctl = 0; 86 per_info->control_regs.bits.storage_alt_space_ctl = 0;
87} 87}
88 88
89void 89static void set_single_step(struct task_struct *task)
90set_single_step(struct task_struct *task)
91{ 90{
92 task->thread.per_info.single_step = 1; 91 task->thread.per_info.single_step = 1;
93 FixPerRegisters(task); 92 FixPerRegisters(task);
94} 93}
95 94
96void 95static void clear_single_step(struct task_struct *task)
97clear_single_step(struct task_struct *task)
98{ 96{
99 task->thread.per_info.single_step = 0; 97 task->thread.per_info.single_step = 0;
100 FixPerRegisters(task); 98 FixPerRegisters(task);
@@ -232,9 +230,9 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data)
232 */ 230 */
233 if (addr == (addr_t) &dummy->regs.psw.mask && 231 if (addr == (addr_t) &dummy->regs.psw.mask &&
234#ifdef CONFIG_COMPAT 232#ifdef CONFIG_COMPAT
235 data != PSW_MASK_MERGE(PSW_USER32_BITS, data) && 233 data != PSW_MASK_MERGE(psw_user32_bits, data) &&
236#endif 234#endif
237 data != PSW_MASK_MERGE(PSW_USER_BITS, data)) 235 data != PSW_MASK_MERGE(psw_user_bits, data))
238 /* Invalid psw mask. */ 236 /* Invalid psw mask. */
239 return -EINVAL; 237 return -EINVAL;
240#ifndef CONFIG_64BIT 238#ifndef CONFIG_64BIT
@@ -309,7 +307,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
309 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 307 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
310 if (copied != sizeof(tmp)) 308 if (copied != sizeof(tmp))
311 return -EIO; 309 return -EIO;
312 return put_user(tmp, (unsigned long __user *) data); 310 return put_user(tmp, (unsigned long __force __user *) data);
313 311
314 case PTRACE_PEEKUSR: 312 case PTRACE_PEEKUSR:
315 /* read the word at location addr in the USER area. */ 313 /* read the word at location addr in the USER area. */
@@ -331,7 +329,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
331 329
332 case PTRACE_PEEKUSR_AREA: 330 case PTRACE_PEEKUSR_AREA:
333 case PTRACE_POKEUSR_AREA: 331 case PTRACE_POKEUSR_AREA:
334 if (copy_from_user(&parea, (void __user *) addr, 332 if (copy_from_user(&parea, (void __force __user *) addr,
335 sizeof(parea))) 333 sizeof(parea)))
336 return -EFAULT; 334 return -EFAULT;
337 addr = parea.kernel_addr; 335 addr = parea.kernel_addr;
@@ -341,10 +339,11 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data)
341 if (request == PTRACE_PEEKUSR_AREA) 339 if (request == PTRACE_PEEKUSR_AREA)
342 ret = peek_user(child, addr, data); 340 ret = peek_user(child, addr, data);
343 else { 341 else {
344 addr_t tmp; 342 addr_t utmp;
345 if (get_user (tmp, (addr_t __user *) data)) 343 if (get_user(utmp,
344 (addr_t __force __user *) data))
346 return -EFAULT; 345 return -EFAULT;
347 ret = poke_user(child, addr, tmp); 346 ret = poke_user(child, addr, utmp);
348 } 347 }
349 if (ret) 348 if (ret)
350 return ret; 349 return ret;
@@ -394,7 +393,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
394 if (addr == (addr_t) &dummy32->regs.psw.mask) { 393 if (addr == (addr_t) &dummy32->regs.psw.mask) {
395 /* Fake a 31 bit psw mask. */ 394 /* Fake a 31 bit psw mask. */
396 tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32); 395 tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32);
397 tmp = PSW32_MASK_MERGE(PSW32_USER_BITS, tmp); 396 tmp = PSW32_MASK_MERGE(psw32_user_bits, tmp);
398 } else if (addr == (addr_t) &dummy32->regs.psw.addr) { 397 } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
399 /* Fake a 31 bit psw address. */ 398 /* Fake a 31 bit psw address. */
400 tmp = (__u32) task_pt_regs(child)->psw.addr | 399 tmp = (__u32) task_pt_regs(child)->psw.addr |
@@ -469,11 +468,11 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data)
469 */ 468 */
470 if (addr == (addr_t) &dummy32->regs.psw.mask) { 469 if (addr == (addr_t) &dummy32->regs.psw.mask) {
471 /* Build a 64 bit psw mask from 31 bit mask. */ 470 /* Build a 64 bit psw mask from 31 bit mask. */
472 if (tmp != PSW32_MASK_MERGE(PSW32_USER_BITS, tmp)) 471 if (tmp != PSW32_MASK_MERGE(psw32_user_bits, tmp))
473 /* Invalid psw mask. */ 472 /* Invalid psw mask. */
474 return -EINVAL; 473 return -EINVAL;
475 task_pt_regs(child)->psw.mask = 474 task_pt_regs(child)->psw.mask =
476 PSW_MASK_MERGE(PSW_USER32_BITS, (__u64) tmp << 32); 475 PSW_MASK_MERGE(psw_user32_bits, (__u64) tmp << 32);
477 } else if (addr == (addr_t) &dummy32->regs.psw.addr) { 476 } else if (addr == (addr_t) &dummy32->regs.psw.addr) {
478 /* Build a 64 bit psw address from 31 bit address. */ 477 /* Build a 64 bit psw address from 31 bit address. */
479 task_pt_regs(child)->psw.addr = 478 task_pt_regs(child)->psw.addr =
@@ -550,7 +549,7 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
550 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); 549 copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
551 if (copied != sizeof(tmp)) 550 if (copied != sizeof(tmp))
552 return -EIO; 551 return -EIO;
553 return put_user(tmp, (unsigned int __user *) data); 552 return put_user(tmp, (unsigned int __force __user *) data);
554 553
555 case PTRACE_PEEKUSR: 554 case PTRACE_PEEKUSR:
556 /* read the word at location addr in the USER area. */ 555 /* read the word at location addr in the USER area. */
@@ -571,7 +570,7 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
571 570
572 case PTRACE_PEEKUSR_AREA: 571 case PTRACE_PEEKUSR_AREA:
573 case PTRACE_POKEUSR_AREA: 572 case PTRACE_POKEUSR_AREA:
574 if (copy_from_user(&parea, (void __user *) addr, 573 if (copy_from_user(&parea, (void __force __user *) addr,
575 sizeof(parea))) 574 sizeof(parea)))
576 return -EFAULT; 575 return -EFAULT;
577 addr = parea.kernel_addr; 576 addr = parea.kernel_addr;
@@ -581,10 +580,11 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
581 if (request == PTRACE_PEEKUSR_AREA) 580 if (request == PTRACE_PEEKUSR_AREA)
582 ret = peek_user_emu31(child, addr, data); 581 ret = peek_user_emu31(child, addr, data);
583 else { 582 else {
584 __u32 tmp; 583 __u32 utmp;
585 if (get_user (tmp, (__u32 __user *) data)) 584 if (get_user(utmp,
585 (__u32 __force __user *) data))
586 return -EFAULT; 586 return -EFAULT;
587 ret = poke_user_emu31(child, addr, tmp); 587 ret = poke_user_emu31(child, addr, utmp);
588 } 588 }
589 if (ret) 589 if (ret)
590 return ret; 590 return ret;
@@ -595,17 +595,19 @@ do_ptrace_emu31(struct task_struct *child, long request, long addr, long data)
595 return 0; 595 return 0;
596 case PTRACE_GETEVENTMSG: 596 case PTRACE_GETEVENTMSG:
597 return put_user((__u32) child->ptrace_message, 597 return put_user((__u32) child->ptrace_message,
598 (unsigned int __user *) data); 598 (unsigned int __force __user *) data);
599 case PTRACE_GETSIGINFO: 599 case PTRACE_GETSIGINFO:
600 if (child->last_siginfo == NULL) 600 if (child->last_siginfo == NULL)
601 return -EINVAL; 601 return -EINVAL;
602 return copy_siginfo_to_user32((compat_siginfo_t __user *) data, 602 return copy_siginfo_to_user32((compat_siginfo_t
603 __force __user *) data,
603 child->last_siginfo); 604 child->last_siginfo);
604 case PTRACE_SETSIGINFO: 605 case PTRACE_SETSIGINFO:
605 if (child->last_siginfo == NULL) 606 if (child->last_siginfo == NULL)
606 return -EINVAL; 607 return -EINVAL;
607 return copy_siginfo_from_user32(child->last_siginfo, 608 return copy_siginfo_from_user32(child->last_siginfo,
608 (compat_siginfo_t __user *) data); 609 (compat_siginfo_t
610 __force __user *) data);
609 } 611 }
610 return ptrace_request(child, request, addr, data); 612 return ptrace_request(child, request, addr, data);
611} 613}
diff --git a/arch/s390/kernel/reset.S b/arch/s390/kernel/reset.S
deleted file mode 100644
index 8a87355161fa..000000000000
--- a/arch/s390/kernel/reset.S
+++ /dev/null
@@ -1,90 +0,0 @@
1/*
2 * arch/s390/kernel/reset.S
3 *
4 * Copyright (C) IBM Corp. 2006
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 * Michael Holzheu <holzheu@de.ibm.com>
7 */
8
9#include <asm/ptrace.h>
10#include <asm/lowcore.h>
11
12#ifdef CONFIG_64BIT
13
14 .globl reset_mcck_handler
15reset_mcck_handler:
16 basr %r13,0
170: lg %r15,__LC_PANIC_STACK # load panic stack
18 aghi %r15,-STACK_FRAME_OVERHEAD
19 lg %r1,s390_reset_mcck_handler-0b(%r13)
20 ltgr %r1,%r1
21 jz 1f
22 basr %r14,%r1
231: la %r1,4095
24 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
25 lpswe __LC_MCK_OLD_PSW
26
27 .globl s390_reset_mcck_handler
28s390_reset_mcck_handler:
29 .quad 0
30
31 .globl reset_pgm_handler
32reset_pgm_handler:
33 stmg %r0,%r15,__LC_SAVE_AREA
34 basr %r13,0
350: lg %r15,__LC_PANIC_STACK # load panic stack
36 aghi %r15,-STACK_FRAME_OVERHEAD
37 lg %r1,s390_reset_pgm_handler-0b(%r13)
38 ltgr %r1,%r1
39 jz 1f
40 basr %r14,%r1
41 lmg %r0,%r15,__LC_SAVE_AREA
42 lpswe __LC_PGM_OLD_PSW
431: lpswe disabled_wait_psw-0b(%r13)
44 .globl s390_reset_pgm_handler
45s390_reset_pgm_handler:
46 .quad 0
47 .align 8
48disabled_wait_psw:
49 .quad 0x0002000180000000,0x0000000000000000 + reset_pgm_handler
50
51#else /* CONFIG_64BIT */
52
53 .globl reset_mcck_handler
54reset_mcck_handler:
55 basr %r13,0
560: l %r15,__LC_PANIC_STACK # load panic stack
57 ahi %r15,-STACK_FRAME_OVERHEAD
58 l %r1,s390_reset_mcck_handler-0b(%r13)
59 ltr %r1,%r1
60 jz 1f
61 basr %r14,%r1
621: lm %r0,%r15,__LC_GPREGS_SAVE_AREA
63 lpsw __LC_MCK_OLD_PSW
64
65 .globl s390_reset_mcck_handler
66s390_reset_mcck_handler:
67 .long 0
68
69 .globl reset_pgm_handler
70reset_pgm_handler:
71 stm %r0,%r15,__LC_SAVE_AREA
72 basr %r13,0
730: l %r15,__LC_PANIC_STACK # load panic stack
74 ahi %r15,-STACK_FRAME_OVERHEAD
75 l %r1,s390_reset_pgm_handler-0b(%r13)
76 ltr %r1,%r1
77 jz 1f
78 basr %r14,%r1
79 lm %r0,%r15,__LC_SAVE_AREA
80 lpsw __LC_PGM_OLD_PSW
81
821: lpsw disabled_wait_psw-0b(%r13)
83 .globl s390_reset_pgm_handler
84s390_reset_pgm_handler:
85 .long 0
86disabled_wait_psw:
87 .align 8
88 .long 0x000a0000,0x00000000 + reset_pgm_handler
89
90#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index bc5beaa8f98e..acf93dba7727 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -125,14 +125,12 @@ void do_extint(struct pt_regs *regs, unsigned short code)
125 * Make sure that the i/o interrupt did not "overtake" 125 * Make sure that the i/o interrupt did not "overtake"
126 * the last HZ timer interrupt. 126 * the last HZ timer interrupt.
127 */ 127 */
128 account_ticks(); 128 account_ticks(S390_lowcore.int_clock);
129 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++; 129 kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
130 index = ext_hash(code); 130 index = ext_hash(code);
131 for (p = ext_int_hash[index]; p; p = p->next) { 131 for (p = ext_int_hash[index]; p; p = p->next) {
132 if (likely(p->code == code)) { 132 if (likely(p->code == code))
133 if (likely(p->handler)) 133 p->handler(code);
134 p->handler(code);
135 }
136 } 134 }
137 irq_exit(); 135 irq_exit();
138 set_irq_regs(old_regs); 136 set_irq_regs(old_regs);
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 5d8ee3baac14..03739813d3bf 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -38,6 +38,8 @@
38#include <linux/device.h> 38#include <linux/device.h>
39#include <linux/notifier.h> 39#include <linux/notifier.h>
40#include <linux/pfn.h> 40#include <linux/pfn.h>
41#include <linux/ctype.h>
42#include <linux/reboot.h>
41 43
42#include <asm/uaccess.h> 44#include <asm/uaccess.h>
43#include <asm/system.h> 45#include <asm/system.h>
@@ -49,6 +51,14 @@
49#include <asm/page.h> 51#include <asm/page.h>
50#include <asm/ptrace.h> 52#include <asm/ptrace.h>
51#include <asm/sections.h> 53#include <asm/sections.h>
54#include <asm/ebcdic.h>
55#include <asm/compat.h>
56
57long psw_kernel_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY |
58 PSW_MASK_MCHECK | PSW_DEFAULT_KEY);
59long psw_user_bits = (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
60 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
61 PSW_MASK_PSTATE | PSW_DEFAULT_KEY);
52 62
53/* 63/*
54 * User copy operations. 64 * User copy operations.
@@ -117,9 +127,9 @@ void __devinit cpu_init (void)
117 */ 127 */
118char vmhalt_cmd[128] = ""; 128char vmhalt_cmd[128] = "";
119char vmpoff_cmd[128] = ""; 129char vmpoff_cmd[128] = "";
120char vmpanic_cmd[128] = ""; 130static char vmpanic_cmd[128] = "";
121 131
122static inline void strncpy_skip_quote(char *dst, char *src, int n) 132static void strncpy_skip_quote(char *dst, char *src, int n)
123{ 133{
124 int sx, dx; 134 int sx, dx;
125 135
@@ -275,10 +285,6 @@ static void __init conmode_default(void)
275} 285}
276 286
277#ifdef CONFIG_SMP 287#ifdef CONFIG_SMP
278extern void machine_restart_smp(char *);
279extern void machine_halt_smp(void);
280extern void machine_power_off_smp(void);
281
282void (*_machine_restart)(char *command) = machine_restart_smp; 288void (*_machine_restart)(char *command) = machine_restart_smp;
283void (*_machine_halt)(void) = machine_halt_smp; 289void (*_machine_halt)(void) = machine_halt_smp;
284void (*_machine_power_off)(void) = machine_power_off_smp; 290void (*_machine_power_off)(void) = machine_power_off_smp;
@@ -386,6 +392,84 @@ static int __init early_parse_ipldelay(char *p)
386} 392}
387early_param("ipldelay", early_parse_ipldelay); 393early_param("ipldelay", early_parse_ipldelay);
388 394
395#ifdef CONFIG_S390_SWITCH_AMODE
396unsigned int switch_amode = 0;
397EXPORT_SYMBOL_GPL(switch_amode);
398
399static void set_amode_and_uaccess(unsigned long user_amode,
400 unsigned long user32_amode)
401{
402 psw_user_bits = PSW_BASE_BITS | PSW_MASK_DAT | user_amode |
403 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
404 PSW_MASK_PSTATE | PSW_DEFAULT_KEY;
405#ifdef CONFIG_COMPAT
406 psw_user32_bits = PSW_BASE32_BITS | PSW_MASK_DAT | user_amode |
407 PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK |
408 PSW_MASK_PSTATE | PSW_DEFAULT_KEY;
409 psw32_user_bits = PSW32_BASE_BITS | PSW32_MASK_DAT | user32_amode |
410 PSW32_MASK_IO | PSW32_MASK_EXT | PSW32_MASK_MCHECK |
411 PSW32_MASK_PSTATE;
412#endif
413 psw_kernel_bits = PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME |
414 PSW_MASK_MCHECK | PSW_DEFAULT_KEY;
415
416 if (MACHINE_HAS_MVCOS) {
417 printk("mvcos available.\n");
418 memcpy(&uaccess, &uaccess_mvcos_switch, sizeof(uaccess));
419 } else {
420 printk("mvcos not available.\n");
421 memcpy(&uaccess, &uaccess_pt, sizeof(uaccess));
422 }
423}
424
425/*
426 * Switch kernel/user addressing modes?
427 */
428static int __init early_parse_switch_amode(char *p)
429{
430 switch_amode = 1;
431 return 0;
432}
433early_param("switch_amode", early_parse_switch_amode);
434
435#else /* CONFIG_S390_SWITCH_AMODE */
436static inline void set_amode_and_uaccess(unsigned long user_amode,
437 unsigned long user32_amode)
438{
439}
440#endif /* CONFIG_S390_SWITCH_AMODE */
441
442#ifdef CONFIG_S390_EXEC_PROTECT
443unsigned int s390_noexec = 0;
444EXPORT_SYMBOL_GPL(s390_noexec);
445
446/*
447 * Enable execute protection?
448 */
449static int __init early_parse_noexec(char *p)
450{
451 if (!strncmp(p, "off", 3))
452 return 0;
453 switch_amode = 1;
454 s390_noexec = 1;
455 return 0;
456}
457early_param("noexec", early_parse_noexec);
458#endif /* CONFIG_S390_EXEC_PROTECT */
459
460static void setup_addressing_mode(void)
461{
462 if (s390_noexec) {
463 printk("S390 execute protection active, ");
464 set_amode_and_uaccess(PSW_ASC_SECONDARY, PSW32_ASC_SECONDARY);
465 return;
466 }
467 if (switch_amode) {
468 printk("S390 address spaces switched, ");
469 set_amode_and_uaccess(PSW_ASC_PRIMARY, PSW32_ASC_PRIMARY);
470 }
471}
472
389static void __init 473static void __init
390setup_lowcore(void) 474setup_lowcore(void)
391{ 475{
@@ -402,19 +486,21 @@ setup_lowcore(void)
402 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY; 486 lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;
403 lc->restart_psw.addr = 487 lc->restart_psw.addr =
404 PSW_ADDR_AMODE | (unsigned long) restart_int_handler; 488 PSW_ADDR_AMODE | (unsigned long) restart_int_handler;
405 lc->external_new_psw.mask = PSW_KERNEL_BITS; 489 if (switch_amode)
490 lc->restart_psw.mask |= PSW_ASC_HOME;
491 lc->external_new_psw.mask = psw_kernel_bits;
406 lc->external_new_psw.addr = 492 lc->external_new_psw.addr =
407 PSW_ADDR_AMODE | (unsigned long) ext_int_handler; 493 PSW_ADDR_AMODE | (unsigned long) ext_int_handler;
408 lc->svc_new_psw.mask = PSW_KERNEL_BITS | PSW_MASK_IO | PSW_MASK_EXT; 494 lc->svc_new_psw.mask = psw_kernel_bits | PSW_MASK_IO | PSW_MASK_EXT;
409 lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call; 495 lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;
410 lc->program_new_psw.mask = PSW_KERNEL_BITS; 496 lc->program_new_psw.mask = psw_kernel_bits;
411 lc->program_new_psw.addr = 497 lc->program_new_psw.addr =
412 PSW_ADDR_AMODE | (unsigned long)pgm_check_handler; 498 PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;
413 lc->mcck_new_psw.mask = 499 lc->mcck_new_psw.mask =
414 PSW_KERNEL_BITS & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT; 500 psw_kernel_bits & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT;
415 lc->mcck_new_psw.addr = 501 lc->mcck_new_psw.addr =
416 PSW_ADDR_AMODE | (unsigned long) mcck_int_handler; 502 PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;
417 lc->io_new_psw.mask = PSW_KERNEL_BITS; 503 lc->io_new_psw.mask = psw_kernel_bits;
418 lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; 504 lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;
419 lc->ipl_device = S390_lowcore.ipl_device; 505 lc->ipl_device = S390_lowcore.ipl_device;
420 lc->jiffy_timer = -1LL; 506 lc->jiffy_timer = -1LL;
@@ -439,7 +525,7 @@ setup_lowcore(void)
439static void __init 525static void __init
440setup_resources(void) 526setup_resources(void)
441{ 527{
442 struct resource *res; 528 struct resource *res, *sub_res;
443 int i; 529 int i;
444 530
445 code_resource.start = (unsigned long) &_text; 531 code_resource.start = (unsigned long) &_text;
@@ -464,8 +550,38 @@ setup_resources(void)
464 res->start = memory_chunk[i].addr; 550 res->start = memory_chunk[i].addr;
465 res->end = memory_chunk[i].addr + memory_chunk[i].size - 1; 551 res->end = memory_chunk[i].addr + memory_chunk[i].size - 1;
466 request_resource(&iomem_resource, res); 552 request_resource(&iomem_resource, res);
467 request_resource(res, &code_resource); 553
468 request_resource(res, &data_resource); 554 if (code_resource.start >= res->start &&
555 code_resource.start <= res->end &&
556 code_resource.end > res->end) {
557 sub_res = alloc_bootmem_low(sizeof(struct resource));
558 memcpy(sub_res, &code_resource,
559 sizeof(struct resource));
560 sub_res->end = res->end;
561 code_resource.start = res->end + 1;
562 request_resource(res, sub_res);
563 }
564
565 if (code_resource.start >= res->start &&
566 code_resource.start <= res->end &&
567 code_resource.end <= res->end)
568 request_resource(res, &code_resource);
569
570 if (data_resource.start >= res->start &&
571 data_resource.start <= res->end &&
572 data_resource.end > res->end) {
573 sub_res = alloc_bootmem_low(sizeof(struct resource));
574 memcpy(sub_res, &data_resource,
575 sizeof(struct resource));
576 sub_res->end = res->end;
577 data_resource.start = res->end + 1;
578 request_resource(res, sub_res);
579 }
580
581 if (data_resource.start >= res->start &&
582 data_resource.start <= res->end &&
583 data_resource.end <= res->end)
584 request_resource(res, &data_resource);
469 } 585 }
470} 586}
471 587
@@ -495,16 +611,13 @@ static void __init setup_memory_end(void)
495 } 611 }
496 if (!memory_end) 612 if (!memory_end)
497 memory_end = memory_size; 613 memory_end = memory_size;
498 if (real_size > memory_end)
499 printk("More memory detected than supported. Unused: %luk\n",
500 (real_size - memory_end) >> 10);
501} 614}
502 615
503static void __init 616static void __init
504setup_memory(void) 617setup_memory(void)
505{ 618{
506 unsigned long bootmap_size; 619 unsigned long bootmap_size;
507 unsigned long start_pfn, end_pfn, init_pfn; 620 unsigned long start_pfn, end_pfn;
508 int i; 621 int i;
509 622
510 /* 623 /*
@@ -514,10 +627,6 @@ setup_memory(void)
514 start_pfn = PFN_UP(__pa(&_end)); 627 start_pfn = PFN_UP(__pa(&_end));
515 end_pfn = max_pfn = PFN_DOWN(memory_end); 628 end_pfn = max_pfn = PFN_DOWN(memory_end);
516 629
517 /* Initialize storage key for kernel pages */
518 for (init_pfn = 0 ; init_pfn < start_pfn; init_pfn++)
519 page_set_storage_key(init_pfn << PAGE_SHIFT, PAGE_DEFAULT_KEY);
520
521#ifdef CONFIG_BLK_DEV_INITRD 630#ifdef CONFIG_BLK_DEV_INITRD
522 /* 631 /*
523 * Move the initrd in case the bitmap of the bootmem allocater 632 * Move the initrd in case the bitmap of the bootmem allocater
@@ -651,6 +760,7 @@ setup_arch(char **cmdline_p)
651 parse_early_param(); 760 parse_early_param();
652 761
653 setup_memory_end(); 762 setup_memory_end();
763 setup_addressing_mode();
654 setup_memory(); 764 setup_memory();
655 setup_resources(); 765 setup_resources();
656 setup_lowcore(); 766 setup_lowcore();
@@ -694,6 +804,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
694 struct cpuinfo_S390 *cpuinfo; 804 struct cpuinfo_S390 *cpuinfo;
695 unsigned long n = (unsigned long) v - 1; 805 unsigned long n = (unsigned long) v - 1;
696 806
807 s390_adjust_jiffies();
697 preempt_disable(); 808 preempt_disable();
698 if (!n) { 809 if (!n) {
699 seq_printf(m, "vendor_id : IBM/S390\n" 810 seq_printf(m, "vendor_id : IBM/S390\n"
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 4c8a7954ef48..554f9cf7499c 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -119,7 +119,7 @@ static int save_sigregs(struct pt_regs *regs, _sigregs __user *sregs)
119 119
120 /* Copy a 'clean' PSW mask to the user to avoid leaking 120 /* Copy a 'clean' PSW mask to the user to avoid leaking
121 information about whether PER is currently on. */ 121 information about whether PER is currently on. */
122 user_sregs.regs.psw.mask = PSW_MASK_MERGE(PSW_USER_BITS, regs->psw.mask); 122 user_sregs.regs.psw.mask = PSW_MASK_MERGE(psw_user_bits, regs->psw.mask);
123 user_sregs.regs.psw.addr = regs->psw.addr; 123 user_sregs.regs.psw.addr = regs->psw.addr;
124 memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs)); 124 memcpy(&user_sregs.regs.gprs, &regs->gprs, sizeof(sregs->regs.gprs));
125 memcpy(&user_sregs.regs.acrs, current->thread.acrs, 125 memcpy(&user_sregs.regs.acrs, current->thread.acrs,
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index c0cd255fddbd..65b52320d145 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -22,23 +22,23 @@
22 22
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/init.h> 24#include <linux/init.h>
25
26#include <linux/mm.h> 25#include <linux/mm.h>
27#include <linux/spinlock.h> 26#include <linux/spinlock.h>
28#include <linux/kernel_stat.h> 27#include <linux/kernel_stat.h>
29#include <linux/smp_lock.h> 28#include <linux/smp_lock.h>
30
31#include <linux/delay.h> 29#include <linux/delay.h>
32#include <linux/cache.h> 30#include <linux/cache.h>
33#include <linux/interrupt.h> 31#include <linux/interrupt.h>
34#include <linux/cpu.h> 32#include <linux/cpu.h>
35 33#include <linux/timex.h>
34#include <asm/setup.h>
36#include <asm/sigp.h> 35#include <asm/sigp.h>
37#include <asm/pgalloc.h> 36#include <asm/pgalloc.h>
38#include <asm/irq.h> 37#include <asm/irq.h>
39#include <asm/s390_ext.h> 38#include <asm/s390_ext.h>
40#include <asm/cpcmd.h> 39#include <asm/cpcmd.h>
41#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
41#include <asm/timer.h>
42 42
43extern volatile int __cpu_logical_map[]; 43extern volatile int __cpu_logical_map[];
44 44
@@ -53,12 +53,6 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE;
53 53
54static struct task_struct *current_set[NR_CPUS]; 54static struct task_struct *current_set[NR_CPUS];
55 55
56/*
57 * Reboot, halt and power_off routines for SMP.
58 */
59extern char vmhalt_cmd[];
60extern char vmpoff_cmd[];
61
62static void smp_ext_bitcall(int, ec_bit_sig); 56static void smp_ext_bitcall(int, ec_bit_sig);
63static void smp_ext_bitcall_others(ec_bit_sig); 57static void smp_ext_bitcall_others(ec_bit_sig);
64 58
@@ -200,7 +194,7 @@ int smp_call_function_on(void (*func) (void *info), void *info,
200} 194}
201EXPORT_SYMBOL(smp_call_function_on); 195EXPORT_SYMBOL(smp_call_function_on);
202 196
203static inline void do_send_stop(void) 197static void do_send_stop(void)
204{ 198{
205 int cpu, rc; 199 int cpu, rc;
206 200
@@ -214,7 +208,7 @@ static inline void do_send_stop(void)
214 } 208 }
215} 209}
216 210
217static inline void do_store_status(void) 211static void do_store_status(void)
218{ 212{
219 int cpu, rc; 213 int cpu, rc;
220 214
@@ -230,7 +224,7 @@ static inline void do_store_status(void)
230 } 224 }
231} 225}
232 226
233static inline void do_wait_for_stop(void) 227static void do_wait_for_stop(void)
234{ 228{
235 int cpu; 229 int cpu;
236 230
@@ -250,7 +244,7 @@ static inline void do_wait_for_stop(void)
250void smp_send_stop(void) 244void smp_send_stop(void)
251{ 245{
252 /* Disable all interrupts/machine checks */ 246 /* Disable all interrupts/machine checks */
253 __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK); 247 __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK);
254 248
255 /* write magic number to zero page (absolute 0) */ 249 /* write magic number to zero page (absolute 0) */
256 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC; 250 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
@@ -298,7 +292,7 @@ void machine_power_off_smp(void)
298 * cpus are handled. 292 * cpus are handled.
299 */ 293 */
300 294
301void do_ext_call_interrupt(__u16 code) 295static void do_ext_call_interrupt(__u16 code)
302{ 296{
303 unsigned long bits; 297 unsigned long bits;
304 298
@@ -385,7 +379,7 @@ struct ec_creg_mask_parms {
385/* 379/*
386 * callback for setting/clearing control bits 380 * callback for setting/clearing control bits
387 */ 381 */
388void smp_ctl_bit_callback(void *info) { 382static void smp_ctl_bit_callback(void *info) {
389 struct ec_creg_mask_parms *pp = info; 383 struct ec_creg_mask_parms *pp = info;
390 unsigned long cregs[16]; 384 unsigned long cregs[16];
391 int i; 385 int i;
@@ -458,17 +452,15 @@ __init smp_count_cpus(void)
458/* 452/*
459 * Activate a secondary processor. 453 * Activate a secondary processor.
460 */ 454 */
461extern void init_cpu_timer(void);
462extern void init_cpu_vtimer(void);
463
464int __devinit start_secondary(void *cpuvoid) 455int __devinit start_secondary(void *cpuvoid)
465{ 456{
466 /* Setup the cpu */ 457 /* Setup the cpu */
467 cpu_init(); 458 cpu_init();
468 preempt_disable(); 459 preempt_disable();
469 /* init per CPU timer */ 460 /* Enable TOD clock interrupts on the secondary cpu. */
470 init_cpu_timer(); 461 init_cpu_timer();
471#ifdef CONFIG_VIRT_TIMER 462#ifdef CONFIG_VIRT_TIMER
463 /* Enable cpu timer interrupts on the secondary cpu. */
472 init_cpu_vtimer(); 464 init_cpu_vtimer();
473#endif 465#endif
474 /* Enable pfault pseudo page faults on this cpu. */ 466 /* Enable pfault pseudo page faults on this cpu. */
@@ -542,7 +534,7 @@ smp_put_cpu(int cpu)
542 spin_unlock_irqrestore(&smp_reserve_lock, flags); 534 spin_unlock_irqrestore(&smp_reserve_lock, flags);
543} 535}
544 536
545static inline int 537static int
546cpu_stopped(int cpu) 538cpu_stopped(int cpu)
547{ 539{
548 __u32 status; 540 __u32 status;
diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
index 0d14a4789bf2..2e5c65a1863e 100644
--- a/arch/s390/kernel/stacktrace.c
+++ b/arch/s390/kernel/stacktrace.c
@@ -11,11 +11,11 @@
11#include <linux/stacktrace.h> 11#include <linux/stacktrace.h>
12#include <linux/kallsyms.h> 12#include <linux/kallsyms.h>
13 13
14static inline unsigned long save_context_stack(struct stack_trace *trace, 14static unsigned long save_context_stack(struct stack_trace *trace,
15 unsigned int *skip, 15 unsigned int *skip,
16 unsigned long sp, 16 unsigned long sp,
17 unsigned long low, 17 unsigned long low,
18 unsigned long high) 18 unsigned long high)
19{ 19{
20 struct stack_frame *sf; 20 struct stack_frame *sf;
21 struct pt_regs *regs; 21 struct pt_regs *regs;
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 6cceed4df73e..3b91f27ab202 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -37,11 +37,15 @@
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/irq_regs.h> 38#include <asm/irq_regs.h>
39#include <asm/timer.h> 39#include <asm/timer.h>
40#include <asm/etr.h>
40 41
41/* change this if you have some constant time drift */ 42/* change this if you have some constant time drift */
42#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ) 43#define USECS_PER_JIFFY ((unsigned long) 1000000/HZ)
43#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12) 44#define CLK_TICKS_PER_JIFFY ((unsigned long) USECS_PER_JIFFY << 12)
44 45
46/* The value of the TOD clock for 1.1.1970. */
47#define TOD_UNIX_EPOCH 0x7d91048bca000000ULL
48
45/* 49/*
46 * Create a small time difference between the timer interrupts 50 * Create a small time difference between the timer interrupts
47 * on the different cpus to avoid lock contention. 51 * on the different cpus to avoid lock contention.
@@ -51,6 +55,7 @@
51#define TICK_SIZE tick 55#define TICK_SIZE tick
52 56
53static ext_int_info_t ext_int_info_cc; 57static ext_int_info_t ext_int_info_cc;
58static ext_int_info_t ext_int_etr_cc;
54static u64 init_timer_cc; 59static u64 init_timer_cc;
55static u64 jiffies_timer_cc; 60static u64 jiffies_timer_cc;
56static u64 xtime_cc; 61static u64 xtime_cc;
@@ -89,29 +94,21 @@ void tod_to_timeval(__u64 todval, struct timespec *xtime)
89#define s390_do_profile() do { ; } while(0) 94#define s390_do_profile() do { ; } while(0)
90#endif /* CONFIG_PROFILING */ 95#endif /* CONFIG_PROFILING */
91 96
92
93/* 97/*
94 * timer_interrupt() needs to keep up the real-time clock, 98 * Advance the per cpu tick counter up to the time given with the
95 * as well as call the "do_timer()" routine every clocktick 99 * "time" argument. The per cpu update consists of accounting
100 * the virtual cpu time, calling update_process_times and calling
101 * the profiling hook. If xtime is before time it is advanced as well.
96 */ 102 */
97void account_ticks(void) 103void account_ticks(u64 time)
98{ 104{
99 __u64 tmp;
100 __u32 ticks; 105 __u32 ticks;
106 __u64 tmp;
101 107
102 /* Calculate how many ticks have passed. */ 108 /* Calculate how many ticks have passed. */
103 if (S390_lowcore.int_clock < S390_lowcore.jiffy_timer) { 109 if (time < S390_lowcore.jiffy_timer)
104 /*
105 * We have to program the clock comparator even if
106 * no tick has passed. That happens if e.g. an i/o
107 * interrupt wakes up an idle processor that has
108 * switched off its hz timer.
109 */
110 tmp = S390_lowcore.jiffy_timer + CPU_DEVIATION;
111 asm volatile ("SCKC %0" : : "m" (tmp));
112 return; 110 return;
113 } 111 tmp = time - S390_lowcore.jiffy_timer;
114 tmp = S390_lowcore.int_clock - S390_lowcore.jiffy_timer;
115 if (tmp >= 2*CLK_TICKS_PER_JIFFY) { /* more than two ticks ? */ 112 if (tmp >= 2*CLK_TICKS_PER_JIFFY) { /* more than two ticks ? */
116 ticks = __div(tmp, CLK_TICKS_PER_JIFFY) + 1; 113 ticks = __div(tmp, CLK_TICKS_PER_JIFFY) + 1;
117 S390_lowcore.jiffy_timer += 114 S390_lowcore.jiffy_timer +=
@@ -124,10 +121,6 @@ void account_ticks(void)
124 S390_lowcore.jiffy_timer += CLK_TICKS_PER_JIFFY; 121 S390_lowcore.jiffy_timer += CLK_TICKS_PER_JIFFY;
125 } 122 }
126 123
127 /* set clock comparator for next tick */
128 tmp = S390_lowcore.jiffy_timer + CPU_DEVIATION;
129 asm volatile ("SCKC %0" : : "m" (tmp));
130
131#ifdef CONFIG_SMP 124#ifdef CONFIG_SMP
132 /* 125 /*
133 * Do not rely on the boot cpu to do the calls to do_timer. 126 * Do not rely on the boot cpu to do the calls to do_timer.
@@ -173,7 +166,7 @@ int sysctl_hz_timer = 1;
173 * Stop the HZ tick on the current CPU. 166 * Stop the HZ tick on the current CPU.
174 * Only cpu_idle may call this function. 167 * Only cpu_idle may call this function.
175 */ 168 */
176static inline void stop_hz_timer(void) 169static void stop_hz_timer(void)
177{ 170{
178 unsigned long flags; 171 unsigned long flags;
179 unsigned long seq, next; 172 unsigned long seq, next;
@@ -210,20 +203,21 @@ static inline void stop_hz_timer(void)
210 if (timer >= jiffies_timer_cc) 203 if (timer >= jiffies_timer_cc)
211 todval = timer; 204 todval = timer;
212 } 205 }
213 asm volatile ("SCKC %0" : : "m" (todval)); 206 set_clock_comparator(todval);
214} 207}
215 208
216/* 209/*
217 * Start the HZ tick on the current CPU. 210 * Start the HZ tick on the current CPU.
218 * Only cpu_idle may call this function. 211 * Only cpu_idle may call this function.
219 */ 212 */
220static inline void start_hz_timer(void) 213static void start_hz_timer(void)
221{ 214{
222 BUG_ON(!in_interrupt()); 215 BUG_ON(!in_interrupt());
223 216
224 if (!cpu_isset(smp_processor_id(), nohz_cpu_mask)) 217 if (!cpu_isset(smp_processor_id(), nohz_cpu_mask))
225 return; 218 return;
226 account_ticks(); 219 account_ticks(get_clock());
220 set_clock_comparator(S390_lowcore.jiffy_timer + CPU_DEVIATION);
227 cpu_clear(smp_processor_id(), nohz_cpu_mask); 221 cpu_clear(smp_processor_id(), nohz_cpu_mask);
228} 222}
229 223
@@ -245,7 +239,7 @@ static struct notifier_block nohz_idle_nb = {
245 .notifier_call = nohz_idle_notify, 239 .notifier_call = nohz_idle_notify,
246}; 240};
247 241
248void __init nohz_init(void) 242static void __init nohz_init(void)
249{ 243{
250 if (register_idle_notifier(&nohz_idle_nb)) 244 if (register_idle_notifier(&nohz_idle_nb))
251 panic("Couldn't register idle notifier"); 245 panic("Couldn't register idle notifier");
@@ -254,24 +248,57 @@ void __init nohz_init(void)
254#endif 248#endif
255 249
256/* 250/*
257 * Start the clock comparator on the current CPU. 251 * Set up per cpu jiffy timer and set the clock comparator.
252 */
253static void setup_jiffy_timer(void)
254{
255 /* Set up clock comparator to next jiffy. */
256 S390_lowcore.jiffy_timer =
257 jiffies_timer_cc + (jiffies_64 + 1) * CLK_TICKS_PER_JIFFY;
258 set_clock_comparator(S390_lowcore.jiffy_timer + CPU_DEVIATION);
259}
260
261/*
262 * Set up lowcore and control register of the current cpu to
263 * enable TOD clock and clock comparator interrupts.
258 */ 264 */
259void init_cpu_timer(void) 265void init_cpu_timer(void)
260{ 266{
261 unsigned long cr0; 267 setup_jiffy_timer();
262 __u64 timer;
263 268
264 timer = jiffies_timer_cc + jiffies_64 * CLK_TICKS_PER_JIFFY; 269 /* Enable clock comparator timer interrupt. */
265 S390_lowcore.jiffy_timer = timer + CLK_TICKS_PER_JIFFY; 270 __ctl_set_bit(0,11);
266 timer += CLK_TICKS_PER_JIFFY + CPU_DEVIATION; 271
267 asm volatile ("SCKC %0" : : "m" (timer)); 272 /* Always allow ETR external interrupts, even without an ETR. */
268 /* allow clock comparator timer interrupt */ 273 __ctl_set_bit(0, 4);
269 __ctl_store(cr0, 0, 0);
270 cr0 |= 0x800;
271 __ctl_load(cr0, 0, 0);
272} 274}
273 275
274extern void vtime_init(void); 276static void clock_comparator_interrupt(__u16 code)
277{
278 /* set clock comparator for next tick */
279 set_clock_comparator(S390_lowcore.jiffy_timer + CPU_DEVIATION);
280}
281
282static void etr_reset(void);
283static void etr_init(void);
284static void etr_ext_handler(__u16);
285
286/*
287 * Get the TOD clock running.
288 */
289static u64 __init reset_tod_clock(void)
290{
291 u64 time;
292
293 etr_reset();
294 if (store_clock(&time) == 0)
295 return time;
296 /* TOD clock not running. Set the clock to Unix Epoch. */
297 if (set_clock(TOD_UNIX_EPOCH) != 0 || store_clock(&time) != 0)
298 panic("TOD clock not operational.");
299
300 return TOD_UNIX_EPOCH;
301}
275 302
276static cycle_t read_tod_clock(void) 303static cycle_t read_tod_clock(void)
277{ 304{
@@ -295,48 +322,31 @@ static struct clocksource clocksource_tod = {
295 */ 322 */
296void __init time_init(void) 323void __init time_init(void)
297{ 324{
298 __u64 set_time_cc; 325 init_timer_cc = reset_tod_clock();
299 int cc; 326 xtime_cc = init_timer_cc + CLK_TICKS_PER_JIFFY;
300
301 /* kick the TOD clock */
302 asm volatile(
303 " stck 0(%2)\n"
304 " ipm %0\n"
305 " srl %0,28"
306 : "=d" (cc), "=m" (init_timer_cc)
307 : "a" (&init_timer_cc) : "cc");
308 switch (cc) {
309 case 0: /* clock in set state: all is fine */
310 break;
311 case 1: /* clock in non-set state: FIXME */
312 printk("time_init: TOD clock in non-set state\n");
313 break;
314 case 2: /* clock in error state: FIXME */
315 printk("time_init: TOD clock in error state\n");
316 break;
317 case 3: /* clock in stopped or not-operational state: FIXME */
318 printk("time_init: TOD clock stopped/non-operational\n");
319 break;
320 }
321 jiffies_timer_cc = init_timer_cc - jiffies_64 * CLK_TICKS_PER_JIFFY; 327 jiffies_timer_cc = init_timer_cc - jiffies_64 * CLK_TICKS_PER_JIFFY;
322 328
323 /* set xtime */ 329 /* set xtime */
324 xtime_cc = init_timer_cc + CLK_TICKS_PER_JIFFY; 330 tod_to_timeval(init_timer_cc - TOD_UNIX_EPOCH, &xtime);
325 set_time_cc = init_timer_cc - 0x8126d60e46000000LL +
326 (0x3c26700LL*1000000*4096);
327 tod_to_timeval(set_time_cc, &xtime);
328 set_normalized_timespec(&wall_to_monotonic, 331 set_normalized_timespec(&wall_to_monotonic,
329 -xtime.tv_sec, -xtime.tv_nsec); 332 -xtime.tv_sec, -xtime.tv_nsec);
330 333
331 /* request the clock comparator external interrupt */ 334 /* request the clock comparator external interrupt */
332 if (register_early_external_interrupt(0x1004, NULL, 335 if (register_early_external_interrupt(0x1004,
336 clock_comparator_interrupt,
333 &ext_int_info_cc) != 0) 337 &ext_int_info_cc) != 0)
334 panic("Couldn't request external interrupt 0x1004"); 338 panic("Couldn't request external interrupt 0x1004");
335 339
336 if (clocksource_register(&clocksource_tod) != 0) 340 if (clocksource_register(&clocksource_tod) != 0)
337 panic("Could not register TOD clock source"); 341 panic("Could not register TOD clock source");
338 342
339 init_cpu_timer(); 343 /* request the etr external interrupt */
344 if (register_early_external_interrupt(0x1406, etr_ext_handler,
345 &ext_int_etr_cc) != 0)
346 panic("Couldn't request external interrupt 0x1406");
347
348 /* Enable TOD clock interrupts on the boot cpu. */
349 init_cpu_timer();
340 350
341#ifdef CONFIG_NO_IDLE_HZ 351#ifdef CONFIG_NO_IDLE_HZ
342 nohz_init(); 352 nohz_init();
@@ -345,5 +355,1048 @@ void __init time_init(void)
345#ifdef CONFIG_VIRT_TIMER 355#ifdef CONFIG_VIRT_TIMER
346 vtime_init(); 356 vtime_init();
347#endif 357#endif
358 etr_init();
359}
360
361/*
362 * External Time Reference (ETR) code.
363 */
364static int etr_port0_online;
365static int etr_port1_online;
366
367static int __init early_parse_etr(char *p)
368{
369 if (strncmp(p, "off", 3) == 0)
370 etr_port0_online = etr_port1_online = 0;
371 else if (strncmp(p, "port0", 5) == 0)
372 etr_port0_online = 1;
373 else if (strncmp(p, "port1", 5) == 0)
374 etr_port1_online = 1;
375 else if (strncmp(p, "on", 2) == 0)
376 etr_port0_online = etr_port1_online = 1;
377 return 0;
378}
379early_param("etr", early_parse_etr);
380
381enum etr_event {
382 ETR_EVENT_PORT0_CHANGE,
383 ETR_EVENT_PORT1_CHANGE,
384 ETR_EVENT_PORT_ALERT,
385 ETR_EVENT_SYNC_CHECK,
386 ETR_EVENT_SWITCH_LOCAL,
387 ETR_EVENT_UPDATE,
388};
389
390enum etr_flags {
391 ETR_FLAG_ENOSYS,
392 ETR_FLAG_EACCES,
393 ETR_FLAG_STEAI,
394};
395
396/*
397 * Valid bit combinations of the eacr register are (x = don't care):
398 * e0 e1 dp p0 p1 ea es sl
399 * 0 0 x 0 0 0 0 0 initial, disabled state
400 * 0 0 x 0 1 1 0 0 port 1 online
401 * 0 0 x 1 0 1 0 0 port 0 online
402 * 0 0 x 1 1 1 0 0 both ports online
403 * 0 1 x 0 1 1 0 0 port 1 online and usable, ETR or PPS mode
404 * 0 1 x 0 1 1 0 1 port 1 online, usable and ETR mode
405 * 0 1 x 0 1 1 1 0 port 1 online, usable, PPS mode, in-sync
406 * 0 1 x 0 1 1 1 1 port 1 online, usable, ETR mode, in-sync
407 * 0 1 x 1 1 1 0 0 both ports online, port 1 usable
408 * 0 1 x 1 1 1 1 0 both ports online, port 1 usable, PPS mode, in-sync
409 * 0 1 x 1 1 1 1 1 both ports online, port 1 usable, ETR mode, in-sync
410 * 1 0 x 1 0 1 0 0 port 0 online and usable, ETR or PPS mode
411 * 1 0 x 1 0 1 0 1 port 0 online, usable and ETR mode
412 * 1 0 x 1 0 1 1 0 port 0 online, usable, PPS mode, in-sync
413 * 1 0 x 1 0 1 1 1 port 0 online, usable, ETR mode, in-sync
414 * 1 0 x 1 1 1 0 0 both ports online, port 0 usable
415 * 1 0 x 1 1 1 1 0 both ports online, port 0 usable, PPS mode, in-sync
416 * 1 0 x 1 1 1 1 1 both ports online, port 0 usable, ETR mode, in-sync
417 * 1 1 x 1 1 1 1 0 both ports online & usable, ETR, in-sync
418 * 1 1 x 1 1 1 1 1 both ports online & usable, ETR, in-sync
419 */
420static struct etr_eacr etr_eacr;
421static u64 etr_tolec; /* time of last eacr update */
422static unsigned long etr_flags;
423static struct etr_aib etr_port0;
424static int etr_port0_uptodate;
425static struct etr_aib etr_port1;
426static int etr_port1_uptodate;
427static unsigned long etr_events;
428static struct timer_list etr_timer;
429static struct tasklet_struct etr_tasklet;
430static DEFINE_PER_CPU(atomic_t, etr_sync_word);
431
432static void etr_timeout(unsigned long dummy);
433static void etr_tasklet_fn(unsigned long dummy);
434
435/*
436 * The etr get_clock function. It will write the current clock value
437 * to the clock pointer and return 0 if the clock is in sync with the
438 * external time source. If the clock mode is local it will return
439 * -ENOSYS and -EAGAIN if the clock is not in sync with the external
440 * reference. This function is what ETR is all about..
441 */
442int get_sync_clock(unsigned long long *clock)
443{
444 atomic_t *sw_ptr;
445 unsigned int sw0, sw1;
446
447 sw_ptr = &get_cpu_var(etr_sync_word);
448 sw0 = atomic_read(sw_ptr);
449 *clock = get_clock();
450 sw1 = atomic_read(sw_ptr);
451 put_cpu_var(etr_sync_sync);
452 if (sw0 == sw1 && (sw0 & 0x80000000U))
453 /* Success: time is in sync. */
454 return 0;
455 if (test_bit(ETR_FLAG_ENOSYS, &etr_flags))
456 return -ENOSYS;
457 if (test_bit(ETR_FLAG_EACCES, &etr_flags))
458 return -EACCES;
459 return -EAGAIN;
460}
461EXPORT_SYMBOL(get_sync_clock);
462
463/*
464 * Make get_sync_clock return -EAGAIN.
465 */
466static void etr_disable_sync_clock(void *dummy)
467{
468 atomic_t *sw_ptr = &__get_cpu_var(etr_sync_word);
469 /*
470 * Clear the in-sync bit 2^31. All get_sync_clock calls will
471 * fail until the sync bit is turned back on. In addition
472 * increase the "sequence" counter to avoid the race of an
473 * etr event and the complete recovery against get_sync_clock.
474 */
475 atomic_clear_mask(0x80000000, sw_ptr);
476 atomic_inc(sw_ptr);
477}
478
479/*
480 * Make get_sync_clock return 0 again.
481 * Needs to be called from a context disabled for preemption.
482 */
483static void etr_enable_sync_clock(void)
484{
485 atomic_t *sw_ptr = &__get_cpu_var(etr_sync_word);
486 atomic_set_mask(0x80000000, sw_ptr);
487}
488
489/*
490 * Reset ETR attachment.
491 */
492static void etr_reset(void)
493{
494 etr_eacr = (struct etr_eacr) {
495 .e0 = 0, .e1 = 0, ._pad0 = 4, .dp = 0,
496 .p0 = 0, .p1 = 0, ._pad1 = 0, .ea = 0,
497 .es = 0, .sl = 0 };
498 if (etr_setr(&etr_eacr) == 0)
499 etr_tolec = get_clock();
500 else {
501 set_bit(ETR_FLAG_ENOSYS, &etr_flags);
502 if (etr_port0_online || etr_port1_online) {
503 printk(KERN_WARNING "Running on non ETR capable "
504 "machine, only local mode available.\n");
505 etr_port0_online = etr_port1_online = 0;
506 }
507 }
508}
509
510static void etr_init(void)
511{
512 struct etr_aib aib;
513
514 if (test_bit(ETR_FLAG_ENOSYS, &etr_flags))
515 return;
516 /* Check if this machine has the steai instruction. */
517 if (etr_steai(&aib, ETR_STEAI_STEPPING_PORT) == 0)
518 set_bit(ETR_FLAG_STEAI, &etr_flags);
519 setup_timer(&etr_timer, etr_timeout, 0UL);
520 tasklet_init(&etr_tasklet, etr_tasklet_fn, 0);
521 if (!etr_port0_online && !etr_port1_online)
522 set_bit(ETR_FLAG_EACCES, &etr_flags);
523 if (etr_port0_online) {
524 set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);
525 tasklet_hi_schedule(&etr_tasklet);
526 }
527 if (etr_port1_online) {
528 set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);
529 tasklet_hi_schedule(&etr_tasklet);
530 }
531}
532
533/*
534 * Two sorts of ETR machine checks. The architecture reads:
535 * "When a machine-check niterruption occurs and if a switch-to-local or
536 * ETR-sync-check interrupt request is pending but disabled, this pending
537 * disabled interruption request is indicated and is cleared".
538 * Which means that we can get etr_switch_to_local events from the machine
539 * check handler although the interruption condition is disabled. Lovely..
540 */
541
542/*
543 * Switch to local machine check. This is called when the last usable
544 * ETR port goes inactive. After switch to local the clock is not in sync.
545 */
546void etr_switch_to_local(void)
547{
548 if (!etr_eacr.sl)
549 return;
550 etr_disable_sync_clock(NULL);
551 set_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events);
552 tasklet_hi_schedule(&etr_tasklet);
553}
554
555/*
556 * ETR sync check machine check. This is called when the ETR OTE and the
557 * local clock OTE are farther apart than the ETR sync check tolerance.
558 * After a ETR sync check the clock is not in sync. The machine check
559 * is broadcasted to all cpus at the same time.
560 */
561void etr_sync_check(void)
562{
563 if (!etr_eacr.es)
564 return;
565 etr_disable_sync_clock(NULL);
566 set_bit(ETR_EVENT_SYNC_CHECK, &etr_events);
567 tasklet_hi_schedule(&etr_tasklet);
568}
569
570/*
571 * ETR external interrupt. There are two causes:
572 * 1) port state change, check the usability of the port
573 * 2) port alert, one of the ETR-data-validity bits (v1-v2 bits of the
574 * sldr-status word) or ETR-data word 1 (edf1) or ETR-data word 3 (edf3)
575 * or ETR-data word 4 (edf4) has changed.
576 */
577static void etr_ext_handler(__u16 code)
578{
579 struct etr_interruption_parameter *intparm =
580 (struct etr_interruption_parameter *) &S390_lowcore.ext_params;
581
582 if (intparm->pc0)
583 /* ETR port 0 state change. */
584 set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);
585 if (intparm->pc1)
586 /* ETR port 1 state change. */
587 set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);
588 if (intparm->eai)
589 /*
590 * ETR port alert on either port 0, 1 or both.
591 * Both ports are not up-to-date now.
592 */
593 set_bit(ETR_EVENT_PORT_ALERT, &etr_events);
594 tasklet_hi_schedule(&etr_tasklet);
595}
596
597static void etr_timeout(unsigned long dummy)
598{
599 set_bit(ETR_EVENT_UPDATE, &etr_events);
600 tasklet_hi_schedule(&etr_tasklet);
601}
602
603/*
604 * Check if the etr mode is pss.
605 */
606static inline int etr_mode_is_pps(struct etr_eacr eacr)
607{
608 return eacr.es && !eacr.sl;
609}
610
611/*
612 * Check if the etr mode is etr.
613 */
614static inline int etr_mode_is_etr(struct etr_eacr eacr)
615{
616 return eacr.es && eacr.sl;
617}
618
619/*
620 * Check if the port can be used for TOD synchronization.
621 * For PPS mode the port has to receive OTEs. For ETR mode
622 * the port has to receive OTEs, the ETR stepping bit has to
623 * be zero and the validity bits for data frame 1, 2, and 3
624 * have to be 1.
625 */
626static int etr_port_valid(struct etr_aib *aib, int port)
627{
628 unsigned int psc;
629
630 /* Check that this port is receiving OTEs. */
631 if (aib->tsp == 0)
632 return 0;
633
634 psc = port ? aib->esw.psc1 : aib->esw.psc0;
635 if (psc == etr_lpsc_pps_mode)
636 return 1;
637 if (psc == etr_lpsc_operational_step)
638 return !aib->esw.y && aib->slsw.v1 &&
639 aib->slsw.v2 && aib->slsw.v3;
640 return 0;
641}
642
643/*
644 * Check if two ports are on the same network.
645 */
646static int etr_compare_network(struct etr_aib *aib1, struct etr_aib *aib2)
647{
648 // FIXME: any other fields we have to compare?
649 return aib1->edf1.net_id == aib2->edf1.net_id;
650}
651
652/*
653 * Wrapper for etr_stei that converts physical port states
654 * to logical port states to be consistent with the output
655 * of stetr (see etr_psc vs. etr_lpsc).
656 */
657static void etr_steai_cv(struct etr_aib *aib, unsigned int func)
658{
659 BUG_ON(etr_steai(aib, func) != 0);
660 /* Convert port state to logical port state. */
661 if (aib->esw.psc0 == 1)
662 aib->esw.psc0 = 2;
663 else if (aib->esw.psc0 == 0 && aib->esw.p == 0)
664 aib->esw.psc0 = 1;
665 if (aib->esw.psc1 == 1)
666 aib->esw.psc1 = 2;
667 else if (aib->esw.psc1 == 0 && aib->esw.p == 1)
668 aib->esw.psc1 = 1;
669}
670
671/*
672 * Check if the aib a2 is still connected to the same attachment as
673 * aib a1, the etv values differ by one and a2 is valid.
674 */
675static int etr_aib_follows(struct etr_aib *a1, struct etr_aib *a2, int p)
676{
677 int state_a1, state_a2;
678
679 /* Paranoia check: e0/e1 should better be the same. */
680 if (a1->esw.eacr.e0 != a2->esw.eacr.e0 ||
681 a1->esw.eacr.e1 != a2->esw.eacr.e1)
682 return 0;
683
684 /* Still connected to the same etr ? */
685 state_a1 = p ? a1->esw.psc1 : a1->esw.psc0;
686 state_a2 = p ? a2->esw.psc1 : a2->esw.psc0;
687 if (state_a1 == etr_lpsc_operational_step) {
688 if (state_a2 != etr_lpsc_operational_step ||
689 a1->edf1.net_id != a2->edf1.net_id ||
690 a1->edf1.etr_id != a2->edf1.etr_id ||
691 a1->edf1.etr_pn != a2->edf1.etr_pn)
692 return 0;
693 } else if (state_a2 != etr_lpsc_pps_mode)
694 return 0;
695
696 /* The ETV value of a2 needs to be ETV of a1 + 1. */
697 if (a1->edf2.etv + 1 != a2->edf2.etv)
698 return 0;
699
700 if (!etr_port_valid(a2, p))
701 return 0;
702
703 return 1;
704}
705
706/*
707 * The time is "clock". xtime is what we think the time is.
708 * Adjust the value by a multiple of jiffies and add the delta to ntp.
709 * "delay" is an approximation how long the synchronization took. If
710 * the time correction is positive, then "delay" is subtracted from
711 * the time difference and only the remaining part is passed to ntp.
712 */
713static void etr_adjust_time(unsigned long long clock, unsigned long long delay)
714{
715 unsigned long long delta, ticks;
716 struct timex adjust;
717
718 /*
719 * We don't have to take the xtime lock because the cpu
720 * executing etr_adjust_time is running disabled in
721 * tasklet context and all other cpus are looping in
722 * etr_sync_cpu_start.
723 */
724 if (clock > xtime_cc) {
725 /* It is later than we thought. */
726 delta = ticks = clock - xtime_cc;
727 delta = ticks = (delta < delay) ? 0 : delta - delay;
728 delta -= do_div(ticks, CLK_TICKS_PER_JIFFY);
729 init_timer_cc = init_timer_cc + delta;
730 jiffies_timer_cc = jiffies_timer_cc + delta;
731 xtime_cc = xtime_cc + delta;
732 adjust.offset = ticks * (1000000 / HZ);
733 } else {
734 /* It is earlier than we thought. */
735 delta = ticks = xtime_cc - clock;
736 delta -= do_div(ticks, CLK_TICKS_PER_JIFFY);
737 init_timer_cc = init_timer_cc - delta;
738 jiffies_timer_cc = jiffies_timer_cc - delta;
739 xtime_cc = xtime_cc - delta;
740 adjust.offset = -ticks * (1000000 / HZ);
741 }
742 if (adjust.offset != 0) {
743 printk(KERN_NOTICE "etr: time adjusted by %li micro-seconds\n",
744 adjust.offset);
745 adjust.modes = ADJ_OFFSET_SINGLESHOT;
746 do_adjtimex(&adjust);
747 }
748}
749
750static void etr_sync_cpu_start(void *dummy)
751{
752 int *in_sync = dummy;
753
754 etr_enable_sync_clock();
755 /*
756 * This looks like a busy wait loop but it isn't. etr_sync_cpus
757 * is called on all other cpus while the TOD clocks is stopped.
758 * __udelay will stop the cpu on an enabled wait psw until the
759 * TOD is running again.
760 */
761 while (*in_sync == 0)
762 __udelay(1);
763 if (*in_sync != 1)
764 /* Didn't work. Clear per-cpu in sync bit again. */
765 etr_disable_sync_clock(NULL);
766 /*
767 * This round of TOD syncing is done. Set the clock comparator
768 * to the next tick and let the processor continue.
769 */
770 setup_jiffy_timer();
771}
772
773static void etr_sync_cpu_end(void *dummy)
774{
775}
776
777/*
778 * Sync the TOD clock using the port refered to by aibp. This port
779 * has to be enabled and the other port has to be disabled. The
780 * last eacr update has to be more than 1.6 seconds in the past.
781 */
782static int etr_sync_clock(struct etr_aib *aib, int port)
783{
784 struct etr_aib *sync_port;
785 unsigned long long clock, delay;
786 int in_sync, follows;
787 int rc;
788
789 /* Check if the current aib is adjacent to the sync port aib. */
790 sync_port = (port == 0) ? &etr_port0 : &etr_port1;
791 follows = etr_aib_follows(sync_port, aib, port);
792 memcpy(sync_port, aib, sizeof(*aib));
793 if (!follows)
794 return -EAGAIN;
795
796 /*
797 * Catch all other cpus and make them wait until we have
798 * successfully synced the clock. smp_call_function will
799 * return after all other cpus are in etr_sync_cpu_start.
800 */
801 in_sync = 0;
802 preempt_disable();
803 smp_call_function(etr_sync_cpu_start,&in_sync,0,0);
804 local_irq_disable();
805 etr_enable_sync_clock();
806
807 /* Set clock to next OTE. */
808 __ctl_set_bit(14, 21);
809 __ctl_set_bit(0, 29);
810 clock = ((unsigned long long) (aib->edf2.etv + 1)) << 32;
811 if (set_clock(clock) == 0) {
812 __udelay(1); /* Wait for the clock to start. */
813 __ctl_clear_bit(0, 29);
814 __ctl_clear_bit(14, 21);
815 etr_stetr(aib);
816 /* Adjust Linux timing variables. */
817 delay = (unsigned long long)
818 (aib->edf2.etv - sync_port->edf2.etv) << 32;
819 etr_adjust_time(clock, delay);
820 setup_jiffy_timer();
821 /* Verify that the clock is properly set. */
822 if (!etr_aib_follows(sync_port, aib, port)) {
823 /* Didn't work. */
824 etr_disable_sync_clock(NULL);
825 in_sync = -EAGAIN;
826 rc = -EAGAIN;
827 } else {
828 in_sync = 1;
829 rc = 0;
830 }
831 } else {
832 /* Could not set the clock ?!? */
833 __ctl_clear_bit(0, 29);
834 __ctl_clear_bit(14, 21);
835 etr_disable_sync_clock(NULL);
836 in_sync = -EAGAIN;
837 rc = -EAGAIN;
838 }
839 local_irq_enable();
840 smp_call_function(etr_sync_cpu_end,NULL,0,0);
841 preempt_enable();
842 return rc;
843}
844
845/*
846 * Handle the immediate effects of the different events.
847 * The port change event is used for online/offline changes.
848 */
849static struct etr_eacr etr_handle_events(struct etr_eacr eacr)
850{
851 if (test_and_clear_bit(ETR_EVENT_SYNC_CHECK, &etr_events))
852 eacr.es = 0;
853 if (test_and_clear_bit(ETR_EVENT_SWITCH_LOCAL, &etr_events))
854 eacr.es = eacr.sl = 0;
855 if (test_and_clear_bit(ETR_EVENT_PORT_ALERT, &etr_events))
856 etr_port0_uptodate = etr_port1_uptodate = 0;
857
858 if (test_and_clear_bit(ETR_EVENT_PORT0_CHANGE, &etr_events)) {
859 if (eacr.e0)
860 /*
861 * Port change of an enabled port. We have to
862 * assume that this can have caused an stepping
863 * port switch.
864 */
865 etr_tolec = get_clock();
866 eacr.p0 = etr_port0_online;
867 if (!eacr.p0)
868 eacr.e0 = 0;
869 etr_port0_uptodate = 0;
870 }
871 if (test_and_clear_bit(ETR_EVENT_PORT1_CHANGE, &etr_events)) {
872 if (eacr.e1)
873 /*
874 * Port change of an enabled port. We have to
875 * assume that this can have caused an stepping
876 * port switch.
877 */
878 etr_tolec = get_clock();
879 eacr.p1 = etr_port1_online;
880 if (!eacr.p1)
881 eacr.e1 = 0;
882 etr_port1_uptodate = 0;
883 }
884 clear_bit(ETR_EVENT_UPDATE, &etr_events);
885 return eacr;
886}
887
888/*
889 * Set up a timer that expires after the etr_tolec + 1.6 seconds if
890 * one of the ports needs an update.
891 */
892static void etr_set_tolec_timeout(unsigned long long now)
893{
894 unsigned long micros;
895
896 if ((!etr_eacr.p0 || etr_port0_uptodate) &&
897 (!etr_eacr.p1 || etr_port1_uptodate))
898 return;
899 micros = (now > etr_tolec) ? ((now - etr_tolec) >> 12) : 0;
900 micros = (micros > 1600000) ? 0 : 1600000 - micros;
901 mod_timer(&etr_timer, jiffies + (micros * HZ) / 1000000 + 1);
902}
903
904/*
905 * Set up a time that expires after 1/2 second.
906 */
907static void etr_set_sync_timeout(void)
908{
909 mod_timer(&etr_timer, jiffies + HZ/2);
910}
911
912/*
913 * Update the aib information for one or both ports.
914 */
915static struct etr_eacr etr_handle_update(struct etr_aib *aib,
916 struct etr_eacr eacr)
917{
918 /* With both ports disabled the aib information is useless. */
919 if (!eacr.e0 && !eacr.e1)
920 return eacr;
921
922 /* Update port0 or port1 with aib stored in etr_tasklet_fn. */
923 if (aib->esw.q == 0) {
924 /* Information for port 0 stored. */
925 if (eacr.p0 && !etr_port0_uptodate) {
926 etr_port0 = *aib;
927 if (etr_port0_online)
928 etr_port0_uptodate = 1;
929 }
930 } else {
931 /* Information for port 1 stored. */
932 if (eacr.p1 && !etr_port1_uptodate) {
933 etr_port1 = *aib;
934 if (etr_port0_online)
935 etr_port1_uptodate = 1;
936 }
937 }
938
939 /*
940 * Do not try to get the alternate port aib if the clock
941 * is not in sync yet.
942 */
943 if (!eacr.es)
944 return eacr;
945
946 /*
947 * If steai is available we can get the information about
948 * the other port immediately. If only stetr is available the
949 * data-port bit toggle has to be used.
950 */
951 if (test_bit(ETR_FLAG_STEAI, &etr_flags)) {
952 if (eacr.p0 && !etr_port0_uptodate) {
953 etr_steai_cv(&etr_port0, ETR_STEAI_PORT_0);
954 etr_port0_uptodate = 1;
955 }
956 if (eacr.p1 && !etr_port1_uptodate) {
957 etr_steai_cv(&etr_port1, ETR_STEAI_PORT_1);
958 etr_port1_uptodate = 1;
959 }
960 } else {
961 /*
962 * One port was updated above, if the other
963 * port is not uptodate toggle dp bit.
964 */
965 if ((eacr.p0 && !etr_port0_uptodate) ||
966 (eacr.p1 && !etr_port1_uptodate))
967 eacr.dp ^= 1;
968 else
969 eacr.dp = 0;
970 }
971 return eacr;
972}
973
974/*
975 * Write new etr control register if it differs from the current one.
976 * Return 1 if etr_tolec has been updated as well.
977 */
978static void etr_update_eacr(struct etr_eacr eacr)
979{
980 int dp_changed;
981
982 if (memcmp(&etr_eacr, &eacr, sizeof(eacr)) == 0)
983 /* No change, return. */
984 return;
985 /*
986 * The disable of an active port of the change of the data port
987 * bit can/will cause a change in the data port.
988 */
989 dp_changed = etr_eacr.e0 > eacr.e0 || etr_eacr.e1 > eacr.e1 ||
990 (etr_eacr.dp ^ eacr.dp) != 0;
991 etr_eacr = eacr;
992 etr_setr(&etr_eacr);
993 if (dp_changed)
994 etr_tolec = get_clock();
995}
996
997/*
998 * ETR tasklet. In this function you'll find the main logic. In
999 * particular this is the only function that calls etr_update_eacr(),
1000 * it "controls" the etr control register.
1001 */
1002static void etr_tasklet_fn(unsigned long dummy)
1003{
1004 unsigned long long now;
1005 struct etr_eacr eacr;
1006 struct etr_aib aib;
1007 int sync_port;
1008
1009 /* Create working copy of etr_eacr. */
1010 eacr = etr_eacr;
1011
1012 /* Check for the different events and their immediate effects. */
1013 eacr = etr_handle_events(eacr);
1014
1015 /* Check if ETR is supposed to be active. */
1016 eacr.ea = eacr.p0 || eacr.p1;
1017 if (!eacr.ea) {
1018 /* Both ports offline. Reset everything. */
1019 eacr.dp = eacr.es = eacr.sl = 0;
1020 on_each_cpu(etr_disable_sync_clock, NULL, 0, 1);
1021 del_timer_sync(&etr_timer);
1022 etr_update_eacr(eacr);
1023 set_bit(ETR_FLAG_EACCES, &etr_flags);
1024 return;
1025 }
1026
1027 /* Store aib to get the current ETR status word. */
1028 BUG_ON(etr_stetr(&aib) != 0);
1029 etr_port0.esw = etr_port1.esw = aib.esw; /* Copy status word. */
1030 now = get_clock();
1031
1032 /*
1033 * Update the port information if the last stepping port change
1034 * or data port change is older than 1.6 seconds.
1035 */
1036 if (now >= etr_tolec + (1600000 << 12))
1037 eacr = etr_handle_update(&aib, eacr);
1038
1039 /*
1040 * Select ports to enable. The prefered synchronization mode is PPS.
1041 * If a port can be enabled depends on a number of things:
1042 * 1) The port needs to be online and uptodate. A port is not
1043 * disabled just because it is not uptodate, but it is only
1044 * enabled if it is uptodate.
1045 * 2) The port needs to have the same mode (pps / etr).
1046 * 3) The port needs to be usable -> etr_port_valid() == 1
1047 * 4) To enable the second port the clock needs to be in sync.
1048 * 5) If both ports are useable and are ETR ports, the network id
1049 * has to be the same.
1050 * The eacr.sl bit is used to indicate etr mode vs. pps mode.
1051 */
1052 if (eacr.p0 && aib.esw.psc0 == etr_lpsc_pps_mode) {
1053 eacr.sl = 0;
1054 eacr.e0 = 1;
1055 if (!etr_mode_is_pps(etr_eacr))
1056 eacr.es = 0;
1057 if (!eacr.es || !eacr.p1 || aib.esw.psc1 != etr_lpsc_pps_mode)
1058 eacr.e1 = 0;
1059 // FIXME: uptodate checks ?
1060 else if (etr_port0_uptodate && etr_port1_uptodate)
1061 eacr.e1 = 1;
1062 sync_port = (etr_port0_uptodate &&
1063 etr_port_valid(&etr_port0, 0)) ? 0 : -1;
1064 clear_bit(ETR_FLAG_EACCES, &etr_flags);
1065 } else if (eacr.p1 && aib.esw.psc1 == etr_lpsc_pps_mode) {
1066 eacr.sl = 0;
1067 eacr.e0 = 0;
1068 eacr.e1 = 1;
1069 if (!etr_mode_is_pps(etr_eacr))
1070 eacr.es = 0;
1071 sync_port = (etr_port1_uptodate &&
1072 etr_port_valid(&etr_port1, 1)) ? 1 : -1;
1073 clear_bit(ETR_FLAG_EACCES, &etr_flags);
1074 } else if (eacr.p0 && aib.esw.psc0 == etr_lpsc_operational_step) {
1075 eacr.sl = 1;
1076 eacr.e0 = 1;
1077 if (!etr_mode_is_etr(etr_eacr))
1078 eacr.es = 0;
1079 if (!eacr.es || !eacr.p1 ||
1080 aib.esw.psc1 != etr_lpsc_operational_alt)
1081 eacr.e1 = 0;
1082 else if (etr_port0_uptodate && etr_port1_uptodate &&
1083 etr_compare_network(&etr_port0, &etr_port1))
1084 eacr.e1 = 1;
1085 sync_port = (etr_port0_uptodate &&
1086 etr_port_valid(&etr_port0, 0)) ? 0 : -1;
1087 clear_bit(ETR_FLAG_EACCES, &etr_flags);
1088 } else if (eacr.p1 && aib.esw.psc1 == etr_lpsc_operational_step) {
1089 eacr.sl = 1;
1090 eacr.e0 = 0;
1091 eacr.e1 = 1;
1092 if (!etr_mode_is_etr(etr_eacr))
1093 eacr.es = 0;
1094 sync_port = (etr_port1_uptodate &&
1095 etr_port_valid(&etr_port1, 1)) ? 1 : -1;
1096 clear_bit(ETR_FLAG_EACCES, &etr_flags);
1097 } else {
1098 /* Both ports not usable. */
1099 eacr.es = eacr.sl = 0;
1100 sync_port = -1;
1101 set_bit(ETR_FLAG_EACCES, &etr_flags);
1102 }
1103
1104 /*
1105 * If the clock is in sync just update the eacr and return.
1106 * If there is no valid sync port wait for a port update.
1107 */
1108 if (eacr.es || sync_port < 0) {
1109 etr_update_eacr(eacr);
1110 etr_set_tolec_timeout(now);
1111 return;
1112 }
1113
1114 /*
1115 * Prepare control register for clock syncing
1116 * (reset data port bit, set sync check control.
1117 */
1118 eacr.dp = 0;
1119 eacr.es = 1;
1120
1121 /*
1122 * Update eacr and try to synchronize the clock. If the update
1123 * of eacr caused a stepping port switch (or if we have to
1124 * assume that a stepping port switch has occured) or the
1125 * clock syncing failed, reset the sync check control bit
1126 * and set up a timer to try again after 0.5 seconds
1127 */
1128 etr_update_eacr(eacr);
1129 if (now < etr_tolec + (1600000 << 12) ||
1130 etr_sync_clock(&aib, sync_port) != 0) {
1131 /* Sync failed. Try again in 1/2 second. */
1132 eacr.es = 0;
1133 etr_update_eacr(eacr);
1134 etr_set_sync_timeout();
1135 } else
1136 etr_set_tolec_timeout(now);
1137}
1138
1139/*
1140 * Sysfs interface functions
1141 */
1142static struct sysdev_class etr_sysclass = {
1143 set_kset_name("etr")
1144};
1145
1146static struct sys_device etr_port0_dev = {
1147 .id = 0,
1148 .cls = &etr_sysclass,
1149};
1150
1151static struct sys_device etr_port1_dev = {
1152 .id = 1,
1153 .cls = &etr_sysclass,
1154};
1155
1156/*
1157 * ETR class attributes
1158 */
1159static ssize_t etr_stepping_port_show(struct sysdev_class *class, char *buf)
1160{
1161 return sprintf(buf, "%i\n", etr_port0.esw.p);
1162}
1163
1164static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
1165
1166static ssize_t etr_stepping_mode_show(struct sysdev_class *class, char *buf)
1167{
1168 char *mode_str;
1169
1170 if (etr_mode_is_pps(etr_eacr))
1171 mode_str = "pps";
1172 else if (etr_mode_is_etr(etr_eacr))
1173 mode_str = "etr";
1174 else
1175 mode_str = "local";
1176 return sprintf(buf, "%s\n", mode_str);
1177}
1178
1179static SYSDEV_CLASS_ATTR(stepping_mode, 0400, etr_stepping_mode_show, NULL);
1180
1181/*
1182 * ETR port attributes
1183 */
1184static inline struct etr_aib *etr_aib_from_dev(struct sys_device *dev)
1185{
1186 if (dev == &etr_port0_dev)
1187 return etr_port0_online ? &etr_port0 : NULL;
1188 else
1189 return etr_port1_online ? &etr_port1 : NULL;
1190}
1191
1192static ssize_t etr_online_show(struct sys_device *dev, char *buf)
1193{
1194 unsigned int online;
1195
1196 online = (dev == &etr_port0_dev) ? etr_port0_online : etr_port1_online;
1197 return sprintf(buf, "%i\n", online);
1198}
1199
1200static ssize_t etr_online_store(struct sys_device *dev,
1201 const char *buf, size_t count)
1202{
1203 unsigned int value;
1204
1205 value = simple_strtoul(buf, NULL, 0);
1206 if (value != 0 && value != 1)
1207 return -EINVAL;
1208 if (test_bit(ETR_FLAG_ENOSYS, &etr_flags))
1209 return -ENOSYS;
1210 if (dev == &etr_port0_dev) {
1211 if (etr_port0_online == value)
1212 return count; /* Nothing to do. */
1213 etr_port0_online = value;
1214 set_bit(ETR_EVENT_PORT0_CHANGE, &etr_events);
1215 tasklet_hi_schedule(&etr_tasklet);
1216 } else {
1217 if (etr_port1_online == value)
1218 return count; /* Nothing to do. */
1219 etr_port1_online = value;
1220 set_bit(ETR_EVENT_PORT1_CHANGE, &etr_events);
1221 tasklet_hi_schedule(&etr_tasklet);
1222 }
1223 return count;
1224}
1225
1226static SYSDEV_ATTR(online, 0600, etr_online_show, etr_online_store);
1227
1228static ssize_t etr_stepping_control_show(struct sys_device *dev, char *buf)
1229{
1230 return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?
1231 etr_eacr.e0 : etr_eacr.e1);
1232}
1233
1234static SYSDEV_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL);
1235
1236static ssize_t etr_mode_code_show(struct sys_device *dev, char *buf)
1237{
1238 if (!etr_port0_online && !etr_port1_online)
1239 /* Status word is not uptodate if both ports are offline. */
1240 return -ENODATA;
1241 return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?
1242 etr_port0.esw.psc0 : etr_port0.esw.psc1);
1243}
1244
1245static SYSDEV_ATTR(state_code, 0400, etr_mode_code_show, NULL);
1246
1247static ssize_t etr_untuned_show(struct sys_device *dev, char *buf)
1248{
1249 struct etr_aib *aib = etr_aib_from_dev(dev);
1250
1251 if (!aib || !aib->slsw.v1)
1252 return -ENODATA;
1253 return sprintf(buf, "%i\n", aib->edf1.u);
1254}
1255
1256static SYSDEV_ATTR(untuned, 0400, etr_untuned_show, NULL);
1257
1258static ssize_t etr_network_id_show(struct sys_device *dev, char *buf)
1259{
1260 struct etr_aib *aib = etr_aib_from_dev(dev);
1261
1262 if (!aib || !aib->slsw.v1)
1263 return -ENODATA;
1264 return sprintf(buf, "%i\n", aib->edf1.net_id);
1265}
1266
1267static SYSDEV_ATTR(network, 0400, etr_network_id_show, NULL);
1268
1269static ssize_t etr_id_show(struct sys_device *dev, char *buf)
1270{
1271 struct etr_aib *aib = etr_aib_from_dev(dev);
1272
1273 if (!aib || !aib->slsw.v1)
1274 return -ENODATA;
1275 return sprintf(buf, "%i\n", aib->edf1.etr_id);
1276}
1277
1278static SYSDEV_ATTR(id, 0400, etr_id_show, NULL);
1279
1280static ssize_t etr_port_number_show(struct sys_device *dev, char *buf)
1281{
1282 struct etr_aib *aib = etr_aib_from_dev(dev);
1283
1284 if (!aib || !aib->slsw.v1)
1285 return -ENODATA;
1286 return sprintf(buf, "%i\n", aib->edf1.etr_pn);
1287}
1288
1289static SYSDEV_ATTR(port, 0400, etr_port_number_show, NULL);
1290
1291static ssize_t etr_coupled_show(struct sys_device *dev, char *buf)
1292{
1293 struct etr_aib *aib = etr_aib_from_dev(dev);
1294
1295 if (!aib || !aib->slsw.v3)
1296 return -ENODATA;
1297 return sprintf(buf, "%i\n", aib->edf3.c);
1298}
1299
1300static SYSDEV_ATTR(coupled, 0400, etr_coupled_show, NULL);
1301
1302static ssize_t etr_local_time_show(struct sys_device *dev, char *buf)
1303{
1304 struct etr_aib *aib = etr_aib_from_dev(dev);
1305
1306 if (!aib || !aib->slsw.v3)
1307 return -ENODATA;
1308 return sprintf(buf, "%i\n", aib->edf3.blto);
1309}
1310
1311static SYSDEV_ATTR(local_time, 0400, etr_local_time_show, NULL);
1312
1313static ssize_t etr_utc_offset_show(struct sys_device *dev, char *buf)
1314{
1315 struct etr_aib *aib = etr_aib_from_dev(dev);
1316
1317 if (!aib || !aib->slsw.v3)
1318 return -ENODATA;
1319 return sprintf(buf, "%i\n", aib->edf3.buo);
1320}
1321
1322static SYSDEV_ATTR(utc_offset, 0400, etr_utc_offset_show, NULL);
1323
1324static struct sysdev_attribute *etr_port_attributes[] = {
1325 &attr_online,
1326 &attr_stepping_control,
1327 &attr_state_code,
1328 &attr_untuned,
1329 &attr_network,
1330 &attr_id,
1331 &attr_port,
1332 &attr_coupled,
1333 &attr_local_time,
1334 &attr_utc_offset,
1335 NULL
1336};
1337
1338static int __init etr_register_port(struct sys_device *dev)
1339{
1340 struct sysdev_attribute **attr;
1341 int rc;
1342
1343 rc = sysdev_register(dev);
1344 if (rc)
1345 goto out;
1346 for (attr = etr_port_attributes; *attr; attr++) {
1347 rc = sysdev_create_file(dev, *attr);
1348 if (rc)
1349 goto out_unreg;
1350 }
1351 return 0;
1352out_unreg:
1353 for (; attr >= etr_port_attributes; attr--)
1354 sysdev_remove_file(dev, *attr);
1355 sysdev_unregister(dev);
1356out:
1357 return rc;
1358}
1359
1360static void __init etr_unregister_port(struct sys_device *dev)
1361{
1362 struct sysdev_attribute **attr;
1363
1364 for (attr = etr_port_attributes; *attr; attr++)
1365 sysdev_remove_file(dev, *attr);
1366 sysdev_unregister(dev);
1367}
1368
1369static int __init etr_init_sysfs(void)
1370{
1371 int rc;
1372
1373 rc = sysdev_class_register(&etr_sysclass);
1374 if (rc)
1375 goto out;
1376 rc = sysdev_class_create_file(&etr_sysclass, &attr_stepping_port);
1377 if (rc)
1378 goto out_unreg_class;
1379 rc = sysdev_class_create_file(&etr_sysclass, &attr_stepping_mode);
1380 if (rc)
1381 goto out_remove_stepping_port;
1382 rc = etr_register_port(&etr_port0_dev);
1383 if (rc)
1384 goto out_remove_stepping_mode;
1385 rc = etr_register_port(&etr_port1_dev);
1386 if (rc)
1387 goto out_remove_port0;
1388 return 0;
1389
1390out_remove_port0:
1391 etr_unregister_port(&etr_port0_dev);
1392out_remove_stepping_mode:
1393 sysdev_class_remove_file(&etr_sysclass, &attr_stepping_mode);
1394out_remove_stepping_port:
1395 sysdev_class_remove_file(&etr_sysclass, &attr_stepping_port);
1396out_unreg_class:
1397 sysdev_class_unregister(&etr_sysclass);
1398out:
1399 return rc;
348} 1400}
349 1401
1402device_initcall(etr_init_sysfs);
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 3cbb0dcf1f1d..f0e5a320e2ec 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -283,7 +283,7 @@ char *task_show_regs(struct task_struct *task, char *buffer)
283 return buffer; 283 return buffer;
284} 284}
285 285
286DEFINE_SPINLOCK(die_lock); 286static DEFINE_SPINLOCK(die_lock);
287 287
288void die(const char * str, struct pt_regs * regs, long err) 288void die(const char * str, struct pt_regs * regs, long err)
289{ 289{
@@ -364,8 +364,7 @@ void __kprobes do_single_step(struct pt_regs *regs)
364 force_sig(SIGTRAP, current); 364 force_sig(SIGTRAP, current);
365} 365}
366 366
367asmlinkage void 367static void default_trap_handler(struct pt_regs * regs, long interruption_code)
368default_trap_handler(struct pt_regs * regs, long interruption_code)
369{ 368{
370 if (regs->psw.mask & PSW_MASK_PSTATE) { 369 if (regs->psw.mask & PSW_MASK_PSTATE) {
371 local_irq_enable(); 370 local_irq_enable();
@@ -376,7 +375,7 @@ default_trap_handler(struct pt_regs * regs, long interruption_code)
376} 375}
377 376
378#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \ 377#define DO_ERROR_INFO(signr, str, name, sicode, siaddr) \
379asmlinkage void name(struct pt_regs * regs, long interruption_code) \ 378static void name(struct pt_regs * regs, long interruption_code) \
380{ \ 379{ \
381 siginfo_t info; \ 380 siginfo_t info; \
382 info.si_signo = signr; \ 381 info.si_signo = signr; \
@@ -442,7 +441,7 @@ do_fp_trap(struct pt_regs *regs, void __user *location,
442 "floating point exception", regs, &si); 441 "floating point exception", regs, &si);
443} 442}
444 443
445asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code) 444static void illegal_op(struct pt_regs * regs, long interruption_code)
446{ 445{
447 siginfo_t info; 446 siginfo_t info;
448 __u8 opcode[6]; 447 __u8 opcode[6];
@@ -491,8 +490,15 @@ asmlinkage void illegal_op(struct pt_regs * regs, long interruption_code)
491#endif 490#endif
492 } else 491 } else
493 signal = SIGILL; 492 signal = SIGILL;
494 } else 493 } else {
495 signal = SIGILL; 494 /*
495 * If we get an illegal op in kernel mode, send it through the
496 * kprobes notifier. If kprobes doesn't pick it up, SIGILL
497 */
498 if (notify_die(DIE_BPT, "bpt", regs, interruption_code,
499 3, SIGTRAP) != NOTIFY_STOP)
500 signal = SIGILL;
501 }
496 502
497#ifdef CONFIG_MATHEMU 503#ifdef CONFIG_MATHEMU
498 if (signal == SIGFPE) 504 if (signal == SIGFPE)
@@ -585,7 +591,7 @@ DO_ERROR_INFO(SIGILL, "specification exception", specification_exception,
585 ILL_ILLOPN, get_check_address(regs)); 591 ILL_ILLOPN, get_check_address(regs));
586#endif 592#endif
587 593
588asmlinkage void data_exception(struct pt_regs * regs, long interruption_code) 594static void data_exception(struct pt_regs * regs, long interruption_code)
589{ 595{
590 __u16 __user *location; 596 __u16 __user *location;
591 int signal = 0; 597 int signal = 0;
@@ -675,7 +681,7 @@ asmlinkage void data_exception(struct pt_regs * regs, long interruption_code)
675 } 681 }
676} 682}
677 683
678asmlinkage void space_switch_exception(struct pt_regs * regs, long int_code) 684static void space_switch_exception(struct pt_regs * regs, long int_code)
679{ 685{
680 siginfo_t info; 686 siginfo_t info;
681 687
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index fe0f2e97ba7b..a48907392522 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -31,18 +31,19 @@ SECTIONS
31 31
32 _etext = .; /* End of text section */ 32 _etext = .; /* End of text section */
33 33
34 . = ALIGN(16); /* Exception table */
35 __start___ex_table = .;
36 __ex_table : { *(__ex_table) }
37 __stop___ex_table = .;
38
39 RODATA 34 RODATA
40 35
41#ifdef CONFIG_SHARED_KERNEL 36#ifdef CONFIG_SHARED_KERNEL
42 . = ALIGN(1048576); /* VM shared segments are 1MB aligned */ 37 . = ALIGN(1048576); /* VM shared segments are 1MB aligned */
38#endif
43 39
40 . = ALIGN(4096);
44 _eshared = .; /* End of shareable data */ 41 _eshared = .; /* End of shareable data */
45#endif 42
43 . = ALIGN(16); /* Exception table */
44 __start___ex_table = .;
45 __ex_table : { *(__ex_table) }
46 __stop___ex_table = .;
46 47
47 .data : { /* Data */ 48 .data : { /* Data */
48 *(.data) 49 *(.data)
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index 21baaf5496d6..9d5b02801b46 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -25,7 +25,7 @@
25#include <asm/irq_regs.h> 25#include <asm/irq_regs.h>
26 26
27static ext_int_info_t ext_int_info_timer; 27static ext_int_info_t ext_int_info_timer;
28DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); 28static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
29 29
30#ifdef CONFIG_VIRT_CPU_ACCOUNTING 30#ifdef CONFIG_VIRT_CPU_ACCOUNTING
31/* 31/*
@@ -524,16 +524,15 @@ EXPORT_SYMBOL(del_virt_timer);
524void init_cpu_vtimer(void) 524void init_cpu_vtimer(void)
525{ 525{
526 struct vtimer_queue *vt_list; 526 struct vtimer_queue *vt_list;
527 unsigned long cr0;
528 527
529 /* kick the virtual timer */ 528 /* kick the virtual timer */
530 S390_lowcore.exit_timer = VTIMER_MAX_SLICE; 529 S390_lowcore.exit_timer = VTIMER_MAX_SLICE;
531 S390_lowcore.last_update_timer = VTIMER_MAX_SLICE; 530 S390_lowcore.last_update_timer = VTIMER_MAX_SLICE;
532 asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer)); 531 asm volatile ("SPT %0" : : "m" (S390_lowcore.last_update_timer));
533 asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock)); 532 asm volatile ("STCK %0" : "=m" (S390_lowcore.last_update_clock));
534 __ctl_store(cr0, 0, 0); 533
535 cr0 |= 0x400; 534 /* enable cpu timer interrupts */
536 __ctl_load(cr0, 0, 0); 535 __ctl_set_bit(0,10);
537 536
538 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id()); 537 vt_list = &per_cpu(virt_cpu_timer, smp_processor_id());
539 INIT_LIST_HEAD(&vt_list->list); 538 INIT_LIST_HEAD(&vt_list->list);
@@ -572,6 +571,7 @@ void __init vtime_init(void)
572 if (register_idle_notifier(&vtimer_idle_nb)) 571 if (register_idle_notifier(&vtimer_idle_nb))
573 panic("Couldn't register idle notifier"); 572 panic("Couldn't register idle notifier");
574 573
574 /* Enable cpu timer interrupts on the boot cpu. */
575 init_cpu_vtimer(); 575 init_cpu_vtimer();
576} 576}
577 577