Skip to content

Commit 14a3a26

Browse files
Alexander GordeevVasily Gorbik
authored andcommitted
s390/dump: save IPL CPU registers once DAT is available
Function smp_save_dump_cpus() collects CPU state of a crashed system for secondary CPUs and for the IPL CPU very differently. The Signal Processor stop-and-store-status orders are used for the former while Hardware System Area requests and memcpy_real() routine are called for the latter. In addition a system reset is triggered, which pins smp_save_dump_cpus() function call before CPU and device initialization. Move the collection of IPL CPU state to a later stage when DAT becomes available. That is needed to allow a follow-up rework of memcpy_real() routine. Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
1 parent 2187582 commit 14a3a26

3 files changed

Lines changed: 34 additions & 35 deletions

File tree

arch/s390/include/asm/smp.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ extern void smp_emergency_stop(void);
3030

3131
extern int smp_find_processor_id(u16 address);
3232
extern int smp_store_status(int cpu);
33-
extern void smp_save_dump_cpus(void);
33+
extern void smp_save_dump_ipl_cpu(void);
34+
extern void smp_save_dump_secondary_cpus(void);
3435
extern void smp_yield_cpu(int cpu);
3536
extern void smp_cpu_set_polarization(int cpu, int val);
3637
extern int smp_cpu_get_polarization(int cpu);

arch/s390/kernel/setup.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,10 +1028,10 @@ void __init setup_arch(char **cmdline_p)
10281028
reserve_crashkernel();
10291029
#ifdef CONFIG_CRASH_DUMP
10301030
/*
1031-
* Be aware that smp_save_dump_cpus() triggers a system reset.
1031+
* Be aware that smp_save_dump_secondary_cpus() triggers a system reset.
10321032
* Therefore CPU and device initialization should be done afterwards.
10331033
*/
1034-
smp_save_dump_cpus();
1034+
smp_save_dump_secondary_cpus();
10351035
#endif
10361036

10371037
setup_resources();
@@ -1056,6 +1056,9 @@ void __init setup_arch(char **cmdline_p)
10561056
* in lowcore can now run with DAT enabled.
10571057
*/
10581058
setup_lowcore_dat_on();
1059+
#ifdef CONFIG_CRASH_DUMP
1060+
smp_save_dump_ipl_cpu();
1061+
#endif
10591062

10601063
/* Setup default console */
10611064
conmode_default();

arch/s390/kernel/smp.c

Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -664,35 +664,36 @@ int smp_store_status(int cpu)
664664
* This case does not exist for s390 anymore, setup_arch explicitly
665665
* deactivates the elfcorehdr= kernel parameter
666666
*/
667-
static __init void smp_save_cpu_vxrs(struct save_area *sa, u16 addr,
668-
bool is_boot_cpu, __vector128 *vxrs)
667+
static bool dump_available(void)
669668
{
670-
if (is_boot_cpu)
671-
vxrs = boot_cpu_vector_save_area;
672-
else
673-
__pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, __pa(vxrs));
674-
save_area_add_vxrs(sa, vxrs);
669+
return oldmem_data.start || is_ipl_type_dump();
675670
}
676671

677-
static __init void smp_save_cpu_regs(struct save_area *sa, u16 addr,
678-
bool is_boot_cpu, void *regs)
672+
void __init smp_save_dump_ipl_cpu(void)
679673
{
680-
if (is_boot_cpu)
681-
copy_oldmem_kernel(regs, __LC_FPREGS_SAVE_AREA, 512);
682-
else
683-
__pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, __pa(regs));
674+
struct save_area *sa;
675+
void *regs;
676+
677+
if (!dump_available())
678+
return;
679+
sa = save_area_alloc(true);
680+
regs = memblock_alloc(512, 8);
681+
if (!sa || !regs)
682+
panic("could not allocate memory for boot CPU save area\n");
683+
copy_oldmem_kernel(regs, __LC_FPREGS_SAVE_AREA, 512);
684684
save_area_add_regs(sa, regs);
685+
memblock_free(regs, 512);
686+
if (MACHINE_HAS_VX)
687+
save_area_add_vxrs(sa, boot_cpu_vector_save_area);
685688
}
686689

687-
void __init smp_save_dump_cpus(void)
690+
void __init smp_save_dump_secondary_cpus(void)
688691
{
689692
int addr, boot_cpu_addr, max_cpu_addr;
690693
struct save_area *sa;
691-
bool is_boot_cpu;
692694
void *page;
693695

694-
if (!(oldmem_data.start || is_ipl_type_dump()))
695-
/* No previous system present, normal boot. */
696+
if (!dump_available())
696697
return;
697698
/* Allocate a page as dumping area for the store status sigps */
698699
page = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
@@ -705,26 +706,20 @@ void __init smp_save_dump_cpus(void)
705706
boot_cpu_addr = stap();
706707
max_cpu_addr = SCLP_MAX_CORES << sclp.mtid_prev;
707708
for (addr = 0; addr <= max_cpu_addr; addr++) {
709+
if (addr == boot_cpu_addr)
710+
continue;
708711
if (__pcpu_sigp_relax(addr, SIGP_SENSE, 0) ==
709712
SIGP_CC_NOT_OPERATIONAL)
710713
continue;
711-
is_boot_cpu = (addr == boot_cpu_addr);
712-
/* Allocate save area */
713-
sa = save_area_alloc(is_boot_cpu);
714+
sa = save_area_alloc(false);
714715
if (!sa)
715716
panic("could not allocate memory for save area\n");
716-
if (MACHINE_HAS_VX)
717-
/* Get the vector registers */
718-
smp_save_cpu_vxrs(sa, addr, is_boot_cpu, page);
719-
/*
720-
* For a zfcp/nvme dump OLDMEM_BASE == NULL and the registers
721-
* of the boot CPU are stored in the HSA. To retrieve
722-
* these registers an SCLP request is required which is
723-
* done by drivers/s390/char/zcore.c:init_cpu_info()
724-
*/
725-
if (!is_boot_cpu || oldmem_data.start)
726-
/* Get the CPU registers */
727-
smp_save_cpu_regs(sa, addr, is_boot_cpu, page);
717+
__pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, __pa(page));
718+
save_area_add_regs(sa, page);
719+
if (MACHINE_HAS_VX) {
720+
__pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, __pa(page));
721+
save_area_add_vxrs(sa, page);
722+
}
728723
}
729724
memblock_free(page, PAGE_SIZE);
730725
diag_amode31_ops.diag308_reset();

0 commit comments

Comments
 (0)