Message ID | 20220819102037.2697798-1-chenhuacai@loongson.cn |
---|---|
State | Accepted |
Commit | ead384d956345681e1ddf97890d5e15ded015f07 |
Headers | show |
Series | [V3] LoongArch: Add efistub booting support | expand |
On Fri, 19 Aug 2022 at 12:20, Huacai Chen <chenhuacai@loongson.cn> wrote: > > This patch adds efistub booting support, which is the standard UEFI boot > protocol for us to use. > > We use generic efistub, which means we can pass boot information (i.e., > system table, memory map, kernel command line, initrd) via a light FDT > and drop a lot of non-standard code. > > We use a flat mapping to map the efi runtime in the kernel's address > space. In efi, VA = PA; in kernel, VA = PA + PAGE_OFFSET. As a result, > flat mapping is not identity mapping, SetVirtualAddressMap() is still > needed for the efi runtime. > > Tested-by: Xi Ruoyao <xry111@xry111.site> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > --- > V1 --> V2: > 1, Call SetVirtualAddressMap() in stub; > 2, Use core kernel data directly in alloc_screen_info(); > 3, Remove the magic number in MS-DOS header; > 4, Disable EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER; > 5, Some other small changes suggested by Ard Biesheuvel. > > V2 --> V3: > 1, Adjust Makefile to adapt zboot; > 2, Introduce EFI_RT_VIRTUAL_OFFSET instead of changing flat_va_mapping. > Thanks for the update. I am going to queue this up in the efi/next tree. However, due to the many changes to arch/loongarch in this patch, conflicts are not unlikely, so I created a signed stable tag for the patch that you can merge into the loongarch arch tree if you want. *However*, you must *not* rebase your tree after merging this tag. Therefore, it is probably best that the merge of this tag appears as the very first change on your PR to Linus for v6.1. Everything after can be rebased at will (assuming there are no other impediments to doing so) You can fetch it and merge it like so: git fetch -t git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git git verify-tag efi-loongarch-for-v6.1 # if you like git merge efi-loongarch-for-v6.1 and all your other v6.1 changes can go on top. This way, you can resolve conflicts locally without affecting the EFI changes going via the other tree. The EFI stub for LoongArch change will arrive into Linus's tree via whichever tree he pulls first: the LoongArch one or the EFI one. I will rebase my zboot decompressor changes on top of this - I will cc you again, as the LoongArch builds ok but still does not boot. Thanks, Ard.
On Mon, 22 Aug 2022 at 12:44, Ard Biesheuvel <ardb@kernel.org> wrote: > > On Fri, 19 Aug 2022 at 12:20, Huacai Chen <chenhuacai@loongson.cn> wrote: > > > > This patch adds efistub booting support, which is the standard UEFI boot > > protocol for us to use. > > > > We use generic efistub, which means we can pass boot information (i.e., > > system table, memory map, kernel command line, initrd) via a light FDT > > and drop a lot of non-standard code. > > > > We use a flat mapping to map the efi runtime in the kernel's address > > space. In efi, VA = PA; in kernel, VA = PA + PAGE_OFFSET. As a result, > > flat mapping is not identity mapping, SetVirtualAddressMap() is still > > needed for the efi runtime. > > > > Tested-by: Xi Ruoyao <xry111@xry111.site> > > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > > --- > > V1 --> V2: > > 1, Call SetVirtualAddressMap() in stub; > > 2, Use core kernel data directly in alloc_screen_info(); > > 3, Remove the magic number in MS-DOS header; > > 4, Disable EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER; > > 5, Some other small changes suggested by Ard Biesheuvel. > > > > V2 --> V3: > > 1, Adjust Makefile to adapt zboot; > > 2, Introduce EFI_RT_VIRTUAL_OFFSET instead of changing flat_va_mapping. > > > > Thanks for the update. > > I am going to queue this up in the efi/next tree. However, due to the > many changes to arch/loongarch in this patch, conflicts are not > unlikely, so I created a signed stable tag for the patch that you can > merge into the loongarch arch tree if you want. > > *However*, you must *not* rebase your tree after merging this tag. > Therefore, it is probably best that the merge of this tag appears as > the very first change on your PR to Linus for v6.1. Everything after > can be rebased at will (assuming there are no other impediments to > doing so) > > You can fetch it and merge it like so: > > git fetch -t git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git > git verify-tag efi-loongarch-for-v6.1 # if you like > git merge efi-loongarch-for-v6.1 > > and all your other v6.1 changes can go on top. > > This way, you can resolve conflicts locally without affecting the EFI > changes going via the other tree. The EFI stub for LoongArch change > will arrive into Linus's tree via whichever tree he pulls first: the > LoongArch one or the EFI one. > > I will rebase my zboot decompressor changes on top of this - I will cc > you again, as the LoongArch builds ok but still does not boot. > I have pushed a branch here that includes EFI decompressor support for LoongArch https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 You will need to enable CONFIG_EFI_ZBOOT and build the zImage.efi target. The resulting image should be bootable jus tlike the vmlinux.efi but for some reason, it produces the crash I reported earlier. Please give it a try, and if you manage to figure out what's wrong with my code, please let me know :-) Thanks, Ard.
Hi, Ard, On Mon, Aug 22, 2022 at 6:44 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > On Fri, 19 Aug 2022 at 12:20, Huacai Chen <chenhuacai@loongson.cn> wrote: > > > > This patch adds efistub booting support, which is the standard UEFI boot > > protocol for us to use. > > > > We use generic efistub, which means we can pass boot information (i.e., > > system table, memory map, kernel command line, initrd) via a light FDT > > and drop a lot of non-standard code. > > > > We use a flat mapping to map the efi runtime in the kernel's address > > space. In efi, VA = PA; in kernel, VA = PA + PAGE_OFFSET. As a result, > > flat mapping is not identity mapping, SetVirtualAddressMap() is still > > needed for the efi runtime. > > > > Tested-by: Xi Ruoyao <xry111@xry111.site> > > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > > --- > > V1 --> V2: > > 1, Call SetVirtualAddressMap() in stub; > > 2, Use core kernel data directly in alloc_screen_info(); > > 3, Remove the magic number in MS-DOS header; > > 4, Disable EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER; > > 5, Some other small changes suggested by Ard Biesheuvel. > > > > V2 --> V3: > > 1, Adjust Makefile to adapt zboot; > > 2, Introduce EFI_RT_VIRTUAL_OFFSET instead of changing flat_va_mapping. > > > > Thanks for the update. > > I am going to queue this up in the efi/next tree. However, due to the > many changes to arch/loongarch in this patch, conflicts are not > unlikely, so I created a signed stable tag for the patch that you can > merge into the loongarch arch tree if you want. > > *However*, you must *not* rebase your tree after merging this tag. > Therefore, it is probably best that the merge of this tag appears as > the very first change on your PR to Linus for v6.1. Everything after > can be rebased at will (assuming there are no other impediments to > doing so) > > You can fetch it and merge it like so: > > git fetch -t git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git > git verify-tag efi-loongarch-for-v6.1 # if you like > git merge efi-loongarch-for-v6.1 > > and all your other v6.1 changes can go on top. > > This way, you can resolve conflicts locally without affecting the EFI > changes going via the other tree. The EFI stub for LoongArch change > will arrive into Linus's tree via whichever tree he pulls first: the > LoongArch one or the EFI one. > > I will rebase my zboot decompressor changes on top of this - I will cc > you again, as the LoongArch builds ok but still does not boot. Thank you very much. There are several bugs that need to be fixed first for the 6.0 cycle, I will merge the efi-loongarch-for-v6.1 tag after that. Huacai > > Thanks, > Ard.
Hi, Ard, On Tue, Aug 23, 2022 at 2:03 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > On Mon, 22 Aug 2022 at 12:44, Ard Biesheuvel <ardb@kernel.org> wrote: > > > > On Fri, 19 Aug 2022 at 12:20, Huacai Chen <chenhuacai@loongson.cn> wrote: > > > > > > This patch adds efistub booting support, which is the standard UEFI boot > > > protocol for us to use. > > > > > > We use generic efistub, which means we can pass boot information (i.e., > > > system table, memory map, kernel command line, initrd) via a light FDT > > > and drop a lot of non-standard code. > > > > > > We use a flat mapping to map the efi runtime in the kernel's address > > > space. In efi, VA = PA; in kernel, VA = PA + PAGE_OFFSET. As a result, > > > flat mapping is not identity mapping, SetVirtualAddressMap() is still > > > needed for the efi runtime. > > > > > > Tested-by: Xi Ruoyao <xry111@xry111.site> > > > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > > > --- > > > V1 --> V2: > > > 1, Call SetVirtualAddressMap() in stub; > > > 2, Use core kernel data directly in alloc_screen_info(); > > > 3, Remove the magic number in MS-DOS header; > > > 4, Disable EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER; > > > 5, Some other small changes suggested by Ard Biesheuvel. > > > > > > V2 --> V3: > > > 1, Adjust Makefile to adapt zboot; > > > 2, Introduce EFI_RT_VIRTUAL_OFFSET instead of changing flat_va_mapping. > > > > > > > Thanks for the update. > > > > I am going to queue this up in the efi/next tree. However, due to the > > many changes to arch/loongarch in this patch, conflicts are not > > unlikely, so I created a signed stable tag for the patch that you can > > merge into the loongarch arch tree if you want. > > > > *However*, you must *not* rebase your tree after merging this tag. > > Therefore, it is probably best that the merge of this tag appears as > > the very first change on your PR to Linus for v6.1. Everything after > > can be rebased at will (assuming there are no other impediments to > > doing so) > > > > You can fetch it and merge it like so: > > > > git fetch -t git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git > > git verify-tag efi-loongarch-for-v6.1 # if you like > > git merge efi-loongarch-for-v6.1 > > > > and all your other v6.1 changes can go on top. > > > > This way, you can resolve conflicts locally without affecting the EFI > > changes going via the other tree. The EFI stub for LoongArch change > > will arrive into Linus's tree via whichever tree he pulls first: the > > LoongArch one or the EFI one. > > > > I will rebase my zboot decompressor changes on top of this - I will cc > > you again, as the LoongArch builds ok but still does not boot. > > > > I have pushed a branch here that includes EFI decompressor support for LoongArch > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > > You will need to enable CONFIG_EFI_ZBOOT and build the zImage.efi > target. The resulting image should be bootable jus tlike the > vmlinux.efi but for some reason, it produces the crash I reported > earlier. > > Please give it a try, and if you manage to figure out what's wrong > with my code, please let me know :-) I will try zboot on my real machine. For the code, I prefer vmlinuz.efi rather than zImage.efi for LoongArch since it keeps the naming consistency. Huacai > > Thanks, > Ard.
Tested V3 with the magic number check manually removed in my GRUB build. The system boots successfully. I've not tested Arnd's zBoot patch yet.
On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > Tested V3 with the magic number check manually removed in my GRUB build. > The system boots successfully. I've not tested Arnd's zBoot patch yet. I am Ard not Arnd :-) Please use this branch when testing the EFI decompressor: https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4
Hi, Ard, On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > > > Tested V3 with the magic number check manually removed in my GRUB build. > > The system boots successfully. I've not tested Arnd's zBoot patch yet. > > I am Ard not Arnd :-) > > Please use this branch when testing the EFI decompressor: > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 The root cause of LoongArch zboot boot failure has been found, it is a binutils bug, latest toolchain with the below patch can solve the problem. diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index 5b44901b9e0..fafdc7c7458 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, case R_LARCH_SOP_PUSH_PLT_PCREL: unresolved_reloc = false; - if (resolved_to_const) + if (!is_undefweak && resolved_to_const) { relocation += rel->r_addend; + relocation -= pc; break; } else if (is_undefweak) Huacai
Hi, Ard, On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: > > Hi, Ard, > > On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > > > > > Tested V3 with the magic number check manually removed in my GRUB build. > > > The system boots successfully. I've not tested Arnd's zBoot patch yet. > > > > I am Ard not Arnd :-) > > > > Please use this branch when testing the EFI decompressor: > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > The root cause of LoongArch zboot boot failure has been found, it is a > binutils bug, latest toolchain with the below patch can solve the > problem. > > diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c > index 5b44901b9e0..fafdc7c7458 100644 > --- a/bfd/elfnn-loongarch.c > +++ b/bfd/elfnn-loongarch.c > @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd > *output_bfd, struct bfd_link_info *info, > case R_LARCH_SOP_PUSH_PLT_PCREL: > unresolved_reloc = false; > > - if (resolved_to_const) > + if (!is_undefweak && resolved_to_const) > { > relocation += rel->r_addend; > + relocation -= pc; > break; > } > else if (is_undefweak) > > > Huacai Now the patch is submitted here: https://sourceware.org/pipermail/binutils/2022-September/122713.html And I have some other questions about kexec: kexec should jump to the elf entry or the pe entry? I think is the elf entry, because if we jump to the pe entry, then SVAM will be executed twice (but it should be executed only once). However, how can we jump to the elf entry if we use zboot? Maybe it is kexec-tool's responsibility to decompress the zboot kernel image? Huacai
On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: > > Hi, Ard, > > On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: > > > > Hi, Ard, > > > > On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > > > On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > > > > > > > Tested V3 with the magic number check manually removed in my GRUB build. > > > > The system boots successfully. I've not tested Arnd's zBoot patch yet. > > > > > > I am Ard not Arnd :-) > > > > > > Please use this branch when testing the EFI decompressor: > > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > > The root cause of LoongArch zboot boot failure has been found, it is a > > binutils bug, latest toolchain with the below patch can solve the > > problem. > > > > diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c > > index 5b44901b9e0..fafdc7c7458 100644 > > --- a/bfd/elfnn-loongarch.c > > +++ b/bfd/elfnn-loongarch.c > > @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd > > *output_bfd, struct bfd_link_info *info, > > case R_LARCH_SOP_PUSH_PLT_PCREL: > > unresolved_reloc = false; > > > > - if (resolved_to_const) > > + if (!is_undefweak && resolved_to_const) > > { > > relocation += rel->r_addend; > > + relocation -= pc; > > break; > > } > > else if (is_undefweak) > > > > > > Huacai > Now the patch is submitted here: > https://sourceware.org/pipermail/binutils/2022-September/122713.html > Great. Given the severity of this bug, I imagine that building the LoongArch kernel will require a version of binutils that carries this fix. Therefore, i will revert back to the original approach for accessing uncompressed_size, using an extern declaration with an __aligned(1) attribute. > And I have some other questions about kexec: kexec should jump to the > elf entry or the pe entry? I think is the elf entry, because if we > jump to the pe entry, then SVAM will be executed twice (but it should > be executed only once). However, how can we jump to the elf entry if > we use zboot? Maybe it is kexec-tool's responsibility to decompress > the zboot kernel image? > Yes, very good point. Kexec kernels cannot boot via the EFI entry point, as the boot services will already be shutdown. So the kexec kernel needs to boot via the same entrypoint in the core kernel that the EFI stub calls when it hands over. For the EFI zboot image in particular, we will need to teach kexec how to decompress them. The zboot image has a header that a) describes it as a EFI linux zimg b) describes the start and end offset of the compressed payload c) describes which compression algorithm was used. This means that any non-EFI loader (including kexec) should be able to extract the inner PE/COFF image and decompress it. For arm64 and RISC-V, this is sufficient as the EFI and raw images are the same. For LoongArch, I suppose it means we need a way to enter the core kernel directly via the entrypoint that the EFI stub uses when handing over (and pass the original DT argument so the kexec kernel has access to the EFI and ACPI firmware tables)
Hi, Ard, On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: > > > > Hi, Ard, > > > > On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > Hi, Ard, > > > > > > On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > > > > > On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > > > > > > > > > Tested V3 with the magic number check manually removed in my GRUB build. > > > > > The system boots successfully. I've not tested Arnd's zBoot patch yet. > > > > > > > > I am Ard not Arnd :-) > > > > > > > > Please use this branch when testing the EFI decompressor: > > > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > > > The root cause of LoongArch zboot boot failure has been found, it is a > > > binutils bug, latest toolchain with the below patch can solve the > > > problem. > > > > > > diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c > > > index 5b44901b9e0..fafdc7c7458 100644 > > > --- a/bfd/elfnn-loongarch.c > > > +++ b/bfd/elfnn-loongarch.c > > > @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd > > > *output_bfd, struct bfd_link_info *info, > > > case R_LARCH_SOP_PUSH_PLT_PCREL: > > > unresolved_reloc = false; > > > > > > - if (resolved_to_const) > > > + if (!is_undefweak && resolved_to_const) > > > { > > > relocation += rel->r_addend; > > > + relocation -= pc; > > > break; > > > } > > > else if (is_undefweak) > > > > > > > > > Huacai > > Now the patch is submitted here: > > https://sourceware.org/pipermail/binutils/2022-September/122713.html > > > > Great. Given the severity of this bug, I imagine that building the > LoongArch kernel will require a version of binutils that carries this > fix. > > Therefore, i will revert back to the original approach for accessing > uncompressed_size, using an extern declaration with an __aligned(1) > attribute. > > > And I have some other questions about kexec: kexec should jump to the > > elf entry or the pe entry? I think is the elf entry, because if we > > jump to the pe entry, then SVAM will be executed twice (but it should > > be executed only once). However, how can we jump to the elf entry if > > we use zboot? Maybe it is kexec-tool's responsibility to decompress > > the zboot kernel image? > > > > Yes, very good point. Kexec kernels cannot boot via the EFI entry > point, as the boot services will already be shutdown. So the kexec > kernel needs to boot via the same entrypoint in the core kernel that > the EFI stub calls when it hands over. > > For the EFI zboot image in particular, we will need to teach kexec how > to decompress them. The zboot image has a header that > a) describes it as a EFI linux zimg > b) describes the start and end offset of the compressed payload > c) describes which compression algorithm was used. > > This means that any non-EFI loader (including kexec) should be able to > extract the inner PE/COFF image and decompress it. For arm64 and > RISC-V, this is sufficient as the EFI and raw images are the same. For > LoongArch, I suppose it means we need a way to enter the core kernel > directly via the entrypoint that the EFI stub uses when handing over > (and pass the original DT argument so the kexec kernel has access to > the EFI and ACPI firmware tables) OK, then is this implementation [1] acceptable? I remember that you said the MS-DOS header shouldn't contain other information, so I guess this is unacceptable? [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad Huacai
Hi, Ard & Huacai On 09/05/2022 11:50 AM, Huacai Chen wrote: > Hi, Ard, > > On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: >> >> On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: >>> >>> Hi, Ard, >>> >>> On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: >>>> >>>> Hi, Ard, >>>> >>>> On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: >>>>> >>>>> On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: >>>>>> >>>>>> Tested V3 with the magic number check manually removed in my GRUB build. >>>>>> The system boots successfully. I've not tested Arnd's zBoot patch yet. >>>>> >>>>> I am Ard not Arnd :-) >>>>> >>>>> Please use this branch when testing the EFI decompressor: >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 >>>> The root cause of LoongArch zboot boot failure has been found, it is a >>>> binutils bug, latest toolchain with the below patch can solve the >>>> problem. >>>> >>>> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c >>>> index 5b44901b9e0..fafdc7c7458 100644 >>>> --- a/bfd/elfnn-loongarch.c >>>> +++ b/bfd/elfnn-loongarch.c >>>> @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd >>>> *output_bfd, struct bfd_link_info *info, >>>> case R_LARCH_SOP_PUSH_PLT_PCREL: >>>> unresolved_reloc = false; >>>> >>>> - if (resolved_to_const) >>>> + if (!is_undefweak && resolved_to_const) >>>> { >>>> relocation += rel->r_addend; >>>> + relocation -= pc; >>>> break; >>>> } >>>> else if (is_undefweak) >>>> >>>> >>>> Huacai >>> Now the patch is submitted here: >>> https://sourceware.org/pipermail/binutils/2022-September/122713.html >>> >> >> Great. Given the severity of this bug, I imagine that building the >> LoongArch kernel will require a version of binutils that carries this >> fix. >> >> Therefore, i will revert back to the original approach for accessing >> uncompressed_size, using an extern declaration with an __aligned(1) >> attribute. >> >>> And I have some other questions about kexec: kexec should jump to the >>> elf entry or the pe entry? I think is the elf entry, because if we >>> jump to the pe entry, then SVAM will be executed twice (but it should >>> be executed only once). However, how can we jump to the elf entry if >>> we use zboot? Maybe it is kexec-tool's responsibility to decompress >>> the zboot kernel image? >>> >> >> Yes, very good point. Kexec kernels cannot boot via the EFI entry >> point, as the boot services will already be shutdown. So the kexec >> kernel needs to boot via the same entrypoint in the core kernel that >> the EFI stub calls when it hands over. >> >> For the EFI zboot image in particular, we will need to teach kexec how >> to decompress them. The zboot image has a header that >> a) describes it as a EFI linux zimg >> b) describes the start and end offset of the compressed payload >> c) describes which compression algorithm was used. >> >> This means that any non-EFI loader (including kexec) should be able to >> extract the inner PE/COFF image and decompress it. For arm64 and >> RISC-V, this is sufficient as the EFI and raw images are the same. For >> LoongArch, I suppose it means we need a way to enter the core kernel >> directly via the entrypoint that the EFI stub uses when handing over >> (and pass the original DT argument so the kexec kernel has access to >> the EFI and ACPI firmware tables) > OK, then is this implementation [1] acceptable? I remember that you > said the MS-DOS header shouldn't contain other information, so I guess > this is unacceptable? > > [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad Modifications to the MS-DOS header refer to the arm64 and riscv implementations [1], and to provide the necessary information to kexec-tools[2] when loading uncompressed efi images. [1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0f327f2aaad6a87356cbccfa390d4d3b64d0d3b6 [2] https://github.com/horms/kexec-tools/blob/main/kexec/arch/arm64/image-header.h Thanks, Youling > > Huacai >
Hi, Ard & Huacai While applying this patch [1] we need to add vmlinuz* (vmlinuz and vmlinuz.efi) to arch/loongarch/boot/.gitignore to ignore the generated binary (also required for arm64 and riscv). [1] https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/commit/?h=efi-decompressor-v4&id=efcc03a013f2ddbed0ee782e5049b39432dc9db2 Thanks, Youling. On 09/05/2022 12:34 PM, Youling Tang wrote: > Hi, Ard & Huacai > > On 09/05/2022 11:50 AM, Huacai Chen wrote: >> Hi, Ard, >> >> On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: >>> >>> On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: >>>> >>>> Hi, Ard, >>>> >>>> On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> >>>> wrote: >>>>> >>>>> Hi, Ard, >>>>> >>>>> On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> >>>>> wrote: >>>>>> >>>>>> On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: >>>>>>> >>>>>>> Tested V3 with the magic number check manually removed in my GRUB >>>>>>> build. >>>>>>> The system boots successfully. I've not tested Arnd's zBoot >>>>>>> patch yet. >>>>>> >>>>>> I am Ard not Arnd :-) >>>>>> >>>>>> Please use this branch when testing the EFI decompressor: >>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 >>>>>> >>>>> The root cause of LoongArch zboot boot failure has been found, it is a >>>>> binutils bug, latest toolchain with the below patch can solve the >>>>> problem. >>>>> >>>>> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c >>>>> index 5b44901b9e0..fafdc7c7458 100644 >>>>> --- a/bfd/elfnn-loongarch.c >>>>> +++ b/bfd/elfnn-loongarch.c >>>>> @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd >>>>> *output_bfd, struct bfd_link_info *info, >>>>> case R_LARCH_SOP_PUSH_PLT_PCREL: >>>>> unresolved_reloc = false; >>>>> >>>>> - if (resolved_to_const) >>>>> + if (!is_undefweak && resolved_to_const) >>>>> { >>>>> relocation += rel->r_addend; >>>>> + relocation -= pc; >>>>> break; >>>>> } >>>>> else if (is_undefweak) >>>>> >>>>> >>>>> Huacai >>>> Now the patch is submitted here: >>>> https://sourceware.org/pipermail/binutils/2022-September/122713.html >>>> >>> >>> Great. Given the severity of this bug, I imagine that building the >>> LoongArch kernel will require a version of binutils that carries this >>> fix. >>> >>> Therefore, i will revert back to the original approach for accessing >>> uncompressed_size, using an extern declaration with an __aligned(1) >>> attribute. >>> >>>> And I have some other questions about kexec: kexec should jump to the >>>> elf entry or the pe entry? I think is the elf entry, because if we >>>> jump to the pe entry, then SVAM will be executed twice (but it should >>>> be executed only once). However, how can we jump to the elf entry if >>>> we use zboot? Maybe it is kexec-tool's responsibility to decompress >>>> the zboot kernel image? >>>> >>> >>> Yes, very good point. Kexec kernels cannot boot via the EFI entry >>> point, as the boot services will already be shutdown. So the kexec >>> kernel needs to boot via the same entrypoint in the core kernel that >>> the EFI stub calls when it hands over. >>> >>> For the EFI zboot image in particular, we will need to teach kexec how >>> to decompress them. The zboot image has a header that >>> a) describes it as a EFI linux zimg >>> b) describes the start and end offset of the compressed payload >>> c) describes which compression algorithm was used. >>> >>> This means that any non-EFI loader (including kexec) should be able to >>> extract the inner PE/COFF image and decompress it. For arm64 and >>> RISC-V, this is sufficient as the EFI and raw images are the same. For >>> LoongArch, I suppose it means we need a way to enter the core kernel >>> directly via the entrypoint that the EFI stub uses when handing over >>> (and pass the original DT argument so the kexec kernel has access to >>> the EFI and ACPI firmware tables) >> OK, then is this implementation [1] acceptable? I remember that you >> said the MS-DOS header shouldn't contain other information, so I guess >> this is unacceptable? >> >> [1] >> https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad >> > > Modifications to the MS-DOS header refer to the arm64 and riscv > implementations [1], and to provide the necessary information to > kexec-tools[2] when loading uncompressed efi images. > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0f327f2aaad6a87356cbccfa390d4d3b64d0d3b6 > > [2] > https://github.com/horms/kexec-tools/blob/main/kexec/arch/arm64/image-header.h > > > Thanks, > Youling > >> >> Huacai >> >
On Mon, 5 Sept 2022 at 05:51, Huacai Chen <chenhuacai@kernel.org> wrote: > > Hi, Ard, > > On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > Hi, Ard, > > > > > > On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > > > Hi, Ard, > > > > > > > > On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > > > > > > > On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > > > > > > > > > > > Tested V3 with the magic number check manually removed in my GRUB build. > > > > > > The system boots successfully. I've not tested Arnd's zBoot patch yet. > > > > > > > > > > I am Ard not Arnd :-) > > > > > > > > > > Please use this branch when testing the EFI decompressor: > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > > > > The root cause of LoongArch zboot boot failure has been found, it is a > > > > binutils bug, latest toolchain with the below patch can solve the > > > > problem. > > > > > > > > diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c > > > > index 5b44901b9e0..fafdc7c7458 100644 > > > > --- a/bfd/elfnn-loongarch.c > > > > +++ b/bfd/elfnn-loongarch.c > > > > @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd > > > > *output_bfd, struct bfd_link_info *info, > > > > case R_LARCH_SOP_PUSH_PLT_PCREL: > > > > unresolved_reloc = false; > > > > > > > > - if (resolved_to_const) > > > > + if (!is_undefweak && resolved_to_const) > > > > { > > > > relocation += rel->r_addend; > > > > + relocation -= pc; > > > > break; > > > > } > > > > else if (is_undefweak) > > > > > > > > > > > > Huacai > > > Now the patch is submitted here: > > > https://sourceware.org/pipermail/binutils/2022-September/122713.html > > > > > > > Great. Given the severity of this bug, I imagine that building the > > LoongArch kernel will require a version of binutils that carries this > > fix. > > > > Therefore, i will revert back to the original approach for accessing > > uncompressed_size, using an extern declaration with an __aligned(1) > > attribute. > > > > > And I have some other questions about kexec: kexec should jump to the > > > elf entry or the pe entry? I think is the elf entry, because if we > > > jump to the pe entry, then SVAM will be executed twice (but it should > > > be executed only once). However, how can we jump to the elf entry if > > > we use zboot? Maybe it is kexec-tool's responsibility to decompress > > > the zboot kernel image? > > > > > > > Yes, very good point. Kexec kernels cannot boot via the EFI entry > > point, as the boot services will already be shutdown. So the kexec > > kernel needs to boot via the same entrypoint in the core kernel that > > the EFI stub calls when it hands over. > > > > For the EFI zboot image in particular, we will need to teach kexec how > > to decompress them. The zboot image has a header that > > a) describes it as a EFI linux zimg > > b) describes the start and end offset of the compressed payload > > c) describes which compression algorithm was used. > > > > This means that any non-EFI loader (including kexec) should be able to > > extract the inner PE/COFF image and decompress it. For arm64 and > > RISC-V, this is sufficient as the EFI and raw images are the same. For > > LoongArch, I suppose it means we need a way to enter the core kernel > > directly via the entrypoint that the EFI stub uses when handing over > > (and pass the original DT argument so the kexec kernel has access to > > the EFI and ACPI firmware tables) > OK, then is this implementation [1] acceptable? I remember that you > said the MS-DOS header shouldn't contain other information, so I guess > this is unacceptable? > No, this looks reasonable to me. I objected to using magic numbers in the 'pure PE' view of the image, as it does not make sense for a pure PE loader such as GRUB to rely on such metadata. In this case (like on arm64), we are dealing with something else: we need to identify the image to the kernel itself, and here, using the unused space in the MS-DOS header is fine. > [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad > > Huacai
On Mon, 5 Sept 2022 at 06:34, Youling Tang <tangyouling@loongson.cn> wrote: > > Hi, Ard & Huacai > > On 09/05/2022 11:50 AM, Huacai Chen wrote: > > Hi, Ard, > > > > On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: > >> > >> On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: > >>> > >>> Hi, Ard, > >>> > >>> On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: > >>>> > >>>> Hi, Ard, > >>>> > >>>> On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > >>>>> > >>>>> On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > >>>>>> > >>>>>> Tested V3 with the magic number check manually removed in my GRUB build. > >>>>>> The system boots successfully. I've not tested Arnd's zBoot patch yet. > >>>>> > >>>>> I am Ard not Arnd :-) > >>>>> > >>>>> Please use this branch when testing the EFI decompressor: > >>>>> https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > >>>> The root cause of LoongArch zboot boot failure has been found, it is a > >>>> binutils bug, latest toolchain with the below patch can solve the > >>>> problem. > >>>> > >>>> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c > >>>> index 5b44901b9e0..fafdc7c7458 100644 > >>>> --- a/bfd/elfnn-loongarch.c > >>>> +++ b/bfd/elfnn-loongarch.c > >>>> @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd > >>>> *output_bfd, struct bfd_link_info *info, > >>>> case R_LARCH_SOP_PUSH_PLT_PCREL: > >>>> unresolved_reloc = false; > >>>> > >>>> - if (resolved_to_const) > >>>> + if (!is_undefweak && resolved_to_const) > >>>> { > >>>> relocation += rel->r_addend; > >>>> + relocation -= pc; > >>>> break; > >>>> } > >>>> else if (is_undefweak) > >>>> > >>>> > >>>> Huacai > >>> Now the patch is submitted here: > >>> https://sourceware.org/pipermail/binutils/2022-September/122713.html > >>> > >> > >> Great. Given the severity of this bug, I imagine that building the > >> LoongArch kernel will require a version of binutils that carries this > >> fix. > >> > >> Therefore, i will revert back to the original approach for accessing > >> uncompressed_size, using an extern declaration with an __aligned(1) > >> attribute. > >> > >>> And I have some other questions about kexec: kexec should jump to the > >>> elf entry or the pe entry? I think is the elf entry, because if we > >>> jump to the pe entry, then SVAM will be executed twice (but it should > >>> be executed only once). However, how can we jump to the elf entry if > >>> we use zboot? Maybe it is kexec-tool's responsibility to decompress > >>> the zboot kernel image? > >>> > >> > >> Yes, very good point. Kexec kernels cannot boot via the EFI entry > >> point, as the boot services will already be shutdown. So the kexec > >> kernel needs to boot via the same entrypoint in the core kernel that > >> the EFI stub calls when it hands over. > >> > >> For the EFI zboot image in particular, we will need to teach kexec how > >> to decompress them. The zboot image has a header that > >> a) describes it as a EFI linux zimg > >> b) describes the start and end offset of the compressed payload > >> c) describes which compression algorithm was used. > >> > >> This means that any non-EFI loader (including kexec) should be able to > >> extract the inner PE/COFF image and decompress it. For arm64 and > >> RISC-V, this is sufficient as the EFI and raw images are the same. For > >> LoongArch, I suppose it means we need a way to enter the core kernel > >> directly via the entrypoint that the EFI stub uses when handing over > >> (and pass the original DT argument so the kexec kernel has access to > >> the EFI and ACPI firmware tables) > > OK, then is this implementation [1] acceptable? I remember that you > > said the MS-DOS header shouldn't contain other information, so I guess > > this is unacceptable? > > > > [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad > > Modifications to the MS-DOS header refer to the arm64 and riscv > implementations [1], and to provide the necessary information to > kexec-tools[2] when loading uncompressed efi images. > Indeed. On top of the EFI zboot series, we need some [generic!] kexec plumbing to identify such compressed images, and decompress the payload before passing the contents to the arch specific probe/load image hooks.
On Mon, 5 Sept 2022 at 08:29, Youling Tang <tangyouling@loongson.cn> wrote: > > Hi, Ard & Huacai > > While applying this patch [1] we need to add vmlinuz* (vmlinuz and > vmlinuz.efi) to arch/loongarch/boot/.gitignore to ignore the generated > binary (also required for arm64 and riscv). > > [1] > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/commit/?h=efi-decompressor-v4&id=efcc03a013f2ddbed0ee782e5049b39432dc9db2 > Good point. I'll add that.
Hi, Ard and Youling, On Mon, Sep 5, 2022 at 3:02 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > On Mon, 5 Sept 2022 at 05:51, Huacai Chen <chenhuacai@kernel.org> wrote: > > > > Hi, Ard, > > > > On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > > > On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > > > Hi, Ard, > > > > > > > > On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > > > > > Hi, Ard, > > > > > > > > > > On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > > > > > > > > > On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > > > > > > > > > > > > > Tested V3 with the magic number check manually removed in my GRUB build. > > > > > > > The system boots successfully. I've not tested Arnd's zBoot patch yet. > > > > > > > > > > > > I am Ard not Arnd :-) > > > > > > > > > > > > Please use this branch when testing the EFI decompressor: > > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > > > > > The root cause of LoongArch zboot boot failure has been found, it is a > > > > > binutils bug, latest toolchain with the below patch can solve the > > > > > problem. > > > > > > > > > > diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c > > > > > index 5b44901b9e0..fafdc7c7458 100644 > > > > > --- a/bfd/elfnn-loongarch.c > > > > > +++ b/bfd/elfnn-loongarch.c > > > > > @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd > > > > > *output_bfd, struct bfd_link_info *info, > > > > > case R_LARCH_SOP_PUSH_PLT_PCREL: > > > > > unresolved_reloc = false; > > > > > > > > > > - if (resolved_to_const) > > > > > + if (!is_undefweak && resolved_to_const) > > > > > { > > > > > relocation += rel->r_addend; > > > > > + relocation -= pc; > > > > > break; > > > > > } > > > > > else if (is_undefweak) > > > > > > > > > > > > > > > Huacai > > > > Now the patch is submitted here: > > > > https://sourceware.org/pipermail/binutils/2022-September/122713.html > > > > > > > > > > Great. Given the severity of this bug, I imagine that building the > > > LoongArch kernel will require a version of binutils that carries this > > > fix. > > > > > > Therefore, i will revert back to the original approach for accessing > > > uncompressed_size, using an extern declaration with an __aligned(1) > > > attribute. > > > > > > > And I have some other questions about kexec: kexec should jump to the > > > > elf entry or the pe entry? I think is the elf entry, because if we > > > > jump to the pe entry, then SVAM will be executed twice (but it should > > > > be executed only once). However, how can we jump to the elf entry if > > > > we use zboot? Maybe it is kexec-tool's responsibility to decompress > > > > the zboot kernel image? > > > > > > > > > > Yes, very good point. Kexec kernels cannot boot via the EFI entry > > > point, as the boot services will already be shutdown. So the kexec > > > kernel needs to boot via the same entrypoint in the core kernel that > > > the EFI stub calls when it hands over. > > > > > > For the EFI zboot image in particular, we will need to teach kexec how > > > to decompress them. The zboot image has a header that > > > a) describes it as a EFI linux zimg > > > b) describes the start and end offset of the compressed payload > > > c) describes which compression algorithm was used. > > > > > > This means that any non-EFI loader (including kexec) should be able to > > > extract the inner PE/COFF image and decompress it. For arm64 and > > > RISC-V, this is sufficient as the EFI and raw images are the same. For > > > LoongArch, I suppose it means we need a way to enter the core kernel > > > directly via the entrypoint that the EFI stub uses when handing over > > > (and pass the original DT argument so the kexec kernel has access to > > > the EFI and ACPI firmware tables) > > OK, then is this implementation [1] acceptable? I remember that you > > said the MS-DOS header shouldn't contain other information, so I guess > > this is unacceptable? > > > > No, this looks reasonable to me. I objected to using magic numbers in > the 'pure PE' view of the image, as it does not make sense for a pure > PE loader such as GRUB to rely on such metadata. > > In this case (like on arm64), we are dealing with something else: we > need to identify the image to the kernel itself, and here, using the > unused space in the MS-DOS header is fine. > > > [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad OK, then there is no big problem here. And I found that arm64/riscv don't need the kernel entry point in the header. I don't know why, but I think it implies that a unified layout across architectures is unnecessary, and I prefer to put the kernel entry point before effective kernel size. :) Huacai > > > > Huacai
On Mon, 5 Sept 2022 at 09:25, Huacai Chen <chenhuacai@kernel.org> wrote: > > Hi, Ard and Youling, > > On Mon, Sep 5, 2022 at 3:02 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > On Mon, 5 Sept 2022 at 05:51, Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > Hi, Ard, > > > > > > On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > > > > > On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > > > > > Hi, Ard, > > > > > > > > > > On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: > > > > > > > > > > > > Hi, Ard, > > > > > > > > > > > > On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: > > > > > > > > > > > > > > On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: > > > > > > > > > > > > > > > > Tested V3 with the magic number check manually removed in my GRUB build. > > > > > > > > The system boots successfully. I've not tested Arnd's zBoot patch yet. > > > > > > > > > > > > > > I am Ard not Arnd :-) > > > > > > > > > > > > > > Please use this branch when testing the EFI decompressor: > > > > > > > https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 > > > > > > The root cause of LoongArch zboot boot failure has been found, it is a > > > > > > binutils bug, latest toolchain with the below patch can solve the > > > > > > problem. > > > > > > > > > > > > diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c > > > > > > index 5b44901b9e0..fafdc7c7458 100644 > > > > > > --- a/bfd/elfnn-loongarch.c > > > > > > +++ b/bfd/elfnn-loongarch.c > > > > > > @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd > > > > > > *output_bfd, struct bfd_link_info *info, > > > > > > case R_LARCH_SOP_PUSH_PLT_PCREL: > > > > > > unresolved_reloc = false; > > > > > > > > > > > > - if (resolved_to_const) > > > > > > + if (!is_undefweak && resolved_to_const) > > > > > > { > > > > > > relocation += rel->r_addend; > > > > > > + relocation -= pc; > > > > > > break; > > > > > > } > > > > > > else if (is_undefweak) > > > > > > > > > > > > > > > > > > Huacai > > > > > Now the patch is submitted here: > > > > > https://sourceware.org/pipermail/binutils/2022-September/122713.html > > > > > > > > > > > > > Great. Given the severity of this bug, I imagine that building the > > > > LoongArch kernel will require a version of binutils that carries this > > > > fix. > > > > > > > > Therefore, i will revert back to the original approach for accessing > > > > uncompressed_size, using an extern declaration with an __aligned(1) > > > > attribute. > > > > > > > > > And I have some other questions about kexec: kexec should jump to the > > > > > elf entry or the pe entry? I think is the elf entry, because if we > > > > > jump to the pe entry, then SVAM will be executed twice (but it should > > > > > be executed only once). However, how can we jump to the elf entry if > > > > > we use zboot? Maybe it is kexec-tool's responsibility to decompress > > > > > the zboot kernel image? > > > > > > > > > > > > > Yes, very good point. Kexec kernels cannot boot via the EFI entry > > > > point, as the boot services will already be shutdown. So the kexec > > > > kernel needs to boot via the same entrypoint in the core kernel that > > > > the EFI stub calls when it hands over. > > > > > > > > For the EFI zboot image in particular, we will need to teach kexec how > > > > to decompress them. The zboot image has a header that > > > > a) describes it as a EFI linux zimg > > > > b) describes the start and end offset of the compressed payload > > > > c) describes which compression algorithm was used. > > > > > > > > This means that any non-EFI loader (including kexec) should be able to > > > > extract the inner PE/COFF image and decompress it. For arm64 and > > > > RISC-V, this is sufficient as the EFI and raw images are the same. For > > > > LoongArch, I suppose it means we need a way to enter the core kernel > > > > directly via the entrypoint that the EFI stub uses when handing over > > > > (and pass the original DT argument so the kexec kernel has access to > > > > the EFI and ACPI firmware tables) > > > OK, then is this implementation [1] acceptable? I remember that you > > > said the MS-DOS header shouldn't contain other information, so I guess > > > this is unacceptable? > > > > > > > No, this looks reasonable to me. I objected to using magic numbers in > > the 'pure PE' view of the image, as it does not make sense for a pure > > PE loader such as GRUB to rely on such metadata. > > > > In this case (like on arm64), we are dealing with something else: we > > need to identify the image to the kernel itself, and here, using the > > unused space in the MS-DOS header is fine. > > > > > [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad > OK, then there is no big problem here. And I found that arm64/riscv > don't need the kernel entry point in the header. I don't know why, but > I think it implies that a unified layout across architectures is > unnecessary, and I prefer to put the kernel entry point before > effective kernel size. :) > It is fine to put the entry point offset in the header. arm64 and RISC-V don't need this because the first instructions are a pseudo-NOP (an instruction that does nothing but its binary encoding looks like 'MZ..') and a jump to the actual entry point.
Hi, Huacai On 09/05/2022 03:24 PM, Huacai Chen wrote: > Hi, Ard and Youling, > > On Mon, Sep 5, 2022 at 3:02 PM Ard Biesheuvel <ardb@kernel.org> wrote: >> >> On Mon, 5 Sept 2022 at 05:51, Huacai Chen <chenhuacai@kernel.org> wrote: >>> >>> Hi, Ard, >>> >>> On Mon, Sep 5, 2022 at 5:59 AM Ard Biesheuvel <ardb@kernel.org> wrote: >>>> >>>> On Sun, 4 Sept 2022 at 15:24, Huacai Chen <chenhuacai@kernel.org> wrote: >>>>> >>>>> Hi, Ard, >>>>> >>>>> On Thu, Sep 1, 2022 at 6:40 PM Huacai Chen <chenhuacai@kernel.org> wrote: >>>>>> >>>>>> Hi, Ard, >>>>>> >>>>>> On Sat, Aug 27, 2022 at 3:14 PM Ard Biesheuvel <ardb@kernel.org> wrote: >>>>>>> >>>>>>> On Sat, 27 Aug 2022 at 06:41, Xi Ruoyao <xry111@xry111.site> wrote: >>>>>>>> >>>>>>>> Tested V3 with the magic number check manually removed in my GRUB build. >>>>>>>> The system boots successfully. I've not tested Arnd's zBoot patch yet. >>>>>>> >>>>>>> I am Ard not Arnd :-) >>>>>>> >>>>>>> Please use this branch when testing the EFI decompressor: >>>>>>> https://git.kernel.org/pub/scm/linux/kernel/git/ardb/linux.git/log/?h=efi-decompressor-v4 >>>>>> The root cause of LoongArch zboot boot failure has been found, it is a >>>>>> binutils bug, latest toolchain with the below patch can solve the >>>>>> problem. >>>>>> >>>>>> diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c >>>>>> index 5b44901b9e0..fafdc7c7458 100644 >>>>>> --- a/bfd/elfnn-loongarch.c >>>>>> +++ b/bfd/elfnn-loongarch.c >>>>>> @@ -2341,9 +2341,10 @@ loongarch_elf_relocate_section (bfd >>>>>> *output_bfd, struct bfd_link_info *info, >>>>>> case R_LARCH_SOP_PUSH_PLT_PCREL: >>>>>> unresolved_reloc = false; >>>>>> >>>>>> - if (resolved_to_const) >>>>>> + if (!is_undefweak && resolved_to_const) >>>>>> { >>>>>> relocation += rel->r_addend; >>>>>> + relocation -= pc; >>>>>> break; >>>>>> } >>>>>> else if (is_undefweak) >>>>>> >>>>>> >>>>>> Huacai >>>>> Now the patch is submitted here: >>>>> https://sourceware.org/pipermail/binutils/2022-September/122713.html >>>>> >>>> >>>> Great. Given the severity of this bug, I imagine that building the >>>> LoongArch kernel will require a version of binutils that carries this >>>> fix. >>>> >>>> Therefore, i will revert back to the original approach for accessing >>>> uncompressed_size, using an extern declaration with an __aligned(1) >>>> attribute. >>>> >>>>> And I have some other questions about kexec: kexec should jump to the >>>>> elf entry or the pe entry? I think is the elf entry, because if we >>>>> jump to the pe entry, then SVAM will be executed twice (but it should >>>>> be executed only once). However, how can we jump to the elf entry if >>>>> we use zboot? Maybe it is kexec-tool's responsibility to decompress >>>>> the zboot kernel image? >>>>> >>>> >>>> Yes, very good point. Kexec kernels cannot boot via the EFI entry >>>> point, as the boot services will already be shutdown. So the kexec >>>> kernel needs to boot via the same entrypoint in the core kernel that >>>> the EFI stub calls when it hands over. >>>> >>>> For the EFI zboot image in particular, we will need to teach kexec how >>>> to decompress them. The zboot image has a header that >>>> a) describes it as a EFI linux zimg >>>> b) describes the start and end offset of the compressed payload >>>> c) describes which compression algorithm was used. >>>> >>>> This means that any non-EFI loader (including kexec) should be able to >>>> extract the inner PE/COFF image and decompress it. For arm64 and >>>> RISC-V, this is sufficient as the EFI and raw images are the same. For >>>> LoongArch, I suppose it means we need a way to enter the core kernel >>>> directly via the entrypoint that the EFI stub uses when handing over >>>> (and pass the original DT argument so the kexec kernel has access to >>>> the EFI and ACPI firmware tables) >>> OK, then is this implementation [1] acceptable? I remember that you >>> said the MS-DOS header shouldn't contain other information, so I guess >>> this is unacceptable? >>> >> >> No, this looks reasonable to me. I objected to using magic numbers in >> the 'pure PE' view of the image, as it does not make sense for a pure >> PE loader such as GRUB to rely on such metadata. >> >> In this case (like on arm64), we are dealing with something else: we >> need to identify the image to the kernel itself, and here, using the >> unused space in the MS-DOS header is fine. >> >>> [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad > OK, then there is no big problem here. And I found that arm64/riscv > don't need the kernel entry point in the header. I don't know why, but > I think it implies that a unified layout across architectures is > unnecessary, and I prefer to put the kernel entry point before > effective kernel size. :) The kernel entry point is added because LoongArch has not implemented purgatory in kexec-tools, so I want to get it from the head through a simpler method, similar to the elf image operation. Youling. > > Huacai > >>> >>> Huacai
On 9/5/22 15:28, Ard Biesheuvel wrote: > [snip] >>>>>> And I have some other questions about kexec: kexec should jump to the >>>>>> elf entry or the pe entry? I think is the elf entry, because if we >>>>>> jump to the pe entry, then SVAM will be executed twice (but it should >>>>>> be executed only once). However, how can we jump to the elf entry if >>>>>> we use zboot? Maybe it is kexec-tool's responsibility to decompress >>>>>> the zboot kernel image? >>>>>> >>>>> Yes, very good point. Kexec kernels cannot boot via the EFI entry >>>>> point, as the boot services will already be shutdown. So the kexec >>>>> kernel needs to boot via the same entrypoint in the core kernel that >>>>> the EFI stub calls when it hands over. >>>>> >>>>> For the EFI zboot image in particular, we will need to teach kexec how >>>>> to decompress them. The zboot image has a header that >>>>> a) describes it as a EFI linux zimg >>>>> b) describes the start and end offset of the compressed payload >>>>> c) describes which compression algorithm was used. >>>>> >>>>> This means that any non-EFI loader (including kexec) should be able to >>>>> extract the inner PE/COFF image and decompress it. For arm64 and >>>>> RISC-V, this is sufficient as the EFI and raw images are the same. For >>>>> LoongArch, I suppose it means we need a way to enter the core kernel >>>>> directly via the entrypoint that the EFI stub uses when handing over >>>>> (and pass the original DT argument so the kexec kernel has access to >>>>> the EFI and ACPI firmware tables) >>>> OK, then is this implementation [1] acceptable? I remember that you >>>> said the MS-DOS header shouldn't contain other information, so I guess >>>> this is unacceptable? >>>> >>> No, this looks reasonable to me. I objected to using magic numbers in >>> the 'pure PE' view of the image, as it does not make sense for a pure >>> PE loader such as GRUB to rely on such metadata. >>> >>> In this case (like on arm64), we are dealing with something else: we >>> need to identify the image to the kernel itself, and here, using the >>> unused space in the MS-DOS header is fine. >>> >>>> [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad >> OK, then there is no big problem here. And I found that arm64/riscv >> don't need the kernel entry point in the header. I don't know why, but >> I think it implies that a unified layout across architectures is >> unnecessary, and I prefer to put the kernel entry point before >> effective kernel size. :) >> > It is fine to put the entry point offset in the header. arm64 and > RISC-V don't need this because the first instructions are a pseudo-NOP > (an instruction that does nothing but its binary encoding looks like > 'MZ..') and a jump to the actual entry point. FYI the same trick also works for LoongArch: the code "MZ\x00\x00" i.e. 00005a4d is in fact "ext.w.h $t1, $t6", which is going to simply trash one temporary register without any other effect, so a similar jump to the actual entrypoint could follow. This instruction is available for both LA32 and LA64. The only subset without it is the LA32 Primary, which is meant for university courses and probably would never run UEFI, so the instruction is safe to use. P.S. If we'd go the extra mile just for ensuring the instruction works on every possible LoongArch core, due to the prefix construction of LoongArch encoding, we could just change the bytes toward the MSB (so we keep the "MZ" with ease) and still only trash $t1. For example "MZ\x10\x00" or 00105a4d is "add.w $t1, $t6, $fp", which is similarly harmless, but this time it works on even coursework cores!
On Mon, 5 Sept 2022 at 20:08, WANG Xuerui <kernel@xen0n.name> wrote: > > On 9/5/22 15:28, Ard Biesheuvel wrote: > > [snip] > >>>>>> And I have some other questions about kexec: kexec should jump to the > >>>>>> elf entry or the pe entry? I think is the elf entry, because if we > >>>>>> jump to the pe entry, then SVAM will be executed twice (but it should > >>>>>> be executed only once). However, how can we jump to the elf entry if > >>>>>> we use zboot? Maybe it is kexec-tool's responsibility to decompress > >>>>>> the zboot kernel image? > >>>>>> > >>>>> Yes, very good point. Kexec kernels cannot boot via the EFI entry > >>>>> point, as the boot services will already be shutdown. So the kexec > >>>>> kernel needs to boot via the same entrypoint in the core kernel that > >>>>> the EFI stub calls when it hands over. > >>>>> > >>>>> For the EFI zboot image in particular, we will need to teach kexec how > >>>>> to decompress them. The zboot image has a header that > >>>>> a) describes it as a EFI linux zimg > >>>>> b) describes the start and end offset of the compressed payload > >>>>> c) describes which compression algorithm was used. > >>>>> > >>>>> This means that any non-EFI loader (including kexec) should be able to > >>>>> extract the inner PE/COFF image and decompress it. For arm64 and > >>>>> RISC-V, this is sufficient as the EFI and raw images are the same. For > >>>>> LoongArch, I suppose it means we need a way to enter the core kernel > >>>>> directly via the entrypoint that the EFI stub uses when handing over > >>>>> (and pass the original DT argument so the kexec kernel has access to > >>>>> the EFI and ACPI firmware tables) > >>>> OK, then is this implementation [1] acceptable? I remember that you > >>>> said the MS-DOS header shouldn't contain other information, so I guess > >>>> this is unacceptable? > >>>> > >>> No, this looks reasonable to me. I objected to using magic numbers in > >>> the 'pure PE' view of the image, as it does not make sense for a pure > >>> PE loader such as GRUB to rely on such metadata. > >>> > >>> In this case (like on arm64), we are dealing with something else: we > >>> need to identify the image to the kernel itself, and here, using the > >>> unused space in the MS-DOS header is fine. > >>> > >>>> [1] https://lore.kernel.org/loongarch/c4dbb14a-5580-1e47-3d15-5d2079e88404@loongson.cn/T/#mb8c1dc44f7fa2d3ef638877f0cd3f958f0be96ad > >> OK, then there is no big problem here. And I found that arm64/riscv > >> don't need the kernel entry point in the header. I don't know why, but > >> I think it implies that a unified layout across architectures is > >> unnecessary, and I prefer to put the kernel entry point before > >> effective kernel size. :) > >> > > It is fine to put the entry point offset in the header. arm64 and > > RISC-V don't need this because the first instructions are a pseudo-NOP > > (an instruction that does nothing but its binary encoding looks like > > 'MZ..') and a jump to the actual entry point. > > FYI the same trick also works for LoongArch: the code "MZ\x00\x00" i.e. > 00005a4d is in fact "ext.w.h $t1, $t6", which is going to simply trash > one temporary register without any other effect, so a similar jump to > the actual entrypoint could follow. > > This instruction is available for both LA32 and LA64. The only subset > without it is the LA32 Primary, which is meant for university courses > and probably would never run UEFI, so the instruction is safe to use. > > P.S. If we'd go the extra mile just for ensuring the instruction works > on every possible LoongArch core, due to the prefix construction of > LoongArch encoding, we could just change the bytes toward the MSB (so we > keep the "MZ" with ease) and still only trash $t1. For example > "MZ\x10\x00" or 00105a4d is "add.w $t1, $t6, $fp", which is similarly > harmless, but this time it works on even coursework cores! > I don't think this is necessary. On arm64, the boot protocol was already defined when the EFI stub requirements became apparent, and RISC-V just copied arm64 for some reason. There is no reason for the 'bare metal' image to be executable from offset 0x0: in fact, it is better to restrict executable permissions to code regions, and treat the header as a data region, which is what it is fundamentally. In fact, if there is a need to duplicate this information (given that the PE/COFF header also carries the same information), I would recommend describing the code (R-X) and data (RW-) regions, as well as the entry point, and potentially permit the image to be booted with memory protections enabled.
diff --git a/arch/loongarch/Kconfig b/arch/loongarch/Kconfig index 9478f9646fa5..4cb412a82afa 100644 --- a/arch/loongarch/Kconfig +++ b/arch/loongarch/Kconfig @@ -324,6 +324,15 @@ config EFI This enables the kernel to use EFI runtime services that are available (such as the EFI variable services). +config EFI_STUB + bool "EFI boot stub support" + default y + depends on EFI + select EFI_GENERIC_STUB + help + This kernel feature allows the kernel to be loaded directly by + EFI firmware without the use of a bootloader. + config SMP bool "Multi-Processing support" help diff --git a/arch/loongarch/Makefile b/arch/loongarch/Makefile index ec3de6191276..4bc47f47cfd8 100644 --- a/arch/loongarch/Makefile +++ b/arch/loongarch/Makefile @@ -7,7 +7,11 @@ boot := arch/loongarch/boot KBUILD_DEFCONFIG := loongson3_defconfig -KBUILD_IMAGE = $(boot)/vmlinux +ifndef CONFIG_EFI_STUB +KBUILD_IMAGE := $(boot)/vmlinux.elf +else +KBUILD_IMAGE := $(boot)/vmlinux.efi +endif # # Select the object file format to substitute into the linker script. @@ -75,6 +79,7 @@ endif head-y := arch/loongarch/kernel/head.o libs-y += arch/loongarch/lib/ +libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a ifeq ($(KBUILD_EXTMOD),) prepare: vdso_prepare @@ -86,10 +91,10 @@ PHONY += vdso_install vdso_install: $(Q)$(MAKE) $(build)=arch/loongarch/vdso $@ -all: $(KBUILD_IMAGE) +all: $(notdir $(KBUILD_IMAGE)) -$(KBUILD_IMAGE): vmlinux - $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $@ +vmlinux.elf vmlinux.efi: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $(bootvars-y) $(boot)/$@ install: $(Q)install -D -m 755 $(KBUILD_IMAGE) $(INSTALL_PATH)/vmlinux-$(KERNELRELEASE) diff --git a/arch/loongarch/boot/Makefile b/arch/loongarch/boot/Makefile index 0125b17edc98..fecf34f50e56 100644 --- a/arch/loongarch/boot/Makefile +++ b/arch/loongarch/boot/Makefile @@ -8,9 +8,13 @@ drop-sections := .comment .note .options .note.gnu.build-id strip-flags := $(addprefix --remove-section=,$(drop-sections)) -S OBJCOPYFLAGS_vmlinux.efi := -O binary $(strip-flags) -targets := vmlinux quiet_cmd_strip = STRIP $@ cmd_strip = $(STRIP) -s -o $@ $< -$(obj)/vmlinux: vmlinux FORCE +targets := vmlinux.elf +$(obj)/vmlinux.elf: vmlinux FORCE $(call if_changed,strip) + +targets += vmlinux.efi +$(obj)/vmlinux.efi: vmlinux FORCE + $(call if_changed,objcopy) diff --git a/arch/loongarch/include/asm/efi.h b/arch/loongarch/include/asm/efi.h index 9d44c6948be1..50c54b4174eb 100644 --- a/arch/loongarch/include/asm/efi.h +++ b/arch/loongarch/include/asm/efi.h @@ -17,9 +17,16 @@ void efifb_setup_from_dmi(struct screen_info *si, const char *opt); #define arch_efi_call_virt_teardown() #define EFI_ALLOC_ALIGN SZ_64K +#define EFI_RT_VIRTUAL_OFFSET CSR_DMW0_BASE -struct screen_info *alloc_screen_info(void); -void free_screen_info(struct screen_info *si); +static inline struct screen_info *alloc_screen_info(void) +{ + return &screen_info; +} + +static inline void free_screen_info(struct screen_info *si) +{ +} static inline unsigned long efi_get_max_initrd_addr(unsigned long image_addr) { diff --git a/arch/loongarch/kernel/efi-header.S b/arch/loongarch/kernel/efi-header.S new file mode 100644 index 000000000000..8c1d229a2afa --- /dev/null +++ b/arch/loongarch/kernel/efi-header.S @@ -0,0 +1,99 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2020-2022 Loongson Technology Corporation Limited + */ + +#include <linux/pe.h> +#include <linux/sizes.h> + + .macro __EFI_PE_HEADER + .long PE_MAGIC +.Lcoff_header: + .short IMAGE_FILE_MACHINE_LOONGARCH64 /* Machine */ + .short .Lsection_count /* NumberOfSections */ + .long 0 /* TimeDateStamp */ + .long 0 /* PointerToSymbolTable */ + .long 0 /* NumberOfSymbols */ + .short .Lsection_table - .Loptional_header /* SizeOfOptionalHeader */ + .short IMAGE_FILE_DEBUG_STRIPPED | \ + IMAGE_FILE_EXECUTABLE_IMAGE | \ + IMAGE_FILE_LINE_NUMS_STRIPPED /* Characteristics */ + +.Loptional_header: + .short PE_OPT_MAGIC_PE32PLUS /* PE32+ format */ + .byte 0x02 /* MajorLinkerVersion */ + .byte 0x14 /* MinorLinkerVersion */ + .long __inittext_end - .Lefi_header_end /* SizeOfCode */ + .long _end - __initdata_begin /* SizeOfInitializedData */ + .long 0 /* SizeOfUninitializedData */ + .long __efistub_efi_pe_entry - _head /* AddressOfEntryPoint */ + .long .Lefi_header_end - _head /* BaseOfCode */ + +.Lextra_header_fields: + .quad 0 /* ImageBase */ + .long PECOFF_SEGMENT_ALIGN /* SectionAlignment */ + .long PECOFF_FILE_ALIGN /* FileAlignment */ + .short 0 /* MajorOperatingSystemVersion */ + .short 0 /* MinorOperatingSystemVersion */ + .short LINUX_EFISTUB_MAJOR_VERSION /* MajorImageVersion */ + .short LINUX_EFISTUB_MINOR_VERSION /* MinorImageVersion */ + .short 0 /* MajorSubsystemVersion */ + .short 0 /* MinorSubsystemVersion */ + .long 0 /* Win32VersionValue */ + + .long _end - _head /* SizeOfImage */ + + /* Everything before the kernel image is considered part of the header */ + .long .Lefi_header_end - _head /* SizeOfHeaders */ + .long 0 /* CheckSum */ + .short IMAGE_SUBSYSTEM_EFI_APPLICATION /* Subsystem */ + .short 0 /* DllCharacteristics */ + .quad 0 /* SizeOfStackReserve */ + .quad 0 /* SizeOfStackCommit */ + .quad 0 /* SizeOfHeapReserve */ + .quad 0 /* SizeOfHeapCommit */ + .long 0 /* LoaderFlags */ + .long (.Lsection_table - .) / 8 /* NumberOfRvaAndSizes */ + + .quad 0 /* ExportTable */ + .quad 0 /* ImportTable */ + .quad 0 /* ResourceTable */ + .quad 0 /* ExceptionTable */ + .quad 0 /* CertificationTable */ + .quad 0 /* BaseRelocationTable */ + + /* Section table */ +.Lsection_table: + .ascii ".text\0\0\0" + .long __inittext_end - .Lefi_header_end /* VirtualSize */ + .long .Lefi_header_end - _head /* VirtualAddress */ + .long __inittext_end - .Lefi_header_end /* SizeOfRawData */ + .long .Lefi_header_end - _head /* PointerToRawData */ + + .long 0 /* PointerToRelocations */ + .long 0 /* PointerToLineNumbers */ + .short 0 /* NumberOfRelocations */ + .short 0 /* NumberOfLineNumbers */ + .long IMAGE_SCN_CNT_CODE | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_EXECUTE /* Characteristics */ + + .ascii ".data\0\0\0" + .long _end - __initdata_begin /* VirtualSize */ + .long __initdata_begin - _head /* VirtualAddress */ + .long _edata - __initdata_begin /* SizeOfRawData */ + .long __initdata_begin - _head /* PointerToRawData */ + + .long 0 /* PointerToRelocations */ + .long 0 /* PointerToLineNumbers */ + .short 0 /* NumberOfRelocations */ + .short 0 /* NumberOfLineNumbers */ + .long IMAGE_SCN_CNT_INITIALIZED_DATA | \ + IMAGE_SCN_MEM_READ | \ + IMAGE_SCN_MEM_WRITE /* Characteristics */ + + .set .Lsection_count, (. - .Lsection_table) / 40 + + .balign 0x10000 /* PECOFF_SEGMENT_ALIGN */ +.Lefi_header_end: + .endm diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index a50b60c587fa..1f1f755fb425 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -69,4 +69,7 @@ void __init efi_init(void) config_tables = early_memremap(efi_config_table, efi_nr_tables * size); efi_config_parse_tables(config_tables, efi_systab->nr_tables, arch_tables); early_memunmap(config_tables, efi_nr_tables * size); + + if (screen_info.orig_video_isVGA == VIDEO_TYPE_EFI) + memblock_reserve(screen_info.lfb_base, screen_info.lfb_size); } diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S index c60eb66793e3..01bac62a6442 100644 --- a/arch/loongarch/kernel/head.S +++ b/arch/loongarch/kernel/head.S @@ -12,6 +12,26 @@ #include <asm/loongarch.h> #include <asm/stackframe.h> +#ifdef CONFIG_EFI_STUB + +#include "efi-header.S" + + __HEAD + +_head: + .word MZ_MAGIC /* "MZ", MS-DOS header */ + .org 0x3c /* 0x04 ~ 0x3b reserved */ + .long pe_header - _head /* Offset to the PE header */ + +pe_header: + __EFI_PE_HEADER + +SYM_DATA(kernel_asize, .long _end - _text); +SYM_DATA(kernel_fsize, .long _edata - _text); +SYM_DATA(kernel_offset, .long kernel_offset - _text); + +#endif + __REF SYM_CODE_START(kernel_entry) # kernel entry point diff --git a/arch/loongarch/kernel/image-vars.h b/arch/loongarch/kernel/image-vars.h new file mode 100644 index 000000000000..c901ebb903f2 --- /dev/null +++ b/arch/loongarch/kernel/image-vars.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2020-2022 Loongson Technology Corporation Limited + */ +#ifndef __LOONGARCH_KERNEL_IMAGE_VARS_H +#define __LOONGARCH_KERNEL_IMAGE_VARS_H + +#ifdef CONFIG_EFI_STUB + +__efistub_memcmp = memcmp; +__efistub_memchr = memchr; +__efistub_memcpy = memcpy; +__efistub_memmove = memmove; +__efistub_memset = memset; +__efistub_strcat = strcat; +__efistub_strcmp = strcmp; +__efistub_strlen = strlen; +__efistub_strncat = strncat; +__efistub_strnstr = strnstr; +__efistub_strnlen = strnlen; +__efistub_strrchr = strrchr; +__efistub_kernel_entry = kernel_entry; +__efistub_kernel_asize = kernel_asize; +__efistub_kernel_fsize = kernel_fsize; +__efistub_kernel_offset = kernel_offset; +__efistub_screen_info = screen_info; + +#endif + +#endif /* __LOONGARCH_KERNEL_IMAGE_VARS_H */ diff --git a/arch/loongarch/kernel/setup.c b/arch/loongarch/kernel/setup.c index 23ee293e1cd2..f938aae3e92c 100644 --- a/arch/loongarch/kernel/setup.c +++ b/arch/loongarch/kernel/setup.c @@ -49,9 +49,7 @@ #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 #define LOONGSON_EFI_ENABLE (1 << 3) -#ifdef CONFIG_VT -struct screen_info screen_info; -#endif +struct screen_info screen_info __section(".data"); unsigned long fw_arg0, fw_arg1; DEFINE_PER_CPU(unsigned long, kernelsp); @@ -122,16 +120,9 @@ static void __init parse_cpu_table(const struct dmi_header *dm) static void __init parse_bios_table(const struct dmi_header *dm) { - int bios_extern; char *dmi_data = (char *)dm; - bios_extern = *(dmi_data + SMBIOS_BIOSEXTERN_OFFSET); b_info.bios_size = (*(dmi_data + SMBIOS_BIOSSIZE_OFFSET) + 1) << 6; - - if (bios_extern & LOONGSON_EFI_ENABLE) - set_bit(EFI_BOOT, &efi.flags); - else - clear_bit(EFI_BOOT, &efi.flags); } static void __init find_tokens(const struct dmi_header *dm, void *dummy) @@ -145,6 +136,7 @@ static void __init find_tokens(const struct dmi_header *dm, void *dummy) break; } } + static void __init smbios_parse(void) { b_info.bios_vendor = (void *)dmi_get_system_info(DMI_BIOS_VENDOR); diff --git a/arch/loongarch/kernel/vmlinux.lds.S b/arch/loongarch/kernel/vmlinux.lds.S index 69c76f26c1c5..36d042739f3c 100644 --- a/arch/loongarch/kernel/vmlinux.lds.S +++ b/arch/loongarch/kernel/vmlinux.lds.S @@ -12,6 +12,7 @@ #define BSS_FIRST_SECTIONS *(.bss..swapper_pg_dir) #include <asm-generic/vmlinux.lds.h> +#include "image-vars.h" /* * Max avaliable Page Size is 64K, so we set SectionAlignment diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 6cb7384ad2ac..cbf1c55dc224 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -107,7 +107,7 @@ config EFI_GENERIC_STUB config EFI_ARMSTUB_DTB_LOADER bool "Enable the DTB loader" - depends on EFI_GENERIC_STUB && !RISCV + depends on EFI_GENERIC_STUB && !RISCV && !LOONGARCH default y help Select this config option to add support for the dtb= command @@ -124,7 +124,7 @@ config EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER bool "Enable the command line initrd loader" if !X86 depends on EFI_STUB && (EFI_GENERIC_STUB || X86) default y if X86 - depends on !RISCV + depends on !RISCV && !LOONGARCH help Select this config option to add support for the initrd= command line parameter, allowing an initrd that resides on the same volume diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile index d0537573501e..1588c61939e7 100644 --- a/drivers/firmware/efi/libstub/Makefile +++ b/drivers/firmware/efi/libstub/Makefile @@ -26,6 +26,8 @@ cflags-$(CONFIG_ARM) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ $(call cc-option,-mno-single-pic-base) cflags-$(CONFIG_RISCV) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ -fpic +cflags-$(CONFIG_LOONGARCH) := $(subst $(CC_FLAGS_FTRACE),,$(KBUILD_CFLAGS)) \ + -fpic cflags-$(CONFIG_EFI_GENERIC_STUB) += -I$(srctree)/scripts/dtc/libfdt @@ -70,6 +72,8 @@ lib-$(CONFIG_ARM) += arm32-stub.o lib-$(CONFIG_ARM64) += arm64-stub.o lib-$(CONFIG_X86) += x86-stub.o lib-$(CONFIG_RISCV) += riscv-stub.o +lib-$(CONFIG_LOONGARCH) += loongarch-stub.o + CFLAGS_arm32-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) # Even when -mbranch-protection=none is set, Clang will generate a @@ -125,6 +129,12 @@ STUBCOPY_FLAGS-$(CONFIG_RISCV) += --prefix-alloc-sections=.init \ --prefix-symbols=__efistub_ STUBCOPY_RELOC-$(CONFIG_RISCV) := R_RISCV_HI20 +# For LoongArch, keep all the symbols in .init section and make sure that no +# absolute symbols references doesn't exist. +STUBCOPY_FLAGS-$(CONFIG_LOONGARCH) += --prefix-alloc-sections=.init \ + --prefix-symbols=__efistub_ +STUBCOPY_RELOC-$(CONFIG_LOONGARCH) := R_LARCH_MARK_LA + $(obj)/%.stub.o: $(obj)/%.o FORCE $(call if_changed,stubcopy) diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index f515394cce6e..90f1335bc46e 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -40,14 +40,18 @@ #ifdef CONFIG_ARM64 # define EFI_RT_VIRTUAL_LIMIT DEFAULT_MAP_WINDOW_64 -#elif defined(CONFIG_RISCV) +#elif defined(CONFIG_RISCV) || defined(CONFIG_LOONGARCH) # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE_MIN -#else +#else /* Only if TASK_SIZE is a constant */ # define EFI_RT_VIRTUAL_LIMIT TASK_SIZE #endif +#ifndef EFI_RT_VIRTUAL_OFFSET +#define EFI_RT_VIRTUAL_OFFSET 0 +#endif + static u64 virtmap_base = EFI_RT_VIRTUAL_BASE; -static bool flat_va_mapping; +static bool flat_va_mapping = !!EFI_RT_VIRTUAL_OFFSET; const efi_system_table_t *efi_system_table; @@ -254,8 +258,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, * The easiest way to achieve that is to simply use a 1:1 mapping. */ prop_tbl = get_efi_config_table(EFI_PROPERTIES_TABLE_GUID); - flat_va_mapping = prop_tbl && - (prop_tbl->memory_protection_attribute & + flat_va_mapping |= prop_tbl && + (prop_tbl->memory_protection_attribute & EFI_PROPERTIES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); /* force efi_novamap if SetVirtualAddressMap() is unsupported */ @@ -338,7 +342,7 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, paddr = in->phys_addr; size = in->num_pages * EFI_PAGE_SIZE; - in->virt_addr = in->phys_addr; + in->virt_addr = in->phys_addr + EFI_RT_VIRTUAL_OFFSET; if (efi_novamap) { continue; } diff --git a/drivers/firmware/efi/libstub/loongarch-stub.c b/drivers/firmware/efi/libstub/loongarch-stub.c new file mode 100644 index 000000000000..b7ef8d2df59e --- /dev/null +++ b/drivers/firmware/efi/libstub/loongarch-stub.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Author: Yun Liu <liuyun@loongson.cn> + * Huacai Chen <chenhuacai@loongson.cn> + * Copyright (C) 2020-2022 Loongson Technology Corporation Limited + */ + +#include <asm/efi.h> +#include <asm/addrspace.h> +#include "efistub.h" + +typedef void __noreturn (*kernel_entry_t)(bool efi, unsigned long fdt); + +extern int kernel_asize; +extern int kernel_fsize; +extern int kernel_offset; +extern kernel_entry_t kernel_entry; + +efi_status_t check_platform_features(void) +{ + return EFI_SUCCESS; +} + +efi_status_t handle_kernel_image(unsigned long *image_addr, + unsigned long *image_size, + unsigned long *reserve_addr, + unsigned long *reserve_size, + efi_loaded_image_t *image, + efi_handle_t image_handle) +{ + efi_status_t status; + unsigned long kernel_addr = 0; + + kernel_addr = (unsigned long)&kernel_offset - kernel_offset; + + status = efi_relocate_kernel(&kernel_addr, kernel_fsize, kernel_asize, + PHYSADDR(VMLINUX_LOAD_ADDRESS), SZ_2M, 0x0); + + *image_addr = kernel_addr; + *image_size = kernel_asize; + + return status; +} + +void __noreturn efi_enter_kernel(unsigned long entrypoint, unsigned long fdt, unsigned long fdt_size) +{ + kernel_entry_t real_kernel_entry; + + /* Config Direct Mapping */ + csr_write64(CSR_DMW0_INIT, LOONGARCH_CSR_DMWIN0); + csr_write64(CSR_DMW1_INIT, LOONGARCH_CSR_DMWIN1); + + real_kernel_entry = (kernel_entry_t) + ((unsigned long)&kernel_entry - entrypoint + VMLINUX_LOAD_ADDRESS); + + if (!efi_novamap) + real_kernel_entry(true, fdt); + else + real_kernel_entry(false, fdt); +} diff --git a/include/linux/pe.h b/include/linux/pe.h index daf09ffffe38..1d3836ef9d92 100644 --- a/include/linux/pe.h +++ b/include/linux/pe.h @@ -65,6 +65,8 @@ #define IMAGE_FILE_MACHINE_SH5 0x01a8 #define IMAGE_FILE_MACHINE_THUMB 0x01c2 #define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169 +#define IMAGE_FILE_MACHINE_LOONGARCH32 0x6232 +#define IMAGE_FILE_MACHINE_LOONGARCH64 0x6264 /* flags */ #define IMAGE_FILE_RELOCS_STRIPPED 0x0001