aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/Makefile3
-rw-r--r--arch/s390/kernel/asm-offsets.c8
-rw-r--r--arch/s390/kernel/base.S16
-rw-r--r--arch/s390/kernel/compat_linux.c3
-rw-r--r--arch/s390/kernel/compat_signal.c12
-rw-r--r--arch/s390/kernel/debug.c8
-rw-r--r--arch/s390/kernel/dis.c9
-rw-r--r--arch/s390/kernel/early.c20
-rw-r--r--arch/s390/kernel/entry.S1103
-rw-r--r--arch/s390/kernel/entry.h10
-rw-r--r--arch/s390/kernel/entry64.S976
-rw-r--r--arch/s390/kernel/head.S4
-rw-r--r--arch/s390/kernel/machine_kexec.c1
-rw-r--r--arch/s390/kernel/mem_detect.c122
-rw-r--r--arch/s390/kernel/nmi.c2
-rw-r--r--arch/s390/kernel/reipl64.S4
-rw-r--r--arch/s390/kernel/setup.c69
-rw-r--r--arch/s390/kernel/signal.c20
-rw-r--r--arch/s390/kernel/smp.c229
-rw-r--r--arch/s390/kernel/sys_s390.c76
-rw-r--r--arch/s390/kernel/time.c260
-rw-r--r--arch/s390/kernel/topology.c281
-rw-r--r--arch/s390/kernel/traps.c170
23 files changed, 1597 insertions, 1809 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index dd4f07640919..7d9ec924e7e7 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -32,7 +32,8 @@ extra-y += head.o init_task.o vmlinux.lds
32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o) 32extra-y += $(if $(CONFIG_64BIT),head64.o,head31.o)
33 33
34obj-$(CONFIG_MODULES) += s390_ksyms.o module.o 34obj-$(CONFIG_MODULES) += s390_ksyms.o module.o
35obj-$(CONFIG_SMP) += smp.o topology.o 35obj-$(CONFIG_SMP) += smp.o
36obj-$(CONFIG_SCHED_BOOK) += topology.o
36obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \ 37obj-$(CONFIG_SMP) += $(if $(CONFIG_64BIT),switch_cpu64.o, \
37 switch_cpu.o) 38 switch_cpu.o)
38obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o 39obj-$(CONFIG_HIBERNATION) += suspend.o swsusp_asm64.o
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c
index 751318765e2e..6e6a72e66d60 100644
--- a/arch/s390/kernel/asm-offsets.c
+++ b/arch/s390/kernel/asm-offsets.c
@@ -45,7 +45,8 @@ int main(void)
45 DEFINE(__PT_PSW, offsetof(struct pt_regs, psw)); 45 DEFINE(__PT_PSW, offsetof(struct pt_regs, psw));
46 DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs)); 46 DEFINE(__PT_GPRS, offsetof(struct pt_regs, gprs));
47 DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2)); 47 DEFINE(__PT_ORIG_GPR2, offsetof(struct pt_regs, orig_gpr2));
48 DEFINE(__PT_SVC_CODE, offsetof(struct pt_regs, svc_code)); 48 DEFINE(__PT_INT_CODE, offsetof(struct pt_regs, int_code));
49 DEFINE(__PT_INT_PARM_LONG, offsetof(struct pt_regs, int_parm_long));
49 DEFINE(__PT_SIZE, sizeof(struct pt_regs)); 50 DEFINE(__PT_SIZE, sizeof(struct pt_regs));
50 BLANK(); 51 BLANK();
51 DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain)); 52 DEFINE(__SF_BACKCHAIN, offsetof(struct stack_frame, back_chain));
@@ -108,7 +109,9 @@ int main(void)
108 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw)); 109 DEFINE(__LC_PGM_NEW_PSW, offsetof(struct _lowcore, program_new_psw));
109 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw)); 110 DEFINE(__LC_MCK_NEW_PSW, offsetof(struct _lowcore, mcck_new_psw));
110 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw)); 111 DEFINE(__LC_IO_NEW_PSW, offsetof(struct _lowcore, io_new_psw));
111 DEFINE(__LC_SAVE_AREA, offsetof(struct _lowcore, save_area)); 112 DEFINE(__LC_SAVE_AREA_SYNC, offsetof(struct _lowcore, save_area_sync));
113 DEFINE(__LC_SAVE_AREA_ASYNC, offsetof(struct _lowcore, save_area_async));
114 DEFINE(__LC_SAVE_AREA_RESTART, offsetof(struct _lowcore, save_area_restart));
112 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw)); 115 DEFINE(__LC_RETURN_PSW, offsetof(struct _lowcore, return_psw));
113 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw)); 116 DEFINE(__LC_RETURN_MCCK_PSW, offsetof(struct _lowcore, return_mcck_psw));
114 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer)); 117 DEFINE(__LC_SYNC_ENTER_TIMER, offsetof(struct _lowcore, sync_enter_timer));
@@ -150,7 +153,6 @@ int main(void)
150 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr)); 153 DEFINE(__LC_LAST_BREAK, offsetof(struct _lowcore, breaking_event_addr));
151 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data)); 154 DEFINE(__LC_VDSO_PER_CPU, offsetof(struct _lowcore, vdso_per_cpu_data));
152 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap)); 155 DEFINE(__LC_GMAP, offsetof(struct _lowcore, gmap));
153 DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp));
154 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce)); 156 DEFINE(__GMAP_ASCE, offsetof(struct gmap, asce));
155#endif /* CONFIG_32BIT */ 157#endif /* CONFIG_32BIT */
156 return 0; 158 return 0;
diff --git a/arch/s390/kernel/base.S b/arch/s390/kernel/base.S
index f8828d38fa6e..3aa4d00aaf50 100644
--- a/arch/s390/kernel/base.S
+++ b/arch/s390/kernel/base.S
@@ -33,7 +33,7 @@ s390_base_mcck_handler_fn:
33 .previous 33 .previous
34 34
35ENTRY(s390_base_ext_handler) 35ENTRY(s390_base_ext_handler)
36 stmg %r0,%r15,__LC_SAVE_AREA 36 stmg %r0,%r15,__LC_SAVE_AREA_ASYNC
37 basr %r13,0 37 basr %r13,0
380: aghi %r15,-STACK_FRAME_OVERHEAD 380: aghi %r15,-STACK_FRAME_OVERHEAD
39 larl %r1,s390_base_ext_handler_fn 39 larl %r1,s390_base_ext_handler_fn
@@ -41,7 +41,7 @@ ENTRY(s390_base_ext_handler)
41 ltgr %r1,%r1 41 ltgr %r1,%r1
42 jz 1f 42 jz 1f
43 basr %r14,%r1 43 basr %r14,%r1
441: lmg %r0,%r15,__LC_SAVE_AREA 441: lmg %r0,%r15,__LC_SAVE_AREA_ASYNC
45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 45 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
46 lpswe __LC_EXT_OLD_PSW 46 lpswe __LC_EXT_OLD_PSW
47 47
@@ -53,7 +53,7 @@ s390_base_ext_handler_fn:
53 .previous 53 .previous
54 54
55ENTRY(s390_base_pgm_handler) 55ENTRY(s390_base_pgm_handler)
56 stmg %r0,%r15,__LC_SAVE_AREA 56 stmg %r0,%r15,__LC_SAVE_AREA_SYNC
57 basr %r13,0 57 basr %r13,0
580: aghi %r15,-STACK_FRAME_OVERHEAD 580: aghi %r15,-STACK_FRAME_OVERHEAD
59 larl %r1,s390_base_pgm_handler_fn 59 larl %r1,s390_base_pgm_handler_fn
@@ -61,7 +61,7 @@ ENTRY(s390_base_pgm_handler)
61 ltgr %r1,%r1 61 ltgr %r1,%r1
62 jz 1f 62 jz 1f
63 basr %r14,%r1 63 basr %r14,%r1
64 lmg %r0,%r15,__LC_SAVE_AREA 64 lmg %r0,%r15,__LC_SAVE_AREA_SYNC
65 lpswe __LC_PGM_OLD_PSW 65 lpswe __LC_PGM_OLD_PSW
661: lpswe disabled_wait_psw-0b(%r13) 661: lpswe disabled_wait_psw-0b(%r13)
67 67
@@ -142,7 +142,7 @@ s390_base_mcck_handler_fn:
142 .previous 142 .previous
143 143
144ENTRY(s390_base_ext_handler) 144ENTRY(s390_base_ext_handler)
145 stm %r0,%r15,__LC_SAVE_AREA 145 stm %r0,%r15,__LC_SAVE_AREA_ASYNC
146 basr %r13,0 146 basr %r13,0
1470: ahi %r15,-STACK_FRAME_OVERHEAD 1470: ahi %r15,-STACK_FRAME_OVERHEAD
148 l %r1,2f-0b(%r13) 148 l %r1,2f-0b(%r13)
@@ -150,7 +150,7 @@ ENTRY(s390_base_ext_handler)
150 ltr %r1,%r1 150 ltr %r1,%r1
151 jz 1f 151 jz 1f
152 basr %r14,%r1 152 basr %r14,%r1
1531: lm %r0,%r15,__LC_SAVE_AREA 1531: lm %r0,%r15,__LC_SAVE_AREA_ASYNC
154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit 154 ni __LC_EXT_OLD_PSW+1,0xfd # clear wait state bit
155 lpsw __LC_EXT_OLD_PSW 155 lpsw __LC_EXT_OLD_PSW
156 156
@@ -164,7 +164,7 @@ s390_base_ext_handler_fn:
164 .previous 164 .previous
165 165
166ENTRY(s390_base_pgm_handler) 166ENTRY(s390_base_pgm_handler)
167 stm %r0,%r15,__LC_SAVE_AREA 167 stm %r0,%r15,__LC_SAVE_AREA_SYNC
168 basr %r13,0 168 basr %r13,0
1690: ahi %r15,-STACK_FRAME_OVERHEAD 1690: ahi %r15,-STACK_FRAME_OVERHEAD
170 l %r1,2f-0b(%r13) 170 l %r1,2f-0b(%r13)
@@ -172,7 +172,7 @@ ENTRY(s390_base_pgm_handler)
172 ltr %r1,%r1 172 ltr %r1,%r1
173 jz 1f 173 jz 1f
174 basr %r14,%r1 174 basr %r14,%r1
175 lm %r0,%r15,__LC_SAVE_AREA 175 lm %r0,%r15,__LC_SAVE_AREA_SYNC
176 lpsw __LC_PGM_OLD_PSW 176 lpsw __LC_PGM_OLD_PSW
177 177
1781: lpsw disabled_wait_psw-0b(%r13) 1781: lpsw disabled_wait_psw-0b(%r13)
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c
index 84a982898448..ab64bdbab2ae 100644
--- a/arch/s390/kernel/compat_linux.c
+++ b/arch/s390/kernel/compat_linux.c
@@ -278,9 +278,6 @@ asmlinkage long sys32_ipc(u32 call, int first, int second, int third, u32 ptr)
278{ 278{
279 if (call >> 16) /* hack for backward compatibility */ 279 if (call >> 16) /* hack for backward compatibility */
280 return -EINVAL; 280 return -EINVAL;
281
282 call &= 0xffff;
283
284 switch (call) { 281 switch (call) {
285 case SEMTIMEDOP: 282 case SEMTIMEDOP:
286 return compat_sys_semtimedop(first, compat_ptr(ptr), 283 return compat_sys_semtimedop(first, compat_ptr(ptr),
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c
index 4f68c81d3ffa..6fe78c2f95d9 100644
--- a/arch/s390/kernel/compat_signal.c
+++ b/arch/s390/kernel/compat_signal.c
@@ -501,8 +501,12 @@ static int setup_frame32(int sig, struct k_sigaction *ka,
501 501
502 /* We forgot to include these in the sigcontext. 502 /* We forgot to include these in the sigcontext.
503 To avoid breaking binary compatibility, they are passed as args. */ 503 To avoid breaking binary compatibility, they are passed as args. */
504 regs->gprs[4] = current->thread.trap_no; 504 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
505 regs->gprs[5] = current->thread.prot_addr; 505 sig == SIGTRAP || sig == SIGFPE) {
506 /* set extra registers only for synchronous signals */
507 regs->gprs[4] = regs->int_code & 127;
508 regs->gprs[5] = regs->int_parm_long;
509 }
506 510
507 /* Place signal number on stack to allow backtrace from handler. */ 511 /* Place signal number on stack to allow backtrace from handler. */
508 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo)) 512 if (__put_user(regs->gprs[2], (int __force __user *) &frame->signo))
@@ -544,9 +548,9 @@ static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
544 /* Set up to return from userspace. If provided, use a stub 548 /* Set up to return from userspace. If provided, use a stub
545 already in userspace. */ 549 already in userspace. */
546 if (ka->sa.sa_flags & SA_RESTORER) { 550 if (ka->sa.sa_flags & SA_RESTORER) {
547 regs->gprs[14] = (__u64) ka->sa.sa_restorer; 551 regs->gprs[14] = (__u64) ka->sa.sa_restorer | PSW32_ADDR_AMODE;
548 } else { 552 } else {
549 regs->gprs[14] = (__u64) frame->retcode; 553 regs->gprs[14] = (__u64) frame->retcode | PSW32_ADDR_AMODE;
550 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, 554 err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
551 (u16 __force __user *)(frame->retcode)); 555 (u16 __force __user *)(frame->retcode));
552 } 556 }
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 5ad6bc078bfd..6848828b962e 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -74,7 +74,7 @@ static ssize_t debug_input(struct file *file, const char __user *user_buf,
74static int debug_open(struct inode *inode, struct file *file); 74static int debug_open(struct inode *inode, struct file *file);
75static int debug_close(struct inode *inode, struct file *file); 75static int debug_close(struct inode *inode, struct file *file);
76static debug_info_t *debug_info_create(const char *name, int pages_per_area, 76static debug_info_t *debug_info_create(const char *name, int pages_per_area,
77 int nr_areas, int buf_size, mode_t mode); 77 int nr_areas, int buf_size, umode_t mode);
78static void debug_info_get(debug_info_t *); 78static void debug_info_get(debug_info_t *);
79static void debug_info_put(debug_info_t *); 79static void debug_info_put(debug_info_t *);
80static int debug_prolog_level_fn(debug_info_t * id, 80static int debug_prolog_level_fn(debug_info_t * id,
@@ -330,7 +330,7 @@ debug_info_free(debug_info_t* db_info){
330 330
331static debug_info_t* 331static debug_info_t*
332debug_info_create(const char *name, int pages_per_area, int nr_areas, 332debug_info_create(const char *name, int pages_per_area, int nr_areas,
333 int buf_size, mode_t mode) 333 int buf_size, umode_t mode)
334{ 334{
335 debug_info_t* rc; 335 debug_info_t* rc;
336 336
@@ -688,7 +688,7 @@ debug_close(struct inode *inode, struct file *file)
688 */ 688 */
689 689
690debug_info_t *debug_register_mode(const char *name, int pages_per_area, 690debug_info_t *debug_register_mode(const char *name, int pages_per_area,
691 int nr_areas, int buf_size, mode_t mode, 691 int nr_areas, int buf_size, umode_t mode,
692 uid_t uid, gid_t gid) 692 uid_t uid, gid_t gid)
693{ 693{
694 debug_info_t *rc = NULL; 694 debug_info_t *rc = NULL;
@@ -1090,7 +1090,7 @@ debug_register_view(debug_info_t * id, struct debug_view *view)
1090 int rc = 0; 1090 int rc = 0;
1091 int i; 1091 int i;
1092 unsigned long flags; 1092 unsigned long flags;
1093 mode_t mode; 1093 umode_t mode;
1094 struct dentry *pde; 1094 struct dentry *pde;
1095 1095
1096 if (!id) 1096 if (!id)
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 45df6d456aa1..e2f847599c8e 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -1578,10 +1578,15 @@ void show_code(struct pt_regs *regs)
1578 ptr += sprintf(ptr, "%s Code:", mode); 1578 ptr += sprintf(ptr, "%s Code:", mode);
1579 hops = 0; 1579 hops = 0;
1580 while (start < end && hops < 8) { 1580 while (start < end && hops < 8) {
1581 *ptr++ = (start == 32) ? '>' : ' '; 1581 opsize = insn_length(code[start]);
1582 if (start + opsize == 32)
1583 *ptr++ = '#';
1584 else if (start == 32)
1585 *ptr++ = '>';
1586 else
1587 *ptr++ = ' ';
1582 addr = regs->psw.addr + start - 32; 1588 addr = regs->psw.addr + start - 32;
1583 ptr += sprintf(ptr, ONELONG, addr); 1589 ptr += sprintf(ptr, ONELONG, addr);
1584 opsize = insn_length(code[start]);
1585 if (start + opsize >= end) 1590 if (start + opsize >= end)
1586 break; 1591 break;
1587 for (i = 0; i < opsize; i++) 1592 for (i = 0; i < opsize; i++)
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index c9ffe0025197..52098d6dfaa7 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -434,18 +434,22 @@ static void __init append_to_cmdline(size_t (*ipl_data)(char *, size_t))
434 } 434 }
435} 435}
436 436
437static void __init setup_boot_command_line(void) 437static inline int has_ebcdic_char(const char *str)
438{ 438{
439 int i; 439 int i;
440 440
441 /* convert arch command line to ascii */ 441 for (i = 0; str[i]; i++)
442 for (i = 0; i < ARCH_COMMAND_LINE_SIZE; i++) 442 if (str[i] & 0x80)
443 if (COMMAND_LINE[i] & 0x80) 443 return 1;
444 break; 444 return 0;
445 if (i < ARCH_COMMAND_LINE_SIZE) 445}
446 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
447 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE-1] = 0;
448 446
447static void __init setup_boot_command_line(void)
448{
449 COMMAND_LINE[ARCH_COMMAND_LINE_SIZE - 1] = 0;
450 /* convert arch command line to ascii if necessary */
451 if (has_ebcdic_char(COMMAND_LINE))
452 EBCASC(COMMAND_LINE, ARCH_COMMAND_LINE_SIZE);
449 /* copy arch command line */ 453 /* copy arch command line */
450 strlcpy(boot_command_line, strstrip(COMMAND_LINE), 454 strlcpy(boot_command_line, strstrip(COMMAND_LINE),
451 ARCH_COMMAND_LINE_SIZE); 455 ARCH_COMMAND_LINE_SIZE);
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S
index b13157057e02..3705700ed374 100644
--- a/arch/s390/kernel/entry.S
+++ b/arch/s390/kernel/entry.S
@@ -19,32 +19,22 @@
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22/* 22__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 23__PT_R1 = __PT_GPRS + 4
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 8
25 */ 25__PT_R3 = __PT_GPRS + 12
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 16
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 20
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 24
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 28
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 4 30__PT_R8 = __PT_GPRS + 32
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 31__PT_R9 = __PT_GPRS + 36
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 12 32__PT_R10 = __PT_GPRS + 40
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 33__PT_R11 = __PT_GPRS + 44
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 20 34__PT_R12 = __PT_GPRS + 48
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 35__PT_R13 = __PT_GPRS + 524
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 28 36__PT_R14 = __PT_GPRS + 56
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 37__PT_R15 = __PT_GPRS + 60
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 36
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 44
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 52
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 60
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 38
49_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ 39_TIF_WORK_SVC = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \
50 _TIF_MCCK_PENDING | _TIF_PER_TRAP ) 40 _TIF_MCCK_PENDING | _TIF_PER_TRAP )
@@ -58,133 +48,91 @@ STACK_SIZE = 1 << STACK_SHIFT
58 48
59#define BASED(name) name-system_call(%r13) 49#define BASED(name) name-system_call(%r13)
60 50
61#ifdef CONFIG_TRACE_IRQFLAGS
62 .macro TRACE_IRQS_ON 51 .macro TRACE_IRQS_ON
52#ifdef CONFIG_TRACE_IRQFLAGS
63 basr %r2,%r0 53 basr %r2,%r0
64 l %r1,BASED(.Ltrace_irq_on_caller) 54 l %r1,BASED(.Lhardirqs_on)
65 basr %r14,%r1 55 basr %r14,%r1 # call trace_hardirqs_on_caller
56#endif
66 .endm 57 .endm
67 58
68 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
69 basr %r2,%r0 61 basr %r2,%r0
70 l %r1,BASED(.Ltrace_irq_off_caller) 62 l %r1,BASED(.Lhardirqs_off)
71 basr %r14,%r1 63 basr %r14,%r1 # call trace_hardirqs_off_caller
72 .endm
73#else
74#define TRACE_IRQS_ON
75#define TRACE_IRQS_OFF
76#endif 64#endif
65 .endm
77 66
78#ifdef CONFIG_LOCKDEP
79 .macro LOCKDEP_SYS_EXIT 67 .macro LOCKDEP_SYS_EXIT
80 tm SP_PSW+1(%r15),0x01 # returning to user ? 68#ifdef CONFIG_LOCKDEP
81 jz 0f 69 tm __PT_PSW+1(%r11),0x01 # returning to user ?
70 jz .+10
82 l %r1,BASED(.Llockdep_sys_exit) 71 l %r1,BASED(.Llockdep_sys_exit)
83 basr %r14,%r1 72 basr %r14,%r1 # call lockdep_sys_exit
840:
85 .endm
86#else
87#define LOCKDEP_SYS_EXIT
88#endif 73#endif
89
90/*
91 * Register usage in interrupt handlers:
92 * R9 - pointer to current task structure
93 * R13 - pointer to literal pool
94 * R14 - return register for function calls
95 * R15 - kernel stack pointer
96 */
97
98 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
99 lm %r10,%r11,\lc_from
100 sl %r10,\lc_to
101 sl %r11,\lc_to+4
102 bc 3,BASED(0f)
103 sl %r10,BASED(.Lc_1)
1040: al %r10,\lc_sum
105 al %r11,\lc_sum+4
106 bc 12,BASED(1f)
107 al %r10,BASED(.Lc_1)
1081: stm %r10,%r11,\lc_sum
109 .endm
110
111 .macro SAVE_ALL_SVC psworg,savearea
112 stm %r12,%r15,\savearea
113 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
114 l %r15,__LC_KERNEL_STACK # problem state -> load ksp
115 s %r15,BASED(.Lc_spsize) # make room for registers & psw
116 .endm
117
118 .macro SAVE_ALL_BASE savearea
119 stm %r12,%r15,\savearea
120 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13
121 .endm 74 .endm
122 75
123 .macro SAVE_ALL_PGM psworg,savearea 76 .macro CHECK_STACK stacksize,savearea
124 tm \psworg+1,0x01 # test problem state bit
125#ifdef CONFIG_CHECK_STACK 77#ifdef CONFIG_CHECK_STACK
126 bnz BASED(1f) 78 tml %r15,\stacksize - CONFIG_STACK_GUARD
127 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 79 la %r14,\savearea
128 bnz BASED(2f) 80 jz stack_overflow
129 la %r12,\psworg
130 b BASED(stack_overflow)
131#else
132 bz BASED(2f)
133#endif 81#endif
1341: l %r15,__LC_KERNEL_STACK # problem state -> load ksp
1352: s %r15,BASED(.Lc_spsize) # make room for registers & psw
136 .endm 82 .endm
137 83
138 .macro SAVE_ALL_ASYNC psworg,savearea 84 .macro SWITCH_ASYNC savearea,stack,shift
139 stm %r12,%r15,\savearea 85 tmh %r8,0x0001 # interrupting from user ?
140 l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 86 jnz 1f
141 la %r12,\psworg 87 lr %r14,%r9
142 tm \psworg+1,0x01 # test problem state bit 88 sl %r14,BASED(.Lcritical_start)
143 bnz BASED(1f) # from user -> load async stack 89 cl %r14,BASED(.Lcritical_length)
144 clc \psworg+4(4),BASED(.Lcritical_end) 90 jhe 0f
145 bhe BASED(0f) 91 la %r11,\savearea # inside critical section, do cleanup
146 clc \psworg+4(4),BASED(.Lcritical_start) 92 bras %r14,cleanup_critical
147 bl BASED(0f) 93 tmh %r8,0x0001 # retest problem state after cleanup
148 l %r14,BASED(.Lcleanup_critical) 94 jnz 1f
149 basr %r14,%r14 950: l %r14,\stack # are we already on the target stack?
150 tm 1(%r12),0x01 # retest problem state after cleanup
151 bnz BASED(1f)
1520: l %r14,__LC_ASYNC_STACK # are we already on the async stack ?
153 slr %r14,%r15 96 slr %r14,%r15
154 sra %r14,STACK_SHIFT 97 sra %r14,\shift
155#ifdef CONFIG_CHECK_STACK 98 jnz 1f
156 bnz BASED(1f) 99 CHECK_STACK 1<<\shift,\savearea
157 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 j 2f
158 bnz BASED(2f) 1011: l %r15,\stack # load target stack
159 b BASED(stack_overflow) 1022: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
160#else 103 la %r11,STACK_FRAME_OVERHEAD(%r15)
161 bz BASED(2f)
162#endif
1631: l %r15,__LC_ASYNC_STACK
1642: s %r15,BASED(.Lc_spsize) # make room for registers & psw
165 .endm 104 .endm
166 105
167 .macro CREATE_STACK_FRAME savearea 106 .macro ADD64 high,low,timer
168 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 107 al \high,\timer
169 st %r2,SP_ORIG_R2(%r15) # store original content of gpr 2 108 al \low,\timer+4
170 mvc SP_R12(16,%r15),\savearea # move %r12-%r15 to stack 109 brc 12,.+8
171 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 110 ahi \high,1
172 .endm 111 .endm
173 112
174 .macro RESTORE_ALL psworg,sync 113 .macro SUB64 high,low,timer
175 mvc \psworg(8),SP_PSW(%r15) # move user PSW to lowcore 114 sl \high,\timer
176 .if !\sync 115 sl \low,\timer+4
177 ni \psworg+1,0xfd # clear wait state bit 116 brc 3,.+8
178 .endif 117 ahi \high,-1
179 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 of user 118 .endm
180 stpt __LC_EXIT_TIMER 119
181 lpsw \psworg # back to caller 120 .macro UPDATE_VTIME high,low,enter_timer
121 lm \high,\low,__LC_EXIT_TIMER
122 SUB64 \high,\low,\enter_timer
123 ADD64 \high,\low,__LC_USER_TIMER
124 stm \high,\low,__LC_USER_TIMER
125 lm \high,\low,__LC_LAST_UPDATE_TIMER
126 SUB64 \high,\low,__LC_EXIT_TIMER
127 ADD64 \high,\low,__LC_SYSTEM_TIMER
128 stm \high,\low,__LC_SYSTEM_TIMER
129 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
182 .endm 130 .endm
183 131
184 .macro REENABLE_IRQS 132 .macro REENABLE_IRQS
185 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 133 st %r8,__LC_RETURN_PSW
186 ni __SF_EMPTY(%r15),0xbf 134 ni __LC_RETURN_PSW,0xbf
187 ssm __SF_EMPTY(%r15) 135 ssm __LC_RETURN_PSW
188 .endm 136 .endm
189 137
190 .section .kprobes.text, "ax" 138 .section .kprobes.text, "ax"
@@ -197,14 +145,13 @@ STACK_SIZE = 1 << STACK_SHIFT
197 * gpr2 = prev 145 * gpr2 = prev
198 */ 146 */
199ENTRY(__switch_to) 147ENTRY(__switch_to)
200 basr %r1,0 148 l %r4,__THREAD_info(%r2) # get thread_info of prev
2010: l %r4,__THREAD_info(%r2) # get thread_info of prev
202 l %r5,__THREAD_info(%r3) # get thread_info of next 149 l %r5,__THREAD_info(%r3) # get thread_info of next
203 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending? 150 tm __TI_flags+3(%r4),_TIF_MCCK_PENDING # machine check pending?
204 bz 1f-0b(%r1) 151 jz 0f
205 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev 152 ni __TI_flags+3(%r4),255-_TIF_MCCK_PENDING # clear flag in prev
206 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next 153 oi __TI_flags+3(%r5),_TIF_MCCK_PENDING # set it in next
2071: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task 1540: stm %r6,%r15,__SF_GPRS(%r15) # store gprs of prev task
208 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev 155 st %r15,__THREAD_ksp(%r2) # store kernel stack of prev
209 l %r15,__THREAD_ksp(%r3) # load kernel stack of next 156 l %r15,__THREAD_ksp(%r3) # load kernel stack of next
210 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4 157 lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
@@ -224,48 +171,55 @@ __critical_start:
224 171
225ENTRY(system_call) 172ENTRY(system_call)
226 stpt __LC_SYNC_ENTER_TIMER 173 stpt __LC_SYNC_ENTER_TIMER
227sysc_saveall: 174sysc_stm:
228 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 175 stm %r8,%r15,__LC_SAVE_AREA_SYNC
229 CREATE_STACK_FRAME __LC_SAVE_AREA 176 l %r12,__LC_THREAD_INFO
230 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 177 l %r13,__LC_SVC_NEW_PSW+4
231 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 178sysc_per:
232 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 179 l %r15,__LC_KERNEL_STACK
233 oi __TI_flags+3(%r12),_TIF_SYSCALL 180 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
181 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
234sysc_vtime: 182sysc_vtime:
235 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 183 UPDATE_VTIME %r8,%r9,__LC_SYNC_ENTER_TIMER
236sysc_stime: 184 stm %r0,%r7,__PT_R0(%r11)
237 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 185 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
238sysc_update: 186 mvc __PT_PSW(8,%r11),__LC_SVC_OLD_PSW
239 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 187 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
240sysc_do_svc: 188sysc_do_svc:
241 xr %r7,%r7 189 oi __TI_flags+3(%r12),_TIF_SYSCALL
242 icm %r7,3,SP_SVC_CODE+2(%r15)# load svc number and test for svc 0 190 lh %r8,__PT_INT_CODE+2(%r11)
243 bnz BASED(sysc_nr_ok) # svc number > 0 191 sla %r8,2 # shift and test for svc0
192 jnz sysc_nr_ok
244 # svc 0: system call number in %r1 193 # svc 0: system call number in %r1
245 cl %r1,BASED(.Lnr_syscalls) 194 cl %r1,BASED(.Lnr_syscalls)
246 bnl BASED(sysc_nr_ok) 195 jnl sysc_nr_ok
247 sth %r1,SP_SVC_CODE+2(%r15) 196 sth %r1,__PT_INT_CODE+2(%r11)
248 lr %r7,%r1 # copy svc number to %r7 197 lr %r8,%r1
198 sla %r8,2
249sysc_nr_ok: 199sysc_nr_ok:
250 sll %r7,2 # svc number *4 200 l %r10,BASED(.Lsys_call_table) # 31 bit system call table
251 l %r10,BASED(.Lsysc_table) 201 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
202 st %r2,__PT_ORIG_GPR2(%r11)
203 st %r7,STACK_FRAME_OVERHEAD(%r15)
204 l %r9,0(%r8,%r10) # get system call addr.
252 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 205 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
253 mvc SP_ARGS(4,%r15),SP_R7(%r15) 206 jnz sysc_tracesys
254 l %r8,0(%r7,%r10) # get system call addr. 207 basr %r14,%r9 # call sys_xxxx
255 bnz BASED(sysc_tracesys) 208 st %r2,__PT_R2(%r11) # store return value
256 basr %r14,%r8 # call sys_xxxx
257 st %r2,SP_R2(%r15) # store return value (change R2 on stack)
258 209
259sysc_return: 210sysc_return:
260 LOCKDEP_SYS_EXIT 211 LOCKDEP_SYS_EXIT
261sysc_tif: 212sysc_tif:
262 tm SP_PSW+1(%r15),0x01 # returning to user ? 213 tm __PT_PSW+1(%r11),0x01 # returning to user ?
263 bno BASED(sysc_restore) 214 jno sysc_restore
264 tm __TI_flags+3(%r12),_TIF_WORK_SVC 215 tm __TI_flags+3(%r12),_TIF_WORK_SVC
265 bnz BASED(sysc_work) # there is work to do (signals etc.) 216 jnz sysc_work # check for work
266 ni __TI_flags+3(%r12),255-_TIF_SYSCALL 217 ni __TI_flags+3(%r12),255-_TIF_SYSCALL
267sysc_restore: 218sysc_restore:
268 RESTORE_ALL __LC_RETURN_PSW,1 219 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
220 stpt __LC_EXIT_TIMER
221 lm %r0,%r15,__PT_R0(%r11)
222 lpsw __LC_RETURN_PSW
269sysc_done: 223sysc_done:
270 224
271# 225#
@@ -273,16 +227,16 @@ sysc_done:
273# 227#
274sysc_work: 228sysc_work:
275 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 229 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
276 bo BASED(sysc_mcck_pending) 230 jo sysc_mcck_pending
277 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 231 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
278 bo BASED(sysc_reschedule) 232 jo sysc_reschedule
279 tm __TI_flags+3(%r12),_TIF_SIGPENDING 233 tm __TI_flags+3(%r12),_TIF_SIGPENDING
280 bo BASED(sysc_sigpending) 234 jo sysc_sigpending
281 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 235 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
282 bo BASED(sysc_notify_resume) 236 jo sysc_notify_resume
283 tm __TI_flags+3(%r12),_TIF_PER_TRAP 237 tm __TI_flags+3(%r12),_TIF_PER_TRAP
284 bo BASED(sysc_singlestep) 238 jo sysc_singlestep
285 b BASED(sysc_return) # beware of critical section cleanup 239 j sysc_return # beware of critical section cleanup
286 240
287# 241#
288# _TIF_NEED_RESCHED is set, call schedule 242# _TIF_NEED_RESCHED is set, call schedule
@@ -290,13 +244,13 @@ sysc_work:
290sysc_reschedule: 244sysc_reschedule:
291 l %r1,BASED(.Lschedule) 245 l %r1,BASED(.Lschedule)
292 la %r14,BASED(sysc_return) 246 la %r14,BASED(sysc_return)
293 br %r1 # call scheduler 247 br %r1 # call schedule
294 248
295# 249#
296# _TIF_MCCK_PENDING is set, call handler 250# _TIF_MCCK_PENDING is set, call handler
297# 251#
298sysc_mcck_pending: 252sysc_mcck_pending:
299 l %r1,BASED(.Ls390_handle_mcck) 253 l %r1,BASED(.Lhandle_mcck)
300 la %r14,BASED(sysc_return) 254 la %r14,BASED(sysc_return)
301 br %r1 # TIF bit will be cleared by handler 255 br %r1 # TIF bit will be cleared by handler
302 256
@@ -305,23 +259,24 @@ sysc_mcck_pending:
305# 259#
306sysc_sigpending: 260sysc_sigpending:
307 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 261 ni __TI_flags+3(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
308 la %r2,SP_PTREGS(%r15) # load pt_regs 262 lr %r2,%r11 # pass pointer to pt_regs
309 l %r1,BASED(.Ldo_signal) 263 l %r1,BASED(.Ldo_signal)
310 basr %r14,%r1 # call do_signal 264 basr %r14,%r1 # call do_signal
311 tm __TI_flags+3(%r12),_TIF_SYSCALL 265 tm __TI_flags+3(%r12),_TIF_SYSCALL
312 bno BASED(sysc_return) 266 jno sysc_return
313 lm %r2,%r6,SP_R2(%r15) # load svc arguments 267 lm %r2,%r7,__PT_R2(%r11) # load svc arguments
314 xr %r7,%r7 # svc 0 returns -ENOSYS 268 xr %r8,%r8 # svc 0 returns -ENOSYS
315 clc SP_SVC_CODE+2(2,%r15),BASED(.Lnr_syscalls+2) 269 clc __PT_INT_CODE+2(2,%r11),BASED(.Lnr_syscalls+2)
316 bnl BASED(sysc_nr_ok) # invalid svc number -> do svc 0 270 jnl sysc_nr_ok # invalid svc number -> do svc 0
317 icm %r7,3,SP_SVC_CODE+2(%r15)# load new svc number 271 lh %r8,__PT_INT_CODE+2(%r11) # load new svc number
318 b BASED(sysc_nr_ok) # restart svc 272 sla %r8,2
273 j sysc_nr_ok # restart svc
319 274
320# 275#
321# _TIF_NOTIFY_RESUME is set, call do_notify_resume 276# _TIF_NOTIFY_RESUME is set, call do_notify_resume
322# 277#
323sysc_notify_resume: 278sysc_notify_resume:
324 la %r2,SP_PTREGS(%r15) # load pt_regs 279 lr %r2,%r11 # pass pointer to pt_regs
325 l %r1,BASED(.Ldo_notify_resume) 280 l %r1,BASED(.Ldo_notify_resume)
326 la %r14,BASED(sysc_return) 281 la %r14,BASED(sysc_return)
327 br %r1 # call do_notify_resume 282 br %r1 # call do_notify_resume
@@ -331,56 +286,57 @@ sysc_notify_resume:
331# 286#
332sysc_singlestep: 287sysc_singlestep:
333 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 288 ni __TI_flags+3(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
334 la %r2,SP_PTREGS(%r15) # address of register-save area 289 lr %r2,%r11 # pass pointer to pt_regs
335 l %r1,BASED(.Lhandle_per) # load adr. of per handler 290 l %r1,BASED(.Ldo_per_trap)
336 la %r14,BASED(sysc_return) # load adr. of system return 291 la %r14,BASED(sysc_return)
337 br %r1 # branch to do_per_trap 292 br %r1 # call do_per_trap
338 293
339# 294#
340# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before 295# call tracehook_report_syscall_entry/tracehook_report_syscall_exit before
341# and after the system call 296# and after the system call
342# 297#
343sysc_tracesys: 298sysc_tracesys:
344 l %r1,BASED(.Ltrace_entry) 299 l %r1,BASED(.Ltrace_enter)
345 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lr %r2,%r11 # pass pointer to pt_regs
346 la %r3,0 301 la %r3,0
347 xr %r0,%r0 302 xr %r0,%r0
348 icm %r0,3,SP_SVC_CODE(%r15) 303 icm %r0,3,__PT_INT_CODE+2(%r11)
349 st %r0,SP_R2(%r15) 304 st %r0,__PT_R2(%r11)
350 basr %r14,%r1 305 basr %r14,%r1 # call do_syscall_trace_enter
351 cl %r2,BASED(.Lnr_syscalls) 306 cl %r2,BASED(.Lnr_syscalls)
352 bnl BASED(sysc_tracenogo) 307 jnl sysc_tracenogo
353 lr %r7,%r2 308 lr %r8,%r2
354 sll %r7,2 # svc number *4 309 sll %r8,2
355 l %r8,0(%r7,%r10) 310 l %r9,0(%r8,%r10)
356sysc_tracego: 311sysc_tracego:
357 lm %r3,%r6,SP_R3(%r15) 312 lm %r3,%r7,__PT_R3(%r11)
358 mvc SP_ARGS(4,%r15),SP_R7(%r15) 313 st %r7,STACK_FRAME_OVERHEAD(%r15)
359 l %r2,SP_ORIG_R2(%r15) 314 l %r2,__PT_ORIG_GPR2(%r11)
360 basr %r14,%r8 # call sys_xxx 315 basr %r14,%r9 # call sys_xxx
361 st %r2,SP_R2(%r15) # store return value 316 st %r2,__PT_R2(%r11) # store return value
362sysc_tracenogo: 317sysc_tracenogo:
363 tm __TI_flags+2(%r12),_TIF_TRACE >> 8 318 tm __TI_flags+2(%r12),_TIF_TRACE >> 8
364 bz BASED(sysc_return) 319 jz sysc_return
365 l %r1,BASED(.Ltrace_exit) 320 l %r1,BASED(.Ltrace_exit)
366 la %r2,SP_PTREGS(%r15) # load pt_regs 321 lr %r2,%r11 # pass pointer to pt_regs
367 la %r14,BASED(sysc_return) 322 la %r14,BASED(sysc_return)
368 br %r1 323 br %r1 # call do_syscall_trace_exit
369 324
370# 325#
371# a new process exits the kernel with ret_from_fork 326# a new process exits the kernel with ret_from_fork
372# 327#
373ENTRY(ret_from_fork) 328ENTRY(ret_from_fork)
329 la %r11,STACK_FRAME_OVERHEAD(%r15)
330 l %r12,__LC_THREAD_INFO
374 l %r13,__LC_SVC_NEW_PSW+4 331 l %r13,__LC_SVC_NEW_PSW+4
375 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 332 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
376 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 333 jo 0f
377 bo BASED(0f) 334 st %r15,__PT_R15(%r11) # store stack pointer for new kthread
378 st %r15,SP_R15(%r15) # store stack pointer for new kthread 3350: l %r1,BASED(.Lschedule_tail)
3790: l %r1,BASED(.Lschedtail) 336 basr %r14,%r1 # call schedule_tail
380 basr %r14,%r1
381 TRACE_IRQS_ON 337 TRACE_IRQS_ON
382 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 338 ssm __LC_SVC_NEW_PSW # reenable interrupts
383 b BASED(sysc_tracenogo) 339 j sysc_tracenogo
384 340
385# 341#
386# kernel_execve function needs to deal with pt_regs that is not 342# kernel_execve function needs to deal with pt_regs that is not
@@ -390,153 +346,98 @@ ENTRY(kernel_execve)
390 stm %r12,%r15,48(%r15) 346 stm %r12,%r15,48(%r15)
391 lr %r14,%r15 347 lr %r14,%r15
392 l %r13,__LC_SVC_NEW_PSW+4 348 l %r13,__LC_SVC_NEW_PSW+4
393 s %r15,BASED(.Lc_spsize) 349 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
394 st %r14,__SF_BACKCHAIN(%r15) 350 st %r14,__SF_BACKCHAIN(%r15)
395 la %r12,SP_PTREGS(%r15) 351 la %r12,STACK_FRAME_OVERHEAD(%r15)
396 xc 0(__PT_SIZE,%r12),0(%r12) 352 xc 0(__PT_SIZE,%r12),0(%r12)
397 l %r1,BASED(.Ldo_execve) 353 l %r1,BASED(.Ldo_execve)
398 lr %r5,%r12 354 lr %r5,%r12
399 basr %r14,%r1 355 basr %r14,%r1 # call do_execve
400 ltr %r2,%r2 356 ltr %r2,%r2
401 be BASED(0f) 357 je 0f
402 a %r15,BASED(.Lc_spsize) 358 ahi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
403 lm %r12,%r15,48(%r15) 359 lm %r12,%r15,48(%r15)
404 br %r14 360 br %r14
405 # execve succeeded. 361 # execve succeeded.
4060: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3620: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
407 l %r15,__LC_KERNEL_STACK # load ksp 363 l %r15,__LC_KERNEL_STACK # load ksp
408 s %r15,BASED(.Lc_spsize) # make room for registers & psw 364 ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
409 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 365 la %r11,STACK_FRAME_OVERHEAD(%r15)
366 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
410 l %r12,__LC_THREAD_INFO 367 l %r12,__LC_THREAD_INFO
411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) 368 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
412 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 369 ssm __LC_SVC_NEW_PSW # reenable interrupts
413 l %r1,BASED(.Lexecve_tail) 370 l %r1,BASED(.Lexecve_tail)
414 basr %r14,%r1 371 basr %r14,%r1 # call execve_tail
415 b BASED(sysc_return) 372 j sysc_return
416 373
417/* 374/*
418 * Program check handler routine 375 * Program check handler routine
419 */ 376 */
420 377
421ENTRY(pgm_check_handler) 378ENTRY(pgm_check_handler)
422/*
423 * First we need to check for a special case:
424 * Single stepping an instruction that disables the PER event mask will
425 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
426 * For a single stepped SVC the program check handler gets control after
427 * the SVC new PSW has been loaded. But we want to execute the SVC first and
428 * then handle the PER event. Therefore we update the SVC old PSW to point
429 * to the pgm_check_handler and branch to the SVC handler after we checked
430 * if we have to load the kernel stack register.
431 * For every other possible cause for PER event without the PER mask set
432 * we just ignore the PER event (FIXME: is there anything we have to do
433 * for LPSW?).
434 */
435 stpt __LC_SYNC_ENTER_TIMER 379 stpt __LC_SYNC_ENTER_TIMER
436 SAVE_ALL_BASE __LC_SAVE_AREA 380 stm %r8,%r15,__LC_SAVE_AREA_SYNC
437 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 381 l %r12,__LC_THREAD_INFO
438 bnz BASED(pgm_per) # got per exception -> special case 382 l %r13,__LC_SVC_NEW_PSW+4
439 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 383 lm %r8,%r9,__LC_PGM_OLD_PSW
440 CREATE_STACK_FRAME __LC_SAVE_AREA 384 tmh %r8,0x0001 # test problem state bit
441 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW 385 jnz 1f # -> fault in user space
442 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 386 tmh %r8,0x4000 # PER bit set in old PSW ?
443 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 387 jnz 0f # -> enabled, can't be a double fault
444 bz BASED(pgm_no_vtime) 388 tm __LC_PGM_ILC+3,0x80 # check for per exception
445 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 389 jnz pgm_svcper # -> single stepped svc
446 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 3900: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
447 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 391 j 2f
448pgm_no_vtime: 3921: UPDATE_VTIME %r14,%r15,__LC_SYNC_ENTER_TIMER
449 l %r3,__LC_PGM_ILC # load program interruption code 393 l %r15,__LC_KERNEL_STACK
450 l %r4,__LC_TRANS_EXC_CODE 3942: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
451 REENABLE_IRQS 395 la %r11,STACK_FRAME_OVERHEAD(%r15)
452 la %r8,0x7f 396 stm %r0,%r7,__PT_R0(%r11)
453 nr %r8,%r3 397 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_SYNC
454 sll %r8,2 398 stm %r8,%r9,__PT_PSW(%r11)
455 l %r1,BASED(.Ljump_table) 399 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
456 l %r1,0(%r8,%r1) # load address of handler routine 400 mvc __PT_INT_PARM_LONG(4,%r11),__LC_TRANS_EXC_CODE
457 la %r2,SP_PTREGS(%r15) # address of register-save area 401 tm __LC_PGM_ILC+3,0x80 # check for per exception
458 basr %r14,%r1 # branch to interrupt-handler 402 jz 0f
459pgm_exit:
460 b BASED(sysc_return)
461
462#
463# handle per exception
464#
465pgm_per:
466 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
467 bnz BASED(pgm_per_std) # ok, normal per event from user space
468# ok its one of the special cases, now we need to find out which one
469 clc __LC_PGM_OLD_PSW(8),__LC_SVC_NEW_PSW
470 be BASED(pgm_svcper)
471# no interesting special case, ignore PER event
472 lm %r12,%r15,__LC_SAVE_AREA
473 lpsw 0x28
474
475#
476# Normal per exception
477#
478pgm_per_std:
479 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
480 CREATE_STACK_FRAME __LC_SAVE_AREA
481 mvc SP_PSW(8,%r15),__LC_PGM_OLD_PSW
482 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
483 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
484 bz BASED(pgm_no_vtime2)
485 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
486 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
487 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
488pgm_no_vtime2:
489 l %r1,__TI_task(%r12) 403 l %r1,__TI_task(%r12)
490 tm SP_PSW+1(%r15),0x01 # kernel per event ? 404 tmh %r8,0x0001 # kernel per event ?
491 bz BASED(kernel_per) 405 jz pgm_kprobe
492 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 406 oi __TI_flags+3(%r12),_TIF_PER_TRAP
493 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS 407 mvc __THREAD_per_address(4,%r1),__LC_PER_ADDRESS
408 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
494 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 409 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
495 oi __TI_flags+3(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4100: REENABLE_IRQS
496 l %r3,__LC_PGM_ILC # load program interruption code 411 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
497 l %r4,__LC_TRANS_EXC_CODE
498 REENABLE_IRQS
499 la %r8,0x7f
500 nr %r8,%r3 # clear per-event-bit and ilc
501 be BASED(pgm_exit2) # only per or per+check ?
502 sll %r8,2
503 l %r1,BASED(.Ljump_table) 412 l %r1,BASED(.Ljump_table)
504 l %r1,0(%r8,%r1) # load address of handler routine 413 la %r10,0x7f
505 la %r2,SP_PTREGS(%r15) # address of register-save area 414 n %r10,__PT_INT_CODE(%r11)
415 je sysc_return
416 sll %r10,2
417 l %r1,0(%r10,%r1) # load address of handler routine
418 lr %r2,%r11 # pass pointer to pt_regs
506 basr %r14,%r1 # branch to interrupt-handler 419 basr %r14,%r1 # branch to interrupt-handler
507pgm_exit2: 420 j sysc_return
508 b BASED(sysc_return)
509 421
510# 422#
511# it was a single stepped SVC that is causing all the trouble 423# PER event in supervisor state, must be kprobes
512# 424#
513pgm_svcper: 425pgm_kprobe:
514 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 426 REENABLE_IRQS
515 CREATE_STACK_FRAME __LC_SAVE_AREA 427 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
516 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 428 l %r1,BASED(.Ldo_per_trap)
517 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 429 lr %r2,%r11 # pass pointer to pt_regs
518 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 430 basr %r14,%r1 # call do_per_trap
519 oi __TI_flags+3(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP) 431 j sysc_return
520 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
521 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
522 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
523 l %r8,__TI_task(%r12)
524 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
525 mvc __THREAD_per_address(4,%r8),__LC_PER_ADDRESS
526 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
527 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
528 lm %r2,%r6,SP_R2(%r15) # load svc arguments
529 b BASED(sysc_do_svc)
530 432
531# 433#
532# per was called from kernel, must be kprobes 434# single stepped system call
533# 435#
534kernel_per: 436pgm_svcper:
535 REENABLE_IRQS 437 oi __TI_flags+3(%r12),_TIF_PER_TRAP
536 la %r2,SP_PTREGS(%r15) # address of register-save area 438 mvc __LC_RETURN_PSW(4),__LC_SVC_NEW_PSW
537 l %r1,BASED(.Lhandle_per) # load adr. of per handler 439 mvc __LC_RETURN_PSW+4(4),BASED(.Lsysc_per)
538 basr %r14,%r1 # branch to do_single_step 440 lpsw __LC_RETURN_PSW # branch to sysc_per and enable irqs
539 b BASED(pgm_exit)
540 441
541/* 442/*
542 * IO interrupt handler routine 443 * IO interrupt handler routine
@@ -545,28 +446,35 @@ kernel_per:
545ENTRY(io_int_handler) 446ENTRY(io_int_handler)
546 stck __LC_INT_CLOCK 447 stck __LC_INT_CLOCK
547 stpt __LC_ASYNC_ENTER_TIMER 448 stpt __LC_ASYNC_ENTER_TIMER
548 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 449 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
549 CREATE_STACK_FRAME __LC_SAVE_AREA+16 450 l %r12,__LC_THREAD_INFO
550 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 451 l %r13,__LC_SVC_NEW_PSW+4
551 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 452 lm %r8,%r9,__LC_IO_OLD_PSW
552 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 453 tmh %r8,0x0001 # interrupting from user ?
553 bz BASED(io_no_vtime) 454 jz io_skip
554 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 455 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
555 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 456io_skip:
556 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 457 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
557io_no_vtime: 458 stm %r0,%r7,__PT_R0(%r11)
459 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
460 stm %r8,%r9,__PT_PSW(%r11)
558 TRACE_IRQS_OFF 461 TRACE_IRQS_OFF
559 l %r1,BASED(.Ldo_IRQ) # load address of do_IRQ 462 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
560 la %r2,SP_PTREGS(%r15) # address of register-save area 463 l %r1,BASED(.Ldo_IRQ)
561 basr %r14,%r1 # branch to standard irq handler 464 lr %r2,%r11 # pass pointer to pt_regs
465 basr %r14,%r1 # call do_IRQ
562io_return: 466io_return:
563 LOCKDEP_SYS_EXIT 467 LOCKDEP_SYS_EXIT
564 TRACE_IRQS_ON 468 TRACE_IRQS_ON
565io_tif: 469io_tif:
566 tm __TI_flags+3(%r12),_TIF_WORK_INT 470 tm __TI_flags+3(%r12),_TIF_WORK_INT
567 bnz BASED(io_work) # there is work to do (signals etc.) 471 jnz io_work # there is work to do (signals etc.)
568io_restore: 472io_restore:
569 RESTORE_ALL __LC_RETURN_PSW,0 473 mvc __LC_RETURN_PSW(8),__PT_PSW(%r11)
474 ni __LC_RETURN_PSW+1,0xfd # clean wait state bit
475 stpt __LC_EXIT_TIMER
476 lm %r0,%r15,__PT_R0(%r11)
477 lpsw __LC_RETURN_PSW
570io_done: 478io_done:
571 479
572# 480#
@@ -577,28 +485,29 @@ io_done:
577# Before any work can be done, a switch to the kernel stack is required. 485# Before any work can be done, a switch to the kernel stack is required.
578# 486#
579io_work: 487io_work:
580 tm SP_PSW+1(%r15),0x01 # returning to user ? 488 tm __PT_PSW+1(%r11),0x01 # returning to user ?
581 bo BASED(io_work_user) # yes -> do resched & signal 489 jo io_work_user # yes -> do resched & signal
582#ifdef CONFIG_PREEMPT 490#ifdef CONFIG_PREEMPT
583 # check for preemptive scheduling 491 # check for preemptive scheduling
584 icm %r0,15,__TI_precount(%r12) 492 icm %r0,15,__TI_precount(%r12)
585 bnz BASED(io_restore) # preemption disabled 493 jnz io_restore # preemption disabled
586 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 494 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
587 bno BASED(io_restore) 495 jno io_restore
588 # switch to kernel stack 496 # switch to kernel stack
589 l %r1,SP_R15(%r15) 497 l %r1,__PT_R15(%r11)
590 s %r1,BASED(.Lc_spsize) 498 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
591 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 499 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
592 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 500 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
501 la %r11,STACK_FRAME_OVERHEAD(%r1)
593 lr %r15,%r1 502 lr %r15,%r1
594 # TRACE_IRQS_ON already done at io_return, call 503 # TRACE_IRQS_ON already done at io_return, call
595 # TRACE_IRQS_OFF to keep things symmetrical 504 # TRACE_IRQS_OFF to keep things symmetrical
596 TRACE_IRQS_OFF 505 TRACE_IRQS_OFF
597 l %r1,BASED(.Lpreempt_schedule_irq) 506 l %r1,BASED(.Lpreempt_irq)
598 basr %r14,%r1 # call preempt_schedule_irq 507 basr %r14,%r1 # call preempt_schedule_irq
599 b BASED(io_return) 508 j io_return
600#else 509#else
601 b BASED(io_restore) 510 j io_restore
602#endif 511#endif
603 512
604# 513#
@@ -606,9 +515,10 @@ io_work:
606# 515#
607io_work_user: 516io_work_user:
608 l %r1,__LC_KERNEL_STACK 517 l %r1,__LC_KERNEL_STACK
609 s %r1,BASED(.Lc_spsize) 518 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
610 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 519 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
611 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 520 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
521 la %r11,STACK_FRAME_OVERHEAD(%r1)
612 lr %r15,%r1 522 lr %r15,%r1
613 523
614# 524#
@@ -618,24 +528,24 @@ io_work_user:
618# 528#
619io_work_tif: 529io_work_tif:
620 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 530 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
621 bo BASED(io_mcck_pending) 531 jo io_mcck_pending
622 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED 532 tm __TI_flags+3(%r12),_TIF_NEED_RESCHED
623 bo BASED(io_reschedule) 533 jo io_reschedule
624 tm __TI_flags+3(%r12),_TIF_SIGPENDING 534 tm __TI_flags+3(%r12),_TIF_SIGPENDING
625 bo BASED(io_sigpending) 535 jo io_sigpending
626 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME 536 tm __TI_flags+3(%r12),_TIF_NOTIFY_RESUME
627 bo BASED(io_notify_resume) 537 jo io_notify_resume
628 b BASED(io_return) # beware of critical section cleanup 538 j io_return # beware of critical section cleanup
629 539
630# 540#
631# _TIF_MCCK_PENDING is set, call handler 541# _TIF_MCCK_PENDING is set, call handler
632# 542#
633io_mcck_pending: 543io_mcck_pending:
634 # TRACE_IRQS_ON already done at io_return 544 # TRACE_IRQS_ON already done at io_return
635 l %r1,BASED(.Ls390_handle_mcck) 545 l %r1,BASED(.Lhandle_mcck)
636 basr %r14,%r1 # TIF bit will be cleared by handler 546 basr %r14,%r1 # TIF bit will be cleared by handler
637 TRACE_IRQS_OFF 547 TRACE_IRQS_OFF
638 b BASED(io_return) 548 j io_return
639 549
640# 550#
641# _TIF_NEED_RESCHED is set, call schedule 551# _TIF_NEED_RESCHED is set, call schedule
@@ -643,37 +553,37 @@ io_mcck_pending:
643io_reschedule: 553io_reschedule:
644 # TRACE_IRQS_ON already done at io_return 554 # TRACE_IRQS_ON already done at io_return
645 l %r1,BASED(.Lschedule) 555 l %r1,BASED(.Lschedule)
646 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 556 ssm __LC_SVC_NEW_PSW # reenable interrupts
647 basr %r14,%r1 # call scheduler 557 basr %r14,%r1 # call scheduler
648 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 558 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
649 TRACE_IRQS_OFF 559 TRACE_IRQS_OFF
650 b BASED(io_return) 560 j io_return
651 561
652# 562#
653# _TIF_SIGPENDING is set, call do_signal 563# _TIF_SIGPENDING is set, call do_signal
654# 564#
655io_sigpending: 565io_sigpending:
656 # TRACE_IRQS_ON already done at io_return 566 # TRACE_IRQS_ON already done at io_return
657 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
658 la %r2,SP_PTREGS(%r15) # load pt_regs
659 l %r1,BASED(.Ldo_signal) 567 l %r1,BASED(.Ldo_signal)
568 ssm __LC_SVC_NEW_PSW # reenable interrupts
569 lr %r2,%r11 # pass pointer to pt_regs
660 basr %r14,%r1 # call do_signal 570 basr %r14,%r1 # call do_signal
661 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 571 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
662 TRACE_IRQS_OFF 572 TRACE_IRQS_OFF
663 b BASED(io_return) 573 j io_return
664 574
665# 575#
666# _TIF_SIGPENDING is set, call do_signal 576# _TIF_SIGPENDING is set, call do_signal
667# 577#
668io_notify_resume: 578io_notify_resume:
669 # TRACE_IRQS_ON already done at io_return 579 # TRACE_IRQS_ON already done at io_return
670 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
671 la %r2,SP_PTREGS(%r15) # load pt_regs
672 l %r1,BASED(.Ldo_notify_resume) 580 l %r1,BASED(.Ldo_notify_resume)
673 basr %r14,%r1 # call do_signal 581 ssm __LC_SVC_NEW_PSW # reenable interrupts
674 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 582 lr %r2,%r11 # pass pointer to pt_regs
583 basr %r14,%r1 # call do_notify_resume
584 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
675 TRACE_IRQS_OFF 585 TRACE_IRQS_OFF
676 b BASED(io_return) 586 j io_return
677 587
678/* 588/*
679 * External interrupt handler routine 589 * External interrupt handler routine
@@ -682,23 +592,25 @@ io_notify_resume:
682ENTRY(ext_int_handler) 592ENTRY(ext_int_handler)
683 stck __LC_INT_CLOCK 593 stck __LC_INT_CLOCK
684 stpt __LC_ASYNC_ENTER_TIMER 594 stpt __LC_ASYNC_ENTER_TIMER
685 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 595 stm %r8,%r15,__LC_SAVE_AREA_ASYNC
686 CREATE_STACK_FRAME __LC_SAVE_AREA+16 596 l %r12,__LC_THREAD_INFO
687 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 597 l %r13,__LC_SVC_NEW_PSW+4
688 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct 598 lm %r8,%r9,__LC_EXT_OLD_PSW
689 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 599 tmh %r8,0x0001 # interrupting from user ?
690 bz BASED(ext_no_vtime) 600 jz ext_skip
691 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 601 UPDATE_VTIME %r14,%r15,__LC_ASYNC_ENTER_TIMER
692 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 602ext_skip:
693 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 603 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
694ext_no_vtime: 604 stm %r0,%r7,__PT_R0(%r11)
605 mvc __PT_R8(32,%r11),__LC_SAVE_AREA_ASYNC
606 stm %r8,%r9,__PT_PSW(%r11)
695 TRACE_IRQS_OFF 607 TRACE_IRQS_OFF
696 la %r2,SP_PTREGS(%r15) # address of register-save area 608 lr %r2,%r11 # pass pointer to pt_regs
697 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 609 l %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
698 l %r4,__LC_EXT_PARAMS # get external parameters 610 l %r4,__LC_EXT_PARAMS # get external parameters
699 l %r1,BASED(.Ldo_extint) 611 l %r1,BASED(.Ldo_extint)
700 basr %r14,%r1 612 basr %r14,%r1 # call do_extint
701 b BASED(io_return) 613 j io_return
702 614
703__critical_end: 615__critical_end:
704 616
@@ -710,82 +622,74 @@ ENTRY(mcck_int_handler)
710 stck __LC_MCCK_CLOCK 622 stck __LC_MCCK_CLOCK
711 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer 623 spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer
712 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs 624 lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs
713 SAVE_ALL_BASE __LC_SAVE_AREA+32 625 l %r12,__LC_THREAD_INFO
714 la %r12,__LC_MCK_OLD_PSW 626 l %r13,__LC_SVC_NEW_PSW+4
627 lm %r8,%r9,__LC_MCK_OLD_PSW
715 tm __LC_MCCK_CODE,0x80 # system damage? 628 tm __LC_MCCK_CODE,0x80 # system damage?
716 bo BASED(mcck_int_main) # yes -> rest of mcck code invalid 629 jo mcck_panic # yes -> rest of mcck code invalid
717 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA 630 la %r14,__LC_CPU_TIMER_SAVE_AREA
631 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
718 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 632 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
719 bo BASED(1f) 633 jo 3f
720 la %r14,__LC_SYNC_ENTER_TIMER 634 la %r14,__LC_SYNC_ENTER_TIMER
721 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 635 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
722 bl BASED(0f) 636 jl 0f
723 la %r14,__LC_ASYNC_ENTER_TIMER 637 la %r14,__LC_ASYNC_ENTER_TIMER
7240: clc 0(8,%r14),__LC_EXIT_TIMER 6380: clc 0(8,%r14),__LC_EXIT_TIMER
725 bl BASED(0f) 639 jl 1f
726 la %r14,__LC_EXIT_TIMER 640 la %r14,__LC_EXIT_TIMER
7270: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6411: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
728 bl BASED(0f) 642 jl 2f
729 la %r14,__LC_LAST_UPDATE_TIMER 643 la %r14,__LC_LAST_UPDATE_TIMER
7300: spt 0(%r14) 6442: spt 0(%r14)
731 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 645 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7321: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6463: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
733 bno BASED(mcck_int_main) # no -> skip cleanup critical 647 jno mcck_panic # no -> skip cleanup critical
734 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 648 tm %r8,0x0001 # interrupting from user ?
735 bnz BASED(mcck_int_main) # from user -> load async stack 649 jz mcck_skip
736 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_end) 650 UPDATE_VTIME %r14,%r15,__LC_MCCK_ENTER_TIMER
737 bhe BASED(mcck_int_main) 651mcck_skip:
738 clc __LC_MCK_OLD_PSW+4(4),BASED(.Lcritical_start) 652 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+32,__LC_PANIC_STACK,PAGE_SHIFT
739 bl BASED(mcck_int_main) 653 mvc __PT_R0(64,%r11),__LC_GPREGS_SAVE_AREA
740 l %r14,BASED(.Lcleanup_critical) 654 stm %r8,%r9,__PT_PSW(%r11)
741 basr %r14,%r14 655 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
742mcck_int_main: 656 l %r1,BASED(.Ldo_machine_check)
743 l %r14,__LC_PANIC_STACK # are we already on the panic stack? 657 lr %r2,%r11 # pass pointer to pt_regs
744 slr %r14,%r15 658 basr %r14,%r1 # call s390_do_machine_check
745 sra %r14,PAGE_SHIFT 659 tm __PT_PSW+1(%r11),0x01 # returning to user ?
746 be BASED(0f) 660 jno mcck_return
747 l %r15,__LC_PANIC_STACK # load panic stack
7480: s %r15,BASED(.Lc_spsize) # make room for registers & psw
749 CREATE_STACK_FRAME __LC_SAVE_AREA+32
750 mvc SP_PSW(8,%r15),0(%r12)
751 l %r12,__LC_THREAD_INFO # load pointer to thread_info struct
752 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
753 bno BASED(mcck_no_vtime) # no -> skip cleanup critical
754 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
755 bz BASED(mcck_no_vtime)
756 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
757 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
758 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
759mcck_no_vtime:
760 la %r2,SP_PTREGS(%r15) # load pt_regs
761 l %r1,BASED(.Ls390_mcck)
762 basr %r14,%r1 # call machine check handler
763 tm SP_PSW+1(%r15),0x01 # returning to user ?
764 bno BASED(mcck_return)
765 l %r1,__LC_KERNEL_STACK # switch to kernel stack 661 l %r1,__LC_KERNEL_STACK # switch to kernel stack
766 s %r1,BASED(.Lc_spsize) 662 ahi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
767 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 663 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
768 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1) # clear back chain 664 xc __SF_BACKCHAIN(4,%r1),__SF_BACKCHAIN(%r1)
665 la %r11,STACK_FRAME_OVERHEAD(%r15)
769 lr %r15,%r1 666 lr %r15,%r1
770 stosm __SF_EMPTY(%r15),0x04 # turn dat on 667 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
771 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING 668 tm __TI_flags+3(%r12),_TIF_MCCK_PENDING
772 bno BASED(mcck_return) 669 jno mcck_return
773 TRACE_IRQS_OFF 670 TRACE_IRQS_OFF
774 l %r1,BASED(.Ls390_handle_mcck) 671 l %r1,BASED(.Lhandle_mcck)
775 basr %r14,%r1 # call machine check handler 672 basr %r14,%r1 # call s390_handle_mcck
776 TRACE_IRQS_ON 673 TRACE_IRQS_ON
777mcck_return: 674mcck_return:
778 mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW 675 mvc __LC_RETURN_MCCK_PSW(8),__PT_PSW(%r11) # move return PSW
779 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 676 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
780 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 677 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
781 bno BASED(0f) 678 jno 0f
782 lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 679 lm %r0,%r15,__PT_R0(%r11)
783 stpt __LC_EXIT_TIMER 680 stpt __LC_EXIT_TIMER
784 lpsw __LC_RETURN_MCCK_PSW # back to caller 681 lpsw __LC_RETURN_MCCK_PSW
7850: lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 6820: lm %r0,%r15,__PT_R0(%r11)
786 lpsw __LC_RETURN_MCCK_PSW # back to caller 683 lpsw __LC_RETURN_MCCK_PSW
787 684
788 RESTORE_ALL __LC_RETURN_MCCK_PSW,0 685mcck_panic:
686 l %r14,__LC_PANIC_STACK
687 slr %r14,%r15
688 sra %r14,PAGE_SHIFT
689 jz 0f
690 l %r15,__LC_PANIC_STACK
6910: ahi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
692 j mcck_skip
789 693
790/* 694/*
791 * Restart interruption handler, kick starter for additional CPUs 695 * Restart interruption handler, kick starter for additional CPUs
@@ -799,18 +703,18 @@ restart_base:
799 stck __LC_LAST_UPDATE_CLOCK 703 stck __LC_LAST_UPDATE_CLOCK
800 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 704 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
801 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 705 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
802 l %r15,__LC_SAVE_AREA+60 # load ksp 706 l %r15,__LC_GPREGS_SAVE_AREA+60 # load ksp
803 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs 707 lctl %c0,%c15,__LC_CREGS_SAVE_AREA # get new ctl regs
804 lam %a0,%a15,__LC_AREGS_SAVE_AREA 708 lam %a0,%a15,__LC_AREGS_SAVE_AREA
805 lm %r6,%r15,__SF_GPRS(%r15) # load registers from clone 709 lm %r6,%r15,__SF_GPRS(%r15)# load registers from clone
806 l %r1,__LC_THREAD_INFO 710 l %r1,__LC_THREAD_INFO
807 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 711 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
808 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 712 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
809 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 713 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
810 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 714 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
811 basr %r14,0 715 basr %r14,0
812 l %r14,restart_addr-.(%r14) 716 l %r14,restart_addr-.(%r14)
813 basr %r14,%r14 # branch to start_secondary 717 basr %r14,%r14 # call start_secondary
814restart_addr: 718restart_addr:
815 .long start_secondary 719 .long start_secondary
816 .align 8 720 .align 8
@@ -835,19 +739,19 @@ restart_go:
835# PSW restart interrupt handler 739# PSW restart interrupt handler
836# 740#
837ENTRY(psw_restart_int_handler) 741ENTRY(psw_restart_int_handler)
838 st %r15,__LC_SAVE_AREA+48(%r0) # save r15 742 st %r15,__LC_SAVE_AREA_RESTART
839 basr %r15,0 743 basr %r15,0
8400: l %r15,.Lrestart_stack-0b(%r15) # load restart stack 7440: l %r15,.Lrestart_stack-0b(%r15) # load restart stack
841 l %r15,0(%r15) 745 l %r15,0(%r15)
842 ahi %r15,-SP_SIZE # make room for pt_regs 746 ahi %r15,-__PT_SIZE # create pt_regs on stack
843 stm %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 747 stm %r0,%r14,__PT_R0(%r15)
844 mvc SP_R15(4,%r15),__LC_SAVE_AREA+48(%r0)# store saved %r15 to stack 748 mvc __PT_R15(4,%r15),__LC_SAVE_AREA_RESTART
845 mvc SP_PSW(8,%r15),__LC_RST_OLD_PSW(%r0) # store restart old psw 749 mvc __PT_PSW(8,%r15),__LC_RST_OLD_PSW # store restart old psw
846 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 750 ahi %r15,-STACK_FRAME_OVERHEAD
751 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
847 basr %r14,0 752 basr %r14,0
8481: l %r14,.Ldo_restart-1b(%r14) 7531: l %r14,.Ldo_restart-1b(%r14)
849 basr %r14,%r14 754 basr %r14,%r14
850
851 basr %r14,0 # load disabled wait PSW if 755 basr %r14,0 # load disabled wait PSW if
8522: lpsw restart_psw_crash-2b(%r14) # do_restart returns 7562: lpsw restart_psw_crash-2b(%r14) # do_restart returns
853 .align 4 757 .align 4
@@ -869,215 +773,174 @@ restart_psw_crash:
869 */ 773 */
870stack_overflow: 774stack_overflow:
871 l %r15,__LC_PANIC_STACK # change to panic stack 775 l %r15,__LC_PANIC_STACK # change to panic stack
872 sl %r15,BASED(.Lc_spsize) 776 ahi %r15,-__PT_SIZE # create pt_regs
873 mvc SP_PSW(8,%r15),0(%r12) # move user PSW to stack 777 stm %r0,%r7,__PT_R0(%r15)
874 stm %r0,%r11,SP_R0(%r15) # store gprs %r0-%r11 to kernel stack 778 stm %r8,%r9,__PT_PSW(%r15)
875 la %r1,__LC_SAVE_AREA 779 mvc __PT_R8(32,%r11),0(%r14)
876 ch %r12,BASED(.L0x020) # old psw addr == __LC_SVC_OLD_PSW ? 780 lr %r15,%r11
877 be BASED(0f) 781 ahi %r15,-STACK_FRAME_OVERHEAD
878 ch %r12,BASED(.L0x028) # old psw addr == __LC_PGM_OLD_PSW ? 782 l %r1,BASED(1f)
879 be BASED(0f) 783 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15)
880 la %r1,__LC_SAVE_AREA+16 784 lr %r2,%r11 # pass pointer to pt_regs
8810: mvc SP_R12(16,%r15),0(%r1) # move %r12-%r15 to stack 785 br %r1 # branch to kernel_stack_overflow
882 xc __SF_BACKCHAIN(4,%r15),__SF_BACKCHAIN(%r15) # clear back chain
883 l %r1,BASED(1f) # branch to kernel_stack_overflow
884 la %r2,SP_PTREGS(%r15) # load pt_regs
885 br %r1
8861: .long kernel_stack_overflow 7861: .long kernel_stack_overflow
887#endif 787#endif
888 788
889cleanup_table_system_call: 789cleanup_table:
890 .long system_call + 0x80000000, sysc_do_svc + 0x80000000 790 .long system_call + 0x80000000
891cleanup_table_sysc_tif: 791 .long sysc_do_svc + 0x80000000
892 .long sysc_tif + 0x80000000, sysc_restore + 0x80000000 792 .long sysc_tif + 0x80000000
893cleanup_table_sysc_restore: 793 .long sysc_restore + 0x80000000
894 .long sysc_restore + 0x80000000, sysc_done + 0x80000000 794 .long sysc_done + 0x80000000
895cleanup_table_io_tif: 795 .long io_tif + 0x80000000
896 .long io_tif + 0x80000000, io_restore + 0x80000000 796 .long io_restore + 0x80000000
897cleanup_table_io_restore: 797 .long io_done + 0x80000000
898 .long io_restore + 0x80000000, io_done + 0x80000000
899 798
900cleanup_critical: 799cleanup_critical:
901 clc 4(4,%r12),BASED(cleanup_table_system_call) 800 cl %r9,BASED(cleanup_table) # system_call
902 bl BASED(0f) 801 jl 0f
903 clc 4(4,%r12),BASED(cleanup_table_system_call+4) 802 cl %r9,BASED(cleanup_table+4) # sysc_do_svc
904 bl BASED(cleanup_system_call) 803 jl cleanup_system_call
9050: 804 cl %r9,BASED(cleanup_table+8) # sysc_tif
906 clc 4(4,%r12),BASED(cleanup_table_sysc_tif) 805 jl 0f
907 bl BASED(0f) 806 cl %r9,BASED(cleanup_table+12) # sysc_restore
908 clc 4(4,%r12),BASED(cleanup_table_sysc_tif+4) 807 jl cleanup_sysc_tif
909 bl BASED(cleanup_sysc_tif) 808 cl %r9,BASED(cleanup_table+16) # sysc_done
9100: 809 jl cleanup_sysc_restore
911 clc 4(4,%r12),BASED(cleanup_table_sysc_restore) 810 cl %r9,BASED(cleanup_table+20) # io_tif
912 bl BASED(0f) 811 jl 0f
913 clc 4(4,%r12),BASED(cleanup_table_sysc_restore+4) 812 cl %r9,BASED(cleanup_table+24) # io_restore
914 bl BASED(cleanup_sysc_restore) 813 jl cleanup_io_tif
9150: 814 cl %r9,BASED(cleanup_table+28) # io_done
916 clc 4(4,%r12),BASED(cleanup_table_io_tif) 815 jl cleanup_io_restore
917 bl BASED(0f) 8160: br %r14
918 clc 4(4,%r12),BASED(cleanup_table_io_tif+4)
919 bl BASED(cleanup_io_tif)
9200:
921 clc 4(4,%r12),BASED(cleanup_table_io_restore)
922 bl BASED(0f)
923 clc 4(4,%r12),BASED(cleanup_table_io_restore+4)
924 bl BASED(cleanup_io_restore)
9250:
926 br %r14
927 817
928cleanup_system_call: 818cleanup_system_call:
929 mvc __LC_RETURN_PSW(8),0(%r12) 819 # check if stpt has been executed
930 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+4) 820 cl %r9,BASED(cleanup_system_call_insn)
931 bh BASED(0f) 821 jh 0f
932 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
933 c %r12,BASED(.Lmck_old_psw)
934 be BASED(0f)
935 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 822 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9360: c %r12,BASED(.Lmck_old_psw) 823 chi %r11,__LC_SAVE_AREA_ASYNC
937 la %r12,__LC_SAVE_AREA+32 824 je 0f
938 be BASED(0f) 825 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
939 la %r12,__LC_SAVE_AREA+16 8260: # check if stm has been executed
9400: clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+8) 827 cl %r9,BASED(cleanup_system_call_insn+4)
941 bhe BASED(cleanup_vtime) 828 jh 0f
942 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn) 829 mvc __LC_SAVE_AREA_SYNC(32),0(%r11)
943 bh BASED(0f) 8300: # set up saved registers r12, and r13
944 mvc __LC_SAVE_AREA(16),0(%r12) 831 st %r12,16(%r11) # r12 thread-info pointer
9450: st %r13,4(%r12) 832 st %r13,20(%r11) # r13 literal-pool pointer
946 l %r15,__LC_KERNEL_STACK # problem state -> load ksp 833 # check if the user time calculation has been done
947 s %r15,BASED(.Lc_spsize) # make room for registers & psw 834 cl %r9,BASED(cleanup_system_call_insn+8)
948 st %r15,12(%r12) 835 jh 0f
949 CREATE_STACK_FRAME __LC_SAVE_AREA 836 l %r10,__LC_EXIT_TIMER
950 mvc 0(4,%r12),__LC_THREAD_INFO 837 l %r15,__LC_EXIT_TIMER+4
951 l %r12,__LC_THREAD_INFO 838 SUB64 %r10,%r15,__LC_SYNC_ENTER_TIMER
952 mvc SP_PSW(8,%r15),__LC_SVC_OLD_PSW 839 ADD64 %r10,%r15,__LC_USER_TIMER
953 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 840 st %r10,__LC_USER_TIMER
954 oi __TI_flags+3(%r12),_TIF_SYSCALL 841 st %r15,__LC_USER_TIMER+4
955cleanup_vtime: 8420: # check if the system time calculation has been done
956 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+12) 843 cl %r9,BASED(cleanup_system_call_insn+12)
957 bhe BASED(cleanup_stime) 844 jh 0f
958 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 845 l %r10,__LC_LAST_UPDATE_TIMER
959cleanup_stime: 846 l %r15,__LC_LAST_UPDATE_TIMER+4
960 clc __LC_RETURN_PSW+4(4),BASED(cleanup_system_call_insn+16) 847 SUB64 %r10,%r15,__LC_EXIT_TIMER
961 bh BASED(cleanup_update) 848 ADD64 %r10,%r15,__LC_SYSTEM_TIMER
962 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 849 st %r10,__LC_SYSTEM_TIMER
963cleanup_update: 850 st %r15,__LC_SYSTEM_TIMER+4
8510: # update accounting time stamp
964 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 852 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
965 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_system_call+4) 853 # set up saved register 11
966 la %r12,__LC_RETURN_PSW 854 l %r15,__LC_KERNEL_STACK
855 ahi %r15,-__PT_SIZE
856 st %r15,12(%r11) # r11 pt_regs pointer
857 # fill pt_regs
858 mvc __PT_R8(32,%r15),__LC_SAVE_AREA_SYNC
859 stm %r0,%r7,__PT_R0(%r15)
860 mvc __PT_PSW(8,%r15),__LC_SVC_OLD_PSW
861 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
862 # setup saved register 15
863 ahi %r15,-STACK_FRAME_OVERHEAD
864 st %r15,28(%r11) # r15 stack pointer
865 # set new psw address and exit
866 l %r9,BASED(cleanup_table+4) # sysc_do_svc + 0x80000000
967 br %r14 867 br %r14
968cleanup_system_call_insn: 868cleanup_system_call_insn:
969 .long sysc_saveall + 0x80000000
970 .long system_call + 0x80000000 869 .long system_call + 0x80000000
971 .long sysc_vtime + 0x80000000 870 .long sysc_stm + 0x80000000
972 .long sysc_stime + 0x80000000 871 .long sysc_vtime + 0x80000000 + 36
973 .long sysc_update + 0x80000000 872 .long sysc_vtime + 0x80000000 + 76
974 873
975cleanup_sysc_tif: 874cleanup_sysc_tif:
976 mvc __LC_RETURN_PSW(4),0(%r12) 875 l %r9,BASED(cleanup_table+8) # sysc_tif + 0x80000000
977 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_sysc_tif)
978 la %r12,__LC_RETURN_PSW
979 br %r14 876 br %r14
980 877
981cleanup_sysc_restore: 878cleanup_sysc_restore:
982 clc 4(4,%r12),BASED(cleanup_sysc_restore_insn) 879 cl %r9,BASED(cleanup_sysc_restore_insn)
983 be BASED(2f) 880 jhe 0f
984 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 881 l %r9,12(%r11) # get saved pointer to pt_regs
985 c %r12,BASED(.Lmck_old_psw) 882 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
986 be BASED(0f) 883 mvc 0(32,%r11),__PT_R8(%r9)
987 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 884 lm %r0,%r7,__PT_R0(%r9)
9880: clc 4(4,%r12),BASED(cleanup_sysc_restore_insn+4) 8850: lm %r8,%r9,__LC_RETURN_PSW
989 be BASED(2f)
990 mvc __LC_RETURN_PSW(8),SP_PSW(%r15)
991 c %r12,BASED(.Lmck_old_psw)
992 la %r12,__LC_SAVE_AREA+32
993 be BASED(1f)
994 la %r12,__LC_SAVE_AREA+16
9951: mvc 0(16,%r12),SP_R12(%r15)
996 lm %r0,%r11,SP_R0(%r15)
997 l %r15,SP_R15(%r15)
9982: la %r12,__LC_RETURN_PSW
999 br %r14 886 br %r14
1000cleanup_sysc_restore_insn: 887cleanup_sysc_restore_insn:
1001 .long sysc_done - 4 + 0x80000000 888 .long sysc_done - 4 + 0x80000000
1002 .long sysc_done - 8 + 0x80000000
1003 889
1004cleanup_io_tif: 890cleanup_io_tif:
1005 mvc __LC_RETURN_PSW(4),0(%r12) 891 l %r9,BASED(cleanup_table+20) # io_tif + 0x80000000
1006 mvc __LC_RETURN_PSW+4(4),BASED(cleanup_table_io_tif)
1007 la %r12,__LC_RETURN_PSW
1008 br %r14 892 br %r14
1009 893
1010cleanup_io_restore: 894cleanup_io_restore:
1011 clc 4(4,%r12),BASED(cleanup_io_restore_insn) 895 cl %r9,BASED(cleanup_io_restore_insn)
1012 be BASED(1f) 896 jhe 0f
1013 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 897 l %r9,12(%r11) # get saved r11 pointer to pt_regs
1014 clc 4(4,%r12),BASED(cleanup_io_restore_insn+4) 898 mvc __LC_RETURN_PSW(8),__PT_PSW(%r9)
1015 be BASED(1f) 899 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
1016 mvc __LC_RETURN_PSW(8),SP_PSW(%r15) 900 mvc 0(32,%r11),__PT_R8(%r9)
1017 mvc __LC_SAVE_AREA+32(16),SP_R12(%r15) 901 lm %r0,%r7,__PT_R0(%r9)
1018 lm %r0,%r11,SP_R0(%r15) 9020: lm %r8,%r9,__LC_RETURN_PSW
1019 l %r15,SP_R15(%r15)
10201: la %r12,__LC_RETURN_PSW
1021 br %r14 903 br %r14
1022cleanup_io_restore_insn: 904cleanup_io_restore_insn:
1023 .long io_done - 4 + 0x80000000 905 .long io_done - 4 + 0x80000000
1024 .long io_done - 8 + 0x80000000
1025 906
1026/* 907/*
1027 * Integer constants 908 * Integer constants
1028 */ 909 */
1029 .align 4 910 .align 4
1030.Lc_spsize: .long SP_SIZE 911.Lnr_syscalls: .long NR_syscalls
1031.Lc_overhead: .long STACK_FRAME_OVERHEAD
1032.Lnr_syscalls: .long NR_syscalls
1033.L0x018: .short 0x018
1034.L0x020: .short 0x020
1035.L0x028: .short 0x028
1036.L0x030: .short 0x030
1037.L0x038: .short 0x038
1038.Lc_1: .long 1
1039 912
1040/* 913/*
1041 * Symbol constants 914 * Symbol constants
1042 */ 915 */
1043.Ls390_mcck: .long s390_do_machine_check 916.Ldo_machine_check: .long s390_do_machine_check
1044.Ls390_handle_mcck: 917.Lhandle_mcck: .long s390_handle_mcck
1045 .long s390_handle_mcck 918.Ldo_IRQ: .long do_IRQ
1046.Lmck_old_psw: .long __LC_MCK_OLD_PSW 919.Ldo_extint: .long do_extint
1047.Ldo_IRQ: .long do_IRQ 920.Ldo_signal: .long do_signal
1048.Ldo_extint: .long do_extint 921.Ldo_notify_resume: .long do_notify_resume
1049.Ldo_signal: .long do_signal 922.Ldo_per_trap: .long do_per_trap
1050.Ldo_notify_resume: 923.Ldo_execve: .long do_execve
1051 .long do_notify_resume 924.Lexecve_tail: .long execve_tail
1052.Lhandle_per: .long do_per_trap 925.Ljump_table: .long pgm_check_table
1053.Ldo_execve: .long do_execve 926.Lschedule: .long schedule
1054.Lexecve_tail: .long execve_tail
1055.Ljump_table: .long pgm_check_table
1056.Lschedule: .long schedule
1057#ifdef CONFIG_PREEMPT 927#ifdef CONFIG_PREEMPT
1058.Lpreempt_schedule_irq: 928.Lpreempt_irq: .long preempt_schedule_irq
1059 .long preempt_schedule_irq
1060#endif 929#endif
1061.Ltrace_entry: .long do_syscall_trace_enter 930.Ltrace_enter: .long do_syscall_trace_enter
1062.Ltrace_exit: .long do_syscall_trace_exit 931.Ltrace_exit: .long do_syscall_trace_exit
1063.Lschedtail: .long schedule_tail 932.Lschedule_tail: .long schedule_tail
1064.Lsysc_table: .long sys_call_table 933.Lsys_call_table: .long sys_call_table
934.Lsysc_per: .long sysc_per + 0x80000000
1065#ifdef CONFIG_TRACE_IRQFLAGS 935#ifdef CONFIG_TRACE_IRQFLAGS
1066.Ltrace_irq_on_caller: 936.Lhardirqs_on: .long trace_hardirqs_on_caller
1067 .long trace_hardirqs_on_caller 937.Lhardirqs_off: .long trace_hardirqs_off_caller
1068.Ltrace_irq_off_caller:
1069 .long trace_hardirqs_off_caller
1070#endif 938#endif
1071#ifdef CONFIG_LOCKDEP 939#ifdef CONFIG_LOCKDEP
1072.Llockdep_sys_exit: 940.Llockdep_sys_exit: .long lockdep_sys_exit
1073 .long lockdep_sys_exit
1074#endif 941#endif
1075.Lcritical_start: 942.Lcritical_start: .long __critical_start + 0x80000000
1076 .long __critical_start + 0x80000000 943.Lcritical_length: .long __critical_end - __critical_start
1077.Lcritical_end:
1078 .long __critical_end + 0x80000000
1079.Lcleanup_critical:
1080 .long cleanup_critical
1081 944
1082 .section .rodata, "a" 945 .section .rodata, "a"
1083#define SYSCALL(esa,esame,emu) .long esa 946#define SYSCALL(esa,esame,emu) .long esa
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h
index ef8fb1d6e8d7..bf538aaf407d 100644
--- a/arch/s390/kernel/entry.h
+++ b/arch/s390/kernel/entry.h
@@ -6,15 +6,15 @@
6#include <asm/ptrace.h> 6#include <asm/ptrace.h>
7 7
8 8
9extern void (*pgm_check_table[128])(struct pt_regs *, long, unsigned long); 9extern void (*pgm_check_table[128])(struct pt_regs *);
10extern void *restart_stack; 10extern void *restart_stack;
11 11
12asmlinkage long do_syscall_trace_enter(struct pt_regs *regs); 12asmlinkage long do_syscall_trace_enter(struct pt_regs *regs);
13asmlinkage void do_syscall_trace_exit(struct pt_regs *regs); 13asmlinkage void do_syscall_trace_exit(struct pt_regs *regs);
14 14
15void do_protection_exception(struct pt_regs *, long, unsigned long); 15void do_protection_exception(struct pt_regs *regs);
16void do_dat_exception(struct pt_regs *, long, unsigned long); 16void do_dat_exception(struct pt_regs *regs);
17void do_asce_exception(struct pt_regs *, long, unsigned long); 17void do_asce_exception(struct pt_regs *regs);
18 18
19void do_per_trap(struct pt_regs *regs); 19void do_per_trap(struct pt_regs *regs);
20void syscall_trace(struct pt_regs *regs, int entryexit); 20void syscall_trace(struct pt_regs *regs, int entryexit);
@@ -28,7 +28,7 @@ void do_extint(struct pt_regs *regs, unsigned int, unsigned int, unsigned long);
28void do_restart(void); 28void do_restart(void);
29int __cpuinit start_secondary(void *cpuvoid); 29int __cpuinit start_secondary(void *cpuvoid);
30void __init startup_init(void); 30void __init startup_init(void);
31void die(const char * str, struct pt_regs * regs, long err); 31void die(struct pt_regs *regs, const char *str);
32 32
33void __init time_init(void); 33void __init time_init(void);
34 34
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S
index 83a93747e2fd..412a7b8783d7 100644
--- a/arch/s390/kernel/entry64.S
+++ b/arch/s390/kernel/entry64.S
@@ -19,32 +19,22 @@
19#include <asm/unistd.h> 19#include <asm/unistd.h>
20#include <asm/page.h> 20#include <asm/page.h>
21 21
22/* 22__PT_R0 = __PT_GPRS
23 * Stack layout for the system_call stack entry. 23__PT_R1 = __PT_GPRS + 8
24 * The first few entries are identical to the user_regs_struct. 24__PT_R2 = __PT_GPRS + 16
25 */ 25__PT_R3 = __PT_GPRS + 24
26SP_PTREGS = STACK_FRAME_OVERHEAD 26__PT_R4 = __PT_GPRS + 32
27SP_ARGS = STACK_FRAME_OVERHEAD + __PT_ARGS 27__PT_R5 = __PT_GPRS + 40
28SP_PSW = STACK_FRAME_OVERHEAD + __PT_PSW 28__PT_R6 = __PT_GPRS + 48
29SP_R0 = STACK_FRAME_OVERHEAD + __PT_GPRS 29__PT_R7 = __PT_GPRS + 56
30SP_R1 = STACK_FRAME_OVERHEAD + __PT_GPRS + 8 30__PT_R8 = __PT_GPRS + 64
31SP_R2 = STACK_FRAME_OVERHEAD + __PT_GPRS + 16 31__PT_R9 = __PT_GPRS + 72
32SP_R3 = STACK_FRAME_OVERHEAD + __PT_GPRS + 24 32__PT_R10 = __PT_GPRS + 80
33SP_R4 = STACK_FRAME_OVERHEAD + __PT_GPRS + 32 33__PT_R11 = __PT_GPRS + 88
34SP_R5 = STACK_FRAME_OVERHEAD + __PT_GPRS + 40 34__PT_R12 = __PT_GPRS + 96
35SP_R6 = STACK_FRAME_OVERHEAD + __PT_GPRS + 48 35__PT_R13 = __PT_GPRS + 104
36SP_R7 = STACK_FRAME_OVERHEAD + __PT_GPRS + 56 36__PT_R14 = __PT_GPRS + 112
37SP_R8 = STACK_FRAME_OVERHEAD + __PT_GPRS + 64 37__PT_R15 = __PT_GPRS + 120
38SP_R9 = STACK_FRAME_OVERHEAD + __PT_GPRS + 72
39SP_R10 = STACK_FRAME_OVERHEAD + __PT_GPRS + 80
40SP_R11 = STACK_FRAME_OVERHEAD + __PT_GPRS + 88
41SP_R12 = STACK_FRAME_OVERHEAD + __PT_GPRS + 96
42SP_R13 = STACK_FRAME_OVERHEAD + __PT_GPRS + 104
43SP_R14 = STACK_FRAME_OVERHEAD + __PT_GPRS + 112
44SP_R15 = STACK_FRAME_OVERHEAD + __PT_GPRS + 120
45SP_ORIG_R2 = STACK_FRAME_OVERHEAD + __PT_ORIG_GPR2
46SP_SVC_CODE = STACK_FRAME_OVERHEAD + __PT_SVC_CODE
47SP_SIZE = STACK_FRAME_OVERHEAD + __PT_SIZE
48 38
49STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER 39STACK_SHIFT = PAGE_SHIFT + THREAD_ORDER
50STACK_SIZE = 1 << STACK_SHIFT 40STACK_SIZE = 1 << STACK_SHIFT
@@ -59,154 +49,103 @@ _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING)
59 49
60#define BASED(name) name-system_call(%r13) 50#define BASED(name) name-system_call(%r13)
61 51
62 .macro SPP newpp
63#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
64 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
65 jz .+8
66 .insn s,0xb2800000,\newpp
67#endif
68 .endm
69
70 .macro HANDLE_SIE_INTERCEPT
71#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
72 tm __TI_flags+6(%r12),_TIF_SIE>>8
73 jz 0f
74 SPP __LC_CMF_HPP # set host id
75 clc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
76 jl 0f
77 clc SP_PSW+8(8,%r15),BASED(.Lsie_done)
78 jhe 0f
79 mvc SP_PSW+8(8,%r15),BASED(.Lsie_loop)
800:
81#endif
82 .endm
83
84#ifdef CONFIG_TRACE_IRQFLAGS
85 .macro TRACE_IRQS_ON 52 .macro TRACE_IRQS_ON
53#ifdef CONFIG_TRACE_IRQFLAGS
86 basr %r2,%r0 54 basr %r2,%r0
87 brasl %r14,trace_hardirqs_on_caller 55 brasl %r14,trace_hardirqs_on_caller
56#endif
88 .endm 57 .endm
89 58
90 .macro TRACE_IRQS_OFF 59 .macro TRACE_IRQS_OFF
60#ifdef CONFIG_TRACE_IRQFLAGS
91 basr %r2,%r0 61 basr %r2,%r0
92 brasl %r14,trace_hardirqs_off_caller 62 brasl %r14,trace_hardirqs_off_caller
93 .endm
94#else
95#define TRACE_IRQS_ON
96#define TRACE_IRQS_OFF
97#endif 63#endif
64 .endm
98 65
99#ifdef CONFIG_LOCKDEP
100 .macro LOCKDEP_SYS_EXIT 66 .macro LOCKDEP_SYS_EXIT
101 tm SP_PSW+1(%r15),0x01 # returning to user ? 67#ifdef CONFIG_LOCKDEP
102 jz 0f 68 tm __PT_PSW+1(%r11),0x01 # returning to user ?
69 jz .+10
103 brasl %r14,lockdep_sys_exit 70 brasl %r14,lockdep_sys_exit
1040:
105 .endm
106#else
107#define LOCKDEP_SYS_EXIT
108#endif 71#endif
109
110 .macro UPDATE_VTIME lc_from,lc_to,lc_sum
111 lg %r10,\lc_from
112 slg %r10,\lc_to
113 alg %r10,\lc_sum
114 stg %r10,\lc_sum
115 .endm 72 .endm
116 73
117/* 74 .macro SPP newpp
118 * Register usage in interrupt handlers: 75#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
119 * R9 - pointer to current task structure 76 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
120 * R13 - pointer to literal pool 77 jz .+8
121 * R14 - return register for function calls 78 .insn s,0xb2800000,\newpp
122 * R15 - kernel stack pointer 79#endif
123 */ 80 .endm
124 81
125 .macro SAVE_ALL_SVC psworg,savearea 82 .macro HANDLE_SIE_INTERCEPT scratch
126 stmg %r11,%r15,\savearea 83#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
127 lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 84 tm __TI_flags+6(%r12),_TIF_SIE>>8
128 aghi %r15,-SP_SIZE # make room for registers & psw 85 jz .+42
129 lg %r11,__LC_LAST_BREAK 86 tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP
87 jz .+8
88 .insn s,0xb2800000,BASED(.Lhost_id) # set host id
89 lgr \scratch,%r9
90 slg \scratch,BASED(.Lsie_loop)
91 clg \scratch,BASED(.Lsie_length)
92 jhe .+10
93 lg %r9,BASED(.Lsie_loop)
94#endif
130 .endm 95 .endm
131 96
132 .macro SAVE_ALL_PGM psworg,savearea 97 .macro CHECK_STACK stacksize,savearea
133 stmg %r11,%r15,\savearea
134 tm \psworg+1,0x01 # test problem state bit
135#ifdef CONFIG_CHECK_STACK 98#ifdef CONFIG_CHECK_STACK
136 jnz 1f 99 tml %r15,\stacksize - CONFIG_STACK_GUARD
137 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 100 lghi %r14,\savearea
138 jnz 2f 101 jz stack_overflow
139 la %r12,\psworg
140 j stack_overflow
141#else
142 jz 2f
143#endif 102#endif
1441: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp
1452: aghi %r15,-SP_SIZE # make room for registers & psw
146 larl %r13,system_call
147 lg %r11,__LC_LAST_BREAK
148 .endm 103 .endm
149 104
150 .macro SAVE_ALL_ASYNC psworg,savearea 105 .macro SWITCH_ASYNC savearea,stack,shift
151 stmg %r11,%r15,\savearea 106 tmhh %r8,0x0001 # interrupting from user ?
152 larl %r13,system_call 107 jnz 1f
153 lg %r11,__LC_LAST_BREAK 108 lgr %r14,%r9
154 la %r12,\psworg 109 slg %r14,BASED(.Lcritical_start)
155 tm \psworg+1,0x01 # test problem state bit 110 clg %r14,BASED(.Lcritical_length)
156 jnz 1f # from user -> load kernel stack
157 clc \psworg+8(8),BASED(.Lcritical_end)
158 jhe 0f 111 jhe 0f
159 clc \psworg+8(8),BASED(.Lcritical_start) 112 lghi %r11,\savearea # inside critical section, do cleanup
160 jl 0f
161 brasl %r14,cleanup_critical 113 brasl %r14,cleanup_critical
162 tm 1(%r12),0x01 # retest problem state after cleanup 114 tmhh %r8,0x0001 # retest problem state after cleanup
163 jnz 1f 115 jnz 1f
1640: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? 1160: lg %r14,\stack # are we already on the target stack?
165 slgr %r14,%r15 117 slgr %r14,%r15
166 srag %r14,%r14,STACK_SHIFT 118 srag %r14,%r14,\shift
167#ifdef CONFIG_CHECK_STACK
168 jnz 1f 119 jnz 1f
169 tml %r15,STACK_SIZE - CONFIG_STACK_GUARD 120 CHECK_STACK 1<<\shift,\savearea
170 jnz 2f 121 j 2f
171 j stack_overflow 1221: lg %r15,\stack # load target stack
172#else 1232: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
173 jz 2f 124 la %r11,STACK_FRAME_OVERHEAD(%r15)
174#endif
1751: lg %r15,__LC_ASYNC_STACK # load async stack
1762: aghi %r15,-SP_SIZE # make room for registers & psw
177 .endm
178
179 .macro CREATE_STACK_FRAME savearea
180 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
181 stg %r2,SP_ORIG_R2(%r15) # store original content of gpr 2
182 mvc SP_R11(40,%r15),\savearea # move %r11-%r15 to stack
183 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack
184 .endm 125 .endm
185 126
186 .macro RESTORE_ALL psworg,sync 127 .macro UPDATE_VTIME scratch,enter_timer
187 mvc \psworg(16),SP_PSW(%r15) # move user PSW to lowcore 128 lg \scratch,__LC_EXIT_TIMER
188 .if !\sync 129 slg \scratch,\enter_timer
189 ni \psworg+1,0xfd # clear wait state bit 130 alg \scratch,__LC_USER_TIMER
190 .endif 131 stg \scratch,__LC_USER_TIMER
191 lg %r14,__LC_VDSO_PER_CPU 132 lg \scratch,__LC_LAST_UPDATE_TIMER
192 lmg %r0,%r13,SP_R0(%r15) # load gprs 0-13 of user 133 slg \scratch,__LC_EXIT_TIMER
193 stpt __LC_EXIT_TIMER 134 alg \scratch,__LC_SYSTEM_TIMER
194 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER 135 stg \scratch,__LC_SYSTEM_TIMER
195 lmg %r14,%r15,SP_R14(%r15) # load grps 14-15 of user 136 mvc __LC_LAST_UPDATE_TIMER(8),\enter_timer
196 lpswe \psworg # back to caller
197 .endm 137 .endm
198 138
199 .macro LAST_BREAK 139 .macro LAST_BREAK scratch
200 srag %r10,%r11,23 140 srag \scratch,%r10,23
201 jz 0f 141 jz .+10
202 stg %r11,__TI_last_break(%r12) 142 stg %r10,__TI_last_break(%r12)
2030:
204 .endm 143 .endm
205 144
206 .macro REENABLE_IRQS 145 .macro REENABLE_IRQS
207 mvc __SF_EMPTY(1,%r15),SP_PSW(%r15) 146 stg %r8,__LC_RETURN_PSW
208 ni __SF_EMPTY(%r15),0xbf 147 ni __LC_RETURN_PSW,0xbf
209 ssm __SF_EMPTY(%r15) 148 ssm __LC_RETURN_PSW
210 .endm 149 .endm
211 150
212 .section .kprobes.text, "ax" 151 .section .kprobes.text, "ax"
@@ -245,55 +184,66 @@ __critical_start:
245 184
246ENTRY(system_call) 185ENTRY(system_call)
247 stpt __LC_SYNC_ENTER_TIMER 186 stpt __LC_SYNC_ENTER_TIMER
248sysc_saveall: 187sysc_stmg:
249 SAVE_ALL_SVC __LC_SVC_OLD_PSW,__LC_SAVE_AREA 188 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
250 CREATE_STACK_FRAME __LC_SAVE_AREA 189 lg %r10,__LC_LAST_BREAK
251 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 190 lg %r12,__LC_THREAD_INFO
252 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 191 larl %r13,system_call
253 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 192sysc_per:
254 oi __TI_flags+7(%r12),_TIF_SYSCALL 193 lg %r15,__LC_KERNEL_STACK
194 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
195 la %r11,STACK_FRAME_OVERHEAD(%r15) # pointer to pt_regs
255sysc_vtime: 196sysc_vtime:
256 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 197 UPDATE_VTIME %r13,__LC_SYNC_ENTER_TIMER
257sysc_stime: 198 LAST_BREAK %r13
258 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 199 stmg %r0,%r7,__PT_R0(%r11)
259sysc_update: 200 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
260 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 201 mvc __PT_PSW(16,%r11),__LC_SVC_OLD_PSW
261 LAST_BREAK 202 mvc __PT_INT_CODE(4,%r11),__LC_SVC_ILC
262sysc_do_svc: 203sysc_do_svc:
263 llgh %r7,SP_SVC_CODE+2(%r15) 204 oi __TI_flags+7(%r12),_TIF_SYSCALL
264 slag %r7,%r7,2 # shift and test for svc 0 205 llgh %r8,__PT_INT_CODE+2(%r11)
206 slag %r8,%r8,2 # shift and test for svc 0
265 jnz sysc_nr_ok 207 jnz sysc_nr_ok
266 # svc 0: system call number in %r1 208 # svc 0: system call number in %r1
267 llgfr %r1,%r1 # clear high word in r1 209 llgfr %r1,%r1 # clear high word in r1
268 cghi %r1,NR_syscalls 210 cghi %r1,NR_syscalls
269 jnl sysc_nr_ok 211 jnl sysc_nr_ok
270 sth %r1,SP_SVC_CODE+2(%r15) 212 sth %r1,__PT_INT_CODE+2(%r11)
271 slag %r7,%r1,2 # shift and test for svc 0 213 slag %r8,%r1,2
272sysc_nr_ok: 214sysc_nr_ok:
273 larl %r10,sys_call_table 215 larl %r10,sys_call_table # 64 bit system call table
274#ifdef CONFIG_COMPAT 216#ifdef CONFIG_COMPAT
275 tm __TI_flags+5(%r12),(_TIF_31BIT>>16) # running in 31 bit mode ? 217 tm __TI_flags+5(%r12),(_TIF_31BIT>>16)
276 jno sysc_noemu 218 jno sysc_noemu
277 larl %r10,sys_call_table_emu # use 31 bit emulation system calls 219 larl %r10,sys_call_table_emu # 31 bit system call table
278sysc_noemu: 220sysc_noemu:
279#endif 221#endif
222 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
223 stg %r2,__PT_ORIG_GPR2(%r11)
224 stg %r7,STACK_FRAME_OVERHEAD(%r15)
225 lgf %r9,0(%r8,%r10) # get system call add.
280 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 226 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
281 mvc SP_ARGS(8,%r15),SP_R7(%r15)
282 lgf %r8,0(%r7,%r10) # load address of system call routine
283 jnz sysc_tracesys 227 jnz sysc_tracesys
284 basr %r14,%r8 # call sys_xxxx 228 basr %r14,%r9 # call sys_xxxx
285 stg %r2,SP_R2(%r15) # store return value (change R2 on stack) 229 stg %r2,__PT_R2(%r11) # store return value
286 230
287sysc_return: 231sysc_return:
288 LOCKDEP_SYS_EXIT 232 LOCKDEP_SYS_EXIT
289sysc_tif: 233sysc_tif:
290 tm SP_PSW+1(%r15),0x01 # returning to user ? 234 tm __PT_PSW+1(%r11),0x01 # returning to user ?
291 jno sysc_restore 235 jno sysc_restore
292 tm __TI_flags+7(%r12),_TIF_WORK_SVC 236 tm __TI_flags+7(%r12),_TIF_WORK_SVC
293 jnz sysc_work # there is work to do (signals etc.) 237 jnz sysc_work # check for work
294 ni __TI_flags+7(%r12),255-_TIF_SYSCALL 238 ni __TI_flags+7(%r12),255-_TIF_SYSCALL
295sysc_restore: 239sysc_restore:
296 RESTORE_ALL __LC_RETURN_PSW,1 240 lg %r14,__LC_VDSO_PER_CPU
241 lmg %r0,%r10,__PT_R0(%r11)
242 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
243 stpt __LC_EXIT_TIMER
244 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
245 lmg %r11,%r15,__PT_R11(%r11)
246 lpswe __LC_RETURN_PSW
297sysc_done: 247sysc_done:
298 248
299# 249#
@@ -317,7 +267,7 @@ sysc_work:
317# 267#
318sysc_reschedule: 268sysc_reschedule:
319 larl %r14,sysc_return 269 larl %r14,sysc_return
320 jg schedule # return point is sysc_return 270 jg schedule
321 271
322# 272#
323# _TIF_MCCK_PENDING is set, call handler 273# _TIF_MCCK_PENDING is set, call handler
@@ -331,33 +281,33 @@ sysc_mcck_pending:
331# 281#
332sysc_sigpending: 282sysc_sigpending:
333 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP 283 ni __TI_flags+7(%r12),255-_TIF_PER_TRAP # clear TIF_PER_TRAP
334 la %r2,SP_PTREGS(%r15) # load pt_regs 284 lgr %r2,%r11 # pass pointer to pt_regs
335 brasl %r14,do_signal # call do_signal 285 brasl %r14,do_signal
336 tm __TI_flags+7(%r12),_TIF_SYSCALL 286 tm __TI_flags+7(%r12),_TIF_SYSCALL
337 jno sysc_return 287 jno sysc_return
338 lmg %r2,%r6,SP_R2(%r15) # load svc arguments 288 lmg %r2,%r7,__PT_R2(%r11) # load svc arguments
339 lghi %r7,0 # svc 0 returns -ENOSYS 289 lghi %r8,0 # svc 0 returns -ENOSYS
340 lh %r1,SP_SVC_CODE+2(%r15) # load new svc number 290 lh %r1,__PT_INT_CODE+2(%r11) # load new svc number
341 cghi %r1,NR_syscalls 291 cghi %r1,NR_syscalls
342 jnl sysc_nr_ok # invalid svc number -> do svc 0 292 jnl sysc_nr_ok # invalid svc number -> do svc 0
343 slag %r7,%r1,2 293 slag %r8,%r1,2
344 j sysc_nr_ok # restart svc 294 j sysc_nr_ok # restart svc
345 295
346# 296#
347# _TIF_NOTIFY_RESUME is set, call do_notify_resume 297# _TIF_NOTIFY_RESUME is set, call do_notify_resume
348# 298#
349sysc_notify_resume: 299sysc_notify_resume:
350 la %r2,SP_PTREGS(%r15) # load pt_regs 300 lgr %r2,%r11 # pass pointer to pt_regs
351 larl %r14,sysc_return 301 larl %r14,sysc_return
352 jg do_notify_resume # call do_notify_resume 302 jg do_notify_resume
353 303
354# 304#
355# _TIF_PER_TRAP is set, call do_per_trap 305# _TIF_PER_TRAP is set, call do_per_trap
356# 306#
357sysc_singlestep: 307sysc_singlestep:
358 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP) 308 ni __TI_flags+7(%r12),255-(_TIF_SYSCALL | _TIF_PER_TRAP)
359 la %r2,SP_PTREGS(%r15) # address of register-save area 309 lgr %r2,%r11 # pass pointer to pt_regs
360 larl %r14,sysc_return # load adr. of system return 310 larl %r14,sysc_return
361 jg do_per_trap 311 jg do_per_trap
362 312
363# 313#
@@ -365,41 +315,41 @@ sysc_singlestep:
365# and after the system call 315# and after the system call
366# 316#
367sysc_tracesys: 317sysc_tracesys:
368 la %r2,SP_PTREGS(%r15) # load pt_regs 318 lgr %r2,%r11 # pass pointer to pt_regs
369 la %r3,0 319 la %r3,0
370 llgh %r0,SP_SVC_CODE+2(%r15) 320 llgh %r0,__PT_INT_CODE+2(%r11)
371 stg %r0,SP_R2(%r15) 321 stg %r0,__PT_R2(%r11)
372 brasl %r14,do_syscall_trace_enter 322 brasl %r14,do_syscall_trace_enter
373 lghi %r0,NR_syscalls 323 lghi %r0,NR_syscalls
374 clgr %r0,%r2 324 clgr %r0,%r2
375 jnh sysc_tracenogo 325 jnh sysc_tracenogo
376 sllg %r7,%r2,2 # svc number *4 326 sllg %r8,%r2,2
377 lgf %r8,0(%r7,%r10) 327 lgf %r9,0(%r8,%r10)
378sysc_tracego: 328sysc_tracego:
379 lmg %r3,%r6,SP_R3(%r15) 329 lmg %r3,%r7,__PT_R3(%r11)
380 mvc SP_ARGS(8,%r15),SP_R7(%r15) 330 stg %r7,STACK_FRAME_OVERHEAD(%r15)
381 lg %r2,SP_ORIG_R2(%r15) 331 lg %r2,__PT_ORIG_GPR2(%r11)
382 basr %r14,%r8 # call sys_xxx 332 basr %r14,%r9 # call sys_xxx
383 stg %r2,SP_R2(%r15) # store return value 333 stg %r2,__PT_R2(%r11) # store return value
384sysc_tracenogo: 334sysc_tracenogo:
385 tm __TI_flags+6(%r12),_TIF_TRACE >> 8 335 tm __TI_flags+6(%r12),_TIF_TRACE >> 8
386 jz sysc_return 336 jz sysc_return
387 la %r2,SP_PTREGS(%r15) # load pt_regs 337 lgr %r2,%r11 # pass pointer to pt_regs
388 larl %r14,sysc_return # return point is sysc_return 338 larl %r14,sysc_return
389 jg do_syscall_trace_exit 339 jg do_syscall_trace_exit
390 340
391# 341#
392# a new process exits the kernel with ret_from_fork 342# a new process exits the kernel with ret_from_fork
393# 343#
394ENTRY(ret_from_fork) 344ENTRY(ret_from_fork)
395 lg %r13,__LC_SVC_NEW_PSW+8 345 la %r11,STACK_FRAME_OVERHEAD(%r15)
396 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 346 lg %r12,__LC_THREAD_INFO
397 tm SP_PSW+1(%r15),0x01 # forking a kernel thread ? 347 tm __PT_PSW+1(%r11),0x01 # forking a kernel thread ?
398 jo 0f 348 jo 0f
399 stg %r15,SP_R15(%r15) # store stack pointer for new kthread 349 stg %r15,__PT_R15(%r11) # store stack pointer for new kthread
4000: brasl %r14,schedule_tail 3500: brasl %r14,schedule_tail
401 TRACE_IRQS_ON 351 TRACE_IRQS_ON
402 stosm 24(%r15),0x03 # reenable interrupts 352 ssm __LC_SVC_NEW_PSW # reenable interrupts
403 j sysc_tracenogo 353 j sysc_tracenogo
404 354
405# 355#
@@ -409,26 +359,26 @@ ENTRY(ret_from_fork)
409ENTRY(kernel_execve) 359ENTRY(kernel_execve)
410 stmg %r12,%r15,96(%r15) 360 stmg %r12,%r15,96(%r15)
411 lgr %r14,%r15 361 lgr %r14,%r15
412 aghi %r15,-SP_SIZE 362 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
413 stg %r14,__SF_BACKCHAIN(%r15) 363 stg %r14,__SF_BACKCHAIN(%r15)
414 la %r12,SP_PTREGS(%r15) 364 la %r12,STACK_FRAME_OVERHEAD(%r15)
415 xc 0(__PT_SIZE,%r12),0(%r12) 365 xc 0(__PT_SIZE,%r12),0(%r12)
416 lgr %r5,%r12 366 lgr %r5,%r12
417 brasl %r14,do_execve 367 brasl %r14,do_execve
418 ltgfr %r2,%r2 368 ltgfr %r2,%r2
419 je 0f 369 je 0f
420 aghi %r15,SP_SIZE 370 aghi %r15,(STACK_FRAME_OVERHEAD + __PT_SIZE)
421 lmg %r12,%r15,96(%r15) 371 lmg %r12,%r15,96(%r15)
422 br %r14 372 br %r14
423 # execve succeeded. 373 # execve succeeded.
4240: stnsm __SF_EMPTY(%r15),0xfc # disable interrupts 3740: ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
425 lg %r15,__LC_KERNEL_STACK # load ksp 375 lg %r15,__LC_KERNEL_STACK # load ksp
426 aghi %r15,-SP_SIZE # make room for registers & psw 376 aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
427 lg %r13,__LC_SVC_NEW_PSW+8 377 la %r11,STACK_FRAME_OVERHEAD(%r15)
428 mvc SP_PTREGS(__PT_SIZE,%r15),0(%r12) # copy pt_regs 378 mvc 0(__PT_SIZE,%r11),0(%r12) # copy pt_regs
429 lg %r12,__LC_THREAD_INFO 379 lg %r12,__LC_THREAD_INFO
430 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) 380 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
431 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 381 ssm __LC_SVC_NEW_PSW # reenable interrupts
432 brasl %r14,execve_tail 382 brasl %r14,execve_tail
433 j sysc_return 383 j sysc_return
434 384
@@ -437,127 +387,72 @@ ENTRY(kernel_execve)
437 */ 387 */
438 388
439ENTRY(pgm_check_handler) 389ENTRY(pgm_check_handler)
440/*
441 * First we need to check for a special case:
442 * Single stepping an instruction that disables the PER event mask will
443 * cause a PER event AFTER the mask has been set. Example: SVC or LPSW.
444 * For a single stepped SVC the program check handler gets control after
445 * the SVC new PSW has been loaded. But we want to execute the SVC first and
446 * then handle the PER event. Therefore we update the SVC old PSW to point
447 * to the pgm_check_handler and branch to the SVC handler after we checked
448 * if we have to load the kernel stack register.
449 * For every other possible cause for PER event without the PER mask set
450 * we just ignore the PER event (FIXME: is there anything we have to do
451 * for LPSW?).
452 */
453 stpt __LC_SYNC_ENTER_TIMER 390 stpt __LC_SYNC_ENTER_TIMER
454 tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception 391 stmg %r8,%r15,__LC_SAVE_AREA_SYNC
455 jnz pgm_per # got per exception -> special case 392 lg %r10,__LC_LAST_BREAK
456 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA 393 lg %r12,__LC_THREAD_INFO
457 CREATE_STACK_FRAME __LC_SAVE_AREA 394 larl %r13,system_call
458 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW 395 lmg %r8,%r9,__LC_PGM_OLD_PSW
459 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 396 HANDLE_SIE_INTERCEPT %r14
460 HANDLE_SIE_INTERCEPT 397 tmhh %r8,0x0001 # test problem state bit
461 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 398 jnz 1f # -> fault in user space
462 jz pgm_no_vtime 399 tmhh %r8,0x4000 # PER bit set in old PSW ?
463 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 400 jnz 0f # -> enabled, can't be a double fault
464 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 401 tm __LC_PGM_ILC+3,0x80 # check for per exception
465 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 402 jnz pgm_svcper # -> single stepped svc
466 LAST_BREAK 4030: CHECK_STACK STACK_SIZE,__LC_SAVE_AREA_SYNC
467pgm_no_vtime: 404 j 2f
468 stg %r11,SP_ARGS(%r15) 4051: UPDATE_VTIME %r14,__LC_SYNC_ENTER_TIMER
469 lgf %r3,__LC_PGM_ILC # load program interruption code 406 LAST_BREAK %r14
470 lg %r4,__LC_TRANS_EXC_CODE 407 lg %r15,__LC_KERNEL_STACK
471 REENABLE_IRQS 4082: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
472 lghi %r8,0x7f 409 la %r11,STACK_FRAME_OVERHEAD(%r15)
473 ngr %r8,%r3 410 stmg %r0,%r7,__PT_R0(%r11)
474 sll %r8,3 411 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_SYNC
475 larl %r1,pgm_check_table 412 stmg %r8,%r9,__PT_PSW(%r11)
476 lg %r1,0(%r8,%r1) # load address of handler routine 413 mvc __PT_INT_CODE(4,%r11),__LC_PGM_ILC
477 la %r2,SP_PTREGS(%r15) # address of register-save area 414 mvc __PT_INT_PARM_LONG(8,%r11),__LC_TRANS_EXC_CODE
478 basr %r14,%r1 # branch to interrupt-handler 415 stg %r10,__PT_ARGS(%r11)
479pgm_exit: 416 tm __LC_PGM_ILC+3,0x80 # check for per exception
480 j sysc_return 417 jz 0f
481
482#
483# handle per exception
484#
485pgm_per:
486 tm __LC_PGM_OLD_PSW,0x40 # test if per event recording is on
487 jnz pgm_per_std # ok, normal per event from user space
488# ok its one of the special cases, now we need to find out which one
489 clc __LC_PGM_OLD_PSW(16),__LC_SVC_NEW_PSW
490 je pgm_svcper
491# no interesting special case, ignore PER event
492 lpswe __LC_PGM_OLD_PSW
493
494#
495# Normal per exception
496#
497pgm_per_std:
498 SAVE_ALL_PGM __LC_PGM_OLD_PSW,__LC_SAVE_AREA
499 CREATE_STACK_FRAME __LC_SAVE_AREA
500 mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW
501 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
502 HANDLE_SIE_INTERCEPT
503 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
504 jz pgm_no_vtime2
505 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
506 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
507 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
508 LAST_BREAK
509pgm_no_vtime2:
510 lg %r1,__TI_task(%r12) 418 lg %r1,__TI_task(%r12)
511 tm SP_PSW+1(%r15),0x01 # kernel per event ? 419 tmhh %r8,0x0001 # kernel per event ?
512 jz kernel_per 420 jz pgm_kprobe
513 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE 421 oi __TI_flags+7(%r12),_TIF_PER_TRAP
514 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS 422 mvc __THREAD_per_address(8,%r1),__LC_PER_ADDRESS
423 mvc __THREAD_per_cause(2,%r1),__LC_PER_CAUSE
515 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID 424 mvc __THREAD_per_paid(1,%r1),__LC_PER_PAID
516 oi __TI_flags+7(%r12),_TIF_PER_TRAP # set TIF_PER_TRAP 4250: REENABLE_IRQS
517 lgf %r3,__LC_PGM_ILC # load program interruption code 426 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
518 lg %r4,__LC_TRANS_EXC_CODE
519 REENABLE_IRQS
520 lghi %r8,0x7f
521 ngr %r8,%r3 # clear per-event-bit and ilc
522 je pgm_exit2
523 sll %r8,3
524 larl %r1,pgm_check_table 427 larl %r1,pgm_check_table
525 lg %r1,0(%r8,%r1) # load address of handler routine 428 llgh %r10,__PT_INT_CODE+2(%r11)
526 la %r2,SP_PTREGS(%r15) # address of register-save area 429 nill %r10,0x007f
430 sll %r10,3
431 je sysc_return
432 lg %r1,0(%r10,%r1) # load address of handler routine
433 lgr %r2,%r11 # pass pointer to pt_regs
527 basr %r14,%r1 # branch to interrupt-handler 434 basr %r14,%r1 # branch to interrupt-handler
528pgm_exit2:
529 j sysc_return 435 j sysc_return
530 436
531# 437#
532# it was a single stepped SVC that is causing all the trouble 438# PER event in supervisor state, must be kprobes
533# 439#
534pgm_svcper: 440pgm_kprobe:
535 SAVE_ALL_PGM __LC_SVC_OLD_PSW,__LC_SAVE_AREA 441 REENABLE_IRQS
536 CREATE_STACK_FRAME __LC_SAVE_AREA 442 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
537 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 443 lgr %r2,%r11 # pass pointer to pt_regs
538 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 444 brasl %r14,do_per_trap
539 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 445 j sysc_return
540 oi __TI_flags+7(%r12),(_TIF_SYSCALL | _TIF_PER_TRAP)
541 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER
542 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
543 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
544 LAST_BREAK
545 lg %r8,__TI_task(%r12)
546 mvc __THREAD_per_cause(2,%r8),__LC_PER_CAUSE
547 mvc __THREAD_per_address(8,%r8),__LC_PER_ADDRESS
548 mvc __THREAD_per_paid(1,%r8),__LC_PER_PAID
549 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts
550 lmg %r2,%r6,SP_R2(%r15) # load svc arguments
551 j sysc_do_svc
552 446
553# 447#
554# per was called from kernel, must be kprobes 448# single stepped system call
555# 449#
556kernel_per: 450pgm_svcper:
557 REENABLE_IRQS 451 oi __TI_flags+7(%r12),_TIF_PER_TRAP
558 la %r2,SP_PTREGS(%r15) # address of register-save area 452 mvc __LC_RETURN_PSW(8),__LC_SVC_NEW_PSW
559 brasl %r14,do_per_trap 453 larl %r14,sysc_per
560 j pgm_exit 454 stg %r14,__LC_RETURN_PSW+8
455 lpswe __LC_RETURN_PSW # branch to sysc_per and enable irqs
561 456
562/* 457/*
563 * IO interrupt handler routine 458 * IO interrupt handler routine
@@ -565,21 +460,25 @@ kernel_per:
565ENTRY(io_int_handler) 460ENTRY(io_int_handler)
566 stck __LC_INT_CLOCK 461 stck __LC_INT_CLOCK
567 stpt __LC_ASYNC_ENTER_TIMER 462 stpt __LC_ASYNC_ENTER_TIMER
568 SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+40 463 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
569 CREATE_STACK_FRAME __LC_SAVE_AREA+40 464 lg %r10,__LC_LAST_BREAK
570 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 465 lg %r12,__LC_THREAD_INFO
571 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 466 larl %r13,system_call
572 HANDLE_SIE_INTERCEPT 467 lmg %r8,%r9,__LC_IO_OLD_PSW
573 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 468 HANDLE_SIE_INTERCEPT %r14
574 jz io_no_vtime 469 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
575 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 470 tmhh %r8,0x0001 # interrupting from user?
576 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 471 jz io_skip
577 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 472 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
578 LAST_BREAK 473 LAST_BREAK %r14
579io_no_vtime: 474io_skip:
475 stmg %r0,%r7,__PT_R0(%r11)
476 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
477 stmg %r8,%r9,__PT_PSW(%r11)
580 TRACE_IRQS_OFF 478 TRACE_IRQS_OFF
581 la %r2,SP_PTREGS(%r15) # address of register-save area 479 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
582 brasl %r14,do_IRQ # call standard irq handler 480 lgr %r2,%r11 # pass pointer to pt_regs
481 brasl %r14,do_IRQ
583io_return: 482io_return:
584 LOCKDEP_SYS_EXIT 483 LOCKDEP_SYS_EXIT
585 TRACE_IRQS_ON 484 TRACE_IRQS_ON
@@ -587,7 +486,14 @@ io_tif:
587 tm __TI_flags+7(%r12),_TIF_WORK_INT 486 tm __TI_flags+7(%r12),_TIF_WORK_INT
588 jnz io_work # there is work to do (signals etc.) 487 jnz io_work # there is work to do (signals etc.)
589io_restore: 488io_restore:
590 RESTORE_ALL __LC_RETURN_PSW,0 489 lg %r14,__LC_VDSO_PER_CPU
490 lmg %r0,%r10,__PT_R0(%r11)
491 mvc __LC_RETURN_PSW(16),__PT_PSW(%r11)
492 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
493 stpt __LC_EXIT_TIMER
494 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
495 lmg %r11,%r15,__PT_R11(%r11)
496 lpswe __LC_RETURN_PSW
591io_done: 497io_done:
592 498
593# 499#
@@ -600,7 +506,7 @@ io_done:
600# Before any work can be done, a switch to the kernel stack is required. 506# Before any work can be done, a switch to the kernel stack is required.
601# 507#
602io_work: 508io_work:
603 tm SP_PSW+1(%r15),0x01 # returning to user ? 509 tm __PT_PSW+1(%r11),0x01 # returning to user ?
604 jo io_work_user # yes -> do resched & signal 510 jo io_work_user # yes -> do resched & signal
605#ifdef CONFIG_PREEMPT 511#ifdef CONFIG_PREEMPT
606 # check for preemptive scheduling 512 # check for preemptive scheduling
@@ -609,10 +515,11 @@ io_work:
609 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED 515 tm __TI_flags+7(%r12),_TIF_NEED_RESCHED
610 jno io_restore 516 jno io_restore
611 # switch to kernel stack 517 # switch to kernel stack
612 lg %r1,SP_R15(%r15) 518 lg %r1,__PT_R15(%r11)
613 aghi %r1,-SP_SIZE 519 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
614 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 520 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
615 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 521 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
522 la %r11,STACK_FRAME_OVERHEAD(%r1)
616 lgr %r15,%r1 523 lgr %r15,%r1
617 # TRACE_IRQS_ON already done at io_return, call 524 # TRACE_IRQS_ON already done at io_return, call
618 # TRACE_IRQS_OFF to keep things symmetrical 525 # TRACE_IRQS_OFF to keep things symmetrical
@@ -628,9 +535,10 @@ io_work:
628# 535#
629io_work_user: 536io_work_user:
630 lg %r1,__LC_KERNEL_STACK 537 lg %r1,__LC_KERNEL_STACK
631 aghi %r1,-SP_SIZE 538 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
632 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 539 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
633 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 540 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
541 la %r11,STACK_FRAME_OVERHEAD(%r1)
634 lgr %r15,%r1 542 lgr %r15,%r1
635 543
636# 544#
@@ -663,9 +571,9 @@ io_mcck_pending:
663# 571#
664io_reschedule: 572io_reschedule:
665 # TRACE_IRQS_ON already done at io_return 573 # TRACE_IRQS_ON already done at io_return
666 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 574 ssm __LC_SVC_NEW_PSW # reenable interrupts
667 brasl %r14,schedule # call scheduler 575 brasl %r14,schedule # call scheduler
668 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 576 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
669 TRACE_IRQS_OFF 577 TRACE_IRQS_OFF
670 j io_return 578 j io_return
671 579
@@ -674,10 +582,10 @@ io_reschedule:
674# 582#
675io_sigpending: 583io_sigpending:
676 # TRACE_IRQS_ON already done at io_return 584 # TRACE_IRQS_ON already done at io_return
677 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 585 ssm __LC_SVC_NEW_PSW # reenable interrupts
678 la %r2,SP_PTREGS(%r15) # load pt_regs 586 lgr %r2,%r11 # pass pointer to pt_regs
679 brasl %r14,do_signal # call do_signal 587 brasl %r14,do_signal
680 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 588 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
681 TRACE_IRQS_OFF 589 TRACE_IRQS_OFF
682 j io_return 590 j io_return
683 591
@@ -686,10 +594,10 @@ io_sigpending:
686# 594#
687io_notify_resume: 595io_notify_resume:
688 # TRACE_IRQS_ON already done at io_return 596 # TRACE_IRQS_ON already done at io_return
689 stosm __SF_EMPTY(%r15),0x03 # reenable interrupts 597 ssm __LC_SVC_NEW_PSW # reenable interrupts
690 la %r2,SP_PTREGS(%r15) # load pt_regs 598 lgr %r2,%r11 # pass pointer to pt_regs
691 brasl %r14,do_notify_resume # call do_notify_resume 599 brasl %r14,do_notify_resume
692 stnsm __SF_EMPTY(%r15),0xfc # disable I/O and ext. interrupts 600 ssm __LC_PGM_NEW_PSW # disable I/O and ext. interrupts
693 TRACE_IRQS_OFF 601 TRACE_IRQS_OFF
694 j io_return 602 j io_return
695 603
@@ -699,21 +607,24 @@ io_notify_resume:
699ENTRY(ext_int_handler) 607ENTRY(ext_int_handler)
700 stck __LC_INT_CLOCK 608 stck __LC_INT_CLOCK
701 stpt __LC_ASYNC_ENTER_TIMER 609 stpt __LC_ASYNC_ENTER_TIMER
702 SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+40 610 stmg %r8,%r15,__LC_SAVE_AREA_ASYNC
703 CREATE_STACK_FRAME __LC_SAVE_AREA+40 611 lg %r10,__LC_LAST_BREAK
704 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 612 lg %r12,__LC_THREAD_INFO
705 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct 613 larl %r13,system_call
706 HANDLE_SIE_INTERCEPT 614 lmg %r8,%r9,__LC_EXT_OLD_PSW
707 tm SP_PSW+1(%r15),0x01 # interrupting from user ? 615 HANDLE_SIE_INTERCEPT %r14
708 jz ext_no_vtime 616 SWITCH_ASYNC __LC_SAVE_AREA_ASYNC,__LC_ASYNC_STACK,STACK_SHIFT
709 UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER 617 tmhh %r8,0x0001 # interrupting from user ?
710 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 618 jz ext_skip
711 mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER 619 UPDATE_VTIME %r14,__LC_ASYNC_ENTER_TIMER
712 LAST_BREAK 620 LAST_BREAK %r14
713ext_no_vtime: 621ext_skip:
622 stmg %r0,%r7,__PT_R0(%r11)
623 mvc __PT_R8(64,%r11),__LC_SAVE_AREA_ASYNC
624 stmg %r8,%r9,__PT_PSW(%r11)
714 TRACE_IRQS_OFF 625 TRACE_IRQS_OFF
715 lghi %r1,4096 626 lghi %r1,4096
716 la %r2,SP_PTREGS(%r15) # address of register-save area 627 lgr %r2,%r11 # pass pointer to pt_regs
717 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code 628 llgf %r3,__LC_CPU_ADDRESS # get cpu address + interruption code
718 llgf %r4,__LC_EXT_PARAMS # get external parameter 629 llgf %r4,__LC_EXT_PARAMS # get external parameter
719 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter 630 lg %r5,__LC_EXT_PARAMS2-4096(%r1) # get 64 bit external parameter
@@ -730,81 +641,77 @@ ENTRY(mcck_int_handler)
730 la %r1,4095 # revalidate r1 641 la %r1,4095 # revalidate r1
731 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer 642 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer
732 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs 643 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs
733 stmg %r11,%r15,__LC_SAVE_AREA+80 644 lg %r10,__LC_LAST_BREAK
645 lg %r12,__LC_THREAD_INFO
734 larl %r13,system_call 646 larl %r13,system_call
735 lg %r11,__LC_LAST_BREAK 647 lmg %r8,%r9,__LC_MCK_OLD_PSW
736 la %r12,__LC_MCK_OLD_PSW 648 HANDLE_SIE_INTERCEPT %r14
737 tm __LC_MCCK_CODE,0x80 # system damage? 649 tm __LC_MCCK_CODE,0x80 # system damage?
738 jo mcck_int_main # yes -> rest of mcck code invalid 650 jo mcck_panic # yes -> rest of mcck code invalid
739 la %r14,4095 651 lghi %r14,__LC_CPU_TIMER_SAVE_AREA
740 mvc __LC_MCCK_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) 652 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
741 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? 653 tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid?
742 jo 1f 654 jo 3f
743 la %r14,__LC_SYNC_ENTER_TIMER 655 la %r14,__LC_SYNC_ENTER_TIMER
744 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER 656 clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER
745 jl 0f 657 jl 0f
746 la %r14,__LC_ASYNC_ENTER_TIMER 658 la %r14,__LC_ASYNC_ENTER_TIMER
7470: clc 0(8,%r14),__LC_EXIT_TIMER 6590: clc 0(8,%r14),__LC_EXIT_TIMER
748 jl 0f 660 jl 1f
749 la %r14,__LC_EXIT_TIMER 661 la %r14,__LC_EXIT_TIMER
7500: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER 6621: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER
751 jl 0f 663 jl 2f
752 la %r14,__LC_LAST_UPDATE_TIMER 664 la %r14,__LC_LAST_UPDATE_TIMER
7530: spt 0(%r14) 6652: spt 0(%r14)
754 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14) 666 mvc __LC_MCCK_ENTER_TIMER(8),0(%r14)
7551: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? 6673: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid?
756 jno mcck_int_main # no -> skip cleanup critical 668 jno mcck_panic # no -> skip cleanup critical
757 tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit 669 SWITCH_ASYNC __LC_GPREGS_SAVE_AREA+64,__LC_PANIC_STACK,PAGE_SHIFT
758 jnz mcck_int_main # from user -> load kernel stack 670 tm %r8,0x0001 # interrupting from user ?
759 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_end) 671 jz mcck_skip
760 jhe mcck_int_main 672 UPDATE_VTIME %r14,__LC_MCCK_ENTER_TIMER
761 clc __LC_MCK_OLD_PSW+8(8),BASED(.Lcritical_start) 673 LAST_BREAK %r14
762 jl mcck_int_main 674mcck_skip:
763 brasl %r14,cleanup_critical 675 lghi %r14,__LC_GPREGS_SAVE_AREA
764mcck_int_main: 676 mvc __PT_R0(128,%r11),0(%r14)
765 lg %r14,__LC_PANIC_STACK # are we already on the panic stack? 677 stmg %r8,%r9,__PT_PSW(%r11)
766 slgr %r14,%r15 678 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
767 srag %r14,%r14,PAGE_SHIFT 679 lgr %r2,%r11 # pass pointer to pt_regs
768 jz 0f
769 lg %r15,__LC_PANIC_STACK # load panic stack
7700: aghi %r15,-SP_SIZE # make room for registers & psw
771 CREATE_STACK_FRAME __LC_SAVE_AREA+80
772 mvc SP_PSW(16,%r15),0(%r12)
773 lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct
774 tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid?
775 jno mcck_no_vtime # no -> no timer update
776 HANDLE_SIE_INTERCEPT
777 tm SP_PSW+1(%r15),0x01 # interrupting from user ?
778 jz mcck_no_vtime
779 UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER
780 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER
781 mvc __LC_LAST_UPDATE_TIMER(8),__LC_MCCK_ENTER_TIMER
782 LAST_BREAK
783mcck_no_vtime:
784 la %r2,SP_PTREGS(%r15) # load pt_regs
785 brasl %r14,s390_do_machine_check 680 brasl %r14,s390_do_machine_check
786 tm SP_PSW+1(%r15),0x01 # returning to user ? 681 tm __PT_PSW+1(%r11),0x01 # returning to user ?
787 jno mcck_return 682 jno mcck_return
788 lg %r1,__LC_KERNEL_STACK # switch to kernel stack 683 lg %r1,__LC_KERNEL_STACK # switch to kernel stack
789 aghi %r1,-SP_SIZE 684 aghi %r1,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
790 mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) 685 mvc STACK_FRAME_OVERHEAD(__PT_SIZE,%r1),0(%r11)
791 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1) # clear back chain 686 xc __SF_BACKCHAIN(8,%r1),__SF_BACKCHAIN(%r1)
687 la %r11,STACK_FRAME_OVERHEAD(%r1)
792 lgr %r15,%r1 688 lgr %r15,%r1
793 stosm __SF_EMPTY(%r15),0x04 # turn dat on 689 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
794 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING 690 tm __TI_flags+7(%r12),_TIF_MCCK_PENDING
795 jno mcck_return 691 jno mcck_return
796 TRACE_IRQS_OFF 692 TRACE_IRQS_OFF
797 brasl %r14,s390_handle_mcck 693 brasl %r14,s390_handle_mcck
798 TRACE_IRQS_ON 694 TRACE_IRQS_ON
799mcck_return: 695mcck_return:
800 mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW 696 lg %r14,__LC_VDSO_PER_CPU
697 lmg %r0,%r10,__PT_R0(%r11)
698 mvc __LC_RETURN_MCCK_PSW(16),__PT_PSW(%r11) # move return PSW
801 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit 699 ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit
802 lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15
803 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? 700 tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ?
804 jno 0f 701 jno 0f
805 stpt __LC_EXIT_TIMER 702 stpt __LC_EXIT_TIMER
8060: lpswe __LC_RETURN_MCCK_PSW # back to caller 703 mvc __VDSO_ECTG_BASE(16,%r14),__LC_EXIT_TIMER
807mcck_done: 7040: lmg %r11,%r15,__PT_R11(%r11)
705 lpswe __LC_RETURN_MCCK_PSW
706
707mcck_panic:
708 lg %r14,__LC_PANIC_STACK
709 slgr %r14,%r15
710 srag %r14,%r14,PAGE_SHIFT
711 jz 0f
712 lg %r15,__LC_PANIC_STACK
7130: aghi %r15,-(STACK_FRAME_OVERHEAD + __PT_SIZE)
714 j mcck_skip
808 715
809/* 716/*
810 * Restart interruption handler, kick starter for additional CPUs 717 * Restart interruption handler, kick starter for additional CPUs
@@ -818,17 +725,18 @@ restart_base:
818 stck __LC_LAST_UPDATE_CLOCK 725 stck __LC_LAST_UPDATE_CLOCK
819 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1) 726 mvc __LC_LAST_UPDATE_TIMER(8),restart_vtime-restart_base(%r1)
820 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1) 727 mvc __LC_EXIT_TIMER(8),restart_vtime-restart_base(%r1)
821 lg %r15,__LC_SAVE_AREA+120 # load ksp 728 lghi %r10,__LC_GPREGS_SAVE_AREA
729 lg %r15,120(%r10) # load ksp
822 lghi %r10,__LC_CREGS_SAVE_AREA 730 lghi %r10,__LC_CREGS_SAVE_AREA
823 lctlg %c0,%c15,0(%r10) # get new ctl regs 731 lctlg %c0,%c15,0(%r10) # get new ctl regs
824 lghi %r10,__LC_AREGS_SAVE_AREA 732 lghi %r10,__LC_AREGS_SAVE_AREA
825 lam %a0,%a15,0(%r10) 733 lam %a0,%a15,0(%r10)
826 lmg %r6,%r15,__SF_GPRS(%r15) # load registers from clone 734 lmg %r6,%r15,__SF_GPRS(%r15)# load registers from clone
827 lg %r1,__LC_THREAD_INFO 735 lg %r1,__LC_THREAD_INFO
828 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1) 736 mvc __LC_USER_TIMER(8),__TI_user_timer(%r1)
829 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1) 737 mvc __LC_SYSTEM_TIMER(8),__TI_system_timer(%r1)
830 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER 738 xc __LC_STEAL_TIMER(8),__LC_STEAL_TIMER
831 stosm __SF_EMPTY(%r15),0x04 # now we can turn dat on 739 ssm __LC_PGM_NEW_PSW # turn dat on, keep irqs off
832 brasl %r14,start_secondary 740 brasl %r14,start_secondary
833 .align 8 741 .align 8
834restart_vtime: 742restart_vtime:
@@ -852,16 +760,16 @@ restart_go:
852# PSW restart interrupt handler 760# PSW restart interrupt handler
853# 761#
854ENTRY(psw_restart_int_handler) 762ENTRY(psw_restart_int_handler)
855 stg %r15,__LC_SAVE_AREA+120(%r0) # save r15 763 stg %r15,__LC_SAVE_AREA_RESTART
856 larl %r15,restart_stack # load restart stack 764 larl %r15,restart_stack # load restart stack
857 lg %r15,0(%r15) 765 lg %r15,0(%r15)
858 aghi %r15,-SP_SIZE # make room for pt_regs 766 aghi %r15,-__PT_SIZE # create pt_regs on stack
859 stmg %r0,%r14,SP_R0(%r15) # store gprs %r0-%r14 to stack 767 stmg %r0,%r14,__PT_R0(%r15)
860 mvc SP_R15(8,%r15),__LC_SAVE_AREA+120(%r0)# store saved %r15 to stack 768 mvc __PT_R15(8,%r15),__LC_SAVE_AREA_RESTART
861 mvc SP_PSW(16,%r15),__LC_RST_OLD_PSW(%r0)# store restart old psw 769 mvc __PT_PSW(16,%r15),__LC_RST_OLD_PSW # store restart old psw
862 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # set backchain to 0 770 aghi %r15,-STACK_FRAME_OVERHEAD
771 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
863 brasl %r14,do_restart 772 brasl %r14,do_restart
864
865 larl %r14,restart_psw_crash # load disabled wait PSW if 773 larl %r14,restart_psw_crash # load disabled wait PSW if
866 lpswe 0(%r14) # do_restart returns 774 lpswe 0(%r14) # do_restart returns
867 .align 8 775 .align 8
@@ -877,172 +785,153 @@ restart_psw_crash:
877 * Setup a pt_regs so that show_trace can provide a good call trace. 785 * Setup a pt_regs so that show_trace can provide a good call trace.
878 */ 786 */
879stack_overflow: 787stack_overflow:
880 lg %r15,__LC_PANIC_STACK # change to panic stack 788 lg %r11,__LC_PANIC_STACK # change to panic stack
881 aghi %r15,-SP_SIZE 789 aghi %r11,-__PT_SIZE # create pt_regs
882 mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack 790 stmg %r0,%r7,__PT_R0(%r11)
883 stmg %r0,%r10,SP_R0(%r15) # store gprs %r0-%r10 to kernel stack 791 stmg %r8,%r9,__PT_PSW(%r11)
884 la %r1,__LC_SAVE_AREA 792 mvc __PT_R8(64,%r11),0(%r14)
885 chi %r12,__LC_SVC_OLD_PSW 793 stg %r10,__PT_ORIG_GPR2(%r11) # store last break to orig_gpr2
886 je 0f 794 lgr %r15,%r11
887 chi %r12,__LC_PGM_OLD_PSW 795 aghi %r15,-STACK_FRAME_OVERHEAD
888 je 0f 796 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15)
889 la %r1,__LC_SAVE_AREA+40 797 lgr %r2,%r11 # pass pointer to pt_regs
8900: mvc SP_R11(40,%r15),0(%r1) # move %r11-%r15 to stack
891 mvc SP_ARGS(8,%r15),__LC_LAST_BREAK
892 xc __SF_BACKCHAIN(8,%r15),__SF_BACKCHAIN(%r15) # clear back chain
893 la %r2,SP_PTREGS(%r15) # load pt_regs
894 jg kernel_stack_overflow 798 jg kernel_stack_overflow
895#endif 799#endif
896 800
897cleanup_table_system_call: 801 .align 8
898 .quad system_call, sysc_do_svc 802cleanup_table:
899cleanup_table_sysc_tif: 803 .quad system_call
900 .quad sysc_tif, sysc_restore 804 .quad sysc_do_svc
901cleanup_table_sysc_restore: 805 .quad sysc_tif
902 .quad sysc_restore, sysc_done 806 .quad sysc_restore
903cleanup_table_io_tif: 807 .quad sysc_done
904 .quad io_tif, io_restore 808 .quad io_tif
905cleanup_table_io_restore: 809 .quad io_restore
906 .quad io_restore, io_done 810 .quad io_done
907 811
908cleanup_critical: 812cleanup_critical:
909 clc 8(8,%r12),BASED(cleanup_table_system_call) 813 clg %r9,BASED(cleanup_table) # system_call
910 jl 0f 814 jl 0f
911 clc 8(8,%r12),BASED(cleanup_table_system_call+8) 815 clg %r9,BASED(cleanup_table+8) # sysc_do_svc
912 jl cleanup_system_call 816 jl cleanup_system_call
9130: 817 clg %r9,BASED(cleanup_table+16) # sysc_tif
914 clc 8(8,%r12),BASED(cleanup_table_sysc_tif)
915 jl 0f 818 jl 0f
916 clc 8(8,%r12),BASED(cleanup_table_sysc_tif+8) 819 clg %r9,BASED(cleanup_table+24) # sysc_restore
917 jl cleanup_sysc_tif 820 jl cleanup_sysc_tif
9180: 821 clg %r9,BASED(cleanup_table+32) # sysc_done
919 clc 8(8,%r12),BASED(cleanup_table_sysc_restore)
920 jl 0f
921 clc 8(8,%r12),BASED(cleanup_table_sysc_restore+8)
922 jl cleanup_sysc_restore 822 jl cleanup_sysc_restore
9230: 823 clg %r9,BASED(cleanup_table+40) # io_tif
924 clc 8(8,%r12),BASED(cleanup_table_io_tif)
925 jl 0f 824 jl 0f
926 clc 8(8,%r12),BASED(cleanup_table_io_tif+8) 825 clg %r9,BASED(cleanup_table+48) # io_restore
927 jl cleanup_io_tif 826 jl cleanup_io_tif
9280: 827 clg %r9,BASED(cleanup_table+56) # io_done
929 clc 8(8,%r12),BASED(cleanup_table_io_restore)
930 jl 0f
931 clc 8(8,%r12),BASED(cleanup_table_io_restore+8)
932 jl cleanup_io_restore 828 jl cleanup_io_restore
9330: 8290: br %r14
934 br %r14 830
935 831
936cleanup_system_call: 832cleanup_system_call:
937 mvc __LC_RETURN_PSW(16),0(%r12) 833 # check if stpt has been executed
938 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+8) 834 clg %r9,BASED(cleanup_system_call_insn)
939 jh 0f 835 jh 0f
940 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
941 cghi %r12,__LC_MCK_OLD_PSW
942 je 0f
943 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER 836 mvc __LC_SYNC_ENTER_TIMER(8),__LC_ASYNC_ENTER_TIMER
9440: cghi %r12,__LC_MCK_OLD_PSW 837 cghi %r11,__LC_SAVE_AREA_ASYNC
945 la %r12,__LC_SAVE_AREA+80
946 je 0f 838 je 0f
947 la %r12,__LC_SAVE_AREA+40 839 mvc __LC_SYNC_ENTER_TIMER(8),__LC_MCCK_ENTER_TIMER
9480: clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+16) 8400: # check if stmg has been executed
949 jhe cleanup_vtime 841 clg %r9,BASED(cleanup_system_call_insn+8)
950 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn)
951 jh 0f 842 jh 0f
952 mvc __LC_SAVE_AREA(40),0(%r12) 843 mvc __LC_SAVE_AREA_SYNC(64),0(%r11)
9530: lg %r15,__LC_KERNEL_STACK # problem state -> load ksp 8440: # check if base register setup + TIF bit load has been done
954 aghi %r15,-SP_SIZE # make room for registers & psw 845 clg %r9,BASED(cleanup_system_call_insn+16)
955 stg %r15,32(%r12) 846 jhe 0f
956 stg %r11,0(%r12) 847 # set up saved registers r10 and r12
957 CREATE_STACK_FRAME __LC_SAVE_AREA 848 stg %r10,16(%r11) # r10 last break
958 mvc 8(8,%r12),__LC_THREAD_INFO 849 stg %r12,32(%r11) # r12 thread-info pointer
959 lg %r12,__LC_THREAD_INFO 8500: # check if the user time update has been done
960 mvc SP_PSW(16,%r15),__LC_SVC_OLD_PSW 851 clg %r9,BASED(cleanup_system_call_insn+24)
961 mvc SP_SVC_CODE(4,%r15),__LC_SVC_ILC 852 jh 0f
962 oi __TI_flags+7(%r12),_TIF_SYSCALL 853 lg %r15,__LC_EXIT_TIMER
963cleanup_vtime: 854 slg %r15,__LC_SYNC_ENTER_TIMER
964 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+24) 855 alg %r15,__LC_USER_TIMER
965 jhe cleanup_stime 856 stg %r15,__LC_USER_TIMER
966 UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER 8570: # check if the system time update has been done
967cleanup_stime: 858 clg %r9,BASED(cleanup_system_call_insn+32)
968 clc __LC_RETURN_PSW+8(8),BASED(cleanup_system_call_insn+32) 859 jh 0f
969 jh cleanup_update 860 lg %r15,__LC_LAST_UPDATE_TIMER
970 UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER 861 slg %r15,__LC_EXIT_TIMER
971cleanup_update: 862 alg %r15,__LC_SYSTEM_TIMER
863 stg %r15,__LC_SYSTEM_TIMER
8640: # update accounting time stamp
972 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER 865 mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER
973 srag %r12,%r11,23 866 # do LAST_BREAK
974 lg %r12,__LC_THREAD_INFO 867 lg %r9,16(%r11)
868 srag %r9,%r9,23
975 jz 0f 869 jz 0f
976 stg %r11,__TI_last_break(%r12) 870 mvc __TI_last_break(8,%r12),16(%r11)
9770: mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_system_call+8) 8710: # set up saved register r11
978 la %r12,__LC_RETURN_PSW 872 lg %r15,__LC_KERNEL_STACK
873 aghi %r15,-__PT_SIZE
874 stg %r15,24(%r11) # r11 pt_regs pointer
875 # fill pt_regs
876 mvc __PT_R8(64,%r15),__LC_SAVE_AREA_SYNC
877 stmg %r0,%r7,__PT_R0(%r15)
878 mvc __PT_PSW(16,%r15),__LC_SVC_OLD_PSW
879 mvc __PT_INT_CODE(4,%r15),__LC_SVC_ILC
880 # setup saved register r15
881 aghi %r15,-STACK_FRAME_OVERHEAD
882 stg %r15,56(%r11) # r15 stack pointer
883 # set new psw address and exit
884 larl %r9,sysc_do_svc
979 br %r14 885 br %r14
980cleanup_system_call_insn: 886cleanup_system_call_insn:
981 .quad sysc_saveall
982 .quad system_call 887 .quad system_call
983 .quad sysc_vtime 888 .quad sysc_stmg
984 .quad sysc_stime 889 .quad sysc_per
985 .quad sysc_update 890 .quad sysc_vtime+18
891 .quad sysc_vtime+42
986 892
987cleanup_sysc_tif: 893cleanup_sysc_tif:
988 mvc __LC_RETURN_PSW(8),0(%r12) 894 larl %r9,sysc_tif
989 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_sysc_tif)
990 la %r12,__LC_RETURN_PSW
991 br %r14 895 br %r14
992 896
993cleanup_sysc_restore: 897cleanup_sysc_restore:
994 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn) 898 clg %r9,BASED(cleanup_sysc_restore_insn)
995 je 2f
996 clc 8(8,%r12),BASED(cleanup_sysc_restore_insn+8)
997 jhe 0f
998 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER
999 cghi %r12,__LC_MCK_OLD_PSW
1000 je 0f 899 je 0f
1001 mvc __LC_EXIT_TIMER(8),__LC_ASYNC_ENTER_TIMER 900 lg %r9,24(%r11) # get saved pointer to pt_regs
10020: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 901 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1003 cghi %r12,__LC_MCK_OLD_PSW 902 mvc 0(64,%r11),__PT_R8(%r9)
1004 la %r12,__LC_SAVE_AREA+80 903 lmg %r0,%r7,__PT_R0(%r9)
1005 je 1f 9040: lmg %r8,%r9,__LC_RETURN_PSW
1006 la %r12,__LC_SAVE_AREA+40
10071: mvc 0(40,%r12),SP_R11(%r15)
1008 lmg %r0,%r10,SP_R0(%r15)
1009 lg %r15,SP_R15(%r15)
10102: la %r12,__LC_RETURN_PSW
1011 br %r14 905 br %r14
1012cleanup_sysc_restore_insn: 906cleanup_sysc_restore_insn:
1013 .quad sysc_done - 4 907 .quad sysc_done - 4
1014 .quad sysc_done - 16
1015 908
1016cleanup_io_tif: 909cleanup_io_tif:
1017 mvc __LC_RETURN_PSW(8),0(%r12) 910 larl %r9,io_tif
1018 mvc __LC_RETURN_PSW+8(8),BASED(cleanup_table_io_tif)
1019 la %r12,__LC_RETURN_PSW
1020 br %r14 911 br %r14
1021 912
1022cleanup_io_restore: 913cleanup_io_restore:
1023 clc 8(8,%r12),BASED(cleanup_io_restore_insn) 914 clg %r9,BASED(cleanup_io_restore_insn)
1024 je 1f 915 je 0f
1025 clc 8(8,%r12),BASED(cleanup_io_restore_insn+8) 916 lg %r9,24(%r11) # get saved r11 pointer to pt_regs
1026 jhe 0f 917 mvc __LC_RETURN_PSW(16),__PT_PSW(%r9)
1027 mvc __LC_EXIT_TIMER(8),__LC_MCCK_ENTER_TIMER 918 ni __LC_RETURN_PSW+1,0xfd # clear wait state bit
10280: mvc __LC_RETURN_PSW(16),SP_PSW(%r15) 919 mvc 0(64,%r11),__PT_R8(%r9)
1029 mvc __LC_SAVE_AREA+80(40),SP_R11(%r15) 920 lmg %r0,%r7,__PT_R0(%r9)
1030 lmg %r0,%r10,SP_R0(%r15) 9210: lmg %r8,%r9,__LC_RETURN_PSW
1031 lg %r15,SP_R15(%r15)
10321: la %r12,__LC_RETURN_PSW
1033 br %r14 922 br %r14
1034cleanup_io_restore_insn: 923cleanup_io_restore_insn:
1035 .quad io_done - 4 924 .quad io_done - 4
1036 .quad io_done - 16
1037 925
1038/* 926/*
1039 * Integer constants 927 * Integer constants
1040 */ 928 */
1041 .align 4 929 .align 8
1042.Lcritical_start: 930.Lcritical_start:
1043 .quad __critical_start 931 .quad __critical_start
1044.Lcritical_end: 932.Lcritical_length:
1045 .quad __critical_end 933 .quad __critical_end - __critical_start
934
1046 935
1047#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) 936#if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE)
1048/* 937/*
@@ -1054,6 +943,7 @@ ENTRY(sie64a)
1054 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers 943 stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
1055 stg %r2,__SF_EMPTY(%r15) # save control block pointer 944 stg %r2,__SF_EMPTY(%r15) # save control block pointer
1056 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area 945 stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
946 xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # host id == 0
1057 lmg %r0,%r13,0(%r3) # load guest gprs 0-13 947 lmg %r0,%r13,0(%r3) # load guest gprs 0-13
1058 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 948 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1059 oi __TI_flags+6(%r14),_TIF_SIE>>8 949 oi __TI_flags+6(%r14),_TIF_SIE>>8
@@ -1070,7 +960,7 @@ sie_gmap:
1070 SPP __SF_EMPTY(%r15) # set guest id 960 SPP __SF_EMPTY(%r15) # set guest id
1071 sie 0(%r14) 961 sie 0(%r14)
1072sie_done: 962sie_done:
1073 SPP __LC_CMF_HPP # set host id 963 SPP __SF_EMPTY+16(%r15) # set host id
1074 lg %r14,__LC_THREAD_INFO # pointer thread_info struct 964 lg %r14,__LC_THREAD_INFO # pointer thread_info struct
1075sie_exit: 965sie_exit:
1076 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce 966 lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
@@ -1093,8 +983,10 @@ sie_fault:
1093 .align 8 983 .align 8
1094.Lsie_loop: 984.Lsie_loop:
1095 .quad sie_loop 985 .quad sie_loop
1096.Lsie_done: 986.Lsie_length:
1097 .quad sie_done 987 .quad sie_done - sie_loop
988.Lhost_id:
989 .quad 0
1098 990
1099 .section __ex_table,"a" 991 .section __ex_table,"a"
1100 .quad sie_loop,sie_fault 992 .quad sie_loop,sie_fault
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 900068d2bf92..c27a0727f930 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -329,8 +329,8 @@ iplstart:
329# 329#
330# reset files in VM reader 330# reset files in VM reader
331# 331#
332 stidp __LC_SAVE_AREA # store cpuid 332 stidp __LC_SAVE_AREA_SYNC # store cpuid
333 tm __LC_SAVE_AREA,0xff # running VM ? 333 tm __LC_SAVE_AREA_SYNC,0xff# running VM ?
334 bno .Lnoreset 334 bno .Lnoreset
335 la %r2,.Lreset 335 la %r2,.Lreset
336 lhi %r3,26 336 lhi %r3,26
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 3cd0f25ab015..47b168fb29c4 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -208,6 +208,7 @@ void machine_kexec_cleanup(struct kimage *image)
208void arch_crash_save_vmcoreinfo(void) 208void arch_crash_save_vmcoreinfo(void)
209{ 209{
210 VMCOREINFO_SYMBOL(lowcore_ptr); 210 VMCOREINFO_SYMBOL(lowcore_ptr);
211 VMCOREINFO_SYMBOL(high_memory);
211 VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS); 212 VMCOREINFO_LENGTH(lowcore_ptr, NR_CPUS);
212} 213}
213 214
diff --git a/arch/s390/kernel/mem_detect.c b/arch/s390/kernel/mem_detect.c
index 19b4568f4cee..22d502e885ed 100644
--- a/arch/s390/kernel/mem_detect.c
+++ b/arch/s390/kernel/mem_detect.c
@@ -64,70 +64,82 @@ void detect_memory_layout(struct mem_chunk chunk[])
64EXPORT_SYMBOL(detect_memory_layout); 64EXPORT_SYMBOL(detect_memory_layout);
65 65
66/* 66/*
67 * Move memory chunks array from index "from" to index "to"
68 */
69static void mem_chunk_move(struct mem_chunk chunk[], int to, int from)
70{
71 int cnt = MEMORY_CHUNKS - to;
72
73 memmove(&chunk[to], &chunk[from], cnt * sizeof(struct mem_chunk));
74}
75
76/*
77 * Initialize memory chunk
78 */
79static void mem_chunk_init(struct mem_chunk *chunk, unsigned long addr,
80 unsigned long size, int type)
81{
82 chunk->type = type;
83 chunk->addr = addr;
84 chunk->size = size;
85}
86
87/*
67 * Create memory hole with given address, size, and type 88 * Create memory hole with given address, size, and type
68 */ 89 */
69void create_mem_hole(struct mem_chunk chunks[], unsigned long addr, 90void create_mem_hole(struct mem_chunk chunk[], unsigned long addr,
70 unsigned long size, int type) 91 unsigned long size, int type)
71{ 92{
72 unsigned long start, end, new_size; 93 unsigned long lh_start, lh_end, lh_size, ch_start, ch_end, ch_size;
73 int i; 94 int i, ch_type;
74 95
75 for (i = 0; i < MEMORY_CHUNKS; i++) { 96 for (i = 0; i < MEMORY_CHUNKS; i++) {
76 if (chunks[i].size == 0) 97 if (chunk[i].size == 0)
77 continue;
78 if (addr + size < chunks[i].addr)
79 continue;
80 if (addr >= chunks[i].addr + chunks[i].size)
81 continue; 98 continue;
82 start = max(addr, chunks[i].addr); 99
83 end = min(addr + size, chunks[i].addr + chunks[i].size); 100 /* Define chunk properties */
84 new_size = end - start; 101 ch_start = chunk[i].addr;
85 if (new_size == 0) 102 ch_size = chunk[i].size;
86 continue; 103 ch_end = ch_start + ch_size - 1;
87 if (start == chunks[i].addr && 104 ch_type = chunk[i].type;
88 end == chunks[i].addr + chunks[i].size) { 105
89 /* Remove chunk */ 106 /* Is memory chunk hit by memory hole? */
90 chunks[i].type = type; 107 if (addr + size <= ch_start)
91 } else if (start == chunks[i].addr) { 108 continue; /* No: memory hole in front of chunk */
92 /* Make chunk smaller at start */ 109 if (addr > ch_end)
93 if (i >= MEMORY_CHUNKS - 1) 110 continue; /* No: memory hole after chunk */
94 panic("Unable to create memory hole"); 111
95 memmove(&chunks[i + 1], &chunks[i], 112 /* Yes: Define local hole properties */
96 sizeof(struct mem_chunk) * 113 lh_start = max(addr, chunk[i].addr);
97 (MEMORY_CHUNKS - (i + 1))); 114 lh_end = min(addr + size - 1, ch_end);
98 chunks[i + 1].addr = chunks[i].addr + new_size; 115 lh_size = lh_end - lh_start + 1;
99 chunks[i + 1].size = chunks[i].size - new_size; 116
100 chunks[i].size = new_size; 117 if (lh_start == ch_start && lh_end == ch_end) {
101 chunks[i].type = type; 118 /* Hole covers complete memory chunk */
102 i += 1; 119 mem_chunk_init(&chunk[i], lh_start, lh_size, type);
103 } else if (end == chunks[i].addr + chunks[i].size) { 120 } else if (lh_end == ch_end) {
104 /* Make chunk smaller at end */ 121 /* Hole starts in memory chunk and convers chunk end */
105 if (i >= MEMORY_CHUNKS - 1) 122 mem_chunk_move(chunk, i + 1, i);
106 panic("Unable to create memory hole"); 123 mem_chunk_init(&chunk[i], ch_start, ch_size - lh_size,
107 memmove(&chunks[i + 1], &chunks[i], 124 ch_type);
108 sizeof(struct mem_chunk) * 125 mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
109 (MEMORY_CHUNKS - (i + 1)));
110 chunks[i + 1].addr = start;
111 chunks[i + 1].size = new_size;
112 chunks[i + 1].type = type;
113 chunks[i].size -= new_size;
114 i += 1; 126 i += 1;
127 } else if (lh_start == ch_start) {
128 /* Hole ends in memory chunk */
129 mem_chunk_move(chunk, i + 1, i);
130 mem_chunk_init(&chunk[i], lh_start, lh_size, type);
131 mem_chunk_init(&chunk[i + 1], lh_end + 1,
132 ch_size - lh_size, ch_type);
133 break;
115 } else { 134 } else {
116 /* Create memory hole */ 135 /* Hole splits memory chunk */
117 if (i >= MEMORY_CHUNKS - 2) 136 mem_chunk_move(chunk, i + 2, i);
118 panic("Unable to create memory hole"); 137 mem_chunk_init(&chunk[i], ch_start,
119 memmove(&chunks[i + 2], &chunks[i], 138 lh_start - ch_start, ch_type);
120 sizeof(struct mem_chunk) * 139 mem_chunk_init(&chunk[i + 1], lh_start, lh_size, type);
121 (MEMORY_CHUNKS - (i + 2))); 140 mem_chunk_init(&chunk[i + 2], lh_end + 1,
122 chunks[i + 1].addr = addr; 141 ch_end - lh_end, ch_type);
123 chunks[i + 1].size = size; 142 break;
124 chunks[i + 1].type = type;
125 chunks[i + 2].addr = addr + size;
126 chunks[i + 2].size =
127 chunks[i].addr + chunks[i].size - (addr + size);
128 chunks[i + 2].type = chunks[i].type;
129 chunks[i].size = addr - chunks[i].addr;
130 i += 2;
131 } 143 }
132 } 144 }
133} 145}
diff --git a/arch/s390/kernel/nmi.c b/arch/s390/kernel/nmi.c
index fab88431a06f..0fd2e863e114 100644
--- a/arch/s390/kernel/nmi.c
+++ b/arch/s390/kernel/nmi.c
@@ -30,7 +30,7 @@ struct mcck_struct {
30 30
31static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck); 31static DEFINE_PER_CPU(struct mcck_struct, cpu_mcck);
32 32
33static NORET_TYPE void s390_handle_damage(char *msg) 33static void s390_handle_damage(char *msg)
34{ 34{
35 smp_send_stop(); 35 smp_send_stop();
36 disabled_wait((unsigned long) __builtin_return_address(0)); 36 disabled_wait((unsigned long) __builtin_return_address(0));
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index 732a793ec53a..36b32658fb24 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -17,11 +17,11 @@
17# 17#
18ENTRY(store_status) 18ENTRY(store_status)
19 /* Save register one and load save area base */ 19 /* Save register one and load save area base */
20 stg %r1,__LC_SAVE_AREA+120(%r0) 20 stg %r1,__LC_SAVE_AREA_RESTART
21 lghi %r1,SAVE_AREA_BASE 21 lghi %r1,SAVE_AREA_BASE
22 /* General purpose registers */ 22 /* General purpose registers */
23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 23 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
24 lg %r2,__LC_SAVE_AREA+120(%r0) 24 lg %r2,__LC_SAVE_AREA_RESTART
25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1) 25 stg %r2,__LC_GPREGS_SAVE_AREA-SAVE_AREA_BASE+8(%r1)
26 /* Control registers */ 26 /* Control registers */
27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1) 27 stctg %c0,%c15,__LC_CREGS_SAVE_AREA-SAVE_AREA_BASE(%r1)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f11d1b037c50..354de0763eff 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -95,6 +95,15 @@ struct mem_chunk __initdata memory_chunk[MEMORY_CHUNKS];
95int __initdata memory_end_set; 95int __initdata memory_end_set;
96unsigned long __initdata memory_end; 96unsigned long __initdata memory_end;
97 97
98unsigned long VMALLOC_START;
99EXPORT_SYMBOL(VMALLOC_START);
100
101unsigned long VMALLOC_END;
102EXPORT_SYMBOL(VMALLOC_END);
103
104struct page *vmemmap;
105EXPORT_SYMBOL(vmemmap);
106
98/* An array with a pointer to the lowcore of every CPU. */ 107/* An array with a pointer to the lowcore of every CPU. */
99struct _lowcore *lowcore_ptr[NR_CPUS]; 108struct _lowcore *lowcore_ptr[NR_CPUS];
100EXPORT_SYMBOL(lowcore_ptr); 109EXPORT_SYMBOL(lowcore_ptr);
@@ -278,6 +287,15 @@ static int __init early_parse_mem(char *p)
278} 287}
279early_param("mem", early_parse_mem); 288early_param("mem", early_parse_mem);
280 289
290static int __init parse_vmalloc(char *arg)
291{
292 if (!arg)
293 return -EINVAL;
294 VMALLOC_END = (memparse(arg, &arg) + PAGE_SIZE - 1) & PAGE_MASK;
295 return 0;
296}
297early_param("vmalloc", parse_vmalloc);
298
281unsigned int user_mode = HOME_SPACE_MODE; 299unsigned int user_mode = HOME_SPACE_MODE;
282EXPORT_SYMBOL_GPL(user_mode); 300EXPORT_SYMBOL_GPL(user_mode);
283 301
@@ -383,7 +401,6 @@ setup_lowcore(void)
383 __ctl_set_bit(14, 29); 401 __ctl_set_bit(14, 29);
384 } 402 }
385#else 403#else
386 lc->cmf_hpp = -1ULL;
387 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0]; 404 lc->vdso_per_cpu_data = (unsigned long) &lc->paste[0];
388#endif 405#endif
389 lc->sync_enter_timer = S390_lowcore.sync_enter_timer; 406 lc->sync_enter_timer = S390_lowcore.sync_enter_timer;
@@ -479,8 +496,7 @@ EXPORT_SYMBOL_GPL(real_memory_size);
479 496
480static void __init setup_memory_end(void) 497static void __init setup_memory_end(void)
481{ 498{
482 unsigned long memory_size; 499 unsigned long vmax, vmalloc_size, tmp;
483 unsigned long max_mem;
484 int i; 500 int i;
485 501
486 502
@@ -490,12 +506,9 @@ static void __init setup_memory_end(void)
490 memory_end_set = 1; 506 memory_end_set = 1;
491 } 507 }
492#endif 508#endif
493 memory_size = 0; 509 real_memory_size = 0;
494 memory_end &= PAGE_MASK; 510 memory_end &= PAGE_MASK;
495 511
496 max_mem = memory_end ? min(VMEM_MAX_PHYS, memory_end) : VMEM_MAX_PHYS;
497 memory_end = min(max_mem, memory_end);
498
499 /* 512 /*
500 * Make sure all chunks are MAX_ORDER aligned so we don't need the 513 * Make sure all chunks are MAX_ORDER aligned so we don't need the
501 * extra checks that HOLES_IN_ZONE would require. 514 * extra checks that HOLES_IN_ZONE would require.
@@ -515,23 +528,48 @@ static void __init setup_memory_end(void)
515 chunk->addr = start; 528 chunk->addr = start;
516 chunk->size = end - start; 529 chunk->size = end - start;
517 } 530 }
531 real_memory_size = max(real_memory_size,
532 chunk->addr + chunk->size);
518 } 533 }
519 534
535 /* Choose kernel address space layout: 2, 3, or 4 levels. */
536#ifdef CONFIG_64BIT
537 vmalloc_size = VMALLOC_END ?: 128UL << 30;
538 tmp = (memory_end ?: real_memory_size) / PAGE_SIZE;
539 tmp = tmp * (sizeof(struct page) + PAGE_SIZE) + vmalloc_size;
540 if (tmp <= (1UL << 42))
541 vmax = 1UL << 42; /* 3-level kernel page table */
542 else
543 vmax = 1UL << 53; /* 4-level kernel page table */
544#else
545 vmalloc_size = VMALLOC_END ?: 96UL << 20;
546 vmax = 1UL << 31; /* 2-level kernel page table */
547#endif
548 /* vmalloc area is at the end of the kernel address space. */
549 VMALLOC_END = vmax;
550 VMALLOC_START = vmax - vmalloc_size;
551
552 /* Split remaining virtual space between 1:1 mapping & vmemmap array */
553 tmp = VMALLOC_START / (PAGE_SIZE + sizeof(struct page));
554 tmp = VMALLOC_START - tmp * sizeof(struct page);
555 tmp &= ~((vmax >> 11) - 1); /* align to page table level */
556 tmp = min(tmp, 1UL << MAX_PHYSMEM_BITS);
557 vmemmap = (struct page *) tmp;
558
559 /* Take care that memory_end is set and <= vmemmap */
560 memory_end = min(memory_end ?: real_memory_size, tmp);
561
562 /* Fixup memory chunk array to fit into 0..memory_end */
520 for (i = 0; i < MEMORY_CHUNKS; i++) { 563 for (i = 0; i < MEMORY_CHUNKS; i++) {
521 struct mem_chunk *chunk = &memory_chunk[i]; 564 struct mem_chunk *chunk = &memory_chunk[i];
522 565
523 real_memory_size = max(real_memory_size, 566 if (chunk->addr >= memory_end) {
524 chunk->addr + chunk->size);
525 if (chunk->addr >= max_mem) {
526 memset(chunk, 0, sizeof(*chunk)); 567 memset(chunk, 0, sizeof(*chunk));
527 continue; 568 continue;
528 } 569 }
529 if (chunk->addr + chunk->size > max_mem) 570 if (chunk->addr + chunk->size > memory_end)
530 chunk->size = max_mem - chunk->addr; 571 chunk->size = memory_end - chunk->addr;
531 memory_size = max(memory_size, chunk->addr + chunk->size);
532 } 572 }
533 if (!memory_end)
534 memory_end = memory_size;
535} 573}
536 574
537void *restart_stack __attribute__((__section__(".data"))); 575void *restart_stack __attribute__((__section__(".data")));
@@ -655,7 +693,6 @@ static int __init verify_crash_base(unsigned long crash_base,
655static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size, 693static void __init reserve_kdump_bootmem(unsigned long addr, unsigned long size,
656 int type) 694 int type)
657{ 695{
658
659 create_mem_hole(memory_chunk, addr, size, type); 696 create_mem_hole(memory_chunk, addr, size, type);
660} 697}
661 698
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c
index 7f6f9f354545..a8ba840294ff 100644
--- a/arch/s390/kernel/signal.c
+++ b/arch/s390/kernel/signal.c
@@ -302,9 +302,13 @@ static int setup_frame(int sig, struct k_sigaction *ka,
302 302
303 /* We forgot to include these in the sigcontext. 303 /* We forgot to include these in the sigcontext.
304 To avoid breaking binary compatibility, they are passed as args. */ 304 To avoid breaking binary compatibility, they are passed as args. */
305 regs->gprs[4] = current->thread.trap_no; 305 if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL ||
306 regs->gprs[5] = current->thread.prot_addr; 306 sig == SIGTRAP || sig == SIGFPE) {
307 regs->gprs[6] = task_thread_info(current)->last_break; 307 /* set extra registers only for synchronous signals */
308 regs->gprs[4] = regs->int_code & 127;
309 regs->gprs[5] = regs->int_parm_long;
310 regs->gprs[6] = task_thread_info(current)->last_break;
311 }
308 312
309 /* Place signal number on stack to allow backtrace from handler. */ 313 /* Place signal number on stack to allow backtrace from handler. */
310 if (__put_user(regs->gprs[2], (int __user *) &frame->signo)) 314 if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
@@ -434,13 +438,13 @@ void do_signal(struct pt_regs *regs)
434 * call information. 438 * call information.
435 */ 439 */
436 current_thread_info()->system_call = 440 current_thread_info()->system_call =
437 test_thread_flag(TIF_SYSCALL) ? regs->svc_code : 0; 441 test_thread_flag(TIF_SYSCALL) ? regs->int_code : 0;
438 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 442 signr = get_signal_to_deliver(&info, &ka, regs, NULL);
439 443
440 if (signr > 0) { 444 if (signr > 0) {
441 /* Whee! Actually deliver the signal. */ 445 /* Whee! Actually deliver the signal. */
442 if (current_thread_info()->system_call) { 446 if (current_thread_info()->system_call) {
443 regs->svc_code = current_thread_info()->system_call; 447 regs->int_code = current_thread_info()->system_call;
444 /* Check for system call restarting. */ 448 /* Check for system call restarting. */
445 switch (regs->gprs[2]) { 449 switch (regs->gprs[2]) {
446 case -ERESTART_RESTARTBLOCK: 450 case -ERESTART_RESTARTBLOCK:
@@ -457,7 +461,7 @@ void do_signal(struct pt_regs *regs)
457 regs->gprs[2] = regs->orig_gpr2; 461 regs->gprs[2] = regs->orig_gpr2;
458 regs->psw.addr = 462 regs->psw.addr =
459 __rewind_psw(regs->psw, 463 __rewind_psw(regs->psw,
460 regs->svc_code >> 16); 464 regs->int_code >> 16);
461 break; 465 break;
462 } 466 }
463 } 467 }
@@ -488,11 +492,11 @@ void do_signal(struct pt_regs *regs)
488 /* No handlers present - check for system call restart */ 492 /* No handlers present - check for system call restart */
489 clear_thread_flag(TIF_SYSCALL); 493 clear_thread_flag(TIF_SYSCALL);
490 if (current_thread_info()->system_call) { 494 if (current_thread_info()->system_call) {
491 regs->svc_code = current_thread_info()->system_call; 495 regs->int_code = current_thread_info()->system_call;
492 switch (regs->gprs[2]) { 496 switch (regs->gprs[2]) {
493 case -ERESTART_RESTARTBLOCK: 497 case -ERESTART_RESTARTBLOCK:
494 /* Restart with sys_restart_syscall */ 498 /* Restart with sys_restart_syscall */
495 regs->svc_code = __NR_restart_syscall; 499 regs->int_code = __NR_restart_syscall;
496 /* fallthrough */ 500 /* fallthrough */
497 case -ERESTARTNOHAND: 501 case -ERESTARTNOHAND:
498 case -ERESTARTSYS: 502 case -ERESTARTSYS:
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 3ea872890da2..2398ce6b15ae 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -69,9 +69,7 @@ enum s390_cpu_state {
69}; 69};
70 70
71DEFINE_MUTEX(smp_cpu_state_mutex); 71DEFINE_MUTEX(smp_cpu_state_mutex);
72int smp_cpu_polarization[NR_CPUS];
73static int smp_cpu_state[NR_CPUS]; 72static int smp_cpu_state[NR_CPUS];
74static int cpu_management;
75 73
76static DEFINE_PER_CPU(struct cpu, cpu_devices); 74static DEFINE_PER_CPU(struct cpu, cpu_devices);
77 75
@@ -149,29 +147,59 @@ void smp_switch_to_ipl_cpu(void (*func)(void *), void *data)
149 sp -= sizeof(struct pt_regs); 147 sp -= sizeof(struct pt_regs);
150 regs = (struct pt_regs *) sp; 148 regs = (struct pt_regs *) sp;
151 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs)); 149 memcpy(&regs->gprs, &current_lc->gpregs_save_area, sizeof(regs->gprs));
152 regs->psw = lc->psw_save_area; 150 regs->psw = current_lc->psw_save_area;
153 sp -= STACK_FRAME_OVERHEAD; 151 sp -= STACK_FRAME_OVERHEAD;
154 sf = (struct stack_frame *) sp; 152 sf = (struct stack_frame *) sp;
155 sf->back_chain = regs->gprs[15]; 153 sf->back_chain = 0;
156 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]); 154 smp_switch_to_cpu(func, data, sp, stap(), __cpu_logical_map[0]);
157} 155}
158 156
157static void smp_stop_cpu(void)
158{
159 while (sigp(smp_processor_id(), sigp_stop) == sigp_busy)
160 cpu_relax();
161}
162
159void smp_send_stop(void) 163void smp_send_stop(void)
160{ 164{
161 int cpu, rc; 165 cpumask_t cpumask;
166 int cpu;
167 u64 end;
162 168
163 /* Disable all interrupts/machine checks */ 169 /* Disable all interrupts/machine checks */
164 __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT); 170 __load_psw_mask(psw_kernel_bits | PSW_MASK_DAT);
165 trace_hardirqs_off(); 171 trace_hardirqs_off();
166 172
167 /* stop all processors */ 173 cpumask_copy(&cpumask, cpu_online_mask);
168 for_each_online_cpu(cpu) { 174 cpumask_clear_cpu(smp_processor_id(), &cpumask);
169 if (cpu == smp_processor_id()) 175
170 continue; 176 if (oops_in_progress) {
171 do { 177 /*
172 rc = sigp(cpu, sigp_stop); 178 * Give the other cpus the opportunity to complete
173 } while (rc == sigp_busy); 179 * outstanding interrupts before stopping them.
180 */
181 end = get_clock() + (1000000UL << 12);
182 for_each_cpu(cpu, &cpumask) {
183 set_bit(ec_stop_cpu, (unsigned long *)
184 &lowcore_ptr[cpu]->ext_call_fast);
185 while (sigp(cpu, sigp_emergency_signal) == sigp_busy &&
186 get_clock() < end)
187 cpu_relax();
188 }
189 while (get_clock() < end) {
190 for_each_cpu(cpu, &cpumask)
191 if (cpu_stopped(cpu))
192 cpumask_clear_cpu(cpu, &cpumask);
193 if (cpumask_empty(&cpumask))
194 break;
195 cpu_relax();
196 }
197 }
174 198
199 /* stop all processors */
200 for_each_cpu(cpu, &cpumask) {
201 while (sigp(cpu, sigp_stop) == sigp_busy)
202 cpu_relax();
175 while (!cpu_stopped(cpu)) 203 while (!cpu_stopped(cpu))
176 cpu_relax(); 204 cpu_relax();
177 } 205 }
@@ -187,7 +215,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
187{ 215{
188 unsigned long bits; 216 unsigned long bits;
189 217
190 if (ext_int_code == 0x1202) 218 if ((ext_int_code & 0xffff) == 0x1202)
191 kstat_cpu(smp_processor_id()).irqs[EXTINT_EXC]++; 219 kstat_cpu(smp_processor_id()).irqs[EXTINT_EXC]++;
192 else 220 else
193 kstat_cpu(smp_processor_id()).irqs[EXTINT_EMS]++; 221 kstat_cpu(smp_processor_id()).irqs[EXTINT_EMS]++;
@@ -196,6 +224,9 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
196 */ 224 */
197 bits = xchg(&S390_lowcore.ext_call_fast, 0); 225 bits = xchg(&S390_lowcore.ext_call_fast, 0);
198 226
227 if (test_bit(ec_stop_cpu, &bits))
228 smp_stop_cpu();
229
199 if (test_bit(ec_schedule, &bits)) 230 if (test_bit(ec_schedule, &bits))
200 scheduler_ipi(); 231 scheduler_ipi();
201 232
@@ -204,6 +235,7 @@ static void do_ext_call_interrupt(unsigned int ext_int_code,
204 235
205 if (test_bit(ec_call_function_single, &bits)) 236 if (test_bit(ec_call_function_single, &bits))
206 generic_smp_call_function_single_interrupt(); 237 generic_smp_call_function_single_interrupt();
238
207} 239}
208 240
209/* 241/*
@@ -369,7 +401,7 @@ static int smp_rescan_cpus_sigp(cpumask_t avail)
369 if (cpu_known(cpu_id)) 401 if (cpu_known(cpu_id))
370 continue; 402 continue;
371 __cpu_logical_map[logical_cpu] = cpu_id; 403 __cpu_logical_map[logical_cpu] = cpu_id;
372 smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; 404 cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
373 if (!cpu_stopped(logical_cpu)) 405 if (!cpu_stopped(logical_cpu))
374 continue; 406 continue;
375 set_cpu_present(logical_cpu, true); 407 set_cpu_present(logical_cpu, true);
@@ -403,7 +435,7 @@ static int smp_rescan_cpus_sclp(cpumask_t avail)
403 if (cpu_known(cpu_id)) 435 if (cpu_known(cpu_id))
404 continue; 436 continue;
405 __cpu_logical_map[logical_cpu] = cpu_id; 437 __cpu_logical_map[logical_cpu] = cpu_id;
406 smp_cpu_polarization[logical_cpu] = POLARIZATION_UNKNWN; 438 cpu_set_polarization(logical_cpu, POLARIZATION_UNKNOWN);
407 set_cpu_present(logical_cpu, true); 439 set_cpu_present(logical_cpu, true);
408 if (cpu >= info->configured) 440 if (cpu >= info->configured)
409 smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY; 441 smp_cpu_state[logical_cpu] = CPU_STATE_STANDBY;
@@ -656,7 +688,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
656 - sizeof(struct stack_frame)); 688 - sizeof(struct stack_frame));
657 memset(sf, 0, sizeof(struct stack_frame)); 689 memset(sf, 0, sizeof(struct stack_frame));
658 sf->gprs[9] = (unsigned long) sf; 690 sf->gprs[9] = (unsigned long) sf;
659 cpu_lowcore->save_area[15] = (unsigned long) sf; 691 cpu_lowcore->gpregs_save_area[15] = (unsigned long) sf;
660 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15); 692 __ctl_store(cpu_lowcore->cregs_save_area, 0, 15);
661 atomic_inc(&init_mm.context.attach_count); 693 atomic_inc(&init_mm.context.attach_count);
662 asm volatile( 694 asm volatile(
@@ -806,7 +838,7 @@ void __init smp_prepare_boot_cpu(void)
806 S390_lowcore.percpu_offset = __per_cpu_offset[0]; 838 S390_lowcore.percpu_offset = __per_cpu_offset[0];
807 current_set[0] = current; 839 current_set[0] = current;
808 smp_cpu_state[0] = CPU_STATE_CONFIGURED; 840 smp_cpu_state[0] = CPU_STATE_CONFIGURED;
809 smp_cpu_polarization[0] = POLARIZATION_UNKNWN; 841 cpu_set_polarization(0, POLARIZATION_UNKNOWN);
810} 842}
811 843
812void __init smp_cpus_done(unsigned int max_cpus) 844void __init smp_cpus_done(unsigned int max_cpus)
@@ -831,8 +863,8 @@ int setup_profiling_timer(unsigned int multiplier)
831} 863}
832 864
833#ifdef CONFIG_HOTPLUG_CPU 865#ifdef CONFIG_HOTPLUG_CPU
834static ssize_t cpu_configure_show(struct sys_device *dev, 866static ssize_t cpu_configure_show(struct device *dev,
835 struct sysdev_attribute *attr, char *buf) 867 struct device_attribute *attr, char *buf)
836{ 868{
837 ssize_t count; 869 ssize_t count;
838 870
@@ -842,8 +874,8 @@ static ssize_t cpu_configure_show(struct sys_device *dev,
842 return count; 874 return count;
843} 875}
844 876
845static ssize_t cpu_configure_store(struct sys_device *dev, 877static ssize_t cpu_configure_store(struct device *dev,
846 struct sysdev_attribute *attr, 878 struct device_attribute *attr,
847 const char *buf, size_t count) 879 const char *buf, size_t count)
848{ 880{
849 int cpu = dev->id; 881 int cpu = dev->id;
@@ -868,7 +900,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev,
868 rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]); 900 rc = sclp_cpu_deconfigure(__cpu_logical_map[cpu]);
869 if (!rc) { 901 if (!rc) {
870 smp_cpu_state[cpu] = CPU_STATE_STANDBY; 902 smp_cpu_state[cpu] = CPU_STATE_STANDBY;
871 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 903 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
904 topology_expect_change();
872 } 905 }
873 } 906 }
874 break; 907 break;
@@ -877,7 +910,8 @@ static ssize_t cpu_configure_store(struct sys_device *dev,
877 rc = sclp_cpu_configure(__cpu_logical_map[cpu]); 910 rc = sclp_cpu_configure(__cpu_logical_map[cpu]);
878 if (!rc) { 911 if (!rc) {
879 smp_cpu_state[cpu] = CPU_STATE_CONFIGURED; 912 smp_cpu_state[cpu] = CPU_STATE_CONFIGURED;
880 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 913 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
914 topology_expect_change();
881 } 915 }
882 } 916 }
883 break; 917 break;
@@ -889,52 +923,21 @@ out:
889 put_online_cpus(); 923 put_online_cpus();
890 return rc ? rc : count; 924 return rc ? rc : count;
891} 925}
892static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store); 926static DEVICE_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
893#endif /* CONFIG_HOTPLUG_CPU */ 927#endif /* CONFIG_HOTPLUG_CPU */
894 928
895static ssize_t cpu_polarization_show(struct sys_device *dev, 929static ssize_t show_cpu_address(struct device *dev,
896 struct sysdev_attribute *attr, char *buf) 930 struct device_attribute *attr, char *buf)
897{
898 int cpu = dev->id;
899 ssize_t count;
900
901 mutex_lock(&smp_cpu_state_mutex);
902 switch (smp_cpu_polarization[cpu]) {
903 case POLARIZATION_HRZ:
904 count = sprintf(buf, "horizontal\n");
905 break;
906 case POLARIZATION_VL:
907 count = sprintf(buf, "vertical:low\n");
908 break;
909 case POLARIZATION_VM:
910 count = sprintf(buf, "vertical:medium\n");
911 break;
912 case POLARIZATION_VH:
913 count = sprintf(buf, "vertical:high\n");
914 break;
915 default:
916 count = sprintf(buf, "unknown\n");
917 break;
918 }
919 mutex_unlock(&smp_cpu_state_mutex);
920 return count;
921}
922static SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL);
923
924static ssize_t show_cpu_address(struct sys_device *dev,
925 struct sysdev_attribute *attr, char *buf)
926{ 931{
927 return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]); 932 return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
928} 933}
929static SYSDEV_ATTR(address, 0444, show_cpu_address, NULL); 934static DEVICE_ATTR(address, 0444, show_cpu_address, NULL);
930
931 935
932static struct attribute *cpu_common_attrs[] = { 936static struct attribute *cpu_common_attrs[] = {
933#ifdef CONFIG_HOTPLUG_CPU 937#ifdef CONFIG_HOTPLUG_CPU
934 &attr_configure.attr, 938 &dev_attr_configure.attr,
935#endif 939#endif
936 &attr_address.attr, 940 &dev_attr_address.attr,
937 &attr_polarization.attr,
938 NULL, 941 NULL,
939}; 942};
940 943
@@ -942,8 +945,8 @@ static struct attribute_group cpu_common_attr_group = {
942 .attrs = cpu_common_attrs, 945 .attrs = cpu_common_attrs,
943}; 946};
944 947
945static ssize_t show_capability(struct sys_device *dev, 948static ssize_t show_capability(struct device *dev,
946 struct sysdev_attribute *attr, char *buf) 949 struct device_attribute *attr, char *buf)
947{ 950{
948 unsigned int capability; 951 unsigned int capability;
949 int rc; 952 int rc;
@@ -953,10 +956,10 @@ static ssize_t show_capability(struct sys_device *dev,
953 return rc; 956 return rc;
954 return sprintf(buf, "%u\n", capability); 957 return sprintf(buf, "%u\n", capability);
955} 958}
956static SYSDEV_ATTR(capability, 0444, show_capability, NULL); 959static DEVICE_ATTR(capability, 0444, show_capability, NULL);
957 960
958static ssize_t show_idle_count(struct sys_device *dev, 961static ssize_t show_idle_count(struct device *dev,
959 struct sysdev_attribute *attr, char *buf) 962 struct device_attribute *attr, char *buf)
960{ 963{
961 struct s390_idle_data *idle; 964 struct s390_idle_data *idle;
962 unsigned long long idle_count; 965 unsigned long long idle_count;
@@ -976,10 +979,10 @@ repeat:
976 goto repeat; 979 goto repeat;
977 return sprintf(buf, "%llu\n", idle_count); 980 return sprintf(buf, "%llu\n", idle_count);
978} 981}
979static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL); 982static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL);
980 983
981static ssize_t show_idle_time(struct sys_device *dev, 984static ssize_t show_idle_time(struct device *dev,
982 struct sysdev_attribute *attr, char *buf) 985 struct device_attribute *attr, char *buf)
983{ 986{
984 struct s390_idle_data *idle; 987 struct s390_idle_data *idle;
985 unsigned long long now, idle_time, idle_enter; 988 unsigned long long now, idle_time, idle_enter;
@@ -1001,12 +1004,12 @@ repeat:
1001 goto repeat; 1004 goto repeat;
1002 return sprintf(buf, "%llu\n", idle_time >> 12); 1005 return sprintf(buf, "%llu\n", idle_time >> 12);
1003} 1006}
1004static SYSDEV_ATTR(idle_time_us, 0444, show_idle_time, NULL); 1007static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL);
1005 1008
1006static struct attribute *cpu_online_attrs[] = { 1009static struct attribute *cpu_online_attrs[] = {
1007 &attr_capability.attr, 1010 &dev_attr_capability.attr,
1008 &attr_idle_count.attr, 1011 &dev_attr_idle_count.attr,
1009 &attr_idle_time_us.attr, 1012 &dev_attr_idle_time_us.attr,
1010 NULL, 1013 NULL,
1011}; 1014};
1012 1015
@@ -1019,7 +1022,7 @@ static int __cpuinit smp_cpu_notify(struct notifier_block *self,
1019{ 1022{
1020 unsigned int cpu = (unsigned int)(long)hcpu; 1023 unsigned int cpu = (unsigned int)(long)hcpu;
1021 struct cpu *c = &per_cpu(cpu_devices, cpu); 1024 struct cpu *c = &per_cpu(cpu_devices, cpu);
1022 struct sys_device *s = &c->sysdev; 1025 struct device *s = &c->dev;
1023 struct s390_idle_data *idle; 1026 struct s390_idle_data *idle;
1024 int err = 0; 1027 int err = 0;
1025 1028
@@ -1045,7 +1048,7 @@ static struct notifier_block __cpuinitdata smp_cpu_nb = {
1045static int __devinit smp_add_present_cpu(int cpu) 1048static int __devinit smp_add_present_cpu(int cpu)
1046{ 1049{
1047 struct cpu *c = &per_cpu(cpu_devices, cpu); 1050 struct cpu *c = &per_cpu(cpu_devices, cpu);
1048 struct sys_device *s = &c->sysdev; 1051 struct device *s = &c->dev;
1049 int rc; 1052 int rc;
1050 1053
1051 c->hotpluggable = 1; 1054 c->hotpluggable = 1;
@@ -1055,11 +1058,20 @@ static int __devinit smp_add_present_cpu(int cpu)
1055 rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group); 1058 rc = sysfs_create_group(&s->kobj, &cpu_common_attr_group);
1056 if (rc) 1059 if (rc)
1057 goto out_cpu; 1060 goto out_cpu;
1058 if (!cpu_online(cpu)) 1061 if (cpu_online(cpu)) {
1059 goto out; 1062 rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group);
1060 rc = sysfs_create_group(&s->kobj, &cpu_online_attr_group); 1063 if (rc)
1061 if (!rc) 1064 goto out_online;
1062 return 0; 1065 }
1066 rc = topology_cpu_init(c);
1067 if (rc)
1068 goto out_topology;
1069 return 0;
1070
1071out_topology:
1072 if (cpu_online(cpu))
1073 sysfs_remove_group(&s->kobj, &cpu_online_attr_group);
1074out_online:
1063 sysfs_remove_group(&s->kobj, &cpu_common_attr_group); 1075 sysfs_remove_group(&s->kobj, &cpu_common_attr_group);
1064out_cpu: 1076out_cpu:
1065#ifdef CONFIG_HOTPLUG_CPU 1077#ifdef CONFIG_HOTPLUG_CPU
@@ -1098,8 +1110,8 @@ out:
1098 return rc; 1110 return rc;
1099} 1111}
1100 1112
1101static ssize_t __ref rescan_store(struct sysdev_class *class, 1113static ssize_t __ref rescan_store(struct device *dev,
1102 struct sysdev_class_attribute *attr, 1114 struct device_attribute *attr,
1103 const char *buf, 1115 const char *buf,
1104 size_t count) 1116 size_t count)
1105{ 1117{
@@ -1108,64 +1120,19 @@ static ssize_t __ref rescan_store(struct sysdev_class *class,
1108 rc = smp_rescan_cpus(); 1120 rc = smp_rescan_cpus();
1109 return rc ? rc : count; 1121 return rc ? rc : count;
1110} 1122}
1111static SYSDEV_CLASS_ATTR(rescan, 0200, NULL, rescan_store); 1123static DEVICE_ATTR(rescan, 0200, NULL, rescan_store);
1112#endif /* CONFIG_HOTPLUG_CPU */ 1124#endif /* CONFIG_HOTPLUG_CPU */
1113 1125
1114static ssize_t dispatching_show(struct sysdev_class *class, 1126static int __init s390_smp_init(void)
1115 struct sysdev_class_attribute *attr,
1116 char *buf)
1117{
1118 ssize_t count;
1119
1120 mutex_lock(&smp_cpu_state_mutex);
1121 count = sprintf(buf, "%d\n", cpu_management);
1122 mutex_unlock(&smp_cpu_state_mutex);
1123 return count;
1124}
1125
1126static ssize_t dispatching_store(struct sysdev_class *dev,
1127 struct sysdev_class_attribute *attr,
1128 const char *buf,
1129 size_t count)
1130{
1131 int val, rc;
1132 char delim;
1133
1134 if (sscanf(buf, "%d %c", &val, &delim) != 1)
1135 return -EINVAL;
1136 if (val != 0 && val != 1)
1137 return -EINVAL;
1138 rc = 0;
1139 get_online_cpus();
1140 mutex_lock(&smp_cpu_state_mutex);
1141 if (cpu_management == val)
1142 goto out;
1143 rc = topology_set_cpu_management(val);
1144 if (!rc)
1145 cpu_management = val;
1146out:
1147 mutex_unlock(&smp_cpu_state_mutex);
1148 put_online_cpus();
1149 return rc ? rc : count;
1150}
1151static SYSDEV_CLASS_ATTR(dispatching, 0644, dispatching_show,
1152 dispatching_store);
1153
1154static int __init topology_init(void)
1155{ 1127{
1156 int cpu; 1128 int cpu, rc;
1157 int rc;
1158 1129
1159 register_cpu_notifier(&smp_cpu_nb); 1130 register_cpu_notifier(&smp_cpu_nb);
1160
1161#ifdef CONFIG_HOTPLUG_CPU 1131#ifdef CONFIG_HOTPLUG_CPU
1162 rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_rescan); 1132 rc = device_create_file(cpu_subsys.dev_root, &dev_attr_rescan);
1163 if (rc) 1133 if (rc)
1164 return rc; 1134 return rc;
1165#endif 1135#endif
1166 rc = sysdev_class_create_file(&cpu_sysdev_class, &attr_dispatching);
1167 if (rc)
1168 return rc;
1169 for_each_present_cpu(cpu) { 1136 for_each_present_cpu(cpu) {
1170 rc = smp_add_present_cpu(cpu); 1137 rc = smp_add_present_cpu(cpu);
1171 if (rc) 1138 if (rc)
@@ -1173,4 +1140,4 @@ static int __init topology_init(void)
1173 } 1140 }
1174 return 0; 1141 return 0;
1175} 1142}
1176subsys_initcall(topology_init); 1143subsys_initcall(s390_smp_init);
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c
index 476081440df9..78ea1948ff51 100644
--- a/arch/s390/kernel/sys_s390.c
+++ b/arch/s390/kernel/sys_s390.c
@@ -60,74 +60,22 @@ out:
60} 60}
61 61
62/* 62/*
63 * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 63 * sys_ipc() is the de-multiplexer for the SysV IPC calls.
64 *
65 * This is really horribly ugly.
66 */ 64 */
67SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second, 65SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
68 unsigned long, third, void __user *, ptr) 66 unsigned long, third, void __user *, ptr)
69{ 67{
70 struct ipc_kludge tmp; 68 if (call >> 16)
71 int ret; 69 return -EINVAL;
72 70 /* The s390 sys_ipc variant has only five parameters instead of six
73 switch (call) { 71 * like the generic variant. The only difference is the handling of
74 case SEMOP: 72 * the SEMTIMEDOP subcall where on s390 the third parameter is used
75 return sys_semtimedop(first, (struct sembuf __user *)ptr, 73 * as a pointer to a struct timespec where the generic variant uses
76 (unsigned)second, NULL); 74 * the fifth parameter.
77 case SEMTIMEDOP: 75 * Therefore we can call the generic variant by simply passing the
78 return sys_semtimedop(first, (struct sembuf __user *)ptr, 76 * third parameter also as fifth parameter.
79 (unsigned)second, 77 */
80 (const struct timespec __user *) third); 78 return sys_ipc(call, first, second, third, ptr, third);
81 case SEMGET:
82 return sys_semget(first, (int)second, third);
83 case SEMCTL: {
84 union semun fourth;
85 if (!ptr)
86 return -EINVAL;
87 if (get_user(fourth.__pad, (void __user * __user *) ptr))
88 return -EFAULT;
89 return sys_semctl(first, (int)second, third, fourth);
90 }
91 case MSGSND:
92 return sys_msgsnd (first, (struct msgbuf __user *) ptr,
93 (size_t)second, third);
94 break;
95 case MSGRCV:
96 if (!ptr)
97 return -EINVAL;
98 if (copy_from_user (&tmp, (struct ipc_kludge __user *) ptr,
99 sizeof (struct ipc_kludge)))
100 return -EFAULT;
101 return sys_msgrcv (first, tmp.msgp,
102 (size_t)second, tmp.msgtyp, third);
103 case MSGGET:
104 return sys_msgget((key_t)first, (int)second);
105 case MSGCTL:
106 return sys_msgctl(first, (int)second,
107 (struct msqid_ds __user *)ptr);
108
109 case SHMAT: {
110 ulong raddr;
111 ret = do_shmat(first, (char __user *)ptr,
112 (int)second, &raddr);
113 if (ret)
114 return ret;
115 return put_user (raddr, (ulong __user *) third);
116 break;
117 }
118 case SHMDT:
119 return sys_shmdt ((char __user *)ptr);
120 case SHMGET:
121 return sys_shmget(first, (size_t)second, third);
122 case SHMCTL:
123 return sys_shmctl(first, (int)second,
124 (struct shmid_ds __user *) ptr);
125 default:
126 return -ENOSYS;
127
128 }
129
130 return -EINVAL;
131} 79}
132 80
133#ifdef CONFIG_64BIT 81#ifdef CONFIG_64BIT
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index ebbfab3c6e5a..fa02f443f5f6 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -27,7 +27,7 @@
27#include <linux/cpu.h> 27#include <linux/cpu.h>
28#include <linux/stop_machine.h> 28#include <linux/stop_machine.h>
29#include <linux/time.h> 29#include <linux/time.h>
30#include <linux/sysdev.h> 30#include <linux/device.h>
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/init.h> 32#include <linux/init.h>
33#include <linux/smp.h> 33#include <linux/smp.h>
@@ -1116,34 +1116,35 @@ out_unlock:
1116/* 1116/*
1117 * Sysfs interface functions 1117 * Sysfs interface functions
1118 */ 1118 */
1119static struct sysdev_class etr_sysclass = { 1119static struct bus_type etr_subsys = {
1120 .name = "etr", 1120 .name = "etr",
1121 .dev_name = "etr",
1121}; 1122};
1122 1123
1123static struct sys_device etr_port0_dev = { 1124static struct device etr_port0_dev = {
1124 .id = 0, 1125 .id = 0,
1125 .cls = &etr_sysclass, 1126 .bus = &etr_subsys,
1126}; 1127};
1127 1128
1128static struct sys_device etr_port1_dev = { 1129static struct device etr_port1_dev = {
1129 .id = 1, 1130 .id = 1,
1130 .cls = &etr_sysclass, 1131 .bus = &etr_subsys,
1131}; 1132};
1132 1133
1133/* 1134/*
1134 * ETR class attributes 1135 * ETR subsys attributes
1135 */ 1136 */
1136static ssize_t etr_stepping_port_show(struct sysdev_class *class, 1137static ssize_t etr_stepping_port_show(struct device *dev,
1137 struct sysdev_class_attribute *attr, 1138 struct device_attribute *attr,
1138 char *buf) 1139 char *buf)
1139{ 1140{
1140 return sprintf(buf, "%i\n", etr_port0.esw.p); 1141 return sprintf(buf, "%i\n", etr_port0.esw.p);
1141} 1142}
1142 1143
1143static SYSDEV_CLASS_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL); 1144static DEVICE_ATTR(stepping_port, 0400, etr_stepping_port_show, NULL);
1144 1145
1145static ssize_t etr_stepping_mode_show(struct sysdev_class *class, 1146static ssize_t etr_stepping_mode_show(struct device *dev,
1146 struct sysdev_class_attribute *attr, 1147 struct device_attribute *attr,
1147 char *buf) 1148 char *buf)
1148{ 1149{
1149 char *mode_str; 1150 char *mode_str;
@@ -1157,12 +1158,12 @@ static ssize_t etr_stepping_mode_show(struct sysdev_class *class,
1157 return sprintf(buf, "%s\n", mode_str); 1158 return sprintf(buf, "%s\n", mode_str);
1158} 1159}
1159 1160
1160static SYSDEV_CLASS_ATTR(stepping_mode, 0400, etr_stepping_mode_show, NULL); 1161static DEVICE_ATTR(stepping_mode, 0400, etr_stepping_mode_show, NULL);
1161 1162
1162/* 1163/*
1163 * ETR port attributes 1164 * ETR port attributes
1164 */ 1165 */
1165static inline struct etr_aib *etr_aib_from_dev(struct sys_device *dev) 1166static inline struct etr_aib *etr_aib_from_dev(struct device *dev)
1166{ 1167{
1167 if (dev == &etr_port0_dev) 1168 if (dev == &etr_port0_dev)
1168 return etr_port0_online ? &etr_port0 : NULL; 1169 return etr_port0_online ? &etr_port0 : NULL;
@@ -1170,8 +1171,8 @@ static inline struct etr_aib *etr_aib_from_dev(struct sys_device *dev)
1170 return etr_port1_online ? &etr_port1 : NULL; 1171 return etr_port1_online ? &etr_port1 : NULL;
1171} 1172}
1172 1173
1173static ssize_t etr_online_show(struct sys_device *dev, 1174static ssize_t etr_online_show(struct device *dev,
1174 struct sysdev_attribute *attr, 1175 struct device_attribute *attr,
1175 char *buf) 1176 char *buf)
1176{ 1177{
1177 unsigned int online; 1178 unsigned int online;
@@ -1180,8 +1181,8 @@ static ssize_t etr_online_show(struct sys_device *dev,
1180 return sprintf(buf, "%i\n", online); 1181 return sprintf(buf, "%i\n", online);
1181} 1182}
1182 1183
1183static ssize_t etr_online_store(struct sys_device *dev, 1184static ssize_t etr_online_store(struct device *dev,
1184 struct sysdev_attribute *attr, 1185 struct device_attribute *attr,
1185 const char *buf, size_t count) 1186 const char *buf, size_t count)
1186{ 1187{
1187 unsigned int value; 1188 unsigned int value;
@@ -1218,20 +1219,20 @@ out:
1218 return count; 1219 return count;
1219} 1220}
1220 1221
1221static SYSDEV_ATTR(online, 0600, etr_online_show, etr_online_store); 1222static DEVICE_ATTR(online, 0600, etr_online_show, etr_online_store);
1222 1223
1223static ssize_t etr_stepping_control_show(struct sys_device *dev, 1224static ssize_t etr_stepping_control_show(struct device *dev,
1224 struct sysdev_attribute *attr, 1225 struct device_attribute *attr,
1225 char *buf) 1226 char *buf)
1226{ 1227{
1227 return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ? 1228 return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?
1228 etr_eacr.e0 : etr_eacr.e1); 1229 etr_eacr.e0 : etr_eacr.e1);
1229} 1230}
1230 1231
1231static SYSDEV_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL); 1232static DEVICE_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL);
1232 1233
1233static ssize_t etr_mode_code_show(struct sys_device *dev, 1234static ssize_t etr_mode_code_show(struct device *dev,
1234 struct sysdev_attribute *attr, char *buf) 1235 struct device_attribute *attr, char *buf)
1235{ 1236{
1236 if (!etr_port0_online && !etr_port1_online) 1237 if (!etr_port0_online && !etr_port1_online)
1237 /* Status word is not uptodate if both ports are offline. */ 1238 /* Status word is not uptodate if both ports are offline. */
@@ -1240,10 +1241,10 @@ static ssize_t etr_mode_code_show(struct sys_device *dev,
1240 etr_port0.esw.psc0 : etr_port0.esw.psc1); 1241 etr_port0.esw.psc0 : etr_port0.esw.psc1);
1241} 1242}
1242 1243
1243static SYSDEV_ATTR(state_code, 0400, etr_mode_code_show, NULL); 1244static DEVICE_ATTR(state_code, 0400, etr_mode_code_show, NULL);
1244 1245
1245static ssize_t etr_untuned_show(struct sys_device *dev, 1246static ssize_t etr_untuned_show(struct device *dev,
1246 struct sysdev_attribute *attr, char *buf) 1247 struct device_attribute *attr, char *buf)
1247{ 1248{
1248 struct etr_aib *aib = etr_aib_from_dev(dev); 1249 struct etr_aib *aib = etr_aib_from_dev(dev);
1249 1250
@@ -1252,10 +1253,10 @@ static ssize_t etr_untuned_show(struct sys_device *dev,
1252 return sprintf(buf, "%i\n", aib->edf1.u); 1253 return sprintf(buf, "%i\n", aib->edf1.u);
1253} 1254}
1254 1255
1255static SYSDEV_ATTR(untuned, 0400, etr_untuned_show, NULL); 1256static DEVICE_ATTR(untuned, 0400, etr_untuned_show, NULL);
1256 1257
1257static ssize_t etr_network_id_show(struct sys_device *dev, 1258static ssize_t etr_network_id_show(struct device *dev,
1258 struct sysdev_attribute *attr, char *buf) 1259 struct device_attribute *attr, char *buf)
1259{ 1260{
1260 struct etr_aib *aib = etr_aib_from_dev(dev); 1261 struct etr_aib *aib = etr_aib_from_dev(dev);
1261 1262
@@ -1264,10 +1265,10 @@ static ssize_t etr_network_id_show(struct sys_device *dev,
1264 return sprintf(buf, "%i\n", aib->edf1.net_id); 1265 return sprintf(buf, "%i\n", aib->edf1.net_id);
1265} 1266}
1266 1267
1267static SYSDEV_ATTR(network, 0400, etr_network_id_show, NULL); 1268static DEVICE_ATTR(network, 0400, etr_network_id_show, NULL);
1268 1269
1269static ssize_t etr_id_show(struct sys_device *dev, 1270static ssize_t etr_id_show(struct device *dev,
1270 struct sysdev_attribute *attr, char *buf) 1271 struct device_attribute *attr, char *buf)
1271{ 1272{
1272 struct etr_aib *aib = etr_aib_from_dev(dev); 1273 struct etr_aib *aib = etr_aib_from_dev(dev);
1273 1274
@@ -1276,10 +1277,10 @@ static ssize_t etr_id_show(struct sys_device *dev,
1276 return sprintf(buf, "%i\n", aib->edf1.etr_id); 1277 return sprintf(buf, "%i\n", aib->edf1.etr_id);
1277} 1278}
1278 1279
1279static SYSDEV_ATTR(id, 0400, etr_id_show, NULL); 1280static DEVICE_ATTR(id, 0400, etr_id_show, NULL);
1280 1281
1281static ssize_t etr_port_number_show(struct sys_device *dev, 1282static ssize_t etr_port_number_show(struct device *dev,
1282 struct sysdev_attribute *attr, char *buf) 1283 struct device_attribute *attr, char *buf)
1283{ 1284{
1284 struct etr_aib *aib = etr_aib_from_dev(dev); 1285 struct etr_aib *aib = etr_aib_from_dev(dev);
1285 1286
@@ -1288,10 +1289,10 @@ static ssize_t etr_port_number_show(struct sys_device *dev,
1288 return sprintf(buf, "%i\n", aib->edf1.etr_pn); 1289 return sprintf(buf, "%i\n", aib->edf1.etr_pn);
1289} 1290}
1290 1291
1291static SYSDEV_ATTR(port, 0400, etr_port_number_show, NULL); 1292static DEVICE_ATTR(port, 0400, etr_port_number_show, NULL);
1292 1293
1293static ssize_t etr_coupled_show(struct sys_device *dev, 1294static ssize_t etr_coupled_show(struct device *dev,
1294 struct sysdev_attribute *attr, char *buf) 1295 struct device_attribute *attr, char *buf)
1295{ 1296{
1296 struct etr_aib *aib = etr_aib_from_dev(dev); 1297 struct etr_aib *aib = etr_aib_from_dev(dev);
1297 1298
@@ -1300,10 +1301,10 @@ static ssize_t etr_coupled_show(struct sys_device *dev,
1300 return sprintf(buf, "%i\n", aib->edf3.c); 1301 return sprintf(buf, "%i\n", aib->edf3.c);
1301} 1302}
1302 1303
1303static SYSDEV_ATTR(coupled, 0400, etr_coupled_show, NULL); 1304static DEVICE_ATTR(coupled, 0400, etr_coupled_show, NULL);
1304 1305
1305static ssize_t etr_local_time_show(struct sys_device *dev, 1306static ssize_t etr_local_time_show(struct device *dev,
1306 struct sysdev_attribute *attr, char *buf) 1307 struct device_attribute *attr, char *buf)
1307{ 1308{
1308 struct etr_aib *aib = etr_aib_from_dev(dev); 1309 struct etr_aib *aib = etr_aib_from_dev(dev);
1309 1310
@@ -1312,10 +1313,10 @@ static ssize_t etr_local_time_show(struct sys_device *dev,
1312 return sprintf(buf, "%i\n", aib->edf3.blto); 1313 return sprintf(buf, "%i\n", aib->edf3.blto);
1313} 1314}
1314 1315
1315static SYSDEV_ATTR(local_time, 0400, etr_local_time_show, NULL); 1316static DEVICE_ATTR(local_time, 0400, etr_local_time_show, NULL);
1316 1317
1317static ssize_t etr_utc_offset_show(struct sys_device *dev, 1318static ssize_t etr_utc_offset_show(struct device *dev,
1318 struct sysdev_attribute *attr, char *buf) 1319 struct device_attribute *attr, char *buf)
1319{ 1320{
1320 struct etr_aib *aib = etr_aib_from_dev(dev); 1321 struct etr_aib *aib = etr_aib_from_dev(dev);
1321 1322
@@ -1324,64 +1325,64 @@ static ssize_t etr_utc_offset_show(struct sys_device *dev,
1324 return sprintf(buf, "%i\n", aib->edf3.buo); 1325 return sprintf(buf, "%i\n", aib->edf3.buo);
1325} 1326}
1326 1327
1327static SYSDEV_ATTR(utc_offset, 0400, etr_utc_offset_show, NULL); 1328static DEVICE_ATTR(utc_offset, 0400, etr_utc_offset_show, NULL);
1328 1329
1329static struct sysdev_attribute *etr_port_attributes[] = { 1330static struct device_attribute *etr_port_attributes[] = {
1330 &attr_online, 1331 &dev_attr_online,
1331 &attr_stepping_control, 1332 &dev_attr_stepping_control,
1332 &attr_state_code, 1333 &dev_attr_state_code,
1333 &attr_untuned, 1334 &dev_attr_untuned,
1334 &attr_network, 1335 &dev_attr_network,
1335 &attr_id, 1336 &dev_attr_id,
1336 &attr_port, 1337 &dev_attr_port,
1337 &attr_coupled, 1338 &dev_attr_coupled,
1338 &attr_local_time, 1339 &dev_attr_local_time,
1339 &attr_utc_offset, 1340 &dev_attr_utc_offset,
1340 NULL 1341 NULL
1341}; 1342};
1342 1343
1343static int __init etr_register_port(struct sys_device *dev) 1344static int __init etr_register_port(struct device *dev)
1344{ 1345{
1345 struct sysdev_attribute **attr; 1346 struct device_attribute **attr;
1346 int rc; 1347 int rc;
1347 1348
1348 rc = sysdev_register(dev); 1349 rc = device_register(dev);
1349 if (rc) 1350 if (rc)
1350 goto out; 1351 goto out;
1351 for (attr = etr_port_attributes; *attr; attr++) { 1352 for (attr = etr_port_attributes; *attr; attr++) {
1352 rc = sysdev_create_file(dev, *attr); 1353 rc = device_create_file(dev, *attr);
1353 if (rc) 1354 if (rc)
1354 goto out_unreg; 1355 goto out_unreg;
1355 } 1356 }
1356 return 0; 1357 return 0;
1357out_unreg: 1358out_unreg:
1358 for (; attr >= etr_port_attributes; attr--) 1359 for (; attr >= etr_port_attributes; attr--)
1359 sysdev_remove_file(dev, *attr); 1360 device_remove_file(dev, *attr);
1360 sysdev_unregister(dev); 1361 device_unregister(dev);
1361out: 1362out:
1362 return rc; 1363 return rc;
1363} 1364}
1364 1365
1365static void __init etr_unregister_port(struct sys_device *dev) 1366static void __init etr_unregister_port(struct device *dev)
1366{ 1367{
1367 struct sysdev_attribute **attr; 1368 struct device_attribute **attr;
1368 1369
1369 for (attr = etr_port_attributes; *attr; attr++) 1370 for (attr = etr_port_attributes; *attr; attr++)
1370 sysdev_remove_file(dev, *attr); 1371 device_remove_file(dev, *attr);
1371 sysdev_unregister(dev); 1372 device_unregister(dev);
1372} 1373}
1373 1374
1374static int __init etr_init_sysfs(void) 1375static int __init etr_init_sysfs(void)
1375{ 1376{
1376 int rc; 1377 int rc;
1377 1378
1378 rc = sysdev_class_register(&etr_sysclass); 1379 rc = subsys_system_register(&etr_subsys, NULL);
1379 if (rc) 1380 if (rc)
1380 goto out; 1381 goto out;
1381 rc = sysdev_class_create_file(&etr_sysclass, &attr_stepping_port); 1382 rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_port);
1382 if (rc) 1383 if (rc)
1383 goto out_unreg_class; 1384 goto out_unreg_subsys;
1384 rc = sysdev_class_create_file(&etr_sysclass, &attr_stepping_mode); 1385 rc = device_create_file(etr_subsys.dev_root, &dev_attr_stepping_mode);
1385 if (rc) 1386 if (rc)
1386 goto out_remove_stepping_port; 1387 goto out_remove_stepping_port;
1387 rc = etr_register_port(&etr_port0_dev); 1388 rc = etr_register_port(&etr_port0_dev);
@@ -1395,11 +1396,11 @@ static int __init etr_init_sysfs(void)
1395out_remove_port0: 1396out_remove_port0:
1396 etr_unregister_port(&etr_port0_dev); 1397 etr_unregister_port(&etr_port0_dev);
1397out_remove_stepping_mode: 1398out_remove_stepping_mode:
1398 sysdev_class_remove_file(&etr_sysclass, &attr_stepping_mode); 1399 device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_mode);
1399out_remove_stepping_port: 1400out_remove_stepping_port:
1400 sysdev_class_remove_file(&etr_sysclass, &attr_stepping_port); 1401 device_remove_file(etr_subsys.dev_root, &dev_attr_stepping_port);
1401out_unreg_class: 1402out_unreg_subsys:
1402 sysdev_class_unregister(&etr_sysclass); 1403 bus_unregister(&etr_subsys);
1403out: 1404out:
1404 return rc; 1405 return rc;
1405} 1406}
@@ -1599,14 +1600,15 @@ out_unlock:
1599} 1600}
1600 1601
1601/* 1602/*
1602 * STP class sysfs interface functions 1603 * STP subsys sysfs interface functions
1603 */ 1604 */
1604static struct sysdev_class stp_sysclass = { 1605static struct bus_type stp_subsys = {
1605 .name = "stp", 1606 .name = "stp",
1607 .dev_name = "stp",
1606}; 1608};
1607 1609
1608static ssize_t stp_ctn_id_show(struct sysdev_class *class, 1610static ssize_t stp_ctn_id_show(struct device *dev,
1609 struct sysdev_class_attribute *attr, 1611 struct device_attribute *attr,
1610 char *buf) 1612 char *buf)
1611{ 1613{
1612 if (!stp_online) 1614 if (!stp_online)
@@ -1615,10 +1617,10 @@ static ssize_t stp_ctn_id_show(struct sysdev_class *class,
1615 *(unsigned long long *) stp_info.ctnid); 1617 *(unsigned long long *) stp_info.ctnid);
1616} 1618}
1617 1619
1618static SYSDEV_CLASS_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL); 1620static DEVICE_ATTR(ctn_id, 0400, stp_ctn_id_show, NULL);
1619 1621
1620static ssize_t stp_ctn_type_show(struct sysdev_class *class, 1622static ssize_t stp_ctn_type_show(struct device *dev,
1621 struct sysdev_class_attribute *attr, 1623 struct device_attribute *attr,
1622 char *buf) 1624 char *buf)
1623{ 1625{
1624 if (!stp_online) 1626 if (!stp_online)
@@ -1626,10 +1628,10 @@ static ssize_t stp_ctn_type_show(struct sysdev_class *class,
1626 return sprintf(buf, "%i\n", stp_info.ctn); 1628 return sprintf(buf, "%i\n", stp_info.ctn);
1627} 1629}
1628 1630
1629static SYSDEV_CLASS_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL); 1631static DEVICE_ATTR(ctn_type, 0400, stp_ctn_type_show, NULL);
1630 1632
1631static ssize_t stp_dst_offset_show(struct sysdev_class *class, 1633static ssize_t stp_dst_offset_show(struct device *dev,
1632 struct sysdev_class_attribute *attr, 1634 struct device_attribute *attr,
1633 char *buf) 1635 char *buf)
1634{ 1636{
1635 if (!stp_online || !(stp_info.vbits & 0x2000)) 1637 if (!stp_online || !(stp_info.vbits & 0x2000))
@@ -1637,10 +1639,10 @@ static ssize_t stp_dst_offset_show(struct sysdev_class *class,
1637 return sprintf(buf, "%i\n", (int)(s16) stp_info.dsto); 1639 return sprintf(buf, "%i\n", (int)(s16) stp_info.dsto);
1638} 1640}
1639 1641
1640static SYSDEV_CLASS_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL); 1642static DEVICE_ATTR(dst_offset, 0400, stp_dst_offset_show, NULL);
1641 1643
1642static ssize_t stp_leap_seconds_show(struct sysdev_class *class, 1644static ssize_t stp_leap_seconds_show(struct device *dev,
1643 struct sysdev_class_attribute *attr, 1645 struct device_attribute *attr,
1644 char *buf) 1646 char *buf)
1645{ 1647{
1646 if (!stp_online || !(stp_info.vbits & 0x8000)) 1648 if (!stp_online || !(stp_info.vbits & 0x8000))
@@ -1648,10 +1650,10 @@ static ssize_t stp_leap_seconds_show(struct sysdev_class *class,
1648 return sprintf(buf, "%i\n", (int)(s16) stp_info.leaps); 1650 return sprintf(buf, "%i\n", (int)(s16) stp_info.leaps);
1649} 1651}
1650 1652
1651static SYSDEV_CLASS_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL); 1653static DEVICE_ATTR(leap_seconds, 0400, stp_leap_seconds_show, NULL);
1652 1654
1653static ssize_t stp_stratum_show(struct sysdev_class *class, 1655static ssize_t stp_stratum_show(struct device *dev,
1654 struct sysdev_class_attribute *attr, 1656 struct device_attribute *attr,
1655 char *buf) 1657 char *buf)
1656{ 1658{
1657 if (!stp_online) 1659 if (!stp_online)
@@ -1659,10 +1661,10 @@ static ssize_t stp_stratum_show(struct sysdev_class *class,
1659 return sprintf(buf, "%i\n", (int)(s16) stp_info.stratum); 1661 return sprintf(buf, "%i\n", (int)(s16) stp_info.stratum);
1660} 1662}
1661 1663
1662static SYSDEV_CLASS_ATTR(stratum, 0400, stp_stratum_show, NULL); 1664static DEVICE_ATTR(stratum, 0400, stp_stratum_show, NULL);
1663 1665
1664static ssize_t stp_time_offset_show(struct sysdev_class *class, 1666static ssize_t stp_time_offset_show(struct device *dev,
1665 struct sysdev_class_attribute *attr, 1667 struct device_attribute *attr,
1666 char *buf) 1668 char *buf)
1667{ 1669{
1668 if (!stp_online || !(stp_info.vbits & 0x0800)) 1670 if (!stp_online || !(stp_info.vbits & 0x0800))
@@ -1670,10 +1672,10 @@ static ssize_t stp_time_offset_show(struct sysdev_class *class,
1670 return sprintf(buf, "%i\n", (int) stp_info.tto); 1672 return sprintf(buf, "%i\n", (int) stp_info.tto);
1671} 1673}
1672 1674
1673static SYSDEV_CLASS_ATTR(time_offset, 0400, stp_time_offset_show, NULL); 1675static DEVICE_ATTR(time_offset, 0400, stp_time_offset_show, NULL);
1674 1676
1675static ssize_t stp_time_zone_offset_show(struct sysdev_class *class, 1677static ssize_t stp_time_zone_offset_show(struct device *dev,
1676 struct sysdev_class_attribute *attr, 1678 struct device_attribute *attr,
1677 char *buf) 1679 char *buf)
1678{ 1680{
1679 if (!stp_online || !(stp_info.vbits & 0x4000)) 1681 if (!stp_online || !(stp_info.vbits & 0x4000))
@@ -1681,11 +1683,11 @@ static ssize_t stp_time_zone_offset_show(struct sysdev_class *class,
1681 return sprintf(buf, "%i\n", (int)(s16) stp_info.tzo); 1683 return sprintf(buf, "%i\n", (int)(s16) stp_info.tzo);
1682} 1684}
1683 1685
1684static SYSDEV_CLASS_ATTR(time_zone_offset, 0400, 1686static DEVICE_ATTR(time_zone_offset, 0400,
1685 stp_time_zone_offset_show, NULL); 1687 stp_time_zone_offset_show, NULL);
1686 1688
1687static ssize_t stp_timing_mode_show(struct sysdev_class *class, 1689static ssize_t stp_timing_mode_show(struct device *dev,
1688 struct sysdev_class_attribute *attr, 1690 struct device_attribute *attr,
1689 char *buf) 1691 char *buf)
1690{ 1692{
1691 if (!stp_online) 1693 if (!stp_online)
@@ -1693,10 +1695,10 @@ static ssize_t stp_timing_mode_show(struct sysdev_class *class,
1693 return sprintf(buf, "%i\n", stp_info.tmd); 1695 return sprintf(buf, "%i\n", stp_info.tmd);
1694} 1696}
1695 1697
1696static SYSDEV_CLASS_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL); 1698static DEVICE_ATTR(timing_mode, 0400, stp_timing_mode_show, NULL);
1697 1699
1698static ssize_t stp_timing_state_show(struct sysdev_class *class, 1700static ssize_t stp_timing_state_show(struct device *dev,
1699 struct sysdev_class_attribute *attr, 1701 struct device_attribute *attr,
1700 char *buf) 1702 char *buf)
1701{ 1703{
1702 if (!stp_online) 1704 if (!stp_online)
@@ -1704,17 +1706,17 @@ static ssize_t stp_timing_state_show(struct sysdev_class *class,
1704 return sprintf(buf, "%i\n", stp_info.tst); 1706 return sprintf(buf, "%i\n", stp_info.tst);
1705} 1707}
1706 1708
1707static SYSDEV_CLASS_ATTR(timing_state, 0400, stp_timing_state_show, NULL); 1709static DEVICE_ATTR(timing_state, 0400, stp_timing_state_show, NULL);
1708 1710
1709static ssize_t stp_online_show(struct sysdev_class *class, 1711static ssize_t stp_online_show(struct device *dev,
1710 struct sysdev_class_attribute *attr, 1712 struct device_attribute *attr,
1711 char *buf) 1713 char *buf)
1712{ 1714{
1713 return sprintf(buf, "%i\n", stp_online); 1715 return sprintf(buf, "%i\n", stp_online);
1714} 1716}
1715 1717
1716static ssize_t stp_online_store(struct sysdev_class *class, 1718static ssize_t stp_online_store(struct device *dev,
1717 struct sysdev_class_attribute *attr, 1719 struct device_attribute *attr,
1718 const char *buf, size_t count) 1720 const char *buf, size_t count)
1719{ 1721{
1720 unsigned int value; 1722 unsigned int value;
@@ -1736,47 +1738,47 @@ static ssize_t stp_online_store(struct sysdev_class *class,
1736} 1738}
1737 1739
1738/* 1740/*
1739 * Can't use SYSDEV_CLASS_ATTR because the attribute should be named 1741 * Can't use DEVICE_ATTR because the attribute should be named
1740 * stp/online but attr_online already exists in this file .. 1742 * stp/online but dev_attr_online already exists in this file ..
1741 */ 1743 */
1742static struct sysdev_class_attribute attr_stp_online = { 1744static struct device_attribute dev_attr_stp_online = {
1743 .attr = { .name = "online", .mode = 0600 }, 1745 .attr = { .name = "online", .mode = 0600 },
1744 .show = stp_online_show, 1746 .show = stp_online_show,
1745 .store = stp_online_store, 1747 .store = stp_online_store,
1746}; 1748};
1747 1749
1748static struct sysdev_class_attribute *stp_attributes[] = { 1750static struct device_attribute *stp_attributes[] = {
1749 &attr_ctn_id, 1751 &dev_attr_ctn_id,
1750 &attr_ctn_type, 1752 &dev_attr_ctn_type,
1751 &attr_dst_offset, 1753 &dev_attr_dst_offset,
1752 &attr_leap_seconds, 1754 &dev_attr_leap_seconds,
1753 &attr_stp_online, 1755 &dev_attr_stp_online,
1754 &attr_stratum, 1756 &dev_attr_stratum,
1755 &attr_time_offset, 1757 &dev_attr_time_offset,
1756 &attr_time_zone_offset, 1758 &dev_attr_time_zone_offset,
1757 &attr_timing_mode, 1759 &dev_attr_timing_mode,
1758 &attr_timing_state, 1760 &dev_attr_timing_state,
1759 NULL 1761 NULL
1760}; 1762};
1761 1763
1762static int __init stp_init_sysfs(void) 1764static int __init stp_init_sysfs(void)
1763{ 1765{
1764 struct sysdev_class_attribute **attr; 1766 struct device_attribute **attr;
1765 int rc; 1767 int rc;
1766 1768
1767 rc = sysdev_class_register(&stp_sysclass); 1769 rc = subsys_system_register(&stp_subsys, NULL);
1768 if (rc) 1770 if (rc)
1769 goto out; 1771 goto out;
1770 for (attr = stp_attributes; *attr; attr++) { 1772 for (attr = stp_attributes; *attr; attr++) {
1771 rc = sysdev_class_create_file(&stp_sysclass, *attr); 1773 rc = device_create_file(stp_subsys.dev_root, *attr);
1772 if (rc) 1774 if (rc)
1773 goto out_unreg; 1775 goto out_unreg;
1774 } 1776 }
1775 return 0; 1777 return 0;
1776out_unreg: 1778out_unreg:
1777 for (; attr >= stp_attributes; attr--) 1779 for (; attr >= stp_attributes; attr--)
1778 sysdev_class_remove_file(&stp_sysclass, *attr); 1780 device_remove_file(stp_subsys.dev_root, *attr);
1779 sysdev_class_unregister(&stp_sysclass); 1781 bus_unregister(&stp_subsys);
1780out: 1782out:
1781 return rc; 1783 return rc;
1782} 1784}
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index fdb5b8cb260f..7370a41948ca 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -1,22 +1,22 @@
1/* 1/*
2 * Copyright IBM Corp. 2007 2 * Copyright IBM Corp. 2007,2011
3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> 3 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
4 */ 4 */
5 5
6#define KMSG_COMPONENT "cpu" 6#define KMSG_COMPONENT "cpu"
7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt 7#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
8 8
9#include <linux/kernel.h> 9#include <linux/workqueue.h>
10#include <linux/mm.h>
11#include <linux/init.h>
12#include <linux/device.h>
13#include <linux/bootmem.h> 10#include <linux/bootmem.h>
11#include <linux/cpuset.h>
12#include <linux/device.h>
13#include <linux/kernel.h>
14#include <linux/sched.h> 14#include <linux/sched.h>
15#include <linux/workqueue.h> 15#include <linux/init.h>
16#include <linux/delay.h>
16#include <linux/cpu.h> 17#include <linux/cpu.h>
17#include <linux/smp.h> 18#include <linux/smp.h>
18#include <linux/cpuset.h> 19#include <linux/mm.h>
19#include <asm/delay.h>
20 20
21#define PTF_HORIZONTAL (0UL) 21#define PTF_HORIZONTAL (0UL)
22#define PTF_VERTICAL (1UL) 22#define PTF_VERTICAL (1UL)
@@ -31,7 +31,6 @@ struct mask_info {
31static int topology_enabled = 1; 31static int topology_enabled = 1;
32static void topology_work_fn(struct work_struct *work); 32static void topology_work_fn(struct work_struct *work);
33static struct sysinfo_15_1_x *tl_info; 33static struct sysinfo_15_1_x *tl_info;
34static struct timer_list topology_timer;
35static void set_topology_timer(void); 34static void set_topology_timer(void);
36static DECLARE_WORK(topology_work, topology_work_fn); 35static DECLARE_WORK(topology_work, topology_work_fn);
37/* topology_lock protects the core linked list */ 36/* topology_lock protects the core linked list */
@@ -41,11 +40,12 @@ static struct mask_info core_info;
41cpumask_t cpu_core_map[NR_CPUS]; 40cpumask_t cpu_core_map[NR_CPUS];
42unsigned char cpu_core_id[NR_CPUS]; 41unsigned char cpu_core_id[NR_CPUS];
43 42
44#ifdef CONFIG_SCHED_BOOK
45static struct mask_info book_info; 43static struct mask_info book_info;
46cpumask_t cpu_book_map[NR_CPUS]; 44cpumask_t cpu_book_map[NR_CPUS];
47unsigned char cpu_book_id[NR_CPUS]; 45unsigned char cpu_book_id[NR_CPUS];
48#endif 46
47/* smp_cpu_state_mutex must be held when accessing this array */
48int cpu_polarization[NR_CPUS];
49 49
50static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu) 50static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
51{ 51{
@@ -71,7 +71,7 @@ static cpumask_t cpu_group_map(struct mask_info *info, unsigned int cpu)
71static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu, 71static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
72 struct mask_info *book, 72 struct mask_info *book,
73 struct mask_info *core, 73 struct mask_info *core,
74 int z10) 74 int one_core_per_cpu)
75{ 75{
76 unsigned int cpu; 76 unsigned int cpu;
77 77
@@ -85,18 +85,16 @@ static struct mask_info *add_cpus_to_mask(struct topology_cpu *tl_cpu,
85 for_each_present_cpu(lcpu) { 85 for_each_present_cpu(lcpu) {
86 if (cpu_logical_map(lcpu) != rcpu) 86 if (cpu_logical_map(lcpu) != rcpu)
87 continue; 87 continue;
88#ifdef CONFIG_SCHED_BOOK
89 cpumask_set_cpu(lcpu, &book->mask); 88 cpumask_set_cpu(lcpu, &book->mask);
90 cpu_book_id[lcpu] = book->id; 89 cpu_book_id[lcpu] = book->id;
91#endif
92 cpumask_set_cpu(lcpu, &core->mask); 90 cpumask_set_cpu(lcpu, &core->mask);
93 if (z10) { 91 if (one_core_per_cpu) {
94 cpu_core_id[lcpu] = rcpu; 92 cpu_core_id[lcpu] = rcpu;
95 core = core->next; 93 core = core->next;
96 } else { 94 } else {
97 cpu_core_id[lcpu] = core->id; 95 cpu_core_id[lcpu] = core->id;
98 } 96 }
99 smp_cpu_polarization[lcpu] = tl_cpu->pp; 97 cpu_set_polarization(lcpu, tl_cpu->pp);
100 } 98 }
101 } 99 }
102 return core; 100 return core;
@@ -111,13 +109,11 @@ static void clear_masks(void)
111 cpumask_clear(&info->mask); 109 cpumask_clear(&info->mask);
112 info = info->next; 110 info = info->next;
113 } 111 }
114#ifdef CONFIG_SCHED_BOOK
115 info = &book_info; 112 info = &book_info;
116 while (info) { 113 while (info) {
117 cpumask_clear(&info->mask); 114 cpumask_clear(&info->mask);
118 info = info->next; 115 info = info->next;
119 } 116 }
120#endif
121} 117}
122 118
123static union topology_entry *next_tle(union topology_entry *tle) 119static union topology_entry *next_tle(union topology_entry *tle)
@@ -127,66 +123,75 @@ static union topology_entry *next_tle(union topology_entry *tle)
127 return (union topology_entry *)((struct topology_container *)tle + 1); 123 return (union topology_entry *)((struct topology_container *)tle + 1);
128} 124}
129 125
130static void tl_to_cores(struct sysinfo_15_1_x *info) 126static void __tl_to_cores_generic(struct sysinfo_15_1_x *info)
131{ 127{
132#ifdef CONFIG_SCHED_BOOK
133 struct mask_info *book = &book_info;
134 struct cpuid cpu_id;
135#else
136 struct mask_info *book = NULL;
137#endif
138 struct mask_info *core = &core_info; 128 struct mask_info *core = &core_info;
129 struct mask_info *book = &book_info;
139 union topology_entry *tle, *end; 130 union topology_entry *tle, *end;
140 int z10 = 0;
141 131
142#ifdef CONFIG_SCHED_BOOK
143 get_cpu_id(&cpu_id);
144 z10 = cpu_id.machine == 0x2097 || cpu_id.machine == 0x2098;
145#endif
146 spin_lock_irq(&topology_lock);
147 clear_masks();
148 tle = info->tle; 132 tle = info->tle;
149 end = (union topology_entry *)((unsigned long)info + info->length); 133 end = (union topology_entry *)((unsigned long)info + info->length);
150 while (tle < end) { 134 while (tle < end) {
151#ifdef CONFIG_SCHED_BOOK
152 if (z10) {
153 switch (tle->nl) {
154 case 1:
155 book = book->next;
156 book->id = tle->container.id;
157 break;
158 case 0:
159 core = add_cpus_to_mask(&tle->cpu, book, core, z10);
160 break;
161 default:
162 clear_masks();
163 goto out;
164 }
165 tle = next_tle(tle);
166 continue;
167 }
168#endif
169 switch (tle->nl) { 135 switch (tle->nl) {
170#ifdef CONFIG_SCHED_BOOK
171 case 2: 136 case 2:
172 book = book->next; 137 book = book->next;
173 book->id = tle->container.id; 138 book->id = tle->container.id;
174 break; 139 break;
175#endif
176 case 1: 140 case 1:
177 core = core->next; 141 core = core->next;
178 core->id = tle->container.id; 142 core->id = tle->container.id;
179 break; 143 break;
180 case 0: 144 case 0:
181 add_cpus_to_mask(&tle->cpu, book, core, z10); 145 add_cpus_to_mask(&tle->cpu, book, core, 0);
182 break; 146 break;
183 default: 147 default:
184 clear_masks(); 148 clear_masks();
185 goto out; 149 return;
186 } 150 }
187 tle = next_tle(tle); 151 tle = next_tle(tle);
188 } 152 }
189out: 153}
154
155static void __tl_to_cores_z10(struct sysinfo_15_1_x *info)
156{
157 struct mask_info *core = &core_info;
158 struct mask_info *book = &book_info;
159 union topology_entry *tle, *end;
160
161 tle = info->tle;
162 end = (union topology_entry *)((unsigned long)info + info->length);
163 while (tle < end) {
164 switch (tle->nl) {
165 case 1:
166 book = book->next;
167 book->id = tle->container.id;
168 break;
169 case 0:
170 core = add_cpus_to_mask(&tle->cpu, book, core, 1);
171 break;
172 default:
173 clear_masks();
174 return;
175 }
176 tle = next_tle(tle);
177 }
178}
179
180static void tl_to_cores(struct sysinfo_15_1_x *info)
181{
182 struct cpuid cpu_id;
183
184 get_cpu_id(&cpu_id);
185 spin_lock_irq(&topology_lock);
186 clear_masks();
187 switch (cpu_id.machine) {
188 case 0x2097:
189 case 0x2098:
190 __tl_to_cores_z10(info);
191 break;
192 default:
193 __tl_to_cores_generic(info);
194 }
190 spin_unlock_irq(&topology_lock); 195 spin_unlock_irq(&topology_lock);
191} 196}
192 197
@@ -196,7 +201,7 @@ static void topology_update_polarization_simple(void)
196 201
197 mutex_lock(&smp_cpu_state_mutex); 202 mutex_lock(&smp_cpu_state_mutex);
198 for_each_possible_cpu(cpu) 203 for_each_possible_cpu(cpu)
199 smp_cpu_polarization[cpu] = POLARIZATION_HRZ; 204 cpu_set_polarization(cpu, POLARIZATION_HRZ);
200 mutex_unlock(&smp_cpu_state_mutex); 205 mutex_unlock(&smp_cpu_state_mutex);
201} 206}
202 207
@@ -215,8 +220,7 @@ static int ptf(unsigned long fc)
215 220
216int topology_set_cpu_management(int fc) 221int topology_set_cpu_management(int fc)
217{ 222{
218 int cpu; 223 int cpu, rc;
219 int rc;
220 224
221 if (!MACHINE_HAS_TOPOLOGY) 225 if (!MACHINE_HAS_TOPOLOGY)
222 return -EOPNOTSUPP; 226 return -EOPNOTSUPP;
@@ -227,7 +231,7 @@ int topology_set_cpu_management(int fc)
227 if (rc) 231 if (rc)
228 return -EBUSY; 232 return -EBUSY;
229 for_each_possible_cpu(cpu) 233 for_each_possible_cpu(cpu)
230 smp_cpu_polarization[cpu] = POLARIZATION_UNKNWN; 234 cpu_set_polarization(cpu, POLARIZATION_UNKNOWN);
231 return rc; 235 return rc;
232} 236}
233 237
@@ -239,29 +243,25 @@ static void update_cpu_core_map(void)
239 spin_lock_irqsave(&topology_lock, flags); 243 spin_lock_irqsave(&topology_lock, flags);
240 for_each_possible_cpu(cpu) { 244 for_each_possible_cpu(cpu) {
241 cpu_core_map[cpu] = cpu_group_map(&core_info, cpu); 245 cpu_core_map[cpu] = cpu_group_map(&core_info, cpu);
242#ifdef CONFIG_SCHED_BOOK
243 cpu_book_map[cpu] = cpu_group_map(&book_info, cpu); 246 cpu_book_map[cpu] = cpu_group_map(&book_info, cpu);
244#endif
245 } 247 }
246 spin_unlock_irqrestore(&topology_lock, flags); 248 spin_unlock_irqrestore(&topology_lock, flags);
247} 249}
248 250
249void store_topology(struct sysinfo_15_1_x *info) 251void store_topology(struct sysinfo_15_1_x *info)
250{ 252{
251#ifdef CONFIG_SCHED_BOOK
252 int rc; 253 int rc;
253 254
254 rc = stsi(info, 15, 1, 3); 255 rc = stsi(info, 15, 1, 3);
255 if (rc != -ENOSYS) 256 if (rc != -ENOSYS)
256 return; 257 return;
257#endif
258 stsi(info, 15, 1, 2); 258 stsi(info, 15, 1, 2);
259} 259}
260 260
261int arch_update_cpu_topology(void) 261int arch_update_cpu_topology(void)
262{ 262{
263 struct sysinfo_15_1_x *info = tl_info; 263 struct sysinfo_15_1_x *info = tl_info;
264 struct sys_device *sysdev; 264 struct device *dev;
265 int cpu; 265 int cpu;
266 266
267 if (!MACHINE_HAS_TOPOLOGY) { 267 if (!MACHINE_HAS_TOPOLOGY) {
@@ -273,8 +273,8 @@ int arch_update_cpu_topology(void)
273 tl_to_cores(info); 273 tl_to_cores(info);
274 update_cpu_core_map(); 274 update_cpu_core_map();
275 for_each_online_cpu(cpu) { 275 for_each_online_cpu(cpu) {
276 sysdev = get_cpu_sysdev(cpu); 276 dev = get_cpu_device(cpu);
277 kobject_uevent(&sysdev->kobj, KOBJ_CHANGE); 277 kobject_uevent(&dev->kobj, KOBJ_CHANGE);
278 } 278 }
279 return 1; 279 return 1;
280} 280}
@@ -296,12 +296,30 @@ static void topology_timer_fn(unsigned long ignored)
296 set_topology_timer(); 296 set_topology_timer();
297} 297}
298 298
299static struct timer_list topology_timer =
300 TIMER_DEFERRED_INITIALIZER(topology_timer_fn, 0, 0);
301
302static atomic_t topology_poll = ATOMIC_INIT(0);
303
299static void set_topology_timer(void) 304static void set_topology_timer(void)
300{ 305{
301 topology_timer.function = topology_timer_fn; 306 if (atomic_add_unless(&topology_poll, -1, 0))
302 topology_timer.data = 0; 307 mod_timer(&topology_timer, jiffies + HZ / 10);
303 topology_timer.expires = jiffies + 60 * HZ; 308 else
304 add_timer(&topology_timer); 309 mod_timer(&topology_timer, jiffies + HZ * 60);
310}
311
312void topology_expect_change(void)
313{
314 if (!MACHINE_HAS_TOPOLOGY)
315 return;
316 /* This is racy, but it doesn't matter since it is just a heuristic.
317 * Worst case is that we poll in a higher frequency for a bit longer.
318 */
319 if (atomic_read(&topology_poll) > 60)
320 return;
321 atomic_add(60, &topology_poll);
322 set_topology_timer();
305} 323}
306 324
307static int __init early_parse_topology(char *p) 325static int __init early_parse_topology(char *p)
@@ -313,23 +331,6 @@ static int __init early_parse_topology(char *p)
313} 331}
314early_param("topology", early_parse_topology); 332early_param("topology", early_parse_topology);
315 333
316static int __init init_topology_update(void)
317{
318 int rc;
319
320 rc = 0;
321 if (!MACHINE_HAS_TOPOLOGY) {
322 topology_update_polarization_simple();
323 goto out;
324 }
325 init_timer_deferrable(&topology_timer);
326 set_topology_timer();
327out:
328 update_cpu_core_map();
329 return rc;
330}
331__initcall(init_topology_update);
332
333static void __init alloc_masks(struct sysinfo_15_1_x *info, 334static void __init alloc_masks(struct sysinfo_15_1_x *info,
334 struct mask_info *mask, int offset) 335 struct mask_info *mask, int offset)
335{ 336{
@@ -357,10 +358,108 @@ void __init s390_init_cpu_topology(void)
357 store_topology(info); 358 store_topology(info);
358 pr_info("The CPU configuration topology of the machine is:"); 359 pr_info("The CPU configuration topology of the machine is:");
359 for (i = 0; i < TOPOLOGY_NR_MAG; i++) 360 for (i = 0; i < TOPOLOGY_NR_MAG; i++)
360 printk(" %d", info->mag[i]); 361 printk(KERN_CONT " %d", info->mag[i]);
361 printk(" / %d\n", info->mnest); 362 printk(KERN_CONT " / %d\n", info->mnest);
362 alloc_masks(info, &core_info, 1); 363 alloc_masks(info, &core_info, 1);
363#ifdef CONFIG_SCHED_BOOK
364 alloc_masks(info, &book_info, 2); 364 alloc_masks(info, &book_info, 2);
365#endif
366} 365}
366
367static int cpu_management;
368
369static ssize_t dispatching_show(struct device *dev,
370 struct device_attribute *attr,
371 char *buf)
372{
373 ssize_t count;
374
375 mutex_lock(&smp_cpu_state_mutex);
376 count = sprintf(buf, "%d\n", cpu_management);
377 mutex_unlock(&smp_cpu_state_mutex);
378 return count;
379}
380
381static ssize_t dispatching_store(struct device *dev,
382 struct device_attribute *attr,
383 const char *buf,
384 size_t count)
385{
386 int val, rc;
387 char delim;
388
389 if (sscanf(buf, "%d %c", &val, &delim) != 1)
390 return -EINVAL;
391 if (val != 0 && val != 1)
392 return -EINVAL;
393 rc = 0;
394 get_online_cpus();
395 mutex_lock(&smp_cpu_state_mutex);
396 if (cpu_management == val)
397 goto out;
398 rc = topology_set_cpu_management(val);
399 if (rc)
400 goto out;
401 cpu_management = val;
402 topology_expect_change();
403out:
404 mutex_unlock(&smp_cpu_state_mutex);
405 put_online_cpus();
406 return rc ? rc : count;
407}
408static DEVICE_ATTR(dispatching, 0644, dispatching_show,
409 dispatching_store);
410
411static ssize_t cpu_polarization_show(struct device *dev,
412 struct device_attribute *attr, char *buf)
413{
414 int cpu = dev->id;
415 ssize_t count;
416
417 mutex_lock(&smp_cpu_state_mutex);
418 switch (cpu_read_polarization(cpu)) {
419 case POLARIZATION_HRZ:
420 count = sprintf(buf, "horizontal\n");
421 break;
422 case POLARIZATION_VL:
423 count = sprintf(buf, "vertical:low\n");
424 break;
425 case POLARIZATION_VM:
426 count = sprintf(buf, "vertical:medium\n");
427 break;
428 case POLARIZATION_VH:
429 count = sprintf(buf, "vertical:high\n");
430 break;
431 default:
432 count = sprintf(buf, "unknown\n");
433 break;
434 }
435 mutex_unlock(&smp_cpu_state_mutex);
436 return count;
437}
438static DEVICE_ATTR(polarization, 0444, cpu_polarization_show, NULL);
439
440static struct attribute *topology_cpu_attrs[] = {
441 &dev_attr_polarization.attr,
442 NULL,
443};
444
445static struct attribute_group topology_cpu_attr_group = {
446 .attrs = topology_cpu_attrs,
447};
448
449int topology_cpu_init(struct cpu *cpu)
450{
451 return sysfs_create_group(&cpu->dev.kobj, &topology_cpu_attr_group);
452}
453
454static int __init topology_init(void)
455{
456 if (!MACHINE_HAS_TOPOLOGY) {
457 topology_update_polarization_simple();
458 goto out;
459 }
460 set_topology_timer();
461out:
462 update_cpu_core_map();
463 return device_create_file(cpu_subsys.dev_root, &dev_attr_dispatching);
464}
465device_initcall(topology_init);
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index a9807dd86276..5ce3750b181f 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -43,9 +43,9 @@
43#include <asm/debug.h> 43#include <asm/debug.h>
44#include "entry.h" 44#include "entry.h"
45 45
46void (*pgm_check_table[128])(struct pt_regs *, long, unsigned long); 46void (*pgm_check_table[128])(struct pt_regs *regs);
47 47
48int show_unhandled_signals; 48int show_unhandled_signals = 1;
49 49
50#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 50#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
51 51
@@ -234,7 +234,7 @@ void show_regs(struct pt_regs *regs)
234 234
235static DEFINE_SPINLOCK(die_lock); 235static DEFINE_SPINLOCK(die_lock);
236 236
237void die(const char * str, struct pt_regs * regs, long err) 237void die(struct pt_regs *regs, const char *str)
238{ 238{
239 static int die_counter; 239 static int die_counter;
240 240
@@ -243,7 +243,7 @@ void die(const char * str, struct pt_regs * regs, long err)
243 console_verbose(); 243 console_verbose();
244 spin_lock_irq(&die_lock); 244 spin_lock_irq(&die_lock);
245 bust_spinlocks(1); 245 bust_spinlocks(1);
246 printk("%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); 246 printk("%s: %04x [#%d] ", str, regs->int_code & 0xffff, ++die_counter);
247#ifdef CONFIG_PREEMPT 247#ifdef CONFIG_PREEMPT
248 printk("PREEMPT "); 248 printk("PREEMPT ");
249#endif 249#endif
@@ -254,7 +254,7 @@ void die(const char * str, struct pt_regs * regs, long err)
254 printk("DEBUG_PAGEALLOC"); 254 printk("DEBUG_PAGEALLOC");
255#endif 255#endif
256 printk("\n"); 256 printk("\n");
257 notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); 257 notify_die(DIE_OOPS, str, regs, 0, regs->int_code & 0xffff, SIGSEGV);
258 show_regs(regs); 258 show_regs(regs);
259 bust_spinlocks(0); 259 bust_spinlocks(0);
260 add_taint(TAINT_DIE); 260 add_taint(TAINT_DIE);
@@ -267,8 +267,7 @@ void die(const char * str, struct pt_regs * regs, long err)
267 do_exit(SIGSEGV); 267 do_exit(SIGSEGV);
268} 268}
269 269
270static void inline report_user_fault(struct pt_regs *regs, long int_code, 270static inline void report_user_fault(struct pt_regs *regs, int signr)
271 int signr)
272{ 271{
273 if ((task_pid_nr(current) > 1) && !show_unhandled_signals) 272 if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
274 return; 273 return;
@@ -276,7 +275,7 @@ static void inline report_user_fault(struct pt_regs *regs, long int_code,
276 return; 275 return;
277 if (!printk_ratelimit()) 276 if (!printk_ratelimit())
278 return; 277 return;
279 printk("User process fault: interruption code 0x%lX ", int_code); 278 printk("User process fault: interruption code 0x%X ", regs->int_code);
280 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN); 279 print_vma_addr("in ", regs->psw.addr & PSW_ADDR_INSN);
281 printk("\n"); 280 printk("\n");
282 show_regs(regs); 281 show_regs(regs);
@@ -287,19 +286,28 @@ int is_valid_bugaddr(unsigned long addr)
287 return 1; 286 return 1;
288} 287}
289 288
290static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str, 289static inline void __user *get_psw_address(struct pt_regs *regs)
291 struct pt_regs *regs, siginfo_t *info)
292{ 290{
293 if (notify_die(DIE_TRAP, str, regs, pgm_int_code, 291 return (void __user *)
294 pgm_int_code, signr) == NOTIFY_STOP) 292 ((regs->psw.addr - (regs->int_code >> 16)) & PSW_ADDR_INSN);
293}
294
295static void __kprobes do_trap(struct pt_regs *regs,
296 int si_signo, int si_code, char *str)
297{
298 siginfo_t info;
299
300 if (notify_die(DIE_TRAP, str, regs, 0,
301 regs->int_code, si_signo) == NOTIFY_STOP)
295 return; 302 return;
296 303
297 if (regs->psw.mask & PSW_MASK_PSTATE) { 304 if (regs->psw.mask & PSW_MASK_PSTATE) {
298 struct task_struct *tsk = current; 305 info.si_signo = si_signo;
299 306 info.si_errno = 0;
300 tsk->thread.trap_no = pgm_int_code & 0xffff; 307 info.si_code = si_code;
301 force_sig_info(signr, info, tsk); 308 info.si_addr = get_psw_address(regs);
302 report_user_fault(regs, pgm_int_code, signr); 309 force_sig_info(si_signo, &info, current);
310 report_user_fault(regs, si_signo);
303 } else { 311 } else {
304 const struct exception_table_entry *fixup; 312 const struct exception_table_entry *fixup;
305 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN); 313 fixup = search_exception_tables(regs->psw.addr & PSW_ADDR_INSN);
@@ -311,18 +319,11 @@ static inline void __kprobes do_trap(long pgm_int_code, int signr, char *str,
311 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs); 319 btt = report_bug(regs->psw.addr & PSW_ADDR_INSN, regs);
312 if (btt == BUG_TRAP_TYPE_WARN) 320 if (btt == BUG_TRAP_TYPE_WARN)
313 return; 321 return;
314 die(str, regs, pgm_int_code); 322 die(regs, str);
315 } 323 }
316 } 324 }
317} 325}
318 326
319static inline void __user *get_psw_address(struct pt_regs *regs,
320 long pgm_int_code)
321{
322 return (void __user *)
323 ((regs->psw.addr - (pgm_int_code >> 16)) & PSW_ADDR_INSN);
324}
325
326void __kprobes do_per_trap(struct pt_regs *regs) 327void __kprobes do_per_trap(struct pt_regs *regs)
327{ 328{
328 siginfo_t info; 329 siginfo_t info;
@@ -339,26 +340,19 @@ void __kprobes do_per_trap(struct pt_regs *regs)
339 force_sig_info(SIGTRAP, &info, current); 340 force_sig_info(SIGTRAP, &info, current);
340} 341}
341 342
342static void default_trap_handler(struct pt_regs *regs, long pgm_int_code, 343static void default_trap_handler(struct pt_regs *regs)
343 unsigned long trans_exc_code)
344{ 344{
345 if (regs->psw.mask & PSW_MASK_PSTATE) { 345 if (regs->psw.mask & PSW_MASK_PSTATE) {
346 report_user_fault(regs, pgm_int_code, SIGSEGV); 346 report_user_fault(regs, SIGSEGV);
347 do_exit(SIGSEGV); 347 do_exit(SIGSEGV);
348 } else 348 } else
349 die("Unknown program exception", regs, pgm_int_code); 349 die(regs, "Unknown program exception");
350} 350}
351 351
352#define DO_ERROR_INFO(name, signr, sicode, str) \ 352#define DO_ERROR_INFO(name, signr, sicode, str) \
353static void name(struct pt_regs *regs, long pgm_int_code, \ 353static void name(struct pt_regs *regs) \
354 unsigned long trans_exc_code) \
355{ \ 354{ \
356 siginfo_t info; \ 355 do_trap(regs, signr, sicode, str); \
357 info.si_signo = signr; \
358 info.si_errno = 0; \
359 info.si_code = sicode; \
360 info.si_addr = get_psw_address(regs, pgm_int_code); \
361 do_trap(pgm_int_code, signr, str, regs, &info); \
362} 356}
363 357
364DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR, 358DO_ERROR_INFO(addressing_exception, SIGILL, ILL_ILLADR,
@@ -388,42 +382,34 @@ DO_ERROR_INFO(special_op_exception, SIGILL, ILL_ILLOPN,
388DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN, 382DO_ERROR_INFO(translation_exception, SIGILL, ILL_ILLOPN,
389 "translation exception") 383 "translation exception")
390 384
391static inline void do_fp_trap(struct pt_regs *regs, void __user *location, 385static inline void do_fp_trap(struct pt_regs *regs, int fpc)
392 int fpc, long pgm_int_code)
393{ 386{
394 siginfo_t si; 387 int si_code = 0;
395
396 si.si_signo = SIGFPE;
397 si.si_errno = 0;
398 si.si_addr = location;
399 si.si_code = 0;
400 /* FPC[2] is Data Exception Code */ 388 /* FPC[2] is Data Exception Code */
401 if ((fpc & 0x00000300) == 0) { 389 if ((fpc & 0x00000300) == 0) {
402 /* bits 6 and 7 of DXC are 0 iff IEEE exception */ 390 /* bits 6 and 7 of DXC are 0 iff IEEE exception */
403 if (fpc & 0x8000) /* invalid fp operation */ 391 if (fpc & 0x8000) /* invalid fp operation */
404 si.si_code = FPE_FLTINV; 392 si_code = FPE_FLTINV;
405 else if (fpc & 0x4000) /* div by 0 */ 393 else if (fpc & 0x4000) /* div by 0 */
406 si.si_code = FPE_FLTDIV; 394 si_code = FPE_FLTDIV;
407 else if (fpc & 0x2000) /* overflow */ 395 else if (fpc & 0x2000) /* overflow */
408 si.si_code = FPE_FLTOVF; 396 si_code = FPE_FLTOVF;
409 else if (fpc & 0x1000) /* underflow */ 397 else if (fpc & 0x1000) /* underflow */
410 si.si_code = FPE_FLTUND; 398 si_code = FPE_FLTUND;
411 else if (fpc & 0x0800) /* inexact */ 399 else if (fpc & 0x0800) /* inexact */
412 si.si_code = FPE_FLTRES; 400 si_code = FPE_FLTRES;
413 } 401 }
414 do_trap(pgm_int_code, SIGFPE, 402 do_trap(regs, SIGFPE, si_code, "floating point exception");
415 "floating point exception", regs, &si);
416} 403}
417 404
418static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code, 405static void __kprobes illegal_op(struct pt_regs *regs)
419 unsigned long trans_exc_code)
420{ 406{
421 siginfo_t info; 407 siginfo_t info;
422 __u8 opcode[6]; 408 __u8 opcode[6];
423 __u16 __user *location; 409 __u16 __user *location;
424 int signal = 0; 410 int signal = 0;
425 411
426 location = get_psw_address(regs, pgm_int_code); 412 location = get_psw_address(regs);
427 413
428 if (regs->psw.mask & PSW_MASK_PSTATE) { 414 if (regs->psw.mask & PSW_MASK_PSTATE) {
429 if (get_user(*((__u16 *) opcode), (__u16 __user *) location)) 415 if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
@@ -467,44 +453,31 @@ static void __kprobes illegal_op(struct pt_regs *regs, long pgm_int_code,
467 * If we get an illegal op in kernel mode, send it through the 453 * If we get an illegal op in kernel mode, send it through the
468 * kprobes notifier. If kprobes doesn't pick it up, SIGILL 454 * kprobes notifier. If kprobes doesn't pick it up, SIGILL
469 */ 455 */
470 if (notify_die(DIE_BPT, "bpt", regs, pgm_int_code, 456 if (notify_die(DIE_BPT, "bpt", regs, 0,
471 3, SIGTRAP) != NOTIFY_STOP) 457 3, SIGTRAP) != NOTIFY_STOP)
472 signal = SIGILL; 458 signal = SIGILL;
473 } 459 }
474 460
475#ifdef CONFIG_MATHEMU 461#ifdef CONFIG_MATHEMU
476 if (signal == SIGFPE) 462 if (signal == SIGFPE)
477 do_fp_trap(regs, location, 463 do_fp_trap(regs, current->thread.fp_regs.fpc);
478 current->thread.fp_regs.fpc, pgm_int_code); 464 else if (signal == SIGSEGV)
479 else if (signal == SIGSEGV) { 465 do_trap(regs, signal, SEGV_MAPERR, "user address fault");
480 info.si_signo = signal; 466 else
481 info.si_errno = 0;
482 info.si_code = SEGV_MAPERR;
483 info.si_addr = (void __user *) location;
484 do_trap(pgm_int_code, signal,
485 "user address fault", regs, &info);
486 } else
487#endif 467#endif
488 if (signal) { 468 if (signal)
489 info.si_signo = signal; 469 do_trap(regs, signal, ILL_ILLOPC, "illegal operation");
490 info.si_errno = 0;
491 info.si_code = ILL_ILLOPC;
492 info.si_addr = (void __user *) location;
493 do_trap(pgm_int_code, signal,
494 "illegal operation", regs, &info);
495 }
496} 470}
497 471
498 472
499#ifdef CONFIG_MATHEMU 473#ifdef CONFIG_MATHEMU
500void specification_exception(struct pt_regs *regs, long pgm_int_code, 474void specification_exception(struct pt_regs *regs)
501 unsigned long trans_exc_code)
502{ 475{
503 __u8 opcode[6]; 476 __u8 opcode[6];
504 __u16 __user *location = NULL; 477 __u16 __user *location = NULL;
505 int signal = 0; 478 int signal = 0;
506 479
507 location = (__u16 __user *) get_psw_address(regs, pgm_int_code); 480 location = (__u16 __user *) get_psw_address(regs);
508 481
509 if (regs->psw.mask & PSW_MASK_PSTATE) { 482 if (regs->psw.mask & PSW_MASK_PSTATE) {
510 get_user(*((__u16 *) opcode), location); 483 get_user(*((__u16 *) opcode), location);
@@ -539,30 +512,21 @@ void specification_exception(struct pt_regs *regs, long pgm_int_code,
539 signal = SIGILL; 512 signal = SIGILL;
540 513
541 if (signal == SIGFPE) 514 if (signal == SIGFPE)
542 do_fp_trap(regs, location, 515 do_fp_trap(regs, current->thread.fp_regs.fpc);
543 current->thread.fp_regs.fpc, pgm_int_code); 516 else if (signal)
544 else if (signal) { 517 do_trap(regs, signal, ILL_ILLOPN, "specification exception");
545 siginfo_t info;
546 info.si_signo = signal;
547 info.si_errno = 0;
548 info.si_code = ILL_ILLOPN;
549 info.si_addr = location;
550 do_trap(pgm_int_code, signal,
551 "specification exception", regs, &info);
552 }
553} 518}
554#else 519#else
555DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN, 520DO_ERROR_INFO(specification_exception, SIGILL, ILL_ILLOPN,
556 "specification exception"); 521 "specification exception");
557#endif 522#endif
558 523
559static void data_exception(struct pt_regs *regs, long pgm_int_code, 524static void data_exception(struct pt_regs *regs)
560 unsigned long trans_exc_code)
561{ 525{
562 __u16 __user *location; 526 __u16 __user *location;
563 int signal = 0; 527 int signal = 0;
564 528
565 location = get_psw_address(regs, pgm_int_code); 529 location = get_psw_address(regs);
566 530
567 if (MACHINE_HAS_IEEE) 531 if (MACHINE_HAS_IEEE)
568 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc)); 532 asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
@@ -627,32 +591,18 @@ static void data_exception(struct pt_regs *regs, long pgm_int_code,
627 else 591 else
628 signal = SIGILL; 592 signal = SIGILL;
629 if (signal == SIGFPE) 593 if (signal == SIGFPE)
630 do_fp_trap(regs, location, 594 do_fp_trap(regs, current->thread.fp_regs.fpc);
631 current->thread.fp_regs.fpc, pgm_int_code); 595 else if (signal)
632 else if (signal) { 596 do_trap(regs, signal, ILL_ILLOPN, "data exception");
633 siginfo_t info;
634 info.si_signo = signal;
635 info.si_errno = 0;
636 info.si_code = ILL_ILLOPN;
637 info.si_addr = location;
638 do_trap(pgm_int_code, signal, "data exception", regs, &info);
639 }
640} 597}
641 598
642static void space_switch_exception(struct pt_regs *regs, long pgm_int_code, 599static void space_switch_exception(struct pt_regs *regs)
643 unsigned long trans_exc_code)
644{ 600{
645 siginfo_t info;
646
647 /* Set user psw back to home space mode. */ 601 /* Set user psw back to home space mode. */
648 if (regs->psw.mask & PSW_MASK_PSTATE) 602 if (regs->psw.mask & PSW_MASK_PSTATE)
649 regs->psw.mask |= PSW_ASC_HOME; 603 regs->psw.mask |= PSW_ASC_HOME;
650 /* Send SIGILL. */ 604 /* Send SIGILL. */
651 info.si_signo = SIGILL; 605 do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
652 info.si_errno = 0;
653 info.si_code = ILL_PRVOPC;
654 info.si_addr = get_psw_address(regs, pgm_int_code);
655 do_trap(pgm_int_code, SIGILL, "space switch event", regs, &info);
656} 606}
657 607
658void __kprobes kernel_stack_overflow(struct pt_regs * regs) 608void __kprobes kernel_stack_overflow(struct pt_regs * regs)