From 54372cf043276735e29045abf998895b2ac277cf Mon Sep 17 00:00:00 2001 From: Alexander Gordeev Date: Tue, 4 Jul 2023 07:46:26 +0200 Subject: [PATCH] Revert "s390/mm: get rid of VMEM_MAX_PHYS macro" This reverts commit 456be42aa713e7f83b467db66ceae779431c7d9d. The assumption VMEM_MAX_PHYS should match ident_map_size is wrong. At least discontiguous saved segments (DCSS) could be loaded at addresses beyond ident_map_size and dcssblk device driver might fail as result. Reported-by: Gerald Schaefer Signed-off-by: Alexander Gordeev --- arch/s390/boot/startup.c | 1 + arch/s390/include/asm/pgtable.h | 2 ++ arch/s390/mm/extmem.c | 2 +- arch/s390/mm/vmem.c | 2 +- drivers/s390/char/sclp_cmd.c | 6 +++--- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c index de264a2..64bd7ac 100644 --- a/arch/s390/boot/startup.c +++ b/arch/s390/boot/startup.c @@ -220,6 +220,7 @@ static unsigned long setup_kernel_memory_layout(void) pages = SECTION_ALIGN_UP(pages); /* keep vmemmap_start aligned to a top level region table entry */ vmemmap_start = round_down(VMALLOC_START - pages * sizeof(struct page), rte_size); + /* vmemmap_start is the future VMEM_MAX_PHYS, make sure it is within MAX_PHYSMEM */ vmemmap_start = min(vmemmap_start, 1UL << MAX_PHYSMEM_BITS); /* make sure identity map doesn't overlay with vmemmap */ ident_map_size = min(ident_map_size, vmemmap_start); diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h index 30909fe..c55f3c3 100644 --- a/arch/s390/include/asm/pgtable.h +++ b/arch/s390/include/asm/pgtable.h @@ -89,6 +89,8 @@ extern unsigned long __bootdata_preserved(VMALLOC_END); extern struct page *__bootdata_preserved(vmemmap); extern unsigned long __bootdata_preserved(vmemmap_size); +#define VMEM_MAX_PHYS ((unsigned long) vmemmap) + extern unsigned long __bootdata_preserved(MODULES_VADDR); extern unsigned long __bootdata_preserved(MODULES_END); #define MODULES_VADDR MODULES_VADDR diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c index f4d3719..1bc42ce 100644 --- a/arch/s390/mm/extmem.c +++ b/arch/s390/mm/extmem.c @@ -642,7 +642,7 @@ void segment_warning(int rc, char *seg_name) break; case -ERANGE: pr_err("DCSS %s exceeds the kernel mapping range (%lu) " - "and cannot be loaded\n", seg_name, ident_map_size); + "and cannot be loaded\n", seg_name, VMEM_MAX_PHYS); break; default: break; diff --git a/arch/s390/mm/vmem.c b/arch/s390/mm/vmem.c index 9db048c..b266492 100644 --- a/arch/s390/mm/vmem.c +++ b/arch/s390/mm/vmem.c @@ -531,7 +531,7 @@ struct range arch_get_mappable_range(void) struct range mhp_range; mhp_range.start = 0; - mhp_range.end = ident_map_size - 1; + mhp_range.end = VMEM_MAX_PHYS - 1; return mhp_range; } diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c index 594b34c..3c87057 100644 --- a/drivers/s390/char/sclp_cmd.c +++ b/drivers/s390/char/sclp_cmd.c @@ -392,10 +392,10 @@ static void __init add_memory_merged(u16 rn) goto skip_add; start = rn2addr(first_rn); size = (unsigned long long) num * sclp.rzm; - if (start >= ident_map_size) + if (start >= VMEM_MAX_PHYS) goto skip_add; - if (start + size > ident_map_size) - size = ident_map_size - start; + if (start + size > VMEM_MAX_PHYS) + size = VMEM_MAX_PHYS - start; if (start >= ident_map_size) goto skip_add; if (start + size > ident_map_size) -- 2.7.4