[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>
This commit is contained in:

committed by
Martin Schwidefsky

parent
2254f5a777
commit
15e9b586e0
@@ -4,7 +4,7 @@
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
|
||||
obj-y := bitmap.o traps.o time.o process.o \
|
||||
obj-y := bitmap.o traps.o time.o process.o reset.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 ipl.o
|
||||
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include <asm/cpcmd.h>
|
||||
#include <asm/cio.h>
|
||||
#include <asm/ebcdic.h>
|
||||
#include <asm/reset.h>
|
||||
|
||||
#define IPL_PARM_BLOCK_VERSION 0
|
||||
#define LOADPARM_LEN 8
|
||||
@@ -1024,3 +1025,56 @@ static int __init s390_ipl_init(void)
|
||||
}
|
||||
|
||||
__initcall(s390_ipl_init);
|
||||
|
||||
static LIST_HEAD(rcall);
|
||||
static DEFINE_MUTEX(rcall_mutex);
|
||||
|
||||
void register_reset_call(struct reset_call *reset)
|
||||
{
|
||||
mutex_lock(&rcall_mutex);
|
||||
list_add(&reset->list, &rcall);
|
||||
mutex_unlock(&rcall_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(register_reset_call);
|
||||
|
||||
void unregister_reset_call(struct reset_call *reset)
|
||||
{
|
||||
mutex_lock(&rcall_mutex);
|
||||
list_del(&reset->list);
|
||||
mutex_unlock(&rcall_mutex);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(unregister_reset_call);
|
||||
|
||||
static void do_reset_calls(void)
|
||||
{
|
||||
struct reset_call *reset;
|
||||
|
||||
list_for_each_entry(reset, &rcall, list)
|
||||
reset->fn();
|
||||
}
|
||||
|
||||
extern void reset_mcck_handler(void);
|
||||
|
||||
void s390_reset_system(void)
|
||||
{
|
||||
struct _lowcore *lc;
|
||||
|
||||
/* Disable all interrupts/machine checks */
|
||||
__load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK);
|
||||
|
||||
/* Stack for interrupt/machine check handler */
|
||||
lc = (struct _lowcore *)(unsigned long) store_prefix();
|
||||
lc->panic_stack = S390_lowcore.panic_stack;
|
||||
|
||||
/* Disable prefixing */
|
||||
set_prefix(0);
|
||||
|
||||
/* Disable lowcore protection */
|
||||
__ctl_clear_bit(0,28);
|
||||
|
||||
/* Set new machine check handler */
|
||||
S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK;
|
||||
S390_lowcore.mcck_new_psw.addr =
|
||||
PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler;
|
||||
do_reset_calls();
|
||||
}
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/smp.h>
|
||||
#include <asm/reset.h>
|
||||
|
||||
static void kexec_halt_all_cpus(void *);
|
||||
|
||||
@@ -62,12 +63,6 @@ machine_shutdown(void)
|
||||
NORET_TYPE void
|
||||
machine_kexec(struct kimage *image)
|
||||
{
|
||||
clear_all_subchannels();
|
||||
cio_reset_channel_paths();
|
||||
|
||||
/* Disable lowcore protection */
|
||||
ctl_clear_bit(0,28);
|
||||
|
||||
on_each_cpu(kexec_halt_all_cpus, image, 0, 0);
|
||||
for (;;);
|
||||
}
|
||||
@@ -98,6 +93,8 @@ kexec_halt_all_cpus(void *kernel_image)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
s390_reset_system();
|
||||
|
||||
image = (struct kimage *) kernel_image;
|
||||
data_mover = (relocate_kernel_t)
|
||||
(page_to_pfn(image->control_code_page) << PAGE_SHIFT);
|
||||
|
@@ -11,19 +11,10 @@
|
||||
.globl do_reipl_asm
|
||||
do_reipl_asm: basr %r13,0
|
||||
.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13)
|
||||
|
||||
# switch off lowcore protection
|
||||
|
||||
.Lpg1: stctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
|
||||
stctl %c0,%c0,.Lctlsave2-.Lpg0(%r13)
|
||||
ni .Lctlsave1-.Lpg0(%r13),0xef
|
||||
lctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
|
||||
|
||||
# do store status of all registers
|
||||
.Lpg1: # do store status of all registers
|
||||
|
||||
stm %r0,%r15,__LC_GPREGS_SAVE_AREA
|
||||
stctl %c0,%c15,__LC_CREGS_SAVE_AREA
|
||||
mvc __LC_CREGS_SAVE_AREA(4),.Lctlsave2-.Lpg0(%r13)
|
||||
stam %a0,%a15,__LC_AREGS_SAVE_AREA
|
||||
stpx __LC_PREFIX_SAVE_AREA
|
||||
stckc .Lclkcmp-.Lpg0(%r13)
|
||||
@@ -56,8 +47,7 @@ do_reipl_asm: basr %r13,0
|
||||
.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
|
||||
jz .L003
|
||||
bas %r14,.Ldisab-.Lpg0(%r13)
|
||||
.L003: spx .Lnull-.Lpg0(%r13)
|
||||
st %r1,__LC_SUBCHANNEL_ID
|
||||
.L003: st %r1,__LC_SUBCHANNEL_ID
|
||||
lpsw 0
|
||||
sigp 0,0,0(6)
|
||||
.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13)
|
||||
@@ -65,9 +55,6 @@ do_reipl_asm: basr %r13,0
|
||||
.align 8
|
||||
.Lclkcmp: .quad 0x0000000000000000
|
||||
.Lall: .long 0xff000000
|
||||
.Lnull: .long 0x00000000
|
||||
.Lctlsave1: .long 0x00000000
|
||||
.Lctlsave2: .long 0x00000000
|
||||
.align 8
|
||||
.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1
|
||||
.Lpcnew: .long 0x00080000,0x80000000+.Lecs
|
||||
|
@@ -10,10 +10,10 @@
|
||||
#include <asm/lowcore.h>
|
||||
.globl do_reipl_asm
|
||||
do_reipl_asm: basr %r13,0
|
||||
.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
|
||||
.Lpg1: # do store status of all registers
|
||||
|
||||
# do store status of all registers
|
||||
|
||||
.Lpg0: stg %r1,.Lregsave-.Lpg0(%r13)
|
||||
stg %r1,.Lregsave-.Lpg0(%r13)
|
||||
lghi %r1,0x1000
|
||||
stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
|
||||
lg %r0,.Lregsave-.Lpg0(%r13)
|
||||
@@ -27,11 +27,7 @@ do_reipl_asm: basr %r13,0
|
||||
stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
|
||||
stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
|
||||
|
||||
lpswe .Lnewpsw-.Lpg0(%r13)
|
||||
.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
|
||||
stctg %c0,%c0,.Lregsave-.Lpg0(%r13)
|
||||
ni .Lregsave+4-.Lpg0(%r13),0xef
|
||||
lctlg %c0,%c0,.Lregsave-.Lpg0(%r13)
|
||||
lctlg %c6,%c6,.Lall-.Lpg0(%r13)
|
||||
lgr %r1,%r2
|
||||
mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
|
||||
stsch .Lschib-.Lpg0(%r13)
|
||||
@@ -56,8 +52,7 @@ do_reipl_asm: basr %r13,0
|
||||
.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
|
||||
jz .L003
|
||||
bas %r14,.Ldisab-.Lpg0(%r13)
|
||||
.L003: spx .Lnull-.Lpg0(%r13)
|
||||
st %r1,__LC_SUBCHANNEL_ID
|
||||
.L003: st %r1,__LC_SUBCHANNEL_ID
|
||||
lhi %r1,0 # mode 0 = esa
|
||||
slr %r0,%r0 # set cpuid to zero
|
||||
sigp %r1,%r0,0x12 # switch to esa mode
|
||||
@@ -70,7 +65,6 @@ do_reipl_asm: basr %r13,0
|
||||
.Lclkcmp: .quad 0x0000000000000000
|
||||
.Lall: .quad 0x00000000ff000000
|
||||
.Lregsave: .quad 0x0000000000000000
|
||||
.Lnull: .long 0x0000000000000000
|
||||
.align 16
|
||||
/*
|
||||
* These addresses have to be 31 bit otherwise
|
||||
|
@@ -26,8 +26,7 @@
|
||||
relocate_kernel:
|
||||
basr %r13,0 # base address
|
||||
.base:
|
||||
stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQ (external)
|
||||
spx zero64-.base(%r13) # absolute addressing mode
|
||||
stnsm sys_msk-.base(%r13),0xfb # disable DAT
|
||||
stctl %c0,%c15,ctlregs-.base(%r13)
|
||||
stm %r0,%r15,gprregs-.base(%r13)
|
||||
la %r1,load_psw-.base(%r13)
|
||||
@@ -97,8 +96,6 @@
|
||||
lpsw 0 # hopefully start new kernel...
|
||||
|
||||
.align 8
|
||||
zero64:
|
||||
.quad 0
|
||||
load_psw:
|
||||
.long 0x00080000,0x80000000
|
||||
sys_msk:
|
||||
|
@@ -27,8 +27,7 @@
|
||||
relocate_kernel:
|
||||
basr %r13,0 # base address
|
||||
.base:
|
||||
stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQs
|
||||
spx zero64-.base(%r13) # absolute addressing mode
|
||||
stnsm sys_msk-.base(%r13),0xfb # disable DAT
|
||||
stctg %c0,%c15,ctlregs-.base(%r13)
|
||||
stmg %r0,%r15,gprregs-.base(%r13)
|
||||
lghi %r0,3
|
||||
@@ -100,8 +99,6 @@
|
||||
lpsw 0 # hopefully start new kernel...
|
||||
|
||||
.align 8
|
||||
zero64:
|
||||
.quad 0
|
||||
load_psw:
|
||||
.long 0x00080000,0x80000000
|
||||
sys_msk:
|
||||
|
48
arch/s390/kernel/reset.S
Normal file
48
arch/s390/kernel/reset.S
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* arch/s390/kernel/reset.S
|
||||
*
|
||||
* Copyright (C) IBM Corp. 2006
|
||||
* Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
|
||||
*/
|
||||
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/lowcore.h>
|
||||
|
||||
#ifdef CONFIG_64BIT
|
||||
|
||||
.globl reset_mcck_handler
|
||||
reset_mcck_handler:
|
||||
basr %r13,0
|
||||
0: lg %r15,__LC_PANIC_STACK # load panic stack
|
||||
aghi %r15,-STACK_FRAME_OVERHEAD
|
||||
lg %r1,s390_reset_mcck_handler-0b(%r13)
|
||||
ltgr %r1,%r1
|
||||
jz 1f
|
||||
basr %r14,%r1
|
||||
1: la %r1,4095
|
||||
lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
|
||||
lpswe __LC_MCK_OLD_PSW
|
||||
|
||||
.globl s390_reset_mcck_handler
|
||||
s390_reset_mcck_handler:
|
||||
.quad 0
|
||||
|
||||
#else /* CONFIG_64BIT */
|
||||
|
||||
.globl reset_mcck_handler
|
||||
reset_mcck_handler:
|
||||
basr %r13,0
|
||||
0: l %r15,__LC_PANIC_STACK # load panic stack
|
||||
ahi %r15,-STACK_FRAME_OVERHEAD
|
||||
l %r1,s390_reset_mcck_handler-0b(%r13)
|
||||
ltr %r1,%r1
|
||||
jz 1f
|
||||
basr %r14,%r1
|
||||
1: lm %r0,%r15,__LC_GPREGS_SAVE_AREA
|
||||
lpsw __LC_MCK_OLD_PSW
|
||||
|
||||
.globl s390_reset_mcck_handler
|
||||
s390_reset_mcck_handler:
|
||||
.long 0
|
||||
|
||||
#endif /* CONFIG_64BIT */
|
Reference in New Issue
Block a user