Skip to contentSkip to conversation

arm64: Align .text section to PAGE_SIZE

PATCH New Jeremy Linton 2 participants 6 messages Oct 23, 2015 – Oct 24, 2015 arm64

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 arm64: Align .text section to PAGE_SIZE

It appears that 64k page kernel's die early, in a somewhat random set of locations when built without KVM. Most likely during memblock manipulations (depending on kernel debug options).

Normally when KVM is built into the kernel it has an explicit PAGE_SIZE alignment requirement and that forces the text section to be aligned to PAGE_SIZE. Without it, the alignment granularity is likely to be 4k.

This updates the linker script to assure that the the text section is aligned to a minimum of PAGE_SIZE regardless of build options.

---
 arch/arm64/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/vmlinux.lds.S +1 -1
index 8a5d97b..bf7b972 100644
@@ -92,7 +92,7 @@ SECTIONS
 		HEAD_TEXT
 	}
 	ALIGN_DEBUG_RO
-	.text : {			/* Real text segment		*/
+	.text ALIGN(PAGE_SIZE) : {	/* Real text segment		*/
 		_stext = .;		/* Text and read-only data	*/
 			__exception_text_start = .;
 			*(.exception.text)
Signature · 1 line
2.4.3
#1 lore raw

PATCH 1/1 arm64: Align .text section to PAGE_SIZE

Hi Jeremy,

Quoted 1 line · Jeremy Linton

It appears that 64k page kernel's die early, in a somewhat random set

nit: kernels

Quoted 3 lines

of locations when built without KVM. Most likely during memblock manipulations (depending on kernel debug options).

It looks like fixup_executable() [with DEBUG_RODATA enabled] is the culprit here: it calls create mapping() with a size that gets rounded up to a multiple of PAGE_SIZE, which means the region that ends up getting its exec bits cleared is larger than it should. Perhaps it is better to fix that instead?

Quoted 30 lines

Normally when KVM is built into the kernel it has an explicit PAGE_SIZE alignment requirement and that forces the text section to be aligned to PAGE_SIZE. Without it, the alignment granularity is likely to be 4k.

This updates the linker script to assure that the the text section is aligned to a minimum of PAGE_SIZE regardless of build options.

---
 arch/arm64/kernel/vmlinux.lds.S | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/vmlinux.lds.S +1 -2
index 8a5d97b..bf7b972 100644
@@ -92,7 +92,7 @@ SECTIONS
                HEAD_TEXT
        }
        ALIGN_DEBUG_RO
-       .text : {                       /* Real text segment            */
+       .text ALIGN(PAGE_SIZE) : {      /* Real text segment            */
                _stext = .;             /* Text and read-only data      */
                        __exception_text_start = .;
                        *(.exception.text)
--

2.4.3

#2 lore raw

PATCH 1/1 arm64: Align .text section to PAGE_SIZE

Quoted 5 lines · Ard Biesheuvel

It looks like fixup_executable() [with DEBUG_RODATA enabled] is the culprit here: it calls create mapping() with a size that gets rounded up to a multiple of PAGE_SIZE, which means the region that ends up getting its exec bits cleared is larger than it should. Perhaps it is better to fix that instead?

Ard,
Thanks for taking a look at this!

Your probably right.

But AFAIK, with just that fix text/ro sections can be partially mapped
without ro. It seems to me that putting a little padding in so that they are on separate pages is a good idea, especially since it seems the remaining sections of interest are page aligned, either explicitly in the linker script or via assembly directives in assorted places.

Maybe a clearer fix is an additional ifdef in the DEBUG_ALIGN_RODATA
stanza which sets ALIGN_DEBUG_RO to align to pagesize if DEBUG_RODATA is set, that way it only takes affect for RODATA.

Thanks,
Jeremy

#3 lore raw

PATCH 1/1 arm64: Align .text section to PAGE_SIZE

(+ Laura)

http://thread.gmane.org/gmane.linux.ports.arm.kernel/450513

Quoted 9 lines · Jeremy Linton
Quoted 6 lines · Ard Biesheuvel

It looks like fixup_executable() [with DEBUG_RODATA enabled] is the culprit here: it calls create mapping() with a size that gets rounded up to a multiple of PAGE_SIZE, which means the region that ends up getting its exec bits cleared is larger than it should. Perhaps it is better to fix that instead?

Quoted 7 lines

Ard,
Thanks for taking a look at this!

Your probably right.

But AFAIK, with just that fix text/ro sections can be partially
mapped without ro.

Yes.

Quoted 5 lines

It seems to me that putting a little padding in so that
they are on separate pages is a good idea, especially since it seems the remaining sections of interest are page aligned, either explicitly in the linker script or via assembly directives in assorted places.

This should do the trick then, I think:
------8<----------

arch/arm64/kernel/vmlinux.lds.S +1 -1
index e9b8276ca079..db834a464986 100644
@@ -104,7 +104,7 @@ SECTIONS
                _text = .;
                HEAD_TEXT
        }
-       ALIGN_DEBUG_RO
+       ALIGN_DEBUG_RO_MIN(PAGE_SIZE)
        .text : {                       /* Real text segment            */
                _stext = .;             /* Text and read-only data      */
                        __exception_text_start = .;

------8<----------

Quoted 4 lines

Maybe a clearer fix is an additional ifdef in the DEBUG_ALIGN_RODATA
stanza which sets ALIGN_DEBUG_RO to align to pagesize if DEBUG_RODATA is set, that way it only takes affect for RODATA.

I think the diff does what you mean here.

Signature · 1 line
Ard.
#4 lore raw

PATCH 1/1 arm64: Align .text section to PAGE_SIZE

Quoted 1 line · Ard Biesheuvel

On 23 October 2015 at 18:32, Jeremy Linton <[email protected]> wrote:

...

Quoted 5 lines
Quoted 3 lines

Maybe a clearer fix is an additional ifdef in the DEBUG_ALIGN_RODATA
stanza which sets ALIGN_DEBUG_RO to align to pagesize if DEBUG_RODATA is set, that way it only takes affect for RODATA.

I think the diff does what you mean here.

...

This solves the problem I have. But, my comment about was trying to be a little more creative and allow it to align at less than page size if DEBUG_RODATA isn't set, as it does today. Sort of a packed kernel if you will...

But I will re-post shortly with just the ALIGN_DEBUG_RO change you suggest.

Thanks,

#5 lore raw

PATCH 1/1 arm64: Align .text section to PAGE_SIZE

(+ Laura, correct email this time)

http://thread.gmane.org/gmane.linux.ports.arm.kernel/450513

Quoted 12 lines · Jeremy Linton
Quoted 2 lines · Ard Biesheuvel

On 23 October 2015 at 18:32, Jeremy Linton <[email protected]> wrote:

...

Quoted 7 lines
Quoted 5 lines

Maybe a clearer fix is an additional ifdef in the
DEBUG_ALIGN_RODATA
stanza which sets ALIGN_DEBUG_RO to align to pagesize if DEBUG_RODATA is set, that way it only takes affect for RODATA.

Quoted 9 lines
Quoted 1 line

I think the diff does what you mean here.

...

This solves the problem I have. But, my comment about was trying to be a little more creative and allow it to align at less than page size if DEBUG_RODATA isn't set, as it does today. Sort of a packed kernel if you will...

OK, I didn't catch that. Not sure if the average waste of 32 KB is worth the trouble, though. Especially since, in my opinion, CONFIG_DEBUG_RODATA should be promoted to a non-debug 'default y' option.

Signature · 1 line
Ard.
Quoted 5 lines

But I will re-post shortly with just the ALIGN_DEBUG_RO change you suggest.

Thanks,