Skip to content

Commit

Permalink
s390/dump: introduce boot data 'oldmem_data'
Browse files Browse the repository at this point in the history
The new boot data struct shall replace global variables OLDMEM_BASE and
OLDMEM_SIZE. It is initialized in the decompressor and passed
to the decompressed kernel. In comparison to the old solution, this one
doesn't access data at fixed physical addresses which will become important
when the decompressor becomes relocatable.

Signed-off-by: Alexander Egorenkov <[email protected]>
Acked-by: Heiko Carstens <[email protected]>
Signed-off-by: Heiko Carstens <[email protected]>
  • Loading branch information
eaibmz authored and hcahca committed Jul 27, 2021
1 parent 8473328 commit e9e7870
Show file tree
Hide file tree
Showing 9 changed files with 45 additions and 37 deletions.
7 changes: 5 additions & 2 deletions arch/s390/boot/startup.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct initrd_data __bootdata(initrd_data);

u64 __bootdata_preserved(stfle_fac_list[16]);
u64 __bootdata_preserved(alt_stfle_fac_list[16]);
struct oldmem_data __bootdata_preserved(oldmem_data);

/*
* Some code and data needs to stay below 2 GB, even when the kernel would be
Expand Down Expand Up @@ -165,9 +166,9 @@ static void setup_ident_map_size(unsigned long max_physmem_end)
ident_map_size = min(ident_map_size, 1UL << MAX_PHYSMEM_BITS);

#ifdef CONFIG_CRASH_DUMP
if (OLDMEM_BASE) {
if (oldmem_data.start) {
kaslr_enabled = 0;
ident_map_size = min(ident_map_size, OLDMEM_SIZE);
ident_map_size = min(ident_map_size, oldmem_data.size);
} else if (ipl_block_valid && is_ipl_block_dump()) {
kaslr_enabled = 0;
if (!sclp_early_get_hsa_size(&hsa_size) && hsa_size)
Expand Down Expand Up @@ -286,6 +287,8 @@ void startup_kernel(void)

initrd_data.start = parmarea.initrd_start;
initrd_data.size = parmarea.initrd_size;
oldmem_data.start = parmarea.oldmem_base;
oldmem_data.size = parmarea.oldmem_size;

setup_lpp();
store_ipl_parmblock();
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/boot/uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static int is_prot_virt_host_capable(void)
if (!test_facility(158))
return 0;
/* disable if kdump */
if (OLDMEM_BASE)
if (oldmem_data.start)
return 0;
/* disable if stand-alone dump */
if (ipl_block_valid && is_ipl_block_dump())
Expand Down
8 changes: 6 additions & 2 deletions arch/s390/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@
#include <asm/types.h>

#define IPL_DEVICE (*(unsigned long *) (IPL_DEVICE_OFFSET))
#define OLDMEM_BASE (*(unsigned long *) (OLDMEM_BASE_OFFSET))
#define OLDMEM_SIZE (*(unsigned long *) (OLDMEM_SIZE_OFFSET))
#define COMMAND_LINE ((char *) (COMMAND_LINE_OFFSET))

struct parmarea {
Expand Down Expand Up @@ -164,6 +162,12 @@ struct initrd_data {
};
extern struct initrd_data initrd_data;

struct oldmem_data {
unsigned long start;
unsigned long size;
};
extern struct oldmem_data oldmem_data;

static inline u32 gen_lpswe(unsigned long addr)
{
BUILD_BUG_ON(addr > 0xfff);
Expand Down
46 changes: 23 additions & 23 deletions arch/s390/kernel/crash_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,20 +140,20 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count)

while (count) {
from = __pa(src);
if (!OLDMEM_BASE && from < sclp.hsa_size) {
if (!oldmem_data.start && from < sclp.hsa_size) {
/* Copy from zfcp/nvme dump HSA area */
len = min(count, sclp.hsa_size - from);
rc = memcpy_hsa_kernel(dst, from, len);
if (rc)
return rc;
} else {
/* Check for swapped kdump oldmem areas */
if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) {
from -= OLDMEM_BASE;
len = min(count, OLDMEM_SIZE - from);
} else if (OLDMEM_BASE && from < OLDMEM_SIZE) {
len = min(count, OLDMEM_SIZE - from);
from += OLDMEM_BASE;
if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) {
from -= oldmem_data.start;
len = min(count, oldmem_data.size - from);
} else if (oldmem_data.start && from < oldmem_data.size) {
len = min(count, oldmem_data.size - from);
from += oldmem_data.start;
} else {
len = count;
}
Expand Down Expand Up @@ -183,20 +183,20 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count)

while (count) {
from = __pa(src);
if (!OLDMEM_BASE && from < sclp.hsa_size) {
if (!oldmem_data.start && from < sclp.hsa_size) {
/* Copy from zfcp/nvme dump HSA area */
len = min(count, sclp.hsa_size - from);
rc = memcpy_hsa_user(dst, from, len);
if (rc)
return rc;
} else {
/* Check for swapped kdump oldmem areas */
if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) {
from -= OLDMEM_BASE;
len = min(count, OLDMEM_SIZE - from);
} else if (OLDMEM_BASE && from < OLDMEM_SIZE) {
len = min(count, OLDMEM_SIZE - from);
from += OLDMEM_BASE;
if (oldmem_data.start && from - oldmem_data.size < oldmem_data.size) {
from -= oldmem_data.size;
len = min(count, oldmem_data.size - from);
} else if (oldmem_data.start && from < oldmem_data.size) {
len = min(count, oldmem_data.size - from);
from += oldmem_data.start;
} else {
len = count;
}
Expand Down Expand Up @@ -243,10 +243,10 @@ static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma,
unsigned long size_old;
int rc;

if (pfn < OLDMEM_SIZE >> PAGE_SHIFT) {
size_old = min(size, OLDMEM_SIZE - (pfn << PAGE_SHIFT));
if (pfn < oldmem_data.size >> PAGE_SHIFT) {
size_old = min(size, oldmem_data.size - (pfn << PAGE_SHIFT));
rc = remap_pfn_range(vma, from,
pfn + (OLDMEM_BASE >> PAGE_SHIFT),
pfn + (oldmem_data.start >> PAGE_SHIFT),
size_old, prot);
if (rc || size == size_old)
return rc;
Expand Down Expand Up @@ -288,7 +288,7 @@ static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct *vma,
int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long pfn, unsigned long size, pgprot_t prot)
{
if (OLDMEM_BASE)
if (oldmem_data.start)
return remap_oldmem_pfn_range_kdump(vma, from, pfn, size, prot);
else
return remap_oldmem_pfn_range_zfcpdump(vma, from, pfn, size,
Expand Down Expand Up @@ -633,17 +633,17 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
u64 hdr_off;

/* If we are not in kdump or zfcp/nvme dump mode return */
if (!OLDMEM_BASE && !is_ipl_type_dump())
if (!oldmem_data.start && !is_ipl_type_dump())
return 0;
/* If we cannot get HSA size for zfcp/nvme dump return error */
if (is_ipl_type_dump() && !sclp.hsa_size)
return -ENODEV;

/* For kdump, exclude previous crashkernel memory */
if (OLDMEM_BASE) {
oldmem_region.base = OLDMEM_BASE;
oldmem_region.size = OLDMEM_SIZE;
oldmem_type.total_size = OLDMEM_SIZE;
if (oldmem_data.start) {
oldmem_region.base = oldmem_data.start;
oldmem_region.size = oldmem_data.size;
oldmem_type.total_size = oldmem_data.size;
}

mem_chunk_cnt = get_mem_chunk_cnt();
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/os_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ static void os_info_old_init(void)

if (os_info_init)
return;
if (!OLDMEM_BASE)
if (!oldmem_data.start)
goto fail;
if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr)))
goto fail;
Expand Down
9 changes: 5 additions & 4 deletions arch/s390/kernel/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ EXPORT_SYMBOL(zlib_dfltcc_support);
u64 __bootdata_preserved(stfle_fac_list[16]);
EXPORT_SYMBOL(stfle_fac_list);
u64 __bootdata_preserved(alt_stfle_fac_list[16]);
struct oldmem_data __bootdata_preserved(oldmem_data);

unsigned long VMALLOC_START;
EXPORT_SYMBOL(VMALLOC_START);
Expand Down Expand Up @@ -255,7 +256,7 @@ static void __init setup_zfcpdump(void)
{
if (!is_ipl_type_dump())
return;
if (OLDMEM_BASE)
if (oldmem_data.start)
return;
strcat(boot_command_line, " cio_ignore=all,!ipldev,!condev");
console_loglevel = 2;
Expand Down Expand Up @@ -611,9 +612,9 @@ static void __init reserve_crashkernel(void)
return;
}

low = crash_base ?: OLDMEM_BASE;
low = crash_base ?: oldmem_data.start;
high = low + crash_size;
if (low >= OLDMEM_BASE && high <= OLDMEM_BASE + OLDMEM_SIZE) {
if (low >= oldmem_data.start && high <= oldmem_data.start + oldmem_data.size) {
/* The crashkernel fits into OLDMEM, reuse OLDMEM */
crash_base = low;
} else {
Expand All @@ -640,7 +641,7 @@ static void __init reserve_crashkernel(void)
if (register_memory_notifier(&kdump_mem_nb))
return;

if (!OLDMEM_BASE && MACHINE_IS_VM)
if (!oldmem_data.start && MACHINE_IS_VM)
diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1;
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ void __init smp_save_dump_cpus(void)
unsigned long page;
bool is_boot_cpu;

if (!(OLDMEM_BASE || is_ipl_type_dump()))
if (!(oldmem_data.start || is_ipl_type_dump()))
/* No previous system present, normal boot. */
return;
/* Allocate a page as dumping area for the store status sigps */
Expand Down Expand Up @@ -704,7 +704,7 @@ void __init smp_save_dump_cpus(void)
* these registers an SCLP request is required which is
* done by drivers/s390/char/zcore.c:init_cpu_info()
*/
if (!is_boot_cpu || OLDMEM_BASE)
if (!is_boot_cpu || oldmem_data.start)
/* Get the CPU registers */
smp_save_cpu_regs(sa, addr, is_boot_cpu, page);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/char/sclp_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -457,7 +457,7 @@ static int __init sclp_detect_standby_memory(void)
struct read_storage_sccb *sccb;
int i, id, assigned, rc;

if (OLDMEM_BASE) /* No standby memory in kdump mode */
if (oldmem_data.start) /* No standby memory in kdump mode */
return 0;
if ((sclp.facilities & 0xe00000000000ULL) != 0xe00000000000ULL)
return 0;
Expand Down
2 changes: 1 addition & 1 deletion drivers/s390/char/zcore.c
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ static int __init zcore_init(void)

if (!is_ipl_type_dump())
return -ENODATA;
if (OLDMEM_BASE)
if (oldmem_data.start)
return -ENODATA;

zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long));
Expand Down

0 comments on commit e9e7870

Please sign in to comment.