diff mbox

[1/3] ARM: move .vectors and .stubs sections back into the kernel VMA

Message ID 1454419174-21290-2-git-send-email-ard.biesheuvel@linaro.org
State Superseded
Headers show

Commit Message

Ard Biesheuvel Feb. 2, 2016, 1:19 p.m. UTC
Commit b9b32bf70f2f ("ARM: use linker magic for vectors and vector stubs")
updated the linker script to emit the .vectors and .stubs sections into a
VMA range that is zero based and disjoint from the normal static kernel
region. The reason for that was that this way, the sections can be placed
exactly 4 KB apart, while the payload of the .vectors section is only 32
bytes.

Since the symbols that are part of the .stubs section are emitted into the
kallsyms table, they appear with zero based addresses as well, e.g.,

  00000000 t __vectors_start
  00001000 t __stubs_start
  00001004 t vector_rst
  00001020 t vector_irq
  000010a0 t vector_dabt
  00001120 t vector_pabt
  000011a0 t vector_und
  00001220 t vector_addrexcptn
  00001240 t vector_fiq
  00001240 T vector_fiq_offset

As this confuses perf when it accesses the kallsyms tables, commit
7122c3e9154b ("scripts/link-vmlinux.sh: only filter kernel symbols for
arm") implemented a somewhat ugly special case for ARM, where the value
of CONFIG_PAGE_OFFSET is passed to scripts/kallsyms, and symbols whose
address is below it are filtered out. Note that this special case only
applies to CONFIG_XIP_KERNEL=n, not because the issue the patch addresses
exists only in that case, but because finding a limit below which to apply
the filtering is too difficult.

Since the constraint we are trying to meet here is that the .vectors
section lives exactly 4 KB before the .stubs section, regardless of the
absolute addresses of either (since relative branches are used to jump from
the vector table to the stubs), we can simply emit the .stubs section as
part of the kernel VMA, and place the .vectors section 4 KB before it using
an explicit VMA override. By doing that, and renaming the __vectors_start
symbol that is local to arch/arm/kernel/entry-armv.S (not the one in the
linker script), the kallsyms table looks somewhat sane, regardless of
whether CONFIG_XIP_KERNEL is set, and we can drop the special case in
scripts/kallsyms entirely. E.g.,

  00001240 A vector_fiq_offset
  ...
  c0c35000 T __init_begin
  c0c35000 t __stubs_start
  c0c35000 T __stubs_start
  c0c35004 t vector_rst
  c0c35020 t vector_irq
  c0c350a0 t vector_dabt
  c0c35120 t vector_pabt
  c0c351a0 t vector_und
  c0c35220 t vector_addrexcptn
  c0c35240 T vector_fiq
  c0c352c0 T __stubs_end
  c0c352c0 T __vectors_start
  c0c352e0 t __mmap_switched
  c0c352e0 T _sinittext
  c0c352e0 T __vectors_end

(Note that vector_fiq_offset is now an absolute symbol, which kallsyms
already ignores by default)

The sections themselves are emitted 4 KB apart, as required:
  ...
  [16] .stubs       PROGBITS   c0c35000 a35000 0002c0 00  AX  0   0 32
  [17] .vectors     PROGBITS   c0c34000 a44000 000020 00  AX  0   0  2
  ...

and the relative branches in the .vectors section still point to the
right place:

  c0c34000 <.vectors>:
  c0c34000:       f001 b800       b.w     c0c35004 <vector_rst>
  c0c34004:       f001 b8cc       b.w     c0c351a0 <vector_und>
  c0c34008:       f8df fff4       ldr.w   pc, [pc, #4084] ; c0c35000
  c0c3400c:       f001 b888       b.w     c0c35120 <vector_pabt>
  c0c34010:       f001 b846       b.w     c0c350a0 <vector_dabt>
  c0c34014:       f001 b904       b.w     c0c35220 <vector_addrexcptn>
  c0c34018:       f001 b802       b.w     c0c35020 <vector_irq>
  c0c3401c:       f001 b910       b.w     c0c35240 <vector_fiq>

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---
 arch/arm/kernel/entry-armv.S  |  7 +++----
 arch/arm/kernel/vmlinux.lds.S | 15 ++++++++-------
 2 files changed, 11 insertions(+), 11 deletions(-)

-- 
2.5.0


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Comments

Nicolas Pitre Feb. 3, 2016, 12:20 a.m. UTC | #1
On Wed, 3 Feb 2016, Russell King - ARM Linux wrote:

> On Tue, Feb 02, 2016 at 02:19:32PM +0100, Ard Biesheuvel wrote:

> > The sections themselves are emitted 4 KB apart, as required:

> >   ...

> >   [16] .stubs       PROGBITS   c0c35000 a35000 0002c0 00  AX  0   0 32

> >   [17] .vectors     PROGBITS   c0c34000 a44000 000020 00  AX  0   0  2

> >   ...

> 

> ... which means we end up wasting most of a page for absolutely no

> purpose what so ever.  Sorry, I'm really not happy about this

> gratuitous wastage.


In practice this shouldn't make much of a difference given zImage is 
compressed and large zero filled areas compress very well.

But this is not nice for XIP though.


Nicolas

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Ard Biesheuvel Feb. 3, 2016, 7:56 a.m. UTC | #2
On 3 February 2016 at 01:03, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Tue, Feb 02, 2016 at 02:19:32PM +0100, Ard Biesheuvel wrote:

>> The sections themselves are emitted 4 KB apart, as required:

>>   ...

>>   [16] .stubs       PROGBITS   c0c35000 a35000 0002c0 00  AX  0   0 32

>>   [17] .vectors     PROGBITS   c0c34000 a44000 000020 00  AX  0   0  2

>>   ...

>

> ... which means we end up wasting most of a page for absolutely no

> purpose what so ever.  Sorry, I'm really not happy about this

> gratuitous wastage.

>


No, we don't. Here's some more context:

Before:
  [14] .ARM.unwind_tab   PROGBITS        c0c2ef98 a2ef98 005088 00   A  0   0  4
  [15] .notes            NOTE            c0c34020 a34020 000024 00  AX  0   0  4
  [16] .vectors          PROGBITS        00000000 a40000 000020 00  AX  0   0  2
  [17] .stubs            PROGBITS        00001000 a41000 0002c0 00  AX  0   0 32
  [18] .init.text        PROGBITS        c0c352e0 a452e0 06b1b8 00  AX  0   0 32

After
  [14] .ARM.unwind_tab   PROGBITS        c0c2ef98 a2ef98 005088 00   A  0   0  4
  [15] .notes            NOTE            c0c34020 a34020 000024 00  AX  0   0  4
  [16] .stubs            PROGBITS        c0c35000 a35000 0002c0 00  AX  0   0 32
  [17] .vectors          PROGBITS        c0c34000 a44000 000020 00  AX  0   0  2
  [18] .init.text        PROGBITS        c0c352e0 a452e0 06b1b8 00  AX  0   0 32

As you can see, the LMA footprint has not increased, only .stubs and
.vectors have been reordered. The apparent rounding after the .notes
section occurs in both cases, and is due to the fact that __init_begin
is rounded to page size, and has nothing to do with the VMAs chosen
for the .stubs and .vectors section.

> We changed to the existing solution to get rid of the VMA offset

> to make the code easier to read, but if we're going to get rid of

> that improvement, just revert the change.  (Check the kernel history.)

>


I think that change was an improvement. It makes the code itself more
readable, but also results in correct references in the object files
rather than opaque expressions, i.e.,

  c0c34000 <.vectors>:
  c0c34000:       f001 b800       b.w     c0c35004 <vector_rst>
  c0c34004:       f001 b8cc       b.w     c0c351a0 <vector_und>
  c0c34008:       f8df fff4       ldr.w   pc, [pc, #4084] ; c0c35000
  c0c3400c:       f001 b888       b.w     c0c35120 <vector_pabt>
  c0c34010:       f001 b846       b.w     c0c350a0 <vector_dabt>
  c0c34014:       f001 b904       b.w     c0c35220 <vector_addrexcptn>
  c0c34018:       f001 b802       b.w     c0c35020 <vector_irq>
  c0c3401c:       f001 b910       b.w     c0c35240 <vector_fiq>

-- 
Ard.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Ard Biesheuvel Feb. 3, 2016, 9:16 a.m. UTC | #3
On 3 February 2016 at 10:13, Russell King - ARM Linux
<linux@arm.linux.org.uk> wrote:
> On Wed, Feb 03, 2016 at 08:56:35AM +0100, Ard Biesheuvel wrote:

>> On 3 February 2016 at 01:03, Russell King - ARM Linux

>> <linux@arm.linux.org.uk> wrote:

>> > On Tue, Feb 02, 2016 at 02:19:32PM +0100, Ard Biesheuvel wrote:

>> >> The sections themselves are emitted 4 KB apart, as required:

>> >>   ...

>> >>   [16] .stubs       PROGBITS   c0c35000 a35000 0002c0 00  AX  0   0 32

>> >>   [17] .vectors     PROGBITS   c0c34000 a44000 000020 00  AX  0   0  2

>> >>   ...

>> >

>> > ... which means we end up wasting most of a page for absolutely no

>> > purpose what so ever.  Sorry, I'm really not happy about this

>> > gratuitous wastage.

>> >

>>

>> No, we don't. Here's some more context:

>>

>> Before:

>>   [14] .ARM.unwind_tab   PROGBITS        c0c2ef98 a2ef98 005088 00   A  0   0  4

>>   [15] .notes            NOTE            c0c34020 a34020 000024 00  AX  0   0  4

>>   [16] .vectors          PROGBITS        00000000 a40000 000020 00  AX  0   0  2

>>   [17] .stubs            PROGBITS        00001000 a41000 0002c0 00  AX  0   0 32

>>   [18] .init.text        PROGBITS        c0c352e0 a452e0 06b1b8 00  AX  0   0 32

>>

>> After

>>   [14] .ARM.unwind_tab   PROGBITS        c0c2ef98 a2ef98 005088 00   A  0   0  4

>>   [15] .notes            NOTE            c0c34020 a34020 000024 00  AX  0   0  4

>>   [16] .stubs            PROGBITS        c0c35000 a35000 0002c0 00  AX  0   0 32

>>   [17] .vectors          PROGBITS        c0c34000 a44000 000020 00  AX  0   0  2

>>   [18] .init.text        PROGBITS        c0c352e0 a452e0 06b1b8 00  AX  0   0 32

>

> Meaningless numbers... Do you think you can quote with the header

> please?  I don't tend to carry around the objdump headers in my head.

> Thanks.

>


BEFORE

$ readelf -S vmlinux
There are 34 section headers, starting at offset 0x10a6e60:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .head.text        PROGBITS        c0208000 008000 000268 00  AX  0   0  4
  [ 2] .text             PROGBITS        c0209000 009000 5d6e7c 00  AX
 0   0 4096
  [ 3] .fixup            PROGBITS        c07dfe7c 5dfe7c 000024 00  AX  0   0  4
  [ 4] .rodata           PROGBITS        c07e0000 5e0000 3ca310 00   A  0   0 64
  [ 5] __bug_table       PROGBITS        c0baa310 9aa310 0082c8 00   A  0   0  4
  [ 6] .pci_fixup        PROGBITS        c0bb25d8 9b25d8 001910 00   A  0   0  4
  [ 7] __ksymtab         PROGBITS        c0bb3ee8 9b3ee8 008a70 00   A  0   0  4
  [ 8] __ksymtab_gpl     PROGBITS        c0bbc958 9bc958 007d60 00   A  0   0  4
  [ 9] __ksymtab_strings PROGBITS        c0bc46b8 9c46b8 027c07 00   A  0   0  1
  [10] __param           PROGBITS        c0bec2c0 9ec2c0 0015b8 00   A  0   0  4
  [11] __modver          PROGBITS        c0bed878 9ed878 000788 00   A  0   0  4
  [12] __ex_table        PROGBITS        c0bee000 9ee000 001068 00   A  0   0  8
  [13] .ARM.unwind_idx   ARM_EXIDX       c0bef068 9ef068 03ff30 00  AL 18   0  4
  [14] .ARM.unwind_tab   PROGBITS        c0c2ef98 a2ef98 005088 00   A  0   0  4
  [15] .notes            NOTE            c0c34020 a34020 000024 00  AX  0   0  4
  [16] .vectors          PROGBITS        00000000 a40000 000020 00  AX  0   0  2
  [17] .stubs            PROGBITS        00001000 a41000 0002c0 00  AX  0   0 32
  [18] .init.text        PROGBITS        c0c352e0 a452e0 06b1b8 00  AX  0   0 32
  [19] .exit.text        PROGBITS        c0ca0498 ab0498 002f40 00  AX  0   0  4
  [20] .init.arch.info   PROGBITS        c0ca33d8 ab33d8 0026e8 00   A  0   0  8
  [21] .init.tagtable    PROGBITS        c0ca5ac0 ab5ac0 000048 00   A  0   0  4
  [22] .init.smpalt      PROGBITS        c0ca5b08 ab5b08 00dff8 00   A  0   0  4
  [23] .init.pv_table    PROGBITS        c0cb3b00 ac3b00 000a20 00   A  0   0  1
  [24] .init.data        PROGBITS        c0cb5000 ac5000 06de0c 00  WA
 0   0 4096
  [25] .data..percpu     PROGBITS        c0d23000 b33000 0049c0 00  WA  0   0 64
  [26] .data             PROGBITS        c0d28000 b38000 107d00 00  WA  0   0 64
  [27] .data..page_align PROGBITS        c0e30000 c40000 002000 00  WA
 0   0 4096
  [28] .bss              NOBITS          c0e32000 c42000 056ec8 00  WA  0   0 64
  [29] .comment          PROGBITS        00000000 c42000 00002d 01  MS  0   0  1
  [30] .ARM.attributes   ARM_ATTRIBUTES  00000000 c4202d 000033 00      0   0  1
  [31] .shstrtab         STRTAB          00000000 c42060 000165 00      0   0  1
  [32] .symtab           SYMTAB          00000000 c421c8 28f340 10
33 140990  4
  [33] .strtab           STRTAB          00000000 ed1508 1d5956 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

AFTER

$ readelf -S vmlinux
There are 34 section headers, starting at offset 0x10a6e50:

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .head.text        PROGBITS        c0208000 008000 000268 00  AX  0   0  4
  [ 2] .text             PROGBITS        c0209000 009000 5d6e7c 00  AX
 0   0 4096
  [ 3] .fixup            PROGBITS        c07dfe7c 5dfe7c 000024 00  AX  0   0  4
  [ 4] .rodata           PROGBITS        c07e0000 5e0000 3ca310 00   A  0   0 64
  [ 5] __bug_table       PROGBITS        c0baa310 9aa310 0082c8 00   A  0   0  4
  [ 6] .pci_fixup        PROGBITS        c0bb25d8 9b25d8 001910 00   A  0   0  4
  [ 7] __ksymtab         PROGBITS        c0bb3ee8 9b3ee8 008a70 00   A  0   0  4
  [ 8] __ksymtab_gpl     PROGBITS        c0bbc958 9bc958 007d60 00   A  0   0  4
  [ 9] __ksymtab_strings PROGBITS        c0bc46b8 9c46b8 027c07 00   A  0   0  1
  [10] __param           PROGBITS        c0bec2c0 9ec2c0 0015b8 00   A  0   0  4
  [11] __modver          PROGBITS        c0bed878 9ed878 000788 00   A  0   0  4
  [12] __ex_table        PROGBITS        c0bee000 9ee000 001068 00   A  0   0  8
  [13] .ARM.unwind_idx   ARM_EXIDX       c0bef068 9ef068 03ff30 00  AL 18   0  4
  [14] .ARM.unwind_tab   PROGBITS        c0c2ef98 a2ef98 005088 00   A  0   0  4
  [15] .notes            NOTE            c0c34020 a34020 000024 00  AX  0   0  4
  [16] .stubs            PROGBITS        c0c35000 a35000 0002c0 00  AX  0   0 32
  [17] .vectors          PROGBITS        c0c34000 a44000 000020 00  AX  0   0  2
  [18] .init.text        PROGBITS        c0c352e0 a452e0 06b1b8 00  AX  0   0 32
  [19] .exit.text        PROGBITS        c0ca0498 ab0498 002f40 00  AX  0   0  4
  [20] .init.arch.info   PROGBITS        c0ca33d8 ab33d8 0026e8 00   A  0   0  8
  [21] .init.tagtable    PROGBITS        c0ca5ac0 ab5ac0 000048 00   A  0   0  4
  [22] .init.smpalt      PROGBITS        c0ca5b08 ab5b08 00dff8 00   A  0   0  4
  [23] .init.pv_table    PROGBITS        c0cb3b00 ac3b00 000a20 00   A  0   0  1
  [24] .init.data        PROGBITS        c0cb5000 ac5000 06de0c 00  WA
 0   0 4096
  [25] .data..percpu     PROGBITS        c0d23000 b33000 0049c0 00  WA  0   0 64
  [26] .data             PROGBITS        c0d28000 b38000 107d00 00  WA  0   0 64
  [27] .data..page_align PROGBITS        c0e30000 c40000 002000 00  WA
 0   0 4096
  [28] .bss              NOBITS          c0e32000 c42000 056ec8 00  WA  0   0 64
  [29] .comment          PROGBITS        00000000 c42000 00002d 01  MS  0   0  1
  [30] .ARM.attributes   ARM_ATTRIBUTES  00000000 c4202d 000033 00      0   0  1
  [31] .shstrtab         STRTAB          00000000 c42060 000165 00      0   0  1
  [32] .symtab           SYMTAB          00000000 c421c8 28f330 10
33 140988  4
  [33] .strtab           STRTAB          00000000 ed14f8 1d5956 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
diff mbox

Patch

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 3ce377f7251f..8575ff42c0d4 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -1202,14 +1202,13 @@  vector_addrexcptn:
 	.long	__fiq_svc			@  e
 	.long	__fiq_svc			@  f
 
-	.globl	vector_fiq_offset
-	.equ	vector_fiq_offset, vector_fiq
+	.globl	vector_fiq
 
 	.section .vectors, "ax", %progbits
-__vectors_start:
+.L__vectors_start:
 	W(b)	vector_rst
 	W(b)	vector_und
-	W(ldr)	pc, __vectors_start + 0x1000
+	W(ldr)	pc, .L__vectors_start + 0x1000
 	W(b)	vector_pabt
 	W(b)	vector_dabt
 	W(b)	vector_addrexcptn
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 8b60fde5ce48..7160658fd5d4 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -164,19 +164,20 @@  SECTIONS
 	 * The vectors and stubs are relocatable code, and the
 	 * only thing that matters is their relative offsets
 	 */
+	__stubs_start = .;
+	.stubs : {
+		*(.stubs)
+	}
+	__stubs_end = .;
+
 	__vectors_start = .;
-	.vectors 0 : AT(__vectors_start) {
+	.vectors ADDR(.stubs) - 0x1000 : AT(__vectors_start) {
 		*(.vectors)
 	}
 	. = __vectors_start + SIZEOF(.vectors);
 	__vectors_end = .;
 
-	__stubs_start = .;
-	.stubs 0x1000 : AT(__stubs_start) {
-		*(.stubs)
-	}
-	. = __stubs_start + SIZEOF(.stubs);
-	__stubs_end = .;
+	vector_fiq_offset = vector_fiq - ADDR(.vectors);
 
 	INIT_TEXT_SECTION(8)
 	.exit.text : {