Commit af073526 authored by Vasily Gorbik's avatar Vasily Gorbik Committed by Heiko Carstens
Browse files

s390/mem_detect: do not truncate online memory ranges info



Commit bf64f051 ("s390/mem_detect: handle online memory limit
just once") introduced truncation of mem_detect online ranges
based on identity mapping size. For kdump case however the full
set of online memory ranges has to be feed into memblock_physmem_add
so that crashed system memory could be extracted.

Instead of truncating introduce a "usable limit" which is respected by
mem_detect api. Also add extra online memory ranges iterator which still
provides full set of online memory ranges disregarding the "usable limit".

Fixes: bf64f051 ("s390/mem_detect: handle online memory limit just once")
Reported-by: default avatarAlexander Egorenkov <egorenar@linux.ibm.com>
Tested-by: default avatarAlexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
parent 55d169c8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ struct vmlinux_info {

void startup_kernel(void);
unsigned long detect_memory(unsigned long *safe_addr);
void mem_detect_truncate(unsigned long limit);
void mem_detect_set_usable_limit(unsigned long limit);
bool is_ipl_block_dump(void);
void store_ipl_parmblock(void);
unsigned long read_ipl_report(unsigned long safe_addr);
+5 −5
Original line number Diff line number Diff line
@@ -132,7 +132,7 @@ static unsigned long count_valid_kernel_positions(unsigned long kernel_size,
	unsigned long start, end, pos = 0;
	int i;

	for_each_mem_detect_block(i, &start, &end) {
	for_each_mem_detect_usable_block(i, &start, &end) {
		if (_min >= end)
			continue;
		if (start >= _max)
@@ -153,7 +153,7 @@ static unsigned long position_to_address(unsigned long pos, unsigned long kernel
	unsigned long start, end;
	int i;

	for_each_mem_detect_block(i, &start, &end) {
	for_each_mem_detect_usable_block(i, &start, &end) {
		if (_min >= end)
			continue;
		if (start >= _max)
@@ -172,7 +172,7 @@ static unsigned long position_to_address(unsigned long pos, unsigned long kernel

unsigned long get_random_base(unsigned long safe_addr)
{
	unsigned long online_mem_total = get_mem_detect_online_total();
	unsigned long usable_total = get_mem_detect_usable_total();
	unsigned long memory_limit = get_mem_detect_end();
	unsigned long base_pos, max_pos, kernel_size;
	int i;
@@ -182,8 +182,8 @@ unsigned long get_random_base(unsigned long safe_addr)
	 * which vmem and kasan code will use for shadow memory and
	 * pgtable mapping allocations.
	 */
	memory_limit -= kasan_estimate_memory_needs(online_mem_total);
	memory_limit -= vmem_estimate_memory_needs(online_mem_total);
	memory_limit -= kasan_estimate_memory_needs(usable_total);
	memory_limit -= vmem_estimate_memory_needs(usable_total);

	safe_addr = ALIGN(safe_addr, THREAD_SIZE);
	kernel_size = vmlinux.image_size + vmlinux.bss_size;
+6 −6
Original line number Diff line number Diff line
@@ -172,20 +172,20 @@ unsigned long detect_memory(unsigned long *safe_addr)
	return max_physmem_end;
}

void mem_detect_truncate(unsigned long limit)
void mem_detect_set_usable_limit(unsigned long limit)
{
	struct mem_detect_block *block;
	int i;

	/* make sure mem_detect.usable ends up within online memory block */
	for (i = 0; i < mem_detect.count; i++) {
		block = __get_mem_detect_block_ptr(i);
		if (block->start >= limit) {
			mem_detect.count = i;
		if (block->start >= limit)
			break;
		} else if (block->end > limit) {
			block->end = (u64)limit;
			mem_detect.count = i + 1;
		if (block->end >= limit) {
			mem_detect.usable = limit;
			break;
		}
		mem_detect.usable = block->end;
	}
}
+1 −1
Original line number Diff line number Diff line
@@ -304,7 +304,7 @@ void startup_kernel(void)
	setup_ident_map_size(max_physmem_end);
	setup_vmalloc_size();
	asce_limit = setup_kernel_memory_layout();
	mem_detect_truncate(ident_map_size);
	mem_detect_set_usable_limit(ident_map_size);

	if (IS_ENABLED(CONFIG_RANDOMIZE_BASE) && kaslr_enabled) {
		random_lma = get_random_base(safe_addr);
+1 −1
Original line number Diff line number Diff line
@@ -252,7 +252,7 @@ void setup_vmem(unsigned long asce_limit)
	 */
	pgtable_populate_init();
	pgtable_populate(0, sizeof(struct lowcore), POPULATE_ONE2ONE);
	for_each_mem_detect_block(i, &start, &end)
	for_each_mem_detect_usable_block(i, &start, &end)
		pgtable_populate(start, end, POPULATE_ONE2ONE);
	pgtable_populate(__abs_lowcore, __abs_lowcore + sizeof(struct lowcore),
			 POPULATE_ABS_LOWCORE);
Loading