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

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
Loading
Loading
Loading
Loading
+5 −2
Original line number Diff line number Diff line
@@ -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();
+1 −1
Original line number Diff line number Diff line
@@ -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())
+6 −2
Original line number Diff line number Diff line
@@ -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);
+23 −23
Original line number Diff line number Diff line
@@ -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();
+1 −1
Original line number Diff line number Diff line
@@ -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;
Loading