s390/boot: allocate amode31 section in decompressor
The memory for amode31 section is allocated from the decompressed kernel. Instead, allocate that memory from the decompressor. This is a prerequisite to allow initialization of the virtual memory before the decompressed kernel takes over. Reviewed-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
Родитель
584315ed87
Коммит
e3ec8e0f57
|
@ -24,6 +24,7 @@ struct vmlinux_info {
|
||||||
unsigned long dynsym_start;
|
unsigned long dynsym_start;
|
||||||
unsigned long rela_dyn_start;
|
unsigned long rela_dyn_start;
|
||||||
unsigned long rela_dyn_end;
|
unsigned long rela_dyn_end;
|
||||||
|
unsigned long amode31_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Symbols defined by linker scripts */
|
/* Symbols defined by linker scripts */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "uv.h"
|
#include "uv.h"
|
||||||
|
|
||||||
unsigned long __bootdata_preserved(__kaslr_offset);
|
unsigned long __bootdata_preserved(__kaslr_offset);
|
||||||
|
unsigned long __bootdata(__amode31_base);
|
||||||
unsigned long __bootdata_preserved(VMALLOC_START);
|
unsigned long __bootdata_preserved(VMALLOC_START);
|
||||||
unsigned long __bootdata_preserved(VMALLOC_END);
|
unsigned long __bootdata_preserved(VMALLOC_END);
|
||||||
struct page *__bootdata_preserved(vmemmap);
|
struct page *__bootdata_preserved(vmemmap);
|
||||||
|
@ -259,6 +260,12 @@ static void offset_vmlinux_info(unsigned long offset)
|
||||||
vmlinux.dynsym_start += offset;
|
vmlinux.dynsym_start += offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned long reserve_amode31(unsigned long safe_addr)
|
||||||
|
{
|
||||||
|
__amode31_base = PAGE_ALIGN(safe_addr);
|
||||||
|
return safe_addr + vmlinux.amode31_size;
|
||||||
|
}
|
||||||
|
|
||||||
void startup_kernel(void)
|
void startup_kernel(void)
|
||||||
{
|
{
|
||||||
unsigned long random_lma;
|
unsigned long random_lma;
|
||||||
|
@ -273,6 +280,7 @@ void startup_kernel(void)
|
||||||
setup_lpp();
|
setup_lpp();
|
||||||
store_ipl_parmblock();
|
store_ipl_parmblock();
|
||||||
safe_addr = mem_safe_offset();
|
safe_addr = mem_safe_offset();
|
||||||
|
safe_addr = reserve_amode31(safe_addr);
|
||||||
safe_addr = read_ipl_report(safe_addr);
|
safe_addr = read_ipl_report(safe_addr);
|
||||||
uv_query_info();
|
uv_query_info();
|
||||||
rescue_initrd(safe_addr);
|
rescue_initrd(safe_addr);
|
||||||
|
|
|
@ -70,5 +70,6 @@ extern struct exception_table_entry _stop_amode31_ex_table[];
|
||||||
#define __amode31_data __section(".amode31.data")
|
#define __amode31_data __section(".amode31.data")
|
||||||
#define __amode31_ref __section(".amode31.refs")
|
#define __amode31_ref __section(".amode31.refs")
|
||||||
extern long _start_amode31_refs[], _end_amode31_refs[];
|
extern long _start_amode31_refs[], _end_amode31_refs[];
|
||||||
|
extern unsigned long __amode31_base;
|
||||||
|
|
||||||
#endif /* _ENTRY_H */
|
#endif /* _ENTRY_H */
|
||||||
|
|
|
@ -95,10 +95,10 @@ EXPORT_SYMBOL(console_irq);
|
||||||
* relocated above 2 GB, because it has to use 31 bit addresses.
|
* relocated above 2 GB, because it has to use 31 bit addresses.
|
||||||
* Such code and data is part of the .amode31 section.
|
* Such code and data is part of the .amode31 section.
|
||||||
*/
|
*/
|
||||||
unsigned long __amode31_ref __samode31 = __pa(&_samode31);
|
unsigned long __amode31_ref __samode31 = (unsigned long)&_samode31;
|
||||||
unsigned long __amode31_ref __eamode31 = __pa(&_eamode31);
|
unsigned long __amode31_ref __eamode31 = (unsigned long)&_eamode31;
|
||||||
unsigned long __amode31_ref __stext_amode31 = __pa(&_stext_amode31);
|
unsigned long __amode31_ref __stext_amode31 = (unsigned long)&_stext_amode31;
|
||||||
unsigned long __amode31_ref __etext_amode31 = __pa(&_etext_amode31);
|
unsigned long __amode31_ref __etext_amode31 = (unsigned long)&_etext_amode31;
|
||||||
struct exception_table_entry __amode31_ref *__start_amode31_ex_table = _start_amode31_ex_table;
|
struct exception_table_entry __amode31_ref *__start_amode31_ex_table = _start_amode31_ex_table;
|
||||||
struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amode31_ex_table;
|
struct exception_table_entry __amode31_ref *__stop_amode31_ex_table = _stop_amode31_ex_table;
|
||||||
|
|
||||||
|
@ -149,6 +149,7 @@ struct mem_detect_info __bootdata(mem_detect);
|
||||||
struct initrd_data __bootdata(initrd_data);
|
struct initrd_data __bootdata(initrd_data);
|
||||||
|
|
||||||
unsigned long __bootdata_preserved(__kaslr_offset);
|
unsigned long __bootdata_preserved(__kaslr_offset);
|
||||||
|
unsigned long __bootdata(__amode31_base);
|
||||||
unsigned int __bootdata_preserved(zlib_dfltcc_support);
|
unsigned int __bootdata_preserved(zlib_dfltcc_support);
|
||||||
EXPORT_SYMBOL(zlib_dfltcc_support);
|
EXPORT_SYMBOL(zlib_dfltcc_support);
|
||||||
u64 __bootdata_preserved(stfle_fac_list[16]);
|
u64 __bootdata_preserved(stfle_fac_list[16]);
|
||||||
|
@ -808,6 +809,7 @@ static void __init reserve_kernel(void)
|
||||||
|
|
||||||
memblock_reserve(0, STARTUP_NORMAL_OFFSET);
|
memblock_reserve(0, STARTUP_NORMAL_OFFSET);
|
||||||
memblock_reserve((unsigned long)sclp_early_sccb, EXT_SCCB_READ_SCP);
|
memblock_reserve((unsigned long)sclp_early_sccb, EXT_SCCB_READ_SCP);
|
||||||
|
memblock_reserve(__amode31_base, __eamode31 - __samode31);
|
||||||
memblock_reserve((unsigned long)_stext, PFN_PHYS(start_pfn)
|
memblock_reserve((unsigned long)_stext, PFN_PHYS(start_pfn)
|
||||||
- (unsigned long)_stext);
|
- (unsigned long)_stext);
|
||||||
}
|
}
|
||||||
|
@ -831,20 +833,14 @@ static void __init setup_memory(void)
|
||||||
|
|
||||||
static void __init relocate_amode31_section(void)
|
static void __init relocate_amode31_section(void)
|
||||||
{
|
{
|
||||||
unsigned long amode31_addr, amode31_size;
|
unsigned long amode31_size = __eamode31 - __samode31;
|
||||||
long amode31_offset;
|
long amode31_offset = __amode31_base - __samode31;
|
||||||
long *ptr;
|
long *ptr;
|
||||||
|
|
||||||
/* Allocate a new AMODE31 capable memory region */
|
|
||||||
amode31_size = __eamode31 - __samode31;
|
|
||||||
pr_info("Relocating AMODE31 section of size 0x%08lx\n", amode31_size);
|
pr_info("Relocating AMODE31 section of size 0x%08lx\n", amode31_size);
|
||||||
amode31_addr = (unsigned long)memblock_alloc_low(amode31_size, PAGE_SIZE);
|
|
||||||
if (!amode31_addr)
|
|
||||||
panic("Failed to allocate memory for AMODE31 section\n");
|
|
||||||
amode31_offset = amode31_addr - __samode31;
|
|
||||||
|
|
||||||
/* Move original AMODE31 section to the new one */
|
/* Move original AMODE31 section to the new one */
|
||||||
memmove((void *)amode31_addr, (void *)__samode31, amode31_size);
|
memmove((void *)__amode31_base, (void *)__samode31, amode31_size);
|
||||||
/* Zero out the old AMODE31 section to catch invalid accesses within it */
|
/* Zero out the old AMODE31 section to catch invalid accesses within it */
|
||||||
memset((void *)__samode31, 0, amode31_size);
|
memset((void *)__samode31, 0, amode31_size);
|
||||||
|
|
||||||
|
|
|
@ -212,6 +212,7 @@ SECTIONS
|
||||||
QUAD(__dynsym_start) /* dynsym_start */
|
QUAD(__dynsym_start) /* dynsym_start */
|
||||||
QUAD(__rela_dyn_start) /* rela_dyn_start */
|
QUAD(__rela_dyn_start) /* rela_dyn_start */
|
||||||
QUAD(__rela_dyn_end) /* rela_dyn_end */
|
QUAD(__rela_dyn_end) /* rela_dyn_end */
|
||||||
|
QUAD(_eamode31 - _samode31) /* amode31_size */
|
||||||
} :NONE
|
} :NONE
|
||||||
|
|
||||||
/* Debugging sections. */
|
/* Debugging sections. */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче