Skip to content

Commit e916035

Browse files
author
Ard Biesheuvel
committed
arm64: cover the .head.text section in the .text segment mapping
Keeping .head.text out of the .text mapping buys us very little: its actual payload is only 4 KB, most of which is padding, but the page alignment may add up to 2 MB (in case of CONFIG_DEBUG_ALIGN_RODATA=y) of additional padding to the uncompressed kernel Image. Also, on 4 KB granule kernels, the 4 KB misalignment of .text forces us to map the adjacent 56 KB of code without the PTE_CONT attribute, and since this region contains things like the vector table and the GIC interrupt handling entry point, this region is likely to benefit from the reduced TLB pressure that results from PTE_CONT mappings. So remove the alignment between the .head.text and .text sections, and use the [_text, _etext) rather than the [_stext, _etext) interval for mapping the .text segment. Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Will Deacon <will.deacon@arm.com> (cherry picked from commit 7eb90f2ff7e3ee814ff12f3cd909b965cdd4a869) Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
1 parent 4ffdbe3 commit e916035

2 files changed

Lines changed: 5 additions & 6 deletions

File tree

arch/arm64/kernel/vmlinux.lds.S

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ SECTIONS
9696
_text = .;
9797
HEAD_TEXT
9898
}
99-
ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
10099
.text : { /* Real text segment */
101100
_stext = .; /* Text and read-only data */
102101
__exception_text_start = .;

arch/arm64/mm/mmu.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ static void create_mapping_late(phys_addr_t phys, unsigned long virt,
385385

386386
static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end)
387387
{
388-
unsigned long kernel_start = __pa(_stext);
388+
unsigned long kernel_start = __pa(_text);
389389
unsigned long kernel_end = __pa(_etext);
390390

391391
/*
@@ -417,7 +417,7 @@ static void __init __map_memblock(pgd_t *pgd, phys_addr_t start, phys_addr_t end
417417
early_pgtable_alloc);
418418

419419
/*
420-
* Map the linear alias of the [_stext, _etext) interval as
420+
* Map the linear alias of the [_text, _etext) interval as
421421
* read-only/non-executable. This makes the contents of the
422422
* region accessible to subsystems such as hibernate, but
423423
* protects it from inadvertent modification or execution.
@@ -447,8 +447,8 @@ void mark_rodata_ro(void)
447447
{
448448
unsigned long section_size;
449449

450-
section_size = (unsigned long)__start_rodata - (unsigned long)_stext;
451-
create_mapping_late(__pa(_stext), (unsigned long)_stext,
450+
section_size = (unsigned long)__start_rodata - (unsigned long)_text;
451+
create_mapping_late(__pa(_text), (unsigned long)_text,
452452
section_size, PAGE_KERNEL_ROX);
453453
/*
454454
* mark .rodata as read only. Use _etext rather than __end_rodata to
@@ -497,7 +497,7 @@ static void __init map_kernel(pgd_t *pgd)
497497
{
498498
static struct vm_struct vmlinux_text, vmlinux_rodata, vmlinux_init, vmlinux_data;
499499

500-
map_kernel_segment(pgd, _stext, __start_rodata, PAGE_KERNEL_EXEC, &vmlinux_text);
500+
map_kernel_segment(pgd, _text, __start_rodata, PAGE_KERNEL_EXEC, &vmlinux_text);
501501
map_kernel_segment(pgd, __start_rodata, _etext, PAGE_KERNEL, &vmlinux_rodata);
502502
map_kernel_segment(pgd, __init_begin, __init_end, PAGE_KERNEL_EXEC,
503503
&vmlinux_init);

0 commit comments

Comments
 (0)