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 ab1e49d2e518..8584dd823218 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional obj-y := bitmap.o traps.o time.o process.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390_ext.o debug.o profile.o irq.o + semaphore.o s390_ext.o debug.o profile.o irq.o reipl_diag.o extra-$(CONFIG_ARCH_S390_31) += head.o extra-$(CONFIG_ARCH_S390X) += head64.o diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index 7358cdb8441f..4ff6808456ea 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) break; case __SI_FAULT >> 16: err |= __get_user(tmp, &from->si_addr); - to->si_addr = (void *)(u64) (tmp & PSW32_ADDR_INSN); + to->si_addr = (void __user *)(u64) (tmp & PSW32_ADDR_INSN); break; case __SI_POLL >> 16: err |= __get_user(to->si_band, &from->si_band); @@ -338,7 +338,7 @@ sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss, err |= __get_user(kss.ss_flags, &uss->ss_flags); if (err) return -EFAULT; - kss.ss_sp = (void *) ss_sp; + kss.ss_sp = (void __user *) ss_sp; } set_fs (KERNEL_DS); @@ -461,7 +461,7 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) goto badframe; err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp); - st.ss_sp = (void *) A((unsigned long)ss_sp); + st.ss_sp = compat_ptr(ss_sp); err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size); err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags); if (err) diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 58fc7fbcb40e..9b30f4cf32c4 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S @@ -108,7 +108,7 @@ STACK_SIZE = 1 << STACK_SHIFT bl BASED(0f) l %r14,BASED(.Lcleanup_critical) basr %r14,%r14 - tm 0(%r12),0x01 # retest problem state after cleanup + tm 1(%r12),0x01 # retest problem state after cleanup bnz BASED(1f) 0: l %r14,__LC_ASYNC_STACK # are we already on the async stack ? slr %r14,%r15 diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index d0c9ffaa25db..7b9b4a2ba1d7 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) clc \psworg+8(8),BASED(.Lcritical_start) jl 0f brasl %r14,cleanup_critical - tm 0(%r12),0x01 # retest problem state after cleanup + tm 1(%r12),0x01 # retest problem state after cleanup jnz 1f 0: lg %r14,__LC_ASYNC_STACK # are we already on the async. stack ? slgr %r14,%r15 diff --git a/arch/s390/kernel/reipl_diag.c b/arch/s390/kernel/reipl_diag.c new file mode 100644 index 000000000000..83cb42bc0b76 --- /dev/null +++ b/arch/s390/kernel/reipl_diag.c @@ -0,0 +1,39 @@ +/* + * This file contains the implementation of the + * Linux re-IPL support + * + * (C) Copyright IBM Corp. 2005 + * + * Author(s): Volker Sameske (sameske@de.ibm.com) + * + */ + +#include <linux/kernel.h> + +static unsigned int reipl_diag_rc1; +static unsigned int reipl_diag_rc2; + +/* + * re-IPL the system using the last used IPL parameters + */ +void reipl_diag(void) +{ + asm volatile ( + " la %%r4,0\n" + " la %%r5,0\n" + " diag %%r4,%2,0x308\n" + "0:\n" + " st %%r4,%0\n" + " st %%r5,%1\n" + ".section __ex_table,\"a\"\n" +#ifdef __s390x__ + " .align 8\n" + " .quad 0b, 0b\n" +#else + " .align 4\n" + " .long 0b, 0b\n" +#endif + ".previous\n" + : "=m" (reipl_diag_rc1), "=m" (reipl_diag_rc2) + : "d" (3) : "cc", "4", "5" ); +} diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 5ba5a5485da9..5204778b8e5e 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; * Reboot, halt and power_off routines for non SMP. */ extern void reipl(unsigned long devno); +extern void reipl_diag(void); static void do_machine_restart_nonsmp(char * __unused) { + reipl_diag(); + if (MACHINE_IS_VM) cpcmd ("IPL", NULL, 0); else @@ -634,6 +637,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) struct cpuinfo_S390 *cpuinfo; unsigned long n = (unsigned long) v - 1; + preempt_disable(); if (!n) { seq_printf(m, "vendor_id : IBM/S390\n" "# processors : %i\n" @@ -658,6 +662,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) cpuinfo->cpu_id.ident, cpuinfo->cpu_id.machine); } + preempt_enable(); return 0; } diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 6a3f5b7473a9..6e0110d71191 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, /* Create the ucontext. */ err |= __put_user(0, &frame->uc.uc_flags); - err |= __put_user(0, &frame->uc.uc_link); - err |= __put_user((void *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); + err |= __put_user(NULL, &frame->uc.uc_link); + err |= __put_user((void __user *)current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); err |= __put_user(sas_ss_flags(regs->gprs[15]), &frame->uc.uc_stack.ss_flags); 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 85222fee4361..e13c87b446b2 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c @@ -65,6 +65,7 @@ extern char vmhalt_cmd[]; extern char vmpoff_cmd[]; extern void reipl(unsigned long devno); +extern void reipl_diag(void); static void smp_ext_bitcall(int, ec_bit_sig); static void smp_ext_bitcall_others(ec_bit_sig); @@ -283,6 +284,8 @@ static void do_machine_restart(void * __unused) * interrupted by an external interrupt and s390irq * locks are always held disabled). */ + reipl_diag(); + if (MACHINE_IS_VM) cpcmd ("IPL", NULL, 0, NULL); else |