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

Commit 1a36a39e authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

s390/dump: rework CPU register dump code



To collect the CPU registers of the crashed system allocated a single
page with memblock_alloc_base and use it as a copy buffer. Replace the
stop-and-store-status sigp with a store-status-at-address sigp in
smp_save_dump_cpus() and smp_store_status(). In both cases the target
CPU is already stopped and store-status-at-address avoids the detour
via the absolute zero page.

For kexec simplify s390_reset_system and call store_status() before
the prefix register of the boot CPU has been set to zero. Use STPX
to store the prefix register and remove dump_prefix_page.

Acked-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent f08b8414
Loading
Loading
Loading
Loading
+1 −9
Original line number Diff line number Diff line
@@ -12,21 +12,13 @@
#include <asm/ctl_reg.h>
#include <asm/fpu/types.h>

static inline void save_vx_regs_safe(__vector128 *vxrs)
static inline void save_vx_regs(__vector128 *vxrs)
{
	unsigned long cr0, flags;

	flags = arch_local_irq_save();
	__ctl_store(cr0, 0, 0);
	__ctl_set_bit(0, 17);
	__ctl_set_bit(0, 18);
	asm volatile(
		"	la	1,%0\n"
		"	.word	0xe70f,0x1000,0x003e\n"	/* vstm 0,15,0(1) */
		"	.word	0xe70f,0x1100,0x0c3e\n"	/* vstm 16,31,256(1) */
		: "=Q" (*(struct vx_array *) vxrs) : : "1");
	__ctl_load(cr0, 0, 0);
	arch_local_irq_restore(flags);
}

static inline void convert_vx_to_fp(freg_t *fprs, __vector128 *vxrs)
+1 −2
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@ struct ipl_parameter_block {
 * IPL validity flags
 */
extern u32 ipl_flags;
extern u32 dump_prefix_page;

struct dump_save_areas {
	struct save_area_ext **areas;
@@ -176,7 +175,7 @@ enum diag308_rc {

extern int diag308(unsigned long subcode, void *addr);
extern void diag308_reset(void);
extern void store_status(void);
extern void store_status(void (*fn)(void *), void *data);
extern void lgr_info_log(void);

#endif /* _ASM_S390_IPL_H */
+1 −2
Original line number Diff line number Diff line
@@ -15,6 +15,5 @@ struct reset_call {

extern void register_reset_call(struct reset_call *reset);
extern void unregister_reset_call(struct reset_call *reset);
extern void s390_reset_system(void (*fn_pre)(void),
			      void (*fn_post)(void *), void *data);
extern void s390_reset_system(void);
#endif /* _ASM_S390_RESET_H */
+1 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
extern struct mutex smp_cpu_state_mutex;
extern unsigned int smp_cpu_mt_shift;
extern unsigned int smp_cpu_mtid;
extern __vector128 __initdata boot_cpu_vector_save_area[__NUM_VXRS];

extern int __cpu_up(unsigned int cpu, struct task_struct *tidle);

@@ -55,7 +56,6 @@ static inline int smp_store_status(int cpu) { return 0; }
static inline int smp_vcpu_scheduled(int cpu) { return 1; }
static inline void smp_yield_cpu(int cpu) { }
static inline void smp_fill_possible_mask(void) { }
static inline void smp_save_dump_cpus(void) { }

#endif /* CONFIG_SMP */

+9 −0
Original line number Diff line number Diff line
@@ -335,6 +335,14 @@ static __init void detect_machine_facilities(void)
	}
}

static inline void save_vector_registers(void)
{
#ifdef CONFIG_CRASH_DUMP
	if (test_facility(129))
		save_vx_regs(boot_cpu_vector_save_area);
#endif
}

static int __init disable_vector_extension(char *str)
{
	S390_lowcore.machine_flags &= ~MACHINE_FLAG_VX;
@@ -451,6 +459,7 @@ void __init startup_init(void)
	detect_diag9c();
	detect_diag44();
	detect_machine_facilities();
	save_vector_registers();
	setup_topology();
	sclp_early_detect();
	lockdep_on();
Loading