summaryrefslogtreecommitdiffstats
path: root/arch/s390/boot
diff options
context:
space:
mode:
authorAlexander Gordeev <agordeev@linux.ibm.com>2024-02-20 14:35:43 +0100
committerAlexander Gordeev <agordeev@linux.ibm.com>2024-04-17 13:38:00 +0200
commit3bb11234b1d17236ba479f7d0eaa9bd12f2f2493 (patch)
treea76dd92c8cb47191c870dc35529c9be12ddb212b /arch/s390/boot
parent236f324b747370b97030c9582591f459353e3589 (diff)
downloadlinux-stable-3bb11234b1d17236ba479f7d0eaa9bd12f2f2493.tar.gz
linux-stable-3bb11234b1d17236ba479f7d0eaa9bd12f2f2493.tar.bz2
linux-stable-3bb11234b1d17236ba479f7d0eaa9bd12f2f2493.zip
s390/boot: Uncouple virtual and physical kernel offsets
This is a preparatory rework to allow uncoupling virtual and physical addresses spaces. Currently __kaslr_offset is the kernel offset in both physical memory on boot and in virtual memory after DAT mode is enabled. Uncouple these offsets and rename the physical address space variant to __kaslr_offset_phys while keep the name __kaslr_offset for the offset in virtual address space. Do not use __kaslr_offset_phys after DAT mode is enabled just yet, but still make it a persistent boot variable for later use. Use __kaslr_offset and __kaslr_offset_phys offsets in proper contexts and alter handle_relocs() function to distinguish between the two. Acked-by: Heiko Carstens <hca@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Diffstat (limited to 'arch/s390/boot')
-rw-r--r--arch/s390/boot/pgm_check_info.c4
-rw-r--r--arch/s390/boot/startup.c20
2 files changed, 15 insertions, 9 deletions
diff --git a/arch/s390/boot/pgm_check_info.c b/arch/s390/boot/pgm_check_info.c
index 97244cd7a206..ea96275b0380 100644
--- a/arch/s390/boot/pgm_check_info.c
+++ b/arch/s390/boot/pgm_check_info.c
@@ -153,8 +153,10 @@ void print_pgm_check_info(void)
decompressor_printk("Kernel command line: %s\n", early_command_line);
decompressor_printk("Kernel fault: interruption code %04x ilc:%x\n",
S390_lowcore.pgm_code, S390_lowcore.pgm_ilc >> 1);
- if (kaslr_enabled())
+ if (kaslr_enabled()) {
decompressor_printk("Kernel random base: %lx\n", __kaslr_offset);
+ decompressor_printk("Kernel random base phys: %lx\n", __kaslr_offset_phys);
+ }
decompressor_printk("PSW : %016lx %016lx (%pS)\n",
S390_lowcore.psw_save_area.mask,
S390_lowcore.psw_save_area.addr,
diff --git a/arch/s390/boot/startup.c b/arch/s390/boot/startup.c
index 8afb232d7c96..44ef08518f37 100644
--- a/arch/s390/boot/startup.c
+++ b/arch/s390/boot/startup.c
@@ -142,7 +142,8 @@ static void copy_bootdata(void)
}
#ifdef CONFIG_PIE_BUILD
-static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
+static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
+ unsigned long offset, unsigned long phys_offset)
{
Elf64_Rela *rela_start, *rela_end, *rela;
int r_type, r_sym, rc;
@@ -153,7 +154,7 @@ static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
rela_end = (Elf64_Rela *) vmlinux.rela_dyn_end;
dynsym = (Elf64_Sym *) vmlinux.dynsym_start;
for (rela = rela_start; rela < rela_end; rela++) {
- loc = rela->r_offset + offset;
+ loc = rela->r_offset + phys_offset;
val = rela->r_addend;
r_sym = ELF64_R_SYM(rela->r_info);
if (r_sym) {
@@ -194,7 +195,8 @@ static void free_relocs(void)
physmem_free(RR_RELOC);
}
-static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr, unsigned long offset)
+static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
+ unsigned long offset, unsigned long phys_offset)
{
int *reloc;
long loc;
@@ -428,8 +430,9 @@ void startup_kernel(void)
THREAD_SIZE, vmlinux.default_lma,
ident_map_size);
if (vmlinux_lma) {
- __kaslr_offset = vmlinux_lma - vmlinux.default_lma;
- kaslr_adjust_vmlinux_info(__kaslr_offset);
+ __kaslr_offset_phys = vmlinux_lma - vmlinux.default_lma;
+ kaslr_adjust_vmlinux_info(__kaslr_offset_phys);
+ __kaslr_offset = __kaslr_offset_phys;
}
}
vmlinux_lma = vmlinux_lma ?: vmlinux.default_lma;
@@ -438,7 +441,7 @@ void startup_kernel(void)
if (!IS_ENABLED(CONFIG_KERNEL_UNCOMPRESSED)) {
img = decompress_kernel();
memmove((void *)vmlinux_lma, img, vmlinux.image_size);
- } else if (__kaslr_offset) {
+ } else if (__kaslr_offset_phys) {
img = (void *)vmlinux.default_lma;
memmove((void *)vmlinux_lma, img, vmlinux.image_size);
memset(img, 0, vmlinux.image_size);
@@ -465,7 +468,8 @@ void startup_kernel(void)
* to bootdata made by setup_vmem()
*/
clear_bss_section(vmlinux_lma);
- kaslr_adjust_relocs(vmlinux_lma, vmlinux_lma + vmlinux.image_size, __kaslr_offset);
+ kaslr_adjust_relocs(vmlinux_lma, vmlinux_lma + vmlinux.image_size,
+ __kaslr_offset, __kaslr_offset_phys);
kaslr_adjust_got(__kaslr_offset);
free_relocs();
setup_vmem(asce_limit);
@@ -475,7 +479,7 @@ void startup_kernel(void)
* Save KASLR offset for early dumps, before vmcore_info is set.
* Mark as uneven to distinguish from real vmcore_info pointer.
*/
- S390_lowcore.vmcore_info = __kaslr_offset ? __kaslr_offset | 0x1UL : 0;
+ S390_lowcore.vmcore_info = __kaslr_offset_phys ? __kaslr_offset_phys | 0x1UL : 0;
/*
* Jump to the decompressed kernel entry point and switch DAT mode on.