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); ...@@ -27,6 +27,7 @@ struct initrd_data __bootdata(initrd_data);
u64 __bootdata_preserved(stfle_fac_list[16]); u64 __bootdata_preserved(stfle_fac_list[16]);
u64 __bootdata_preserved(alt_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 * 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) ...@@ -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); ident_map_size = min(ident_map_size, 1UL << MAX_PHYSMEM_BITS);
#ifdef CONFIG_CRASH_DUMP #ifdef CONFIG_CRASH_DUMP
if (OLDMEM_BASE) { if (oldmem_data.start) {
kaslr_enabled = 0; 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()) { } else if (ipl_block_valid && is_ipl_block_dump()) {
kaslr_enabled = 0; kaslr_enabled = 0;
if (!sclp_early_get_hsa_size(&hsa_size) && hsa_size) if (!sclp_early_get_hsa_size(&hsa_size) && hsa_size)
...@@ -286,6 +287,8 @@ void startup_kernel(void) ...@@ -286,6 +287,8 @@ void startup_kernel(void)
initrd_data.start = parmarea.initrd_start; initrd_data.start = parmarea.initrd_start;
initrd_data.size = parmarea.initrd_size; initrd_data.size = parmarea.initrd_size;
oldmem_data.start = parmarea.oldmem_base;
oldmem_data.size = parmarea.oldmem_size;
setup_lpp(); setup_lpp();
store_ipl_parmblock(); store_ipl_parmblock();
......
...@@ -69,7 +69,7 @@ static int is_prot_virt_host_capable(void) ...@@ -69,7 +69,7 @@ static int is_prot_virt_host_capable(void)
if (!test_facility(158)) if (!test_facility(158))
return 0; return 0;
/* disable if kdump */ /* disable if kdump */
if (OLDMEM_BASE) if (oldmem_data.start)
return 0; return 0;
/* disable if stand-alone dump */ /* disable if stand-alone dump */
if (ipl_block_valid && is_ipl_block_dump()) if (ipl_block_valid && is_ipl_block_dump())
......
...@@ -60,8 +60,6 @@ ...@@ -60,8 +60,6 @@
#include <asm/types.h> #include <asm/types.h>
#define IPL_DEVICE (*(unsigned long *) (IPL_DEVICE_OFFSET)) #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)) #define COMMAND_LINE ((char *) (COMMAND_LINE_OFFSET))
struct parmarea { struct parmarea {
...@@ -164,6 +162,12 @@ struct initrd_data { ...@@ -164,6 +162,12 @@ struct initrd_data {
}; };
extern struct initrd_data 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) static inline u32 gen_lpswe(unsigned long addr)
{ {
BUILD_BUG_ON(addr > 0xfff); BUILD_BUG_ON(addr > 0xfff);
......
...@@ -140,7 +140,7 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count) ...@@ -140,7 +140,7 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count)
while (count) { while (count) {
from = __pa(src); 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 */ /* Copy from zfcp/nvme dump HSA area */
len = min(count, sclp.hsa_size - from); len = min(count, sclp.hsa_size - from);
rc = memcpy_hsa_kernel(dst, from, len); rc = memcpy_hsa_kernel(dst, from, len);
...@@ -148,12 +148,12 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count) ...@@ -148,12 +148,12 @@ int copy_oldmem_kernel(void *dst, void *src, size_t count)
return rc; return rc;
} else { } else {
/* Check for swapped kdump oldmem areas */ /* Check for swapped kdump oldmem areas */
if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) { if (oldmem_data.start && from - oldmem_data.start < oldmem_data.size) {
from -= OLDMEM_BASE; from -= oldmem_data.start;
len = min(count, OLDMEM_SIZE - from); len = min(count, oldmem_data.size - from);
} else if (OLDMEM_BASE && from < OLDMEM_SIZE) { } else if (oldmem_data.start && from < oldmem_data.size) {
len = min(count, OLDMEM_SIZE - from); len = min(count, oldmem_data.size - from);
from += OLDMEM_BASE; from += oldmem_data.start;
} else { } else {
len = count; len = count;
} }
...@@ -183,7 +183,7 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count) ...@@ -183,7 +183,7 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count)
while (count) { while (count) {
from = __pa(src); 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 */ /* Copy from zfcp/nvme dump HSA area */
len = min(count, sclp.hsa_size - from); len = min(count, sclp.hsa_size - from);
rc = memcpy_hsa_user(dst, from, len); rc = memcpy_hsa_user(dst, from, len);
...@@ -191,12 +191,12 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count) ...@@ -191,12 +191,12 @@ static int copy_oldmem_user(void __user *dst, void *src, size_t count)
return rc; return rc;
} else { } else {
/* Check for swapped kdump oldmem areas */ /* Check for swapped kdump oldmem areas */
if (OLDMEM_BASE && from - OLDMEM_BASE < OLDMEM_SIZE) { if (oldmem_data.start && from - oldmem_data.size < oldmem_data.size) {
from -= OLDMEM_BASE; from -= oldmem_data.size;
len = min(count, OLDMEM_SIZE - from); len = min(count, oldmem_data.size - from);
} else if (OLDMEM_BASE && from < OLDMEM_SIZE) { } else if (oldmem_data.start && from < oldmem_data.size) {
len = min(count, OLDMEM_SIZE - from); len = min(count, oldmem_data.size - from);
from += OLDMEM_BASE; from += oldmem_data.start;
} else { } else {
len = count; len = count;
} }
...@@ -243,10 +243,10 @@ static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma, ...@@ -243,10 +243,10 @@ static int remap_oldmem_pfn_range_kdump(struct vm_area_struct *vma,
unsigned long size_old; unsigned long size_old;
int rc; int rc;
if (pfn < OLDMEM_SIZE >> PAGE_SHIFT) { if (pfn < oldmem_data.size >> PAGE_SHIFT) {
size_old = min(size, OLDMEM_SIZE - (pfn << PAGE_SHIFT)); size_old = min(size, oldmem_data.size - (pfn << PAGE_SHIFT));
rc = remap_pfn_range(vma, from, rc = remap_pfn_range(vma, from,
pfn + (OLDMEM_BASE >> PAGE_SHIFT), pfn + (oldmem_data.start >> PAGE_SHIFT),
size_old, prot); size_old, prot);
if (rc || size == size_old) if (rc || size == size_old)
return rc; return rc;
...@@ -288,7 +288,7 @@ static int remap_oldmem_pfn_range_zfcpdump(struct vm_area_struct *vma, ...@@ -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, int remap_oldmem_pfn_range(struct vm_area_struct *vma, unsigned long from,
unsigned long pfn, unsigned long size, pgprot_t prot) 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); return remap_oldmem_pfn_range_kdump(vma, from, pfn, size, prot);
else else
return remap_oldmem_pfn_range_zfcpdump(vma, from, pfn, size, 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) ...@@ -633,17 +633,17 @@ int elfcorehdr_alloc(unsigned long long *addr, unsigned long long *size)
u64 hdr_off; u64 hdr_off;
/* If we are not in kdump or zfcp/nvme dump mode return */ /* 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; return 0;
/* If we cannot get HSA size for zfcp/nvme dump return error */ /* If we cannot get HSA size for zfcp/nvme dump return error */
if (is_ipl_type_dump() && !sclp.hsa_size) if (is_ipl_type_dump() && !sclp.hsa_size)
return -ENODEV; return -ENODEV;
/* For kdump, exclude previous crashkernel memory */ /* For kdump, exclude previous crashkernel memory */
if (OLDMEM_BASE) { if (oldmem_data.start) {
oldmem_region.base = OLDMEM_BASE; oldmem_region.base = oldmem_data.start;
oldmem_region.size = OLDMEM_SIZE; oldmem_region.size = oldmem_data.size;
oldmem_type.total_size = OLDMEM_SIZE; oldmem_type.total_size = oldmem_data.size;
} }
mem_chunk_cnt = get_mem_chunk_cnt(); mem_chunk_cnt = get_mem_chunk_cnt();
......
...@@ -121,7 +121,7 @@ static void os_info_old_init(void) ...@@ -121,7 +121,7 @@ static void os_info_old_init(void)
if (os_info_init) if (os_info_init)
return; return;
if (!OLDMEM_BASE) if (!oldmem_data.start)
goto fail; goto fail;
if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr))) if (copy_oldmem_kernel(&addr, &S390_lowcore.os_info, sizeof(addr)))
goto fail; goto fail;
......
...@@ -111,6 +111,7 @@ EXPORT_SYMBOL(zlib_dfltcc_support); ...@@ -111,6 +111,7 @@ EXPORT_SYMBOL(zlib_dfltcc_support);
u64 __bootdata_preserved(stfle_fac_list[16]); u64 __bootdata_preserved(stfle_fac_list[16]);
EXPORT_SYMBOL(stfle_fac_list); EXPORT_SYMBOL(stfle_fac_list);
u64 __bootdata_preserved(alt_stfle_fac_list[16]); u64 __bootdata_preserved(alt_stfle_fac_list[16]);
struct oldmem_data __bootdata_preserved(oldmem_data);
unsigned long VMALLOC_START; unsigned long VMALLOC_START;
EXPORT_SYMBOL(VMALLOC_START); EXPORT_SYMBOL(VMALLOC_START);
...@@ -255,7 +256,7 @@ static void __init setup_zfcpdump(void) ...@@ -255,7 +256,7 @@ static void __init setup_zfcpdump(void)
{ {
if (!is_ipl_type_dump()) if (!is_ipl_type_dump())
return; return;
if (OLDMEM_BASE) if (oldmem_data.start)
return; return;
strcat(boot_command_line, " cio_ignore=all,!ipldev,!condev"); strcat(boot_command_line, " cio_ignore=all,!ipldev,!condev");
console_loglevel = 2; console_loglevel = 2;
...@@ -611,9 +612,9 @@ static void __init reserve_crashkernel(void) ...@@ -611,9 +612,9 @@ static void __init reserve_crashkernel(void)
return; return;
} }
low = crash_base ?: OLDMEM_BASE; low = crash_base ?: oldmem_data.start;
high = low + crash_size; 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 */ /* The crashkernel fits into OLDMEM, reuse OLDMEM */
crash_base = low; crash_base = low;
} else { } else {
...@@ -640,7 +641,7 @@ static void __init reserve_crashkernel(void) ...@@ -640,7 +641,7 @@ static void __init reserve_crashkernel(void)
if (register_memory_notifier(&kdump_mem_nb)) if (register_memory_notifier(&kdump_mem_nb))
return; return;
if (!OLDMEM_BASE && MACHINE_IS_VM) if (!oldmem_data.start && MACHINE_IS_VM)
diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size)); diag10_range(PFN_DOWN(crash_base), PFN_DOWN(crash_size));
crashk_res.start = crash_base; crashk_res.start = crash_base;
crashk_res.end = crash_base + crash_size - 1; crashk_res.end = crash_base + crash_size - 1;
......
...@@ -673,7 +673,7 @@ void __init smp_save_dump_cpus(void) ...@@ -673,7 +673,7 @@ void __init smp_save_dump_cpus(void)
unsigned long page; unsigned long page;
bool is_boot_cpu; 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. */ /* No previous system present, normal boot. */
return; return;
/* Allocate a page as dumping area for the store status sigps */ /* Allocate a page as dumping area for the store status sigps */
...@@ -704,7 +704,7 @@ void __init smp_save_dump_cpus(void) ...@@ -704,7 +704,7 @@ void __init smp_save_dump_cpus(void)
* these registers an SCLP request is required which is * these registers an SCLP request is required which is
* done by drivers/s390/char/zcore.c:init_cpu_info() * 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 */ /* Get the CPU registers */
smp_save_cpu_regs(sa, addr, is_boot_cpu, page); smp_save_cpu_regs(sa, addr, is_boot_cpu, page);
} }
......
...@@ -457,7 +457,7 @@ static int __init sclp_detect_standby_memory(void) ...@@ -457,7 +457,7 @@ static int __init sclp_detect_standby_memory(void)
struct read_storage_sccb *sccb; struct read_storage_sccb *sccb;
int i, id, assigned, rc; 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; return 0;
if ((sclp.facilities & 0xe00000000000ULL) != 0xe00000000000ULL) if ((sclp.facilities & 0xe00000000000ULL) != 0xe00000000000ULL)
return 0; return 0;
......
...@@ -269,7 +269,7 @@ static int __init zcore_init(void) ...@@ -269,7 +269,7 @@ static int __init zcore_init(void)
if (!is_ipl_type_dump()) if (!is_ipl_type_dump())
return -ENODATA; return -ENODATA;
if (OLDMEM_BASE) if (oldmem_data.start)
return -ENODATA; return -ENODATA;
zcore_dbf = debug_register("zcore", 4, 1, 4 * sizeof(long)); 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