diff options
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r-- | arch/s390/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/kernel/compat_signal.c | 6 | ||||
-rw-r--r-- | arch/s390/kernel/entry.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 2 | ||||
-rw-r--r-- | arch/s390/kernel/reipl_diag.c | 39 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 5 | ||||
-rw-r--r-- | arch/s390/kernel/signal.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 3 |
8 files changed, 55 insertions, 8 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index ab1e49d2e51..8584dd82321 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional | |||
6 | 6 | ||
7 | obj-y := bitmap.o traps.o time.o process.o \ | 7 | obj-y := bitmap.o traps.o time.o process.o \ |
8 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ | 8 | setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ |
9 | semaphore.o s390_ext.o debug.o profile.o irq.o | 9 | semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o |
10 | 10 | ||
11 | extra-$(CONFIG_ARCH_S390_31) += head.o | 11 | extra-$(CONFIG_ARCH_S390_31) += head.o |
12 | extra-$(CONFIG_ARCH_S390X) += head64.o | 12 | extra-$(CONFIG_ARCH_S390X) += head64.o |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 7358cdb8441..4ff6808456e 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -143,7 +143,7 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from) | |||
143 | break; | 143 | break; |
144 | case __SI_FAULT >> 16: | 144 | case __SI_FAULT >> 16: |
145 | err |= __get_user(tmp, &from->si_addr); | 145 | err |= __get_user(tmp, &from->si_addr); |
146 | to->si_addr = (void *)(u64) (tmp & PSW32_ADDR_INSN); | 146 | to->si_addr = (void __user *)(u64) (tmp & PSW32_ADDR_INSN); |
147 | break; | 147 | break; |
148 | case __SI_POLL >> 16: | 148 | case __SI_POLL >> 16: |
149 | err |= __get_user(to->si_band, &from->si_band); | 149 | err |= __get_user(to->si_band, &from->si_band); |
@@ -338,7 +338,7 @@ sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss, | |||
338 | err |= __get_user(kss.ss_flags, &uss->ss_flags); | 338 | err |= __get_user(kss.ss_flags, &uss->ss_flags); |
339 | if (err) | 339 | if (err) |
340 | return -EFAULT; | 340 | return -EFAULT; |
341 | kss.ss_sp = (void *) ss_sp; | 341 | kss.ss_sp = (void __user *) ss_sp; |
342 | } | 342 | } |
343 | 343 | ||
344 | set_fs (KERNEL_DS); | 344 | set_fs (KERNEL_DS); |
@@ -461,7 +461,7 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) | |||
461 | goto badframe; | 461 | goto badframe; |
462 | 462 | ||
463 | err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); | 463 | err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); |
464 | st.ss_sp = (void *) A((unsigned long)ss_sp); | 464 | st.ss_sp = compat_ptr(ss_sp); |
465 | err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); | 465 | err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); |
466 | err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); | 466 | err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); |
467 | if (err) | 467 | if (err) |
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 58fc7fbcb40..9b30f4cf32c 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -108,7 +108,7 @@ STACK_SIZE = 1 << STACK_SHIFT | |||
108 | bl BASED(0f) | 108 | bl BASED(0f) |
109 | l %r14,BASED(.Lcleanup_critical) | 109 | l %r14,BASED(.Lcleanup_critical) |
110 | basr %r14,%r14 | 110 | basr %r14,%r14 |
111 | tm 0(%r12),0x01 # retest problem state after cleanup | 111 | tm 1(%r12),0x01 # retest problem state after cleanup |
112 | bnz BASED(1f) | 112 | bnz BASED(1f) |
113 | 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? | 113 | 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? |
114 | slr %r14,%r15 | 114 | slr %r14,%r15 |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index d0c9ffaa25d..7b9b4a2ba1d 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -101,7 +101,7 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | |||
101 | clc \psworg+8(8),BASED(.Lcritical_start) | 101 | clc \psworg+8(8),BASED(.Lcritical_start) |
102 | jl 0f | 102 | jl 0f |
103 | brasl %r14,cleanup_critical | 103 | brasl %r14,cleanup_critical |
104 | tm 0(%r12),0x01 # retest problem state after cleanup | 104 | tm 1(%r12),0x01 # retest problem state after cleanup |
105 | jnz 1f | 105 | jnz 1f |
106 | 0: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? | 106 | 0: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? |
107 | slgr %r14,%r15 | 107 | slgr %r14,%r15 |
diff --git a/arch/s390/kernel/reipl_diag.c b/arch/s390/kernel/reipl_diag.c new file mode 100644 index 00000000000..83cb42bc0b7 --- /dev/null +++ b/arch/s390/kernel/reipl_diag.c | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * This file contains the implementation of the | ||
3 | * Linux re-IPL support | ||
4 | * | ||
5 | * (C) Copyright IBM Corp. 2005 | ||
6 | * | ||
7 | * Author(s): Volker Sameske (sameske@de.ibm.com) | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | |||
13 | static unsigned int reipl_diag_rc1; | ||
14 | static unsigned int reipl_diag_rc2; | ||
15 | |||
16 | /* | ||
17 | * re-IPL the system using the last used IPL parameters | ||
18 | */ | ||
19 | void reipl_diag(void) | ||
20 | { | ||
21 | asm volatile ( | ||
22 | " la %%r4,0\n" | ||
23 | " la %%r5,0\n" | ||
24 | " diag %%r4,%2,0x308\n" | ||
25 | "0:\n" | ||
26 | " st %%r4,%0\n" | ||
27 | " st %%r5,%1\n" | ||
28 | ".section __ex_table,\"a\"\n" | ||
29 | #ifdef __s390x__ | ||
30 | " .align 8\n" | ||
31 | " .quad 0b, 0b\n" | ||
32 | #else | ||
33 | " .align 4\n" | ||
34 | " .long 0b, 0b\n" | ||
35 | #endif | ||
36 | ".previous\n" | ||
37 | : "=m" (reipl_diag_rc1), "=m" (reipl_diag_rc2) | ||
38 | : "d" (3) : "cc", "4", "5" ); | ||
39 | } | ||
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 5ba5a5485da..5204778b8e5 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -261,8 +261,11 @@ void (*_machine_power_off)(void) = machine_power_off_smp; | |||
261 | * Reboot, halt and power_off routines for non SMP. | 261 | * Reboot, halt and power_off routines for non SMP. |
262 | */ | 262 | */ |
263 | extern void reipl(unsigned long devno); | 263 | extern void reipl(unsigned long devno); |
264 | extern void reipl_diag(void); | ||
264 | static void do_machine_restart_nonsmp(char * __unused) | 265 | static void do_machine_restart_nonsmp(char * __unused) |
265 | { | 266 | { |
267 | reipl_diag(); | ||
268 | |||
266 | if (MACHINE_IS_VM) | 269 | if (MACHINE_IS_VM) |
267 | cpcmd ("IPL", NULL, 0); | 270 | cpcmd ("IPL", NULL, 0); |
268 | else | 271 | else |
@@ -634,6 +637,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
634 | struct cpuinfo_S390 *cpuinfo; | 637 | struct cpuinfo_S390 *cpuinfo; |
635 | unsigned long n = (unsigned long) v - 1; | 638 | unsigned long n = (unsigned long) v - 1; |
636 | 639 | ||
640 | preempt_disable(); | ||
637 | if (!n) { | 641 | if (!n) { |
638 | seq_printf(m, "vendor_id : IBM/S390\n" | 642 | seq_printf(m, "vendor_id : IBM/S390\n" |
639 | "# processors : %i\n" | 643 | "# processors : %i\n" |
@@ -658,6 +662,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
658 | cpuinfo->cpu_id.ident, | 662 | cpuinfo->cpu_id.ident, |
659 | cpuinfo->cpu_id.machine); | 663 | cpuinfo->cpu_id.machine); |
660 | } | 664 | } |
665 | preempt_enable(); | ||
661 | return 0; | 666 | return 0; |
662 | } | 667 | } |
663 | 668 | ||
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 6a3f5b7473a..6e0110d7119 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -376,8 +376,8 @@ static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
376 | 376 | ||
377 | /* Create the ucontext. */ | 377 | /* Create the ucontext. */ |
378 | err |= __put_user(0, &frame->uc.uc_flags); | 378 | err |= __put_user(0, &frame->uc.uc_flags); |
379 | err |= __put_user(0, &frame->uc.uc_link); | 379 | err |= __put_user(NULL, &frame->uc.uc_link); |
380 | err |= __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); | 380 | err |= __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); |
381 | err |= __put_user(sas_ss_flags(regs->gprs[15]), | 381 | err |= __put_user(sas_ss_flags(regs->gprs[15]), |
382 | &frame->uc.uc_stack.ss_flags); | 382 | &frame->uc.uc_stack.ss_flags); |
383 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); | 383 | err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 85222fee436..e13c87b446b 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -65,6 +65,7 @@ extern char vmhalt_cmd[]; | |||
65 | extern char vmpoff_cmd[]; | 65 | extern char vmpoff_cmd[]; |
66 | 66 | ||
67 | extern void reipl(unsigned long devno); | 67 | extern void reipl(unsigned long devno); |
68 | extern void reipl_diag(void); | ||
68 | 69 | ||
69 | static void smp_ext_bitcall(int, ec_bit_sig); | 70 | static void smp_ext_bitcall(int, ec_bit_sig); |
70 | static void smp_ext_bitcall_others(ec_bit_sig); | 71 | static void smp_ext_bitcall_others(ec_bit_sig); |
@@ -283,6 +284,8 @@ static void do_machine_restart(void * __unused) | |||
283 | * interrupted by an external interrupt and s390irq | 284 | * interrupted by an external interrupt and s390irq |
284 | * locks are always held disabled). | 285 | * locks are always held disabled). |
285 | */ | 286 | */ |
287 | reipl_diag(); | ||
288 | |||
286 | if (MACHINE_IS_VM) | 289 | if (MACHINE_IS_VM) |
287 | cpcmd ("IPL", NULL, 0, NULL); | 290 | cpcmd ("IPL", NULL, 0, NULL); |
288 | else | 291 | else |