aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2006-12-04 09:40:26 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2006-12-04 09:40:26 -0500
commit15e9b586e0bd3692e2a21c5be178810d9d32214e (patch)
tree8bcf2c9b3780281c9562eab965e3ca6ba64e5bc0 /arch/s390/kernel
parent2254f5a7779452395e37ea2f7d6e1a550d34e678 (diff)
[S390] Reset infrastructure for re-IPL.
In case of re-IPL and diag308 doesn't work we have to reset all devices manually and wait synchronously that each reset finished. This patch adds the necessary infrastucture and the first exploiter of it. Subsystems that need to add a function that needs to be called at re-IPL may register/unregister this function via struct reset_call { struct reset_call *next; void (*fn)(void); }; void register_reset_call(struct reset_call *reset); void unregister_reset_call(struct reset_call *reset); When the registered function get called the context is: - all cpus beside the current one are stopped - all machine checks and interrupts are disabled - prefixing is disabled - a default machine check handler is available for use The registered functions may not take any locks are sleep. For the common I/O layer part of this patch: Introduce a reset_call css_reset that does the following: - clear all subchannels - perform a rchp on all channel paths and wait for the resulting machine checks This replaces the calls to clear_all_subchannels() and cio_reset_channel_paths() for kexec and ccw reipl. reipl_ccw_dev() now uses reipl_find_schid() to determine the subchannel id for a given device id. Also remove cio_reset_channel_paths() and friends since they are not needed anymore. Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390/kernel')
-rw-r--r--arch/s390/kernel/Makefile2
-rw-r--r--arch/s390/kernel/ipl.c54
-rw-r--r--arch/s390/kernel/machine_kexec.c9
-rw-r--r--arch/s390/kernel/reipl.S17
-rw-r--r--arch/s390/kernel/reipl64.S16
-rw-r--r--arch/s390/kernel/relocate_kernel.S5
-rw-r--r--arch/s390/kernel/relocate_kernel64.S5
-rw-r--r--arch/s390/kernel/reset.S48
8 files changed, 115 insertions, 41 deletions
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index aa978978d3d1..a81881c9b297 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -4,7 +4,7 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7obj-y := bitmap.o traps.o time.o process.o \ 7obj-y := bitmap.o traps.o time.o process.o reset.o \
8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ 8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
9 semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o 9 semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o
10 10
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index ec127826f221..77f4aff630fe 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -19,6 +19,7 @@
19#include <asm/cpcmd.h> 19#include <asm/cpcmd.h>
20#include <asm/cio.h> 20#include <asm/cio.h>
21#include <asm/ebcdic.h> 21#include <asm/ebcdic.h>
22#include <asm/reset.h>
22 23
23#define IPL_PARM_BLOCK_VERSION 0 24#define IPL_PARM_BLOCK_VERSION 0
24#define LOADPARM_LEN 8 25#define LOADPARM_LEN 8
@@ -1024,3 +1025,56 @@ static int __init s390_ipl_init(void)
1024} 1025}
1025 1026
1026__initcall(s390_ipl_init); 1027__initcall(s390_ipl_init);
1028
1029static LIST_HEAD(rcall);
1030static DEFINE_MUTEX(rcall_mutex);
1031
1032void register_reset_call(struct reset_call *reset)
1033{
1034 mutex_lock(&rcall_mutex);
1035 list_add(&reset->list, &rcall);
1036 mutex_unlock(&rcall_mutex);
1037}
1038EXPORT_SYMBOL_GPL(register_reset_call);
1039
1040void unregister_reset_call(struct reset_call *reset)
1041{
1042 mutex_lock(&rcall_mutex);
1043 list_del(&reset->list);
1044 mutex_unlock(&rcall_mutex);
1045}
1046EXPORT_SYMBOL_GPL(unregister_reset_call);
1047
1048static void do_reset_calls(void)
1049{
1050 struct reset_call *reset;
1051
1052 list_for_each_entry(reset, &rcall, list)
1053 reset->fn();
1054}
1055
1056extern void reset_mcck_handler(void);
1057
1058void s390_reset_system(void)
1059{
1060 struct _lowcore *lc;
1061
1062 /* Disable all interrupts/machine checks */
1063 __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK);
1064
1065 /* Stack for interrupt/machine check handler */
1066 lc = (struct _lowcore *)(unsigned long) store_prefix();
1067 lc->panic_stack = S390_lowcore.panic_stack;
1068
1069 /* Disable prefixing */
1070 set_prefix(0);
1071
1072 /* Disable lowcore protection */
1073 __ctl_clear_bit(0,28);
1074
1075 /* Set new machine check handler */
1076 S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK;
1077 S390_lowcore.mcck_new_psw.addr =
1078 PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler;
1079 do_reset_calls();
1080}
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 60b1ea9f946b..202bf1fdfe39 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -22,6 +22,7 @@
22#include <asm/pgalloc.h> 22#include <asm/pgalloc.h>
23#include <asm/system.h> 23#include <asm/system.h>
24#include <asm/smp.h> 24#include <asm/smp.h>
25#include <asm/reset.h>
25 26
26static void kexec_halt_all_cpus(void *); 27static void kexec_halt_all_cpus(void *);
27 28
@@ -62,12 +63,6 @@ machine_shutdown(void)
62NORET_TYPE void 63NORET_TYPE void
63machine_kexec(struct kimage *image) 64machine_kexec(struct kimage *image)
64{ 65{
65 clear_all_subchannels();
66 cio_reset_channel_paths();
67
68 /* Disable lowcore protection */
69 ctl_clear_bit(0,28);
70
71 on_each_cpu(kexec_halt_all_cpus, image, 0, 0); 66 on_each_cpu(kexec_halt_all_cpus, image, 0, 0);
72 for (;;); 67 for (;;);
73} 68}
@@ -98,6 +93,8 @@ kexec_halt_all_cpus(void *kernel_image)
98 cpu_relax(); 93 cpu_relax();
99 } 94 }
100 95
96 s390_reset_system();
97
101 image = (struct kimage *) kernel_image; 98 image = (struct kimage *) kernel_image;
102 data_mover = (relocate_kernel_t) 99 data_mover = (relocate_kernel_t)
103 (page_to_pfn(image->control_code_page) << PAGE_SHIFT); 100 (page_to_pfn(image->control_code_page) << PAGE_SHIFT);
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 0340477f3b08..f9434d42ce9f 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -11,19 +11,10 @@
11 .globl do_reipl_asm 11 .globl do_reipl_asm
12do_reipl_asm: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13) 13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13)
14 14.Lpg1: # do store status of all registers
15 # switch off lowcore protection
16
17.Lpg1: stctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
18 stctl %c0,%c0,.Lctlsave2-.Lpg0(%r13)
19 ni .Lctlsave1-.Lpg0(%r13),0xef
20 lctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
21
22 # do store status of all registers
23 15
24 stm %r0,%r15,__LC_GPREGS_SAVE_AREA 16 stm %r0,%r15,__LC_GPREGS_SAVE_AREA
25 stctl %c0,%c15,__LC_CREGS_SAVE_AREA 17 stctl %c0,%c15,__LC_CREGS_SAVE_AREA
26 mvc __LC_CREGS_SAVE_AREA(4),.Lctlsave2-.Lpg0(%r13)
27 stam %a0,%a15,__LC_AREGS_SAVE_AREA 18 stam %a0,%a15,__LC_AREGS_SAVE_AREA
28 stpx __LC_PREFIX_SAVE_AREA 19 stpx __LC_PREFIX_SAVE_AREA
29 stckc .Lclkcmp-.Lpg0(%r13) 20 stckc .Lclkcmp-.Lpg0(%r13)
@@ -56,8 +47,7 @@ do_reipl_asm: basr %r13,0
56.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 47.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
57 jz .L003 48 jz .L003
58 bas %r14,.Ldisab-.Lpg0(%r13) 49 bas %r14,.Ldisab-.Lpg0(%r13)
59.L003: spx .Lnull-.Lpg0(%r13) 50.L003: st %r1,__LC_SUBCHANNEL_ID
60 st %r1,__LC_SUBCHANNEL_ID
61 lpsw 0 51 lpsw 0
62 sigp 0,0,0(6) 52 sigp 0,0,0(6)
63.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) 53.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13)
@@ -65,9 +55,6 @@ do_reipl_asm: basr %r13,0
65 .align 8 55 .align 8
66.Lclkcmp: .quad 0x0000000000000000 56.Lclkcmp: .quad 0x0000000000000000
67.Lall: .long 0xff000000 57.Lall: .long 0xff000000
68.Lnull: .long 0x00000000
69.Lctlsave1: .long 0x00000000
70.Lctlsave2: .long 0x00000000
71 .align 8 58 .align 8
72.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 59.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1
73.Lpcnew: .long 0x00080000,0x80000000+.Lecs 60.Lpcnew: .long 0x00080000,0x80000000+.Lecs
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index de7435054f7c..f18ef260ca23 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -10,10 +10,10 @@
10#include <asm/lowcore.h> 10#include <asm/lowcore.h>
11 .globl do_reipl_asm 11 .globl do_reipl_asm
12do_reipl_asm: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
14.Lpg1: # do store status of all registers
13 15
14 # do store status of all registers 16 stg %r1,.Lregsave-.Lpg0(%r13)
15
16.Lpg0: stg %r1,.Lregsave-.Lpg0(%r13)
17 lghi %r1,0x1000 17 lghi %r1,0x1000
18 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1) 18 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
19 lg %r0,.Lregsave-.Lpg0(%r13) 19 lg %r0,.Lregsave-.Lpg0(%r13)
@@ -27,11 +27,7 @@ do_reipl_asm: basr %r13,0
27 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1) 27 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
28 stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1) 28 stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
29 29
30 lpswe .Lnewpsw-.Lpg0(%r13) 30 lctlg %c6,%c6,.Lall-.Lpg0(%r13)
31.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
32 stctg %c0,%c0,.Lregsave-.Lpg0(%r13)
33 ni .Lregsave+4-.Lpg0(%r13),0xef
34 lctlg %c0,%c0,.Lregsave-.Lpg0(%r13)
35 lgr %r1,%r2 31 lgr %r1,%r2
36 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) 32 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
37 stsch .Lschib-.Lpg0(%r13) 33 stsch .Lschib-.Lpg0(%r13)
@@ -56,8 +52,7 @@ do_reipl_asm: basr %r13,0
56.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 52.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
57 jz .L003 53 jz .L003
58 bas %r14,.Ldisab-.Lpg0(%r13) 54 bas %r14,.Ldisab-.Lpg0(%r13)
59.L003: spx .Lnull-.Lpg0(%r13) 55.L003: st %r1,__LC_SUBCHANNEL_ID
60 st %r1,__LC_SUBCHANNEL_ID
61 lhi %r1,0 # mode 0 = esa 56 lhi %r1,0 # mode 0 = esa
62 slr %r0,%r0 # set cpuid to zero 57 slr %r0,%r0 # set cpuid to zero
63 sigp %r1,%r0,0x12 # switch to esa mode 58 sigp %r1,%r0,0x12 # switch to esa mode
@@ -70,7 +65,6 @@ do_reipl_asm: basr %r13,0
70.Lclkcmp: .quad 0x0000000000000000 65.Lclkcmp: .quad 0x0000000000000000
71.Lall: .quad 0x00000000ff000000 66.Lall: .quad 0x00000000ff000000
72.Lregsave: .quad 0x0000000000000000 67.Lregsave: .quad 0x0000000000000000
73.Lnull: .long 0x0000000000000000
74 .align 16 68 .align 16
75/* 69/*
76 * These addresses have to be 31 bit otherwise 70 * These addresses have to be 31 bit otherwise
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
index f9899ff2e5b0..3b456b80bcee 100644
--- a/arch/s390/kernel/relocate_kernel.S
+++ b/arch/s390/kernel/relocate_kernel.S
@@ -26,8 +26,7 @@
26 relocate_kernel: 26 relocate_kernel:
27 basr %r13,0 # base address 27 basr %r13,0 # base address
28 .base: 28 .base:
29 stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQ (external) 29 stnsm sys_msk-.base(%r13),0xfb # disable DAT
30 spx zero64-.base(%r13) # absolute addressing mode
31 stctl %c0,%c15,ctlregs-.base(%r13) 30 stctl %c0,%c15,ctlregs-.base(%r13)
32 stm %r0,%r15,gprregs-.base(%r13) 31 stm %r0,%r15,gprregs-.base(%r13)
33 la %r1,load_psw-.base(%r13) 32 la %r1,load_psw-.base(%r13)
@@ -97,8 +96,6 @@
97 lpsw 0 # hopefully start new kernel... 96 lpsw 0 # hopefully start new kernel...
98 97
99 .align 8 98 .align 8
100 zero64:
101 .quad 0
102 load_psw: 99 load_psw:
103 .long 0x00080000,0x80000000 100 .long 0x00080000,0x80000000
104 sys_msk: 101 sys_msk:
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S
index 4fb443042d9c..1f9ea2067b59 100644
--- a/arch/s390/kernel/relocate_kernel64.S
+++ b/arch/s390/kernel/relocate_kernel64.S
@@ -27,8 +27,7 @@
27 relocate_kernel: 27 relocate_kernel:
28 basr %r13,0 # base address 28 basr %r13,0 # base address
29 .base: 29 .base:
30 stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQs 30 stnsm sys_msk-.base(%r13),0xfb # disable DAT
31 spx zero64-.base(%r13) # absolute addressing mode
32 stctg %c0,%c15,ctlregs-.base(%r13) 31 stctg %c0,%c15,ctlregs-.base(%r13)
33 stmg %r0,%r15,gprregs-.base(%r13) 32 stmg %r0,%r15,gprregs-.base(%r13)
34 lghi %r0,3 33 lghi %r0,3
@@ -100,8 +99,6 @@
100 lpsw 0 # hopefully start new kernel... 99 lpsw 0 # hopefully start new kernel...
101 100
102 .align 8 101 .align 8
103 zero64:
104 .quad 0
105 load_psw: 102 load_psw:
106 .long 0x00080000,0x80000000 103 .long 0x00080000,0x80000000
107 sys_msk: 104 sys_msk:
diff --git a/arch/s390/kernel/reset.S b/arch/s390/kernel/reset.S
new file mode 100644
index 000000000000..be8688c0665c
--- /dev/null
+++ b/arch/s390/kernel/reset.S
@@ -0,0 +1,48 @@
1/*
2 * arch/s390/kernel/reset.S
3 *
4 * Copyright (C) IBM Corp. 2006
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 */
7
8#include <asm/ptrace.h>
9#include <asm/lowcore.h>
10
11#ifdef CONFIG_64BIT
12
13 .globl reset_mcck_handler
14reset_mcck_handler:
15 basr %r13,0
160: lg %r15,__LC_PANIC_STACK # load panic stack
17 aghi %r15,-STACK_FRAME_OVERHEAD
18 lg %r1,s390_reset_mcck_handler-0b(%r13)
19 ltgr %r1,%r1
20 jz 1f
21 basr %r14,%r1
221: la %r1,4095
23 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
24 lpswe __LC_MCK_OLD_PSW
25
26 .globl s390_reset_mcck_handler
27s390_reset_mcck_handler:
28 .quad 0
29
30#else /* CONFIG_64BIT */
31
32 .globl reset_mcck_handler
33reset_mcck_handler:
34 basr %r13,0
350: l %r15,__LC_PANIC_STACK # load panic stack
36 ahi %r15,-STACK_FRAME_OVERHEAD
37 l %r1,s390_reset_mcck_handler-0b(%r13)
38 ltr %r1,%r1
39 jz 1f
40 basr %r14,%r1
411: lm %r0,%r15,__LC_GPREGS_SAVE_AREA
42 lpsw __LC_MCK_OLD_PSW
43
44 .globl s390_reset_mcck_handler
45s390_reset_mcck_handler:
46 .long 0
47
48#endif /* CONFIG_64BIT */