mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 15:41:36 +00:00
s390/boot: Do not rescue .vmlinux.relocs section
The .vmlinux.relocs section is moved in front of the compressed kernel. The interim section rescue step is avoided as result. Suggested-by: Sumanth Korikkar <sumanthk@linux.ibm.com> Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
This commit is contained in:
parent
56b1069c40
commit
236d70f82b
@ -185,26 +185,7 @@ static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
|
||||
}
|
||||
|
||||
static void kaslr_adjust_got(unsigned long offset) {}
|
||||
static void rescue_relocs(void) {}
|
||||
static void free_relocs(void) {}
|
||||
#else
|
||||
static int *vmlinux_relocs_64_start;
|
||||
static int *vmlinux_relocs_64_end;
|
||||
|
||||
static void rescue_relocs(void)
|
||||
{
|
||||
unsigned long size = __vmlinux_relocs_64_end - __vmlinux_relocs_64_start;
|
||||
|
||||
vmlinux_relocs_64_start = (void *)physmem_alloc_top_down(RR_RELOC, size, 0);
|
||||
vmlinux_relocs_64_end = (void *)vmlinux_relocs_64_start + size;
|
||||
memmove(vmlinux_relocs_64_start, __vmlinux_relocs_64_start, size);
|
||||
}
|
||||
|
||||
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, unsigned long phys_offset)
|
||||
{
|
||||
@ -212,7 +193,7 @@ static void kaslr_adjust_relocs(unsigned long min_addr, unsigned long max_addr,
|
||||
long loc;
|
||||
|
||||
/* Adjust R_390_64 relocations */
|
||||
for (reloc = vmlinux_relocs_64_start; reloc < vmlinux_relocs_64_end; reloc++) {
|
||||
for (reloc = (int *)__vmlinux_relocs_64_start; reloc < (int *)__vmlinux_relocs_64_end; reloc++) {
|
||||
loc = (long)*reloc + phys_offset;
|
||||
if (loc < min_addr || loc > max_addr)
|
||||
error("64-bit relocation outside of kernel!\n");
|
||||
@ -486,7 +467,6 @@ void startup_kernel(void)
|
||||
detect_physmem_online_ranges(max_physmem_end);
|
||||
save_ipl_cert_comp_list();
|
||||
rescue_initrd(safe_addr, ident_map_size);
|
||||
rescue_relocs();
|
||||
|
||||
if (kaslr_enabled())
|
||||
__kaslr_offset_phys = randomize_within_range(kernel_size, THREAD_SIZE, 0, ident_map_size);
|
||||
@ -498,6 +478,18 @@ void startup_kernel(void)
|
||||
|
||||
/* vmlinux decompression is done, shrink reserved low memory */
|
||||
physmem_reserve(RR_DECOMPRESSOR, 0, (unsigned long)_decompressor_end);
|
||||
|
||||
/*
|
||||
* In case KASLR is enabled the randomized location of .amode31
|
||||
* section might overlap with .vmlinux.relocs section. To avoid that
|
||||
* the below randomize_within_range() could have been called with
|
||||
* __vmlinux_relocs_64_end as the lower range address. However,
|
||||
* .amode31 section is written to by the decompressed kernel - at
|
||||
* that time the contents of .vmlinux.relocs is not needed anymore.
|
||||
* Conversly, .vmlinux.relocs is read only by the decompressor, even
|
||||
* before the kernel started. Therefore, in case the two sections
|
||||
* overlap there is no risk of corrupting any data.
|
||||
*/
|
||||
if (kaslr_enabled())
|
||||
amode31_lma = randomize_within_range(vmlinux.amode31_size, PAGE_SIZE, 0, SZ_2G);
|
||||
if (!amode31_lma)
|
||||
@ -521,7 +513,6 @@ void startup_kernel(void)
|
||||
kaslr_adjust_relocs(__kaslr_offset_phys, __kaslr_offset_phys + vmlinux.image_size,
|
||||
__kaslr_offset, __kaslr_offset_phys);
|
||||
kaslr_adjust_got(__kaslr_offset);
|
||||
free_relocs();
|
||||
setup_vmem(__kaslr_offset, __kaslr_offset + kernel_size, asce_limit);
|
||||
copy_bootdata();
|
||||
|
||||
|
@ -99,6 +99,15 @@ SECTIONS
|
||||
|
||||
_decompressor_end = .;
|
||||
|
||||
#ifndef CONFIG_PIE_BUILD
|
||||
. = ALIGN(4);
|
||||
.vmlinux.relocs : {
|
||||
__vmlinux_relocs_64_start = .;
|
||||
*(.vmlinux.relocs_64)
|
||||
__vmlinux_relocs_64_end = .;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_KERNEL_UNCOMPRESSED
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
. += AMODE31_SIZE; /* .amode31 section */
|
||||
@ -111,24 +120,6 @@ SECTIONS
|
||||
_compressed_end = .;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PIE_BUILD
|
||||
/*
|
||||
* When the kernel is built with CONFIG_KERNEL_UNCOMPRESSED, the entire
|
||||
* uncompressed vmlinux.bin is positioned in the bzImage decompressor
|
||||
* image at the default kernel LMA of 0x100000, enabling it to be
|
||||
* executed in-place. However, the size of .vmlinux.relocs could be
|
||||
* large enough to cause an overlap with the uncompressed kernel at the
|
||||
* address 0x100000. To address this issue, .vmlinux.relocs is
|
||||
* positioned after the .rodata.compressed.
|
||||
*/
|
||||
. = ALIGN(4);
|
||||
.vmlinux.relocs : {
|
||||
__vmlinux_relocs_64_start = .;
|
||||
*(.vmlinux.relocs_64)
|
||||
__vmlinux_relocs_64_end = .;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define SB_TRAILER_SIZE 32
|
||||
/* Trailer needed for Secure Boot */
|
||||
. += SB_TRAILER_SIZE; /* make sure .sb.trailer does not overwrite the previous section */
|
||||
|
@ -22,7 +22,6 @@ enum reserved_range_type {
|
||||
RR_DECOMPRESSOR,
|
||||
RR_INITRD,
|
||||
RR_VMLINUX,
|
||||
RR_RELOC,
|
||||
RR_AMODE31,
|
||||
RR_IPLREPORT,
|
||||
RR_CERT_COMP_LIST,
|
||||
|
Loading…
Reference in New Issue
Block a user