Message ID | 20200326165905.2240-3-ardb@kernel.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | efi/arm64: execute the kernel in place if possible | expand |
On Thu, Mar 26, 2020 at 05:59:05PM +0100, Ard Biesheuvel wrote: > Update the PE/COFF metadata so that the UEFI image loader will load the > kernel image at an offset that allows it to execute in place. > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org> > --- > arch/arm64/kernel/efi-header.S | 2 +- > arch/arm64/kernel/image-vars.h | 7 +++++++ > 2 files changed, 8 insertions(+), 1 deletion(-) > > diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S > index 914999ccaf8a..f9ee1c2a5fd6 100644 > --- a/arch/arm64/kernel/efi-header.S > +++ b/arch/arm64/kernel/efi-header.S > @@ -32,7 +32,7 @@ optional_header: > > extra_header_fields: > .quad 0 // ImageBase > - .long SZ_4K // SectionAlignment > + .long PECOFF_SECTION_ALIGNMENT // SectionAlignment > .long PECOFF_FILE_ALIGNMENT // FileAlignment > .short 0 // MajorOperatingSystemVersion > .short 0 // MinorOperatingSystemVersion > diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h > index be0a63ffed23..7a7fa3ba7b2f 100644 > --- a/arch/arm64/kernel/image-vars.h > +++ b/arch/arm64/kernel/image-vars.h > @@ -15,6 +15,13 @@ > __efistub_kernel_size = _edata - _text; > __efistub_primary_entry_offset = primary_entry - _text; > > +#ifndef CONFIG_RELOCATABLE > +PECOFF_SECTION_ALIGNMENT = SZ_4K; > +#elif THREAD_ALIGN > SEGMENT_ALIGN > +PECOFF_SECTION_ALIGNMENT = THREAD_ALIGN; > +#else > +PECOFF_SECTION_ALIGNMENT = SEGMENT_ALIGN; > +#endif > > /* > * The EFI stub has its own symbol namespace prefixed by __efistub_, to > -- > 2.17.1 > The section virtual addresses and (possibly) size of image need to be updated to be a multiple of PECOFF_SECTION_ALIGNMENT, no?
Hi Arvind, Thanks for taking a look. On Sat, 28 Mar 2020 at 15:06, Arvind Sankar <nivedita@alum.mit.edu> wrote: > > On Thu, Mar 26, 2020 at 05:59:05PM +0100, Ard Biesheuvel wrote: > > Update the PE/COFF metadata so that the UEFI image loader will load the > > kernel image at an offset that allows it to execute in place. > > > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org> > > --- > > arch/arm64/kernel/efi-header.S | 2 +- > > arch/arm64/kernel/image-vars.h | 7 +++++++ > > 2 files changed, 8 insertions(+), 1 deletion(-) > > > > diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S > > index 914999ccaf8a..f9ee1c2a5fd6 100644 > > --- a/arch/arm64/kernel/efi-header.S > > +++ b/arch/arm64/kernel/efi-header.S > > @@ -32,7 +32,7 @@ optional_header: > > > > extra_header_fields: > > .quad 0 // ImageBase > > - .long SZ_4K // SectionAlignment > > + .long PECOFF_SECTION_ALIGNMENT // SectionAlignment > > .long PECOFF_FILE_ALIGNMENT // FileAlignment > > .short 0 // MajorOperatingSystemVersion > > .short 0 // MinorOperatingSystemVersion > > diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h > > index be0a63ffed23..7a7fa3ba7b2f 100644 > > --- a/arch/arm64/kernel/image-vars.h > > +++ b/arch/arm64/kernel/image-vars.h > > @@ -15,6 +15,13 @@ > > __efistub_kernel_size = _edata - _text; > > __efistub_primary_entry_offset = primary_entry - _text; > > > > +#ifndef CONFIG_RELOCATABLE > > +PECOFF_SECTION_ALIGNMENT = SZ_4K; > > +#elif THREAD_ALIGN > SEGMENT_ALIGN > > +PECOFF_SECTION_ALIGNMENT = THREAD_ALIGN; > > +#else > > +PECOFF_SECTION_ALIGNMENT = SEGMENT_ALIGN; > > +#endif > > > > /* > > * The EFI stub has its own symbol namespace prefixed by __efistub_, to > > -- > > 2.17.1 > > > > The section virtual addresses and (possibly) size of image need to be > updated to be a multiple of PECOFF_SECTION_ALIGNMENT, no? Indeed. I spotted that after sending this patch - both _end and _initdata_begin need to be aligned to this value. I also noticed that it is unclear whether values over 64 KB are permitted: the PE/COFF spec mentions that 64 KB is the max for FileAlignment, and that SectionAlignment should be larger or equal to that. So I think it would be better to set this value to 64 KB unconditionally, and round up the sections to 64 KB. This means 64k pagesize kernels with vmap'ed stack have a 50% chance of ending up at an offset that requires moving the image, but this is still an improvement over doing it all the time.
diff --git a/arch/arm64/kernel/efi-header.S b/arch/arm64/kernel/efi-header.S index 914999ccaf8a..f9ee1c2a5fd6 100644 --- a/arch/arm64/kernel/efi-header.S +++ b/arch/arm64/kernel/efi-header.S @@ -32,7 +32,7 @@ optional_header: extra_header_fields: .quad 0 // ImageBase - .long SZ_4K // SectionAlignment + .long PECOFF_SECTION_ALIGNMENT // SectionAlignment .long PECOFF_FILE_ALIGNMENT // FileAlignment .short 0 // MajorOperatingSystemVersion .short 0 // MinorOperatingSystemVersion diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h index be0a63ffed23..7a7fa3ba7b2f 100644 --- a/arch/arm64/kernel/image-vars.h +++ b/arch/arm64/kernel/image-vars.h @@ -15,6 +15,13 @@ __efistub_kernel_size = _edata - _text; __efistub_primary_entry_offset = primary_entry - _text; +#ifndef CONFIG_RELOCATABLE +PECOFF_SECTION_ALIGNMENT = SZ_4K; +#elif THREAD_ALIGN > SEGMENT_ALIGN +PECOFF_SECTION_ALIGNMENT = THREAD_ALIGN; +#else +PECOFF_SECTION_ALIGNMENT = SEGMENT_ALIGN; +#endif /* * The EFI stub has its own symbol namespace prefixed by __efistub_, to
Update the PE/COFF metadata so that the UEFI image loader will load the kernel image at an offset that allows it to execute in place. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> --- arch/arm64/kernel/efi-header.S | 2 +- arch/arm64/kernel/image-vars.h | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-)