Commit e9e7870f authored by Alexander Egorenkov's avatar Alexander Egorenkov Committed by Heiko Carstens

s390/dump: introduce boot data 'oldmem_data'

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: default avatarAlexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 84733284
......@@ -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
......@@ -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)
......@@ -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();
......
......@@ -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())
......
......@@ -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 {
......@@ -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);
......
......@@ -140,7 +140,7 @@ 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);
......@@ -148,12 +148,12 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count)
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;
}
......@@ -183,7 +183,7 @@ 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);
......@@ -191,12 +191,12 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count)
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;
}
......@@ -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;
......@@ -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,
......@@ -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();
......
......@@ -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;
......
......@@ -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);
......@@ -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;
......@@ -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 {
......@@ -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;
......
......@@ -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 */
......@@ -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);
}
......
......@@ -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;
......
......@@ -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));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment