Skip to content

Commit a0e45d4

Browse files
committed
s390/crash_dump: fix virtual vs physical address handling
Signal processor STORE STATUS requires a physical address where register contents are supposed to be written to, however the kernel must read the data via the corresponding virtual address. Also the allocated save_area, where register contents are copied to, resides in virtual address space. Fix this by using proper __pa() conversion, or correct memblock_alloc() invocation. Reviewed-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
1 parent 39d0282 commit a0e45d4

2 files changed

Lines changed: 8 additions & 12 deletions

File tree

arch/s390/kernel/crash_dump.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct save_area * __init save_area_alloc(bool is_boot_cpu)
6060
{
6161
struct save_area *sa;
6262

63-
sa = (void *) memblock_phys_alloc(sizeof(*sa), 8);
63+
sa = memblock_alloc(sizeof(*sa), 8);
6464
if (!sa)
6565
panic("Failed to allocate save area\n");
6666

arch/s390/kernel/smp.c

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -658,41 +658,37 @@ int smp_store_status(int cpu)
658658
* deactivates the elfcorehdr= kernel parameter
659659
*/
660660
static __init void smp_save_cpu_vxrs(struct save_area *sa, u16 addr,
661-
bool is_boot_cpu, unsigned long page)
661+
bool is_boot_cpu, __vector128 *vxrs)
662662
{
663-
__vector128 *vxrs = (__vector128 *) page;
664-
665663
if (is_boot_cpu)
666664
vxrs = boot_cpu_vector_save_area;
667665
else
668-
__pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, page);
666+
__pcpu_sigp_relax(addr, SIGP_STORE_ADDITIONAL_STATUS, __pa(vxrs));
669667
save_area_add_vxrs(sa, vxrs);
670668
}
671669

672670
static __init void smp_save_cpu_regs(struct save_area *sa, u16 addr,
673-
bool is_boot_cpu, unsigned long page)
671+
bool is_boot_cpu, void *regs)
674672
{
675-
void *regs = (void *) page;
676-
677673
if (is_boot_cpu)
678674
copy_oldmem_kernel(regs, (void *) __LC_FPREGS_SAVE_AREA, 512);
679675
else
680-
__pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, page);
676+
__pcpu_sigp_relax(addr, SIGP_STORE_STATUS_AT_ADDRESS, __pa(regs));
681677
save_area_add_regs(sa, regs);
682678
}
683679

684680
void __init smp_save_dump_cpus(void)
685681
{
686682
int addr, boot_cpu_addr, max_cpu_addr;
687683
struct save_area *sa;
688-
unsigned long page;
689684
bool is_boot_cpu;
685+
void *page;
690686

691687
if (!(oldmem_data.start || is_ipl_type_dump()))
692688
/* No previous system present, normal boot. */
693689
return;
694690
/* Allocate a page as dumping area for the store status sigps */
695-
page = memblock_phys_alloc_range(PAGE_SIZE, PAGE_SIZE, 0, 1UL << 31);
691+
page = memblock_alloc_low(PAGE_SIZE, PAGE_SIZE);
696692
if (!page)
697693
panic("ERROR: Failed to allocate %lx bytes below %lx\n",
698694
PAGE_SIZE, 1UL << 31);
@@ -723,7 +719,7 @@ void __init smp_save_dump_cpus(void)
723719
/* Get the CPU registers */
724720
smp_save_cpu_regs(sa, addr, is_boot_cpu, page);
725721
}
726-
memblock_phys_free(page, PAGE_SIZE);
722+
memblock_free(page, PAGE_SIZE);
727723
diag_amode31_ops.diag308_reset();
728724
pcpu_set_smt(0);
729725
}

0 commit comments

Comments
 (0)