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

Commit 1592a8e4 authored by Michael Holzheu's avatar Michael Holzheu Committed by Martin Schwidefsky
Browse files

s390/kdump: fix nosmt kernel parameter



It turned out that SIGP set-multi-threading can only be done once.
Therefore switching to a different MT level after switching to
sclp.mtid_prev in the dump case fails.

As a symptom specifying the "nosmt" parameter currently fails for
the kdump kernel and the kernel starts with multi-threading enabled.

So fix this and issue diag 308 subcode 1 call after collecting the
CPU states for the dump. Also enhance the diag308_reset() function to
be usable also with enabled lowcore protection and prefix register != 0.
After the reset it is possible to switch the MT level again. We have
to do the reset very early in order not to kill the already initialized
console. Therefore instead of kmalloc() the corresponding memblock
functions have to be used. To avoid copying the sclp cpu code into
sclp_early, we now use the simple sigp loop method for CPU detection.

Signed-off-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 1d1858d2
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -94,7 +94,6 @@ struct dump_save_areas {
};
};


extern struct dump_save_areas dump_save_areas;
extern struct dump_save_areas dump_save_areas;
struct save_area_ext *dump_save_area_create(int cpu);


extern void do_reipl(void);
extern void do_reipl(void);
extern void do_halt(void);
extern void do_halt(void);
+1 −0
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ extern void smp_call_ipl_cpu(void (*func)(void *), void *);


extern int smp_find_processor_id(u16 address);
extern int smp_find_processor_id(u16 address);
extern int smp_store_status(int cpu);
extern int smp_store_status(int cpu);
extern void smp_save_dump_cpus(void);
extern int smp_vcpu_scheduled(int cpu);
extern int smp_vcpu_scheduled(int cpu);
extern void smp_yield_cpu(int cpu);
extern void smp_yield_cpu(int cpu);
extern void smp_cpu_set_polarization(int cpu, int val);
extern void smp_cpu_set_polarization(int cpu, int val);
+17 −4
Original line number Original line Diff line number Diff line
@@ -78,15 +78,20 @@ s390_base_pgm_handler_fn:
#
#
# Calls diag 308 subcode 1 and continues execution
# Calls diag 308 subcode 1 and continues execution
#
#
# The following conditions must be ensured before calling this function:
# * Prefix register = 0
# * Lowcore protection is disabled
#
ENTRY(diag308_reset)
ENTRY(diag308_reset)
	larl	%r4,.Lctlregs		# Save control registers
	larl	%r4,.Lctlregs		# Save control registers
	stctg	%c0,%c15,0(%r4)
	stctg	%c0,%c15,0(%r4)
	lg	%r2,0(%r4)		# Disable lowcore protection
	nilh	%r2,0xefff
	larl	%r4,.Lctlreg0
	stg	%r2,0(%r4)
	lctlg	%c0,%c0,0(%r4)
	larl	%r4,.Lfpctl		# Floating point control register
	larl	%r4,.Lfpctl		# Floating point control register
	stfpc	0(%r4)
	stfpc	0(%r4)
	larl	%r4,.Lprefix		# Save prefix register
	stpx	0(%r4)
	larl	%r4,.Lprefix_zero	# Set prefix register to 0
	spx	0(%r4)
	larl	%r4,.Lcontinue_psw	# Save PSW flags
	larl	%r4,.Lcontinue_psw	# Save PSW flags
	epsw	%r2,%r3
	epsw	%r2,%r3
	stm	%r2,%r3,0(%r4)
	stm	%r2,%r3,0(%r4)
@@ -106,6 +111,8 @@ ENTRY(diag308_reset)
	lctlg	%c0,%c15,0(%r4)
	lctlg	%c0,%c15,0(%r4)
	larl	%r4,.Lfpctl		# Restore floating point ctl register
	larl	%r4,.Lfpctl		# Restore floating point ctl register
	lfpc	0(%r4)
	lfpc	0(%r4)
	larl	%r4,.Lprefix		# Restore prefix register
	spx	0(%r4)
	larl	%r4,.Lcontinue_psw	# Restore PSW flags
	larl	%r4,.Lcontinue_psw	# Restore PSW flags
	lpswe	0(%r4)
	lpswe	0(%r4)
.Lcontinue:
.Lcontinue:
@@ -122,10 +129,16 @@ ENTRY(diag308_reset)


	.section .bss
	.section .bss
.align 8
.align 8
.Lctlreg0:
	.quad	0
.Lctlregs:
.Lctlregs:
	.rept	16
	.rept	16
	.quad	0
	.quad	0
	.endr
	.endr
.Lfpctl:
.Lfpctl:
	.long	0
	.long	0
.Lprefix:
	.long	0
.Lprefix_zero:
	.long	0
	.previous
	.previous
+0 −25
Original line number Original line Diff line number Diff line
@@ -44,31 +44,6 @@ static struct memblock_type oldmem_type = {


struct dump_save_areas dump_save_areas;
struct dump_save_areas dump_save_areas;


/*
 * Allocate and add a save area for a CPU
 */
struct save_area_ext *dump_save_area_create(int cpu)
{
	struct save_area_ext **save_areas, *save_area;

	save_area = kmalloc(sizeof(*save_area), GFP_KERNEL);
	if (!save_area)
		return NULL;
	if (cpu + 1 > dump_save_areas.count) {
		dump_save_areas.count = cpu + 1;
		save_areas = krealloc(dump_save_areas.areas,
				      dump_save_areas.count * sizeof(void *),
				      GFP_KERNEL | __GFP_ZERO);
		if (!save_areas) {
			kfree(save_area);
			return NULL;
		}
		dump_save_areas.areas = save_areas;
	}
	dump_save_areas.areas[cpu] = save_area;
	return save_area;
}

/*
/*
 * Return physical address for virtual address
 * Return physical address for virtual address
 */
 */
+5 −0
Original line number Original line Diff line number Diff line
@@ -868,6 +868,11 @@ void __init setup_arch(char **cmdline_p)


	check_initrd();
	check_initrd();
	reserve_crashkernel();
	reserve_crashkernel();
	/*
	 * Be aware that smp_save_dump_cpus() triggers a system reset.
	 * Therefore CPU and device initialization should be done afterwards.
	 */
	smp_save_dump_cpus();


	setup_resources();
	setup_resources();
	setup_vmcoreinfo();
	setup_vmcoreinfo();
Loading