linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: "Björn Töpel" <bjorn@kernel.org>
To: Alexandre Ghiti <alex@ghiti.fr>,
	Alexandre Ghiti <alexghiti@rivosinc.com>,
	Michael Ellerman <mpe@ellerman.id.au>,
	Nicholas Piggin <npiggin@gmail.com>,
	Christophe Leroy <christophe.leroy@csgroup.eu>,
	Paul Walmsley <paul.walmsley@sifive.com>,
	Palmer Dabbelt <palmer@dabbelt.com>,
	Albert Ou <aou@eecs.berkeley.edu>,
	linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org,
	linux-riscv@lists.infradead.org, nathan@kernel.org,
	linux-kbuild@vger.kernel.org, llvm@lists.linux.dev,
	ndesaulniers@google.com
Subject: Re: [PATCH v8 1/3] riscv: Introduce CONFIG_RELOCATABLE
Date: Fri, 24 Feb 2023 16:58:52 +0100	[thread overview]
Message-ID: <877cw7dphf.fsf@all.your.base.are.belong.to.us> (raw)
In-Reply-To: <4a6fc7a3-9697-a49b-0941-97f32194b0d7@ghiti.fr>

Alexandre Ghiti <alex@ghiti.fr> writes:

> +cc linux-kbuild, llvm, Nathan, Nick
>
> On 2/15/23 15:36, Alexandre Ghiti wrote:
>> From: Alexandre Ghiti <alex@ghiti.fr>
>>
>> This config allows to compile 64b kernel as PIE and to relocate it at
>> any virtual address at runtime: this paves the way to KASLR.
>> Runtime relocation is possible since relocation metadata are embedded into
>> the kernel.
>>
>> Note that relocating at runtime introduces an overhead even if the
>> kernel is loaded at the same address it was linked at and that the compiler
>> options are those used in arm64 which uses the same RELA relocation
>> format.
>>
>> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
>> ---
>>   arch/riscv/Kconfig              | 14 +++++++++
>>   arch/riscv/Makefile             |  7 +++--
>>   arch/riscv/kernel/efi-header.S  |  6 ++--
>>   arch/riscv/kernel/vmlinux.lds.S | 10 ++++--
>>   arch/riscv/mm/Makefile          |  4 +++
>>   arch/riscv/mm/init.c            | 54 ++++++++++++++++++++++++++++++++-
>>   6 files changed, 87 insertions(+), 8 deletions(-)
>>
>> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
>> index e2b656043abf..e0ee7ce4b2e3 100644
>> --- a/arch/riscv/Kconfig
>> +++ b/arch/riscv/Kconfig
>> @@ -544,6 +544,20 @@ config COMPAT
>>   
>>   	  If you want to execute 32-bit userspace applications, say Y.
>>   
>> +config RELOCATABLE
>> +	bool "Build a relocatable kernel"
>> +	depends on MMU && 64BIT && !XIP_KERNEL
>> +	help
>> +          This builds a kernel as a Position Independent Executable (PIE),
>> +          which retains all relocation metadata required to relocate the
>> +          kernel binary at runtime to a different virtual address than the
>> +          address it was linked at.
>> +          Since RISCV uses the RELA relocation format, this requires a
>> +          relocation pass at runtime even if the kernel is loaded at the
>> +          same address it was linked at.
>> +
>> +          If unsure, say N.
>> +
>>   endmenu # "Kernel features"
>>   
>>   menu "Boot options"
>> diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
>> index 82153960ac00..97c34136b027 100644
>> --- a/arch/riscv/Makefile
>> +++ b/arch/riscv/Makefile
>> @@ -7,9 +7,12 @@
>>   #
>>   
>>   OBJCOPYFLAGS    := -O binary
>> -LDFLAGS_vmlinux :=
>> +ifeq ($(CONFIG_RELOCATABLE),y)
>> +	LDFLAGS_vmlinux += -shared -Bsymbolic -z notext -z norelro
>> +	KBUILD_CFLAGS += -fPIE
>> +endif
>>   ifeq ($(CONFIG_DYNAMIC_FTRACE),y)
>> -	LDFLAGS_vmlinux := --no-relax
>> +	LDFLAGS_vmlinux += --no-relax
>>   	KBUILD_CPPFLAGS += -DCC_USING_PATCHABLE_FUNCTION_ENTRY
>>   	CC_FLAGS_FTRACE := -fpatchable-function-entry=8
>>   endif
>> diff --git a/arch/riscv/kernel/efi-header.S b/arch/riscv/kernel/efi-header.S
>> index 8e733aa48ba6..f7ee09c4f12d 100644
>> --- a/arch/riscv/kernel/efi-header.S
>> +++ b/arch/riscv/kernel/efi-header.S
>> @@ -33,7 +33,7 @@ optional_header:
>>   	.byte	0x02					// MajorLinkerVersion
>>   	.byte	0x14					// MinorLinkerVersion
>>   	.long	__pecoff_text_end - efi_header_end	// SizeOfCode
>> -	.long	__pecoff_data_virt_size			// SizeOfInitializedData
>> +	.long	__pecoff_data_virt_end - __pecoff_text_end	// SizeOfInitializedData
>>   	.long	0					// SizeOfUninitializedData
>>   	.long	__efistub_efi_pe_entry - _start		// AddressOfEntryPoint
>>   	.long	efi_header_end - _start			// BaseOfCode
>> @@ -91,9 +91,9 @@ section_table:
>>   		IMAGE_SCN_MEM_EXECUTE			// Characteristics
>>   
>>   	.ascii	".data\0\0\0"
>> -	.long	__pecoff_data_virt_size			// VirtualSize
>> +	.long	__pecoff_data_virt_end - __pecoff_text_end	// VirtualSize
>>   	.long	__pecoff_text_end - _start		// VirtualAddress
>> -	.long	__pecoff_data_raw_size			// SizeOfRawData
>> +	.long	__pecoff_data_raw_end - __pecoff_text_end	// SizeOfRawData
>>   	.long	__pecoff_text_end - _start		// PointerToRawData
>>   
>>   	.long	0					// PointerToRelocations
>> diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S
>> index 4e6c88aa4d87..8be2de3be08c 100644
>> --- a/arch/riscv/kernel/vmlinux.lds.S
>> +++ b/arch/riscv/kernel/vmlinux.lds.S
>> @@ -122,9 +122,15 @@ SECTIONS
>>   		*(.sdata*)
>>   	}
>>   
>> +	.rela.dyn : ALIGN(8) {
>> +		__rela_dyn_start = .;
>> +		*(.rela .rela*)
>> +		__rela_dyn_end = .;
>> +	}
>> +
>
>
> So I realized those relocations would be better in the init section so 
> we can get rid of them at some point. So I tried the following:
>
> diff --git a/arch/riscv/kernel/vmlinux.lds.S 
> b/arch/riscv/kernel/vmlinux.lds.S
> index 7ac215467fd5..6111023a89ef 100644
> --- a/arch/riscv/kernel/vmlinux.lds.S
> +++ b/arch/riscv/kernel/vmlinux.lds.S
> @@ -93,6 +93,12 @@ SECTIONS
>                  *(.rel.dyn*)
>          }
>
> +       .rela.dyn : ALIGN(8) {
> +               __rela_dyn_start = .;
> +               *(.rela .rela*)
> +               __rela_dyn_end = .;
> +       }
> +
>          __init_data_end = .;
>
>          . = ALIGN(8);
> @@ -119,12 +125,6 @@ SECTIONS
>                  *(.sdata*)
>          }
>
> -       .rela.dyn : ALIGN(8) {
> -               __rela_dyn_start = .;
> -               *(.rela .rela*)
> -               __rela_dyn_end = .;
> -       }
> -
>   #ifdef CONFIG_EFI
>          .pecoff_edata_padding : { BYTE(0); . = 
> ALIGN(PECOFF_FILE_ALIGNMENT); }
>          __pecoff_data_raw_end = ABSOLUTE(.);
>
>
> But then all the relocations in vmlinux end up being null:
>
> vmlinux:     file format elf64-littleriscv
>
> $ riscv64-linux-gnu-objdump -R vmlinux
>
> DYNAMIC RELOCATION RECORDS
> OFFSET           TYPE              VALUE
> 0000000000000000 R_RISCV_NONE      *ABS*
> 0000000000000000 R_RISCV_NONE      *ABS*
> ....
>
>   I also noticed that re-linking vmlinux with the same command right 
> after works (ie, the relocations are now valid):
>
> $ riscv64-linux-gnu-objdump -R vmlinux
>
> vmlinux:     file format elf64-littleriscv
>
> DYNAMIC RELOCATION RECORDS
> OFFSET           TYPE              VALUE
> ffffffff82600718 R_RISCV_RELATIVE  *ABS*-0x000000007d9ff8e8
> ffffffff82600720 R_RISCV_RELATIVE  *ABS*-0x000000007d9ff8e8
> ...
>
> Below is the command used to generate this working vmlinux:
>
> riscv64-unknown-linux-gnu-ld -melf64lriscv -z noexecstack 
> --no-warn-rwx-segments -shared -Bsymbolic -z notext -z norelro 
> --no-relax --build-id=sha1 --script=./arch/riscv/kernel/vmlinux.lds 
> -Map=vmlinux.map -o vmlinux --whole-archive vmlinux.a .vmlinux.export.o 
> init/version-timestamp.o --no-whole-archive --start-group 
> ./drivers/firmware/efi/libstub/lib.a --end-group .tmp_vmlinux.kallsyms3.o
>
> I tried a lot of things, but I struggle to understand, does anyone have 
> any idea? FYI, the same problem happens with LLVM.

Don't ask me *why*, but adding --emit-relocs to your linker flags solves
"the NULL .rela.dyn" both for GCC and LLVM.

The downside is that you end up with a bunch of .rela cruft in your
vmlinux.


Björn

  reply	other threads:[~2023-02-24 16:00 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-02-15 14:36 [PATCH v8 0/3] Introduce 64b relocatable kernel Alexandre Ghiti
2023-02-15 14:36 ` [PATCH v8 1/3] riscv: Introduce CONFIG_RELOCATABLE Alexandre Ghiti
2023-02-22 12:29   ` Alexandre Ghiti
2023-02-24 15:58     ` Björn Töpel [this message]
2023-03-22 18:25       ` Nick Desaulniers
2023-03-23 20:01         ` Fangrui Song
2023-03-24 10:34         ` Alexandre Ghiti
2023-03-22 13:38     ` Alexandre Ghiti
2023-05-09 19:07   ` Andreas Schwab
2023-05-09 19:55     ` Alexandre Ghiti
2023-05-11 18:18       ` Andreas Schwab
2023-05-12 18:41         ` Palmer Dabbelt
2023-05-19 11:08         ` Alexandre Ghiti
2023-05-19 21:48           ` Andreas Schwab
2023-05-19 21:55             ` Palmer Dabbelt
2023-05-22 10:48               ` Alexandre Ghiti
2023-02-15 14:36 ` [PATCH v8 2/3] powerpc: Move script to check relocations at compile time in scripts/ Alexandre Ghiti
2023-02-15 14:36 ` [PATCH v8 3/3] riscv: Check relocations at compile time Alexandre Ghiti
2023-02-20  9:14 ` [PATCH v8 0/3] Introduce 64b relocatable kernel Björn Töpel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=877cw7dphf.fsf@all.your.base.are.belong.to.us \
    --to=bjorn@kernel.org \
    --cc=alex@ghiti.fr \
    --cc=alexghiti@rivosinc.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=christophe.leroy@csgroup.eu \
    --cc=linux-kbuild@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=llvm@lists.linux.dev \
    --cc=mpe@ellerman.id.au \
    --cc=nathan@kernel.org \
    --cc=ndesaulniers@google.com \
    --cc=npiggin@gmail.com \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).