s390/boot: introduce boot data 'initrd_data'

The new boot data struct shall replace global variables INITRD_START and
INITRD_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: Alexander Egorenkov <egorenar@linux.ibm.com>
Acked-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
This commit is contained in:
Alexander Egorenkov 2021-06-15 14:15:07 +02:00 committed by Heiko Carstens
parent f1d3c53237
commit 84733284f6
7 changed files with 32 additions and 23 deletions

View file

@ -54,9 +54,9 @@ static unsigned long find_bootdata_space(struct ipl_rb_components *comps,
* not overlap with any component or any certificate.
*/
repeat:
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE &&
intersects(INITRD_START, INITRD_SIZE, safe_addr, size))
safe_addr = INITRD_START + INITRD_SIZE;
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && initrd_data.start && initrd_data.size &&
intersects(initrd_data.start, initrd_data.size, safe_addr, size))
safe_addr = initrd_data.start + initrd_data.size;
for_each_rb_entry(comp, comps)
if (intersects(safe_addr, size, comp->addr, comp->len)) {
safe_addr = comp->addr + comp->len;

View file

@ -186,9 +186,9 @@ unsigned long get_random_base(unsigned long safe_addr)
*/
memory_limit -= kasan_estimate_memory_needs(memory_limit);
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE) {
if (safe_addr < INITRD_START + INITRD_SIZE)
safe_addr = INITRD_START + INITRD_SIZE;
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && initrd_data.start && initrd_data.size) {
if (safe_addr < initrd_data.start + initrd_data.size)
safe_addr = initrd_data.start + initrd_data.size;
}
safe_addr = ALIGN(safe_addr, THREAD_SIZE);

View file

@ -26,9 +26,9 @@ static void *mem_detect_alloc_extended(void)
{
unsigned long offset = ALIGN(mem_safe_offset(), sizeof(u64));
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && INITRD_START && INITRD_SIZE &&
INITRD_START < offset + ENTRIES_EXTENDED_MAX)
offset = ALIGN(INITRD_START + INITRD_SIZE, sizeof(u64));
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD) && initrd_data.start && initrd_data.size &&
initrd_data.start < offset + ENTRIES_EXTENDED_MAX)
offset = ALIGN(initrd_data.start + initrd_data.size, sizeof(u64));
return (void *)offset;
}

View file

@ -23,6 +23,7 @@ unsigned long __bootdata_preserved(MODULES_VADDR);
unsigned long __bootdata_preserved(MODULES_END);
unsigned long __bootdata(ident_map_size);
int __bootdata(is_full_image) = 1;
struct initrd_data __bootdata(initrd_data);
u64 __bootdata_preserved(stfle_fac_list[16]);
u64 __bootdata_preserved(alt_stfle_fac_list[16]);
@ -86,12 +87,12 @@ static void rescue_initrd(unsigned long addr)
{
if (!IS_ENABLED(CONFIG_BLK_DEV_INITRD))
return;
if (!INITRD_START || !INITRD_SIZE)
if (!initrd_data.start || !initrd_data.size)
return;
if (addr <= INITRD_START)
if (addr <= initrd_data.start)
return;
memmove((void *)addr, (void *)INITRD_START, INITRD_SIZE);
INITRD_START = addr;
memmove((void *)addr, (void *)initrd_data.start, initrd_data.size);
initrd_data.start = addr;
}
static void copy_bootdata(void)
@ -283,6 +284,9 @@ void startup_kernel(void)
unsigned long safe_addr;
void *img;
initrd_data.start = parmarea.initrd_start;
initrd_data.size = parmarea.initrd_size;
setup_lpp();
store_ipl_parmblock();
safe_addr = mem_safe_offset();

View file

@ -60,8 +60,6 @@
#include <asm/types.h>
#define IPL_DEVICE (*(unsigned long *) (IPL_DEVICE_OFFSET))
#define INITRD_START (*(unsigned long *) (INITRD_START_OFFSET))
#define INITRD_SIZE (*(unsigned long *) (INITRD_SIZE_OFFSET))
#define OLDMEM_BASE (*(unsigned long *) (OLDMEM_BASE_OFFSET))
#define OLDMEM_SIZE (*(unsigned long *) (OLDMEM_SIZE_OFFSET))
#define COMMAND_LINE ((char *) (COMMAND_LINE_OFFSET))
@ -160,6 +158,12 @@ static inline unsigned long kaslr_offset(void)
extern int is_full_image;
struct initrd_data {
unsigned long start;
unsigned long size;
};
extern struct initrd_data initrd_data;
static inline u32 gen_lpswe(unsigned long addr)
{
BUILD_BUG_ON(addr > 0xfff);

View file

@ -97,6 +97,7 @@ unsigned long int_hwcap = 0;
int __bootdata(noexec_disabled);
unsigned long __bootdata(ident_map_size);
struct mem_detect_info __bootdata(mem_detect);
struct initrd_data __bootdata(initrd_data);
struct exception_table_entry *__bootdata_preserved(__start_dma_ex_table);
struct exception_table_entry *__bootdata_preserved(__stop_dma_ex_table);
@ -658,11 +659,11 @@ static void __init reserve_crashkernel(void)
static void __init reserve_initrd(void)
{
#ifdef CONFIG_BLK_DEV_INITRD
if (!INITRD_START || !INITRD_SIZE)
if (!initrd_data.start || !initrd_data.size)
return;
initrd_start = INITRD_START;
initrd_end = initrd_start + INITRD_SIZE;
memblock_reserve(INITRD_START, INITRD_SIZE);
initrd_start = initrd_data.start;
initrd_end = initrd_start + initrd_data.size;
memblock_reserve(initrd_data.start, initrd_data.size);
#endif
}
@ -732,10 +733,10 @@ static void __init memblock_add_mem_detect_info(void)
static void __init check_initrd(void)
{
#ifdef CONFIG_BLK_DEV_INITRD
if (INITRD_START && INITRD_SIZE &&
!memblock_is_region_memory(INITRD_START, INITRD_SIZE)) {
if (initrd_data.start && initrd_data.size &&
!memblock_is_region_memory(initrd_data.start, initrd_data.size)) {
pr_err("The initial RAM disk does not fit into the memory\n");
memblock_free(INITRD_START, INITRD_SIZE);
memblock_free(initrd_data.start, initrd_data.size);
initrd_start = initrd_end = 0;
}
#endif

View file

@ -300,7 +300,7 @@ void __init kasan_early_init(void)
pgalloc_low = round_up((unsigned long)_end, _SEGMENT_SIZE);
if (IS_ENABLED(CONFIG_BLK_DEV_INITRD)) {
initrd_end =
round_up(INITRD_START + INITRD_SIZE, _SEGMENT_SIZE);
round_up(initrd_data.start + initrd_data.size, _SEGMENT_SIZE);
pgalloc_low = max(pgalloc_low, initrd_end);
}