Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 15e9b586 authored by Heiko Carstens's avatar Heiko Carstens Committed by Martin Schwidefsky
Browse files

[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: default avatarHeiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 2254f5a7
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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

+54 −0
Original line number Diff line number Diff line
@@ -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();
}
+3 −6
Original line number Diff line number Diff line
@@ -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);
+2 −15
Original line number Diff line number Diff line
@@ -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
+5 −11
Original line number Diff line number Diff line
@@ -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
Loading