1
linux/arch/s390/boot/vmlinux.lds.S
Alexander Gordeev 1642285e51 s390/boot: Fix KASLR base offset off by __START_KERNEL bytes
Symbol offsets to the KASLR base do not match symbol address in
the vmlinux image. That is the result of setting the KASLR base
to the beginning of .text section as result of an optimization.

Revert that optimization and allocate virtual memory for the
whole kernel image including __START_KERNEL bytes as per the
linker script. That allows keeping the semantics of the KASLR
base offset in sync with other architectures.

Rename __START_KERNEL to TEXT_OFFSET, since it represents the
offset of the .text section within the kernel image, rather than
a virtual address.

Still skip mapping TEXT_OFFSET bytes to save memory on pgtables
and provoke exceptions in case an attempt to access this area is
made, as no kernel symbol may reside there.

In case CONFIG_KASAN is enabled the location counter might exceed
the value of TEXT_OFFSET, while the decompressor linker script
forcefully resets it to TEXT_OFFSET, which leads to a sections
overlap link failure. Use MAX() expression to avoid that.

Reported-by: Omar Sandoval <osandov@osandov.com>
Closes: https://lore.kernel.org/linux-s390/ZnS8dycxhtXBZVky@telecaster.dhcp.thefacebook.com/
Fixes: 56b1069c40 ("s390/boot: Rework deployment of the kernel image")
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
Acked-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
2024-08-22 19:24:13 +02:00

173 lines
3.3 KiB
ArmAsm

/* SPDX-License-Identifier: GPL-2.0 */
#include <asm-generic/vmlinux.lds.h>
#include <asm/vmlinux.lds.h>
#include <asm/thread_info.h>
#include <asm/page.h>
#include <asm/sclp.h>
#include "boot.h"
OUTPUT_FORMAT("elf64-s390", "elf64-s390", "elf64-s390")
OUTPUT_ARCH(s390:64-bit)
ENTRY(startup)
SECTIONS
{
. = 0;
.ipldata : {
*(.ipldata)
}
. = IPL_START;
.head.text : {
_head = . ;
HEAD_TEXT
_ehead = . ;
}
. = PARMAREA;
.parmarea : {
*(.parmarea)
}
.text : {
_text = .; /* Text */
*(.text)
*(.text.*)
INIT_TEXT
_etext = . ;
}
.rodata : {
_rodata = . ;
*(.rodata) /* read-only data */
*(.rodata.*)
_erodata = . ;
}
.got : {
*(.got)
}
NOTES
.data : {
_data = . ;
*(.data)
*(.data.*)
_edata = . ;
}
BOOT_DATA
BOOT_DATA_PRESERVED
/*
* This is the BSS section of the decompressor and not of the decompressed Linux kernel.
* It will consume place in the decompressor's image.
*/
. = ALIGN(8);
.bss : {
_bss = . ;
*(.bss)
*(.bss.*)
*(COMMON)
/*
* Stacks for the decompressor
*/
. = ALIGN(PAGE_SIZE);
_dump_info_stack_start = .;
. += PAGE_SIZE;
_dump_info_stack_end = .;
. = ALIGN(PAGE_SIZE);
_stack_start = .;
. += BOOT_STACK_SIZE;
_stack_end = .;
_ebss = .;
}
/*
* uncompressed image info used by the decompressor it should match
* struct vmlinux_info. It comes from .vmlinux.info section of
* uncompressed vmlinux in a form of info.o
*/
. = ALIGN(8);
.vmlinux.info : {
_vmlinux_info = .;
*(.vmlinux.info)
}
.decompressor.syms : {
. += 1; /* make sure we have \0 before the first entry */
. = ALIGN(2);
_decompressor_syms_start = .;
*(.decompressor.syms)
_decompressor_syms_end = .;
}
_decompressor_end = .;
. = ALIGN(4);
.vmlinux.relocs : {
__vmlinux_relocs_64_start = .;
*(.vmlinux.relocs_64)
__vmlinux_relocs_64_end = .;
}
#ifdef CONFIG_KERNEL_UNCOMPRESSED
. = ALIGN(PAGE_SIZE);
. += AMODE31_SIZE; /* .amode31 section */
/*
* Make sure the location counter is not less than TEXT_OFFSET.
* _SEGMENT_SIZE is not available, use ALIGN(1 << 20) instead.
*/
. = MAX(TEXT_OFFSET, ALIGN(1 << 20));
#else
. = ALIGN(8);
#endif
.rodata.compressed : {
_compressed_start = .;
*(.vmlinux.bin.compressed)
_compressed_end = .;
}
#define SB_TRAILER_SIZE 32
/* Trailer needed for Secure Boot */
. += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
. = ALIGN(4096) - SB_TRAILER_SIZE;
.sb.trailer : {
QUAD(0)
QUAD(0)
QUAD(0)
QUAD(0x000000207a49504c)
}
_end = .;
DWARF_DEBUG
ELF_DETAILS
/*
* Make sure that the .got.plt is either completely empty or it
* contains only the three reserved double words.
*/
.got.plt : {
*(.got.plt)
}
ASSERT(SIZEOF(.got.plt) == 0 || SIZEOF(.got.plt) == 0x18, "Unexpected GOT/PLT entries detected!")
/*
* Sections that should stay zero sized, which is safer to
* explicitly check instead of blindly discarding.
*/
.plt : {
*(.plt) *(.plt.*) *(.iplt) *(.igot .igot.plt)
}
ASSERT(SIZEOF(.plt) == 0, "Unexpected run-time procedure linkages detected!")
.rela.dyn : {
*(.rela.*) *(.rela_*)
}
ASSERT(SIZEOF(.rela.dyn) == 0, "Unexpected run-time relocations (.rela) detected!")
/* Sections to be discarded */
/DISCARD/ : {
COMMON_DISCARDS
*(.eh_frame)
*(__ex_table)
*(*__ksymtab*)
*(___kcrctab*)
}
}