summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/Makefile2
-rw-r--r--arch/s390/kernel/entry.S2
-rw-r--r--arch/s390/kernel/entry64.S2
-rw-r--r--arch/s390/kernel/reipl_diag.c39
-rw-r--r--arch/s390/kernel/setup.c5
-rw-r--r--arch/s390/kernel/smp.c3
6 files changed, 50 insertions, 3 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
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/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
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 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)
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 00000000000..83cb42bc0b7
--- /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 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;
* 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/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[];
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