Re: [REGRESSION] Re: [PATCH v4 5/5] efi: Use generic EFI loader for x86_64 and i386

2024-07-03 Thread Ard Biesheuvel
On Wed, 3 Jul 2024 at 16:25, Jan Čermák  wrote:
>
> Hi Ard
>
> On 28. 06. 24 19:28, Ard Biesheuvel wrote:
> > Given that you carry your own GRUB build, I would recommend reverting
> > to non-EFI stub boot for affected Atom systems, identified by DMI
> > data, which should be easy to access on such systems.
> >
> > Look for 'goto fallback' in the existing loader logic in
> > grub-core/loader/efi/linux.c - you'd need to jump to the same point to
> > use the GRUB 2.06 logic for systems that fail that cannot load the EFI
> > stub kernel image.
>
> Thanks for the suggestion, that sounds like a more acceptable solution
> (than the revert). However, would a quirk like that be acceptable in
> upstream code as well? In long term, we'd like to only support hardware
> that is supported in upstream, instead of taking the maintenance burden
> of carrying custom patches indefinitely, so if it is GRUB's maintainers'
> decision to abandon support for old buggy hardware, we shall declare it
> abandoned as well.
>

If GRUB no longer works correctly on these systems due to the move to
the generic EFI loader, and we can straight-forwardly identify them
using SMBIOS metadata, I don't anticipate any objections from the GRUB
maintainers.

@Daniel?

> > Out of curiosity - these are all x86_64 Atoms right? How old are they?
>
> Yes, they are, e.g. Atom D525 [1], but from the reports we've received
> it seems the problem is with the NM10 chipset [2] in general (as I
> stated in the first message in the thread). They are ~14 years old so
> pretty archaic I'd say O:-)
>

If you can get me the output of 'dmidecode' from preferably more than
one variant of such a system, I can hack up a GRUB patch that
implements the SMBIOS matching and the opt-out.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [REGRESSION] Re: [PATCH v4 5/5] efi: Use generic EFI loader for x86_64 and i386

2024-06-28 Thread Ard Biesheuvel
On Thu, 27 Jun 2024 at 12:27, Jan Čermák  wrote:
>
> Hi Ard,
>
> sorry, I feel a little ashamed for replying after such a long time but I
> wanted to do some due diligence first and didn't have time (or the Atom
> board around) until now.
>
> > Does your Kconfig have EFI_DISABLE_PCI_DMA enabled by any chance? That
> > could definitely produce the issues you are observing.
>
> No, this option is not set in our kernel.
>
> > In any case, given that you never relied on the EFI stub in the past
> > on x86_64 (as GRUB 2.06 does not rely on it), you could just disable
> > that in your Kconfig.
> >
> > That of course does not solve the Fujitsu issue, which apparently
> > requires boot via the EFI stub, but I don't have a solution for that -
> > I suppose that simply never worked with the old 'working' version of
> > the OS?
>
> The goal is to have a single configuration that works for both (or
> ideally - all amd64) targets so disabling EFI stub is not an option.
> With no changes in the kernel in the meantime, just GRUB 2.06 loaded
> kernel without issues on both devices.
>
> Anyway, what held me up a bit is that I wanted to try any of the major
> distributions that already adopter GRUB 2.12. I tested Ubuntu 24.04 and
> Arch's build of GRUB. While Arch's GRUB behaves exactly the same way
> (error loading image) I was a bit puzzled that it's not the case of
> Ubuntu. It took me a while to figure out why because there are quite
> many patches applied but in the end it boiled up to the following two
> from the grub package repo [1]:
>
> - loader-framework.patch
> - efi-use-peimage-shim.patch
>
> Vanilla GRUB with these two patches AND with the introduced `peimage`
> module added to the GRUB binary boots our kernel correctly.
>
> At this point I don't have the knowledge to figure out if it's just side
> effect of that changes or if they indeed make any difference. And I'm
> not sure what effect it has on the Fujitsu board but I can't find any
> mentions of it in Ubuntu's issue tracker or anywhere on the internet so
> I *guess* it's fine.
>
> I don't know what else to try at this point. If you'd like to look into
> the issue yourself, I can give you the board I have, in the end it has
> no other use for me than making sure that our OS boots correctly there,
> and if the issue gets resolved, it will be just gathering dust. Let me
> know if you're interested - if you give me an EU address to ship to, I
> can arrange that. Outside the EU I'm afraid the shipping costs and
> duties would be higher than the cost of the hardware itself :)
>

Hello Jan,

I appreciate the gesture but please don't send me stuff.

Given that you carry your own GRUB build, I would recommend reverting
to non-EFI stub boot for affected Atom systems, identified by DMI
data, which should be easy to access on such systems.

Look for 'goto fallback' in the existing loader logic in
grub-core/loader/efi/linux.c - you'd need to jump to the same point to
use the GRUB 2.06 logic for systems that fail that cannot load the EFI
stub kernel image.

Out of curiosity - these are all x86_64 Atoms right? How old are they?

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [REGRESSION] Re: [PATCH v4 5/5] efi: Use generic EFI loader for x86_64 and i386

2024-05-16 Thread Ard Biesheuvel
On Thu, 16 May 2024 at 14:24, Jan Čermák  wrote:
>
> Hi Ard, everyone,
>
> On 23. 05. 23 17:31, Ard Biesheuvel wrote:
>  > Switch the x86 based EFI platform builds to the generic EFI loader,
>  > ...
>
> We use GRUB as the loader for the Home Assistant Operating System (based
> on Buildroot, using mostly unpatched GRUB 2 build [1]) and after
> updating to the latest 2.12 release, this patch (commit
> cfbfae1aef0694b416aa199291cfef7596cdfc20) has been identified to break
> boot on Intel Atom NM10, at least with upstream kernel 6.6 with
> CONFIG_EFI_STUB enabled. I reproduced it on Intel D525MW board, and
> there are some more reports from HAOS users on Github [2].
>
> Initially, we decided to revert the patch [3] for the time being,
> however, while it fixed issue for users running on those rather old
> boards, it broke boot [4] on the comparatively newer Fujitsu Esprimo
> Q920. From the user reports, there is no BIOS update available that will
> make any difference but reverting to a "vanilla" 2.12 fixes that.
>
> Do you have a clue what could have gone wrong, either with the original
> patch, or why the revert breaks the other platform? I'll be happy to get
> any details and perform tests on the NM10 board I have here.
> Alternatively, I can also ask users with the Q920 for more details or do
> some tests.
>

Upstream GRUB 2.06 does not boot Linux via the EFI stub, it uses the
legacy EFI boot method where the Linux kernel is only entered after
the EFI firmware has been shut down.

GRUB 2.12 changed this, and will know always use the pure EFI boot
sequence, relying on the EFI stub in the Linux kernel to shut down the
firmware services.

Does your Kconfig have EFI_DISABLE_PCI_DMA enabled by any chance? That
could definitely produce the issues you are observing.

In any case, given that you never relied on the EFI stub in the past
on x86_64 (as GRUB 2.06 does not rely on it), you could just disable
that in your Kconfig.

That of course does not solve the Fujitsu issue, which apparently
requires boot via the EFI stub, but I don't have a solution for that -
I suppose that simply never worked with the old 'working' version of
the OS?

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v5] efi: Fix stack protector issues

2024-04-29 Thread Ard Biesheuvel
On Sat, 27 Apr 2024 at 15:08, Glenn Washburn
 wrote:
>
> From: Ard Biesheuvel 
>
> The 'ground truth' stack protector cookie value is kept in a global
> variable, and loaded in every function prologue and epilogue to store
> it into resp. compare it with the stack slot holding the cookie.
>
> If the comparison fails, the program aborts, and this might occur
> spuriously when the global variable changes values between the entry and
> exit of a function. This implies that assigning the global variable at
> boot should not involve any instrumented function calls, unless special
> care is taken to ensure that the live call stack is synchronized, which
> is non-trivial.
>
> So avoid any function calls, including grub_memcpy(), which is
> unnecessary given that the stack cookie is always a suitably aligned
> variable of the native word size.
>
> While at it, leave the last byte 0x0 to avoid inadvertent unbounded
> strings on the stack.
>
> Note that the use of __attribute__((optimize)) is described as
> unsuitable for production use in the GCC documentation, so let's drop
> this as well now that it is no longer needed.
>
> Signed-off-by: Ard Biesheuvel 
> Reviewed-by: Glenn Washburn 
> Signed-off-by: Glenn Washburn 

Thanks for taking care of this.

I'd ack it but that would make the signoff chain look even weirder :-)


> ---
> v5:
>  * Add missing include
>
> v4:
>  * Rebase to current master
>
> v3:
>  * Add more reasoning to comment as suggested by Vladimir
>
> Range-diff against v4:
> 1:  a79252528231 ! 1:  5731e2978906 efi: Fix stack protector issues
> @@ grub-core/kern/efi/init.c: grub_efi_init (void)
>
>
>   ## grub-core/kern/main.c ##
> +@@
> +  */
> +
> + #include 
> ++#include 
> + #include 
> + #include 
> + #include 
>  @@ grub-core/kern/main.c: reclaim_module_space (void)
>   void __attribute__ ((noreturn))
>   grub_main (void)
>
>  grub-core/kern/efi/init.c  | 27 ---
>  grub-core/kern/main.c  | 11 +++
>  include/grub/stack_protector.h | 13 +
>  3 files changed, 32 insertions(+), 19 deletions(-)
>
> diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
> index 6c54af6e79e5..1637077e1e96 100644
> --- a/grub-core/kern/efi/init.c
> +++ b/grub-core/kern/efi/init.c
> @@ -39,12 +39,6 @@ static grub_efi_char16_t stack_chk_fail_msg[] =
>
>  static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
>
> -/*
> - * Don't put this on grub_efi_init()'s local stack to avoid it
> - * getting a stack check.
> - */
> -static grub_efi_uint8_t stack_chk_guard_buf[32];
> -
>  /* Initialize canary in case there is no RNG protocol. */
>  grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT;
>
> @@ -77,8 +71,8 @@ __stack_chk_fail (void)
>while (1);
>  }
>
> -static void
> -stack_protector_init (void)
> +grub_addr_t
> +grub_stack_protector_init (void)
>  {
>grub_efi_rng_protocol_t *rng;
>
> @@ -87,23 +81,20 @@ stack_protector_init (void)
>if (rng != NULL)
>  {
>grub_efi_status_t status;
> +  grub_addr_t guard = 0;
>
> -  status = rng->get_rng (rng, NULL, sizeof (stack_chk_guard_buf),
> -stack_chk_guard_buf);
> +  status = rng->get_rng (rng, NULL, sizeof (guard) - 1,
> +(grub_efi_uint8_t *) );
>if (status == GRUB_EFI_SUCCESS)
> -   grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof 
> (__stack_chk_guard));
> +   return guard;
>  }
> -}
> -#else
> -static void
> -stack_protector_init (void)
> -{
> +  return 0;
>  }
>  #endif
>
>  grub_addr_t grub_modbase;
>
> -__attribute__ ((__optimize__ ("-fno-stack-protector"))) void
> +void
>  grub_efi_init (void)
>  {
>grub_modbase = grub_efi_section_addr ("mods");
> @@ -111,8 +102,6 @@ grub_efi_init (void)
>   messages.  */
>grub_console_init ();
>
> -  stack_protector_init ();
> -
>/* Initialize the memory management system.  */
>grub_efi_mm_init ();
>
> diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
> index 731c07c2901a..744197785547 100644
> --- a/grub-core/kern/main.c
> +++ b/grub-core/kern/main.c
> @@ -18,6 +18,7 @@
>   */
>
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -265,6 +266,16 @@ reclaim_module_space (void)
>  void __attribute__ ((noreturn))
>  grub_main (void)
>  {
> +#ifdef GRUB_STACK_PROTECTOR
> +  /*
> +   * This call should only be made from a function that does not return 

[PATCH v2] efi: Fix stack protector issues

2024-01-12 Thread Ard Biesheuvel via Grub-devel
From: Ard Biesheuvel 

The 'ground truth' stack protector cookie value is kept in a global
variable, and loaded in every function prologue and epilogue to store
it into resp. compare it with the stack slot holding the cookie.

If the comparison fails, the program aborts, and this might occur
spuriously when the global variable changes values between the entry and
exit of a function. This implies that assigning the global variable at
boot should not involve any instrumented function calls, unless special
care is taken to ensure that the live call stack is synchronized, which
is non-trivial.

So avoid any function calls, including grub_memcpy(), which is
unnecessary given that the stack cookie is always a suitably aligned
variable of the native word size.

While at it, leave the last byte 0x0 to avoid inadvertent unbounded
strings on the stack.

Note that the use of __attribute__((optimize)) is described as
unsuitable for production use in the GCC documentation, so let's drop
this as well now that it is no longer needed.

Cc: Glenn Washburn 
Cc: Daniel Kiper 
Signed-off-by: Ard Biesheuvel 
---
v2:
- init stack guard before machine init
- update commit log to explain that it is possible in theory to fix up a
  live call stack

 grub-core/kern/efi/init.c  | 27 ++--
 grub-core/kern/main.c  |  5 
 include/grub/stack_protector.h | 13 ++
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 6c54af6e7..1637077e1 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -39,12 +39,6 @@ static grub_efi_char16_t stack_chk_fail_msg[] =
 
 static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
 
-/*
- * Don't put this on grub_efi_init()'s local stack to avoid it
- * getting a stack check.
- */
-static grub_efi_uint8_t stack_chk_guard_buf[32];
-
 /* Initialize canary in case there is no RNG protocol. */
 grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT;
 
@@ -77,8 +71,8 @@ __stack_chk_fail (void)
   while (1);
 }
 
-static void
-stack_protector_init (void)
+grub_addr_t
+grub_stack_protector_init (void)
 {
   grub_efi_rng_protocol_t *rng;
 
@@ -87,23 +81,20 @@ stack_protector_init (void)
   if (rng != NULL)
 {
   grub_efi_status_t status;
+  grub_addr_t guard = 0;
 
-  status = rng->get_rng (rng, NULL, sizeof (stack_chk_guard_buf),
-stack_chk_guard_buf);
+  status = rng->get_rng (rng, NULL, sizeof (guard) - 1,
+(grub_efi_uint8_t *) );
   if (status == GRUB_EFI_SUCCESS)
-   grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof 
(__stack_chk_guard));
+   return guard;
 }
-}
-#else
-static void
-stack_protector_init (void)
-{
+  return 0;
 }
 #endif
 
 grub_addr_t grub_modbase;
 
-__attribute__ ((__optimize__ ("-fno-stack-protector"))) void
+void
 grub_efi_init (void)
 {
   grub_modbase = grub_efi_section_addr ("mods");
@@ -111,8 +102,6 @@ grub_efi_init (void)
  messages.  */
   grub_console_init ();
 
-  stack_protector_init ();
-
   /* Initialize the memory management system.  */
   grub_efi_mm_init ();
 
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index 731c07c29..5db504e6e 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -265,6 +265,11 @@ reclaim_module_space (void)
 void __attribute__ ((noreturn))
 grub_main (void)
 {
+#ifdef GRUB_STACK_PROTECTOR
+  /* This call can only be made from a function that does not return. */
+  grub_update_stack_guard ();
+#endif
+
   /* First of all, initialize the machine.  */
   grub_machine_init ();
 
diff --git a/include/grub/stack_protector.h b/include/grub/stack_protector.h
index c88dc00b5..9212bb4a6 100644
--- a/include/grub/stack_protector.h
+++ b/include/grub/stack_protector.h
@@ -25,6 +25,19 @@
 #ifdef GRUB_STACK_PROTECTOR
 extern grub_addr_t EXPORT_VAR (__stack_chk_guard);
 extern void __attribute__ ((noreturn)) EXPORT_FUNC (__stack_chk_fail) (void);
+
+grub_addr_t
+grub_stack_protector_init (void);
+
+static inline __attribute__((__always_inline__))
+void grub_update_stack_guard (void)
+{
+  grub_addr_t guard;
+
+  guard = grub_stack_protector_init ();
+  if (guard)
+ __stack_chk_guard = guard;
+}
 #endif
 
 #endif /* GRUB_STACK_PROTECTOR_H */
-- 
2.43.0.275.g3460e3d667-goog


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] efi: Fix stack protector issues

2024-01-03 Thread Ard Biesheuvel
On Mon, 1 Jan 2024 at 03:52, Glenn Washburn  wrote:
>
> On Sun, 31 Dec 2023 11:56:18 +0100
> Ard Biesheuvel  wrote:
>
> > Hi Glenn,
> >
> > On Thu, 28 Dec 2023 at 03:26, Glenn Washburn
> >  wrote:
> > >
> > > On Sat, 23 Dec 2023 12:45:35 +0100
> > > Ard Biesheuvel via Grub-devel  wrote:
> > >
> > > > From: Ard Biesheuvel 
> > > >
> > > > The 'ground truth' stack protector cookie value is kept in a global
> > > > variable, and loaded in every function prologue and epilogue to store
> > > > it into resp. compare it with the stack slot holding the cookie.
> > > >
> > > > If the comparison fails, the program aborts, and this might occur
> > > > spuriously when the global variable changes values between the entry and
> > > > exit of a function. This implies that assigning the global variable at
> > > > boot must not involve any instrumented function calls.
> > >
> > > Not quite true, I had an alternative patch that searched the stack for
> > > the old canary and replaced it with the new canary. This implementation
> > > is better, though less general (which doesn't add any value).
> > >
> >
> > I don't think exposing an API that circumvents the C runtime and
> > 'fixes' a call stack by replacing invalid cookie values with valid
> > ones belongs in production code. It is not trivial to implement
> > generically, and has the potential to do more harm than good if an
> > attacker manages to access it.
>
> Agreed, which is why I didn't submit it. As it doesn't seem that you
> disagree with me, my point still stands.
>

Not sure what point you are trying to make here. We both agree that
doctoring a live call stack to get the stack cookies in sync is a bad
idea. The upshot of that is that we must never enter any functions
with the old stack cookie value and return from them with another,
which implies that assigning the global variable at boot must not
involve any instrumented function calls.


> >
> > > > Note that the use of __attribute__((optimize)) is described as
> > > > unsuitable for production use in the GCC documentation, so let's drop
> > > > this as well now that it is no longer needed.
> > >
> > > Good to know. I didn't particularly like that change either.
> > >
> > > The added benefit of this change is that it looks like it will make it
> > > easier to add stack protection to other targets.
> > >
> >
> > Indeed.
> >
> > > >
> > > > Signed-off-by: Ard Biesheuvel 
> > > > ---
> > > >  grub-core/kern/efi/init.c  | 27 ---
> > > >  grub-core/kern/main.c  |  5 +
> > > >  include/grub/stack_protector.h | 13 +
> > > >  3 files changed, 26 insertions(+), 19 deletions(-)
> > > >
> > > > diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
> > > > index 6c54af6e7..1637077e1 100644
> > > > --- a/grub-core/kern/efi/init.c
> > > > +++ b/grub-core/kern/efi/init.c
> > > > @@ -39,12 +39,6 @@ static grub_efi_char16_t stack_chk_fail_msg[] =
> > > >
> > > >  static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
> > > >
> > > > -/*
> > > > - * Don't put this on grub_efi_init()'s local stack to avoid it
> > > > - * getting a stack check.
> > > > - */
> > > > -static grub_efi_uint8_t stack_chk_guard_buf[32];
> > > > -
> > > >  /* Initialize canary in case there is no RNG protocol. */
> > > >  grub_addr_t __stack_chk_guard = (grub_addr_t) 
> > > > GRUB_STACK_PROTECTOR_INIT;
> > > >
> > > > @@ -77,8 +71,8 @@ __stack_chk_fail (void)
> > > >while (1);
> > > >  }
> > > >
> > > > -static void
> > > > -stack_protector_init (void)
> > > > +grub_addr_t
> > > > +grub_stack_protector_init (void)
> > > >  {
> > > >grub_efi_rng_protocol_t *rng;
> > > >
> > > > @@ -87,23 +81,20 @@ stack_protector_init (void)
> > > >if (rng != NULL)
> > > >  {
> > > >grub_efi_status_t status;
> > > > +  grub_addr_t guard = 0;
> > > >
> > > > -  status = rng->get_rng (rng, NULL, sizeof (stack_chk_guard_buf),
> > > > -  stack_chk_guard_buf);
> > > > +  status = rng->get_rng (rng,

Re: [PATCH] efi: Fix stack protector issues

2023-12-31 Thread Ard Biesheuvel
Hi Glenn,

On Thu, 28 Dec 2023 at 03:26, Glenn Washburn
 wrote:
>
> On Sat, 23 Dec 2023 12:45:35 +0100
> Ard Biesheuvel via Grub-devel  wrote:
>
> > From: Ard Biesheuvel 
> >
> > The 'ground truth' stack protector cookie value is kept in a global
> > variable, and loaded in every function prologue and epilogue to store
> > it into resp. compare it with the stack slot holding the cookie.
> >
> > If the comparison fails, the program aborts, and this might occur
> > spuriously when the global variable changes values between the entry and
> > exit of a function. This implies that assigning the global variable at
> > boot must not involve any instrumented function calls.
>
> Not quite true, I had an alternative patch that searched the stack for
> the old canary and replaced it with the new canary. This implementation
> is better, though less general (which doesn't add any value).
>

I don't think exposing an API that circumvents the C runtime and
'fixes' a call stack by replacing invalid cookie values with valid
ones belongs in production code. It is not trivial to implement
generically, and has the potential to do more harm than good if an
attacker manages to access it.

...

> > Note that the use of __attribute__((optimize)) is described as
> > unsuitable for production use in the GCC documentation, so let's drop
> > this as well now that it is no longer needed.
>
> Good to know. I didn't particularly like that change either.
>
> The added benefit of this change is that it looks like it will make it
> easier to add stack protection to other targets.
>

Indeed.

> >
> > Signed-off-by: Ard Biesheuvel 
> > ---
> >  grub-core/kern/efi/init.c  | 27 ---
> >  grub-core/kern/main.c  |  5 +
> >  include/grub/stack_protector.h | 13 +
> >  3 files changed, 26 insertions(+), 19 deletions(-)
> >
> > diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
> > index 6c54af6e7..1637077e1 100644
> > --- a/grub-core/kern/efi/init.c
> > +++ b/grub-core/kern/efi/init.c
> > @@ -39,12 +39,6 @@ static grub_efi_char16_t stack_chk_fail_msg[] =
> >
> >  static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
> >
> > -/*
> > - * Don't put this on grub_efi_init()'s local stack to avoid it
> > - * getting a stack check.
> > - */
> > -static grub_efi_uint8_t stack_chk_guard_buf[32];
> > -
> >  /* Initialize canary in case there is no RNG protocol. */
> >  grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT;
> >
> > @@ -77,8 +71,8 @@ __stack_chk_fail (void)
> >while (1);
> >  }
> >
> > -static void
> > -stack_protector_init (void)
> > +grub_addr_t
> > +grub_stack_protector_init (void)
> >  {
> >grub_efi_rng_protocol_t *rng;
> >
> > @@ -87,23 +81,20 @@ stack_protector_init (void)
> >if (rng != NULL)
> >  {
> >grub_efi_status_t status;
> > +  grub_addr_t guard = 0;
> >
> > -  status = rng->get_rng (rng, NULL, sizeof (stack_chk_guard_buf),
> > -  stack_chk_guard_buf);
> > +  status = rng->get_rng (rng, NULL, sizeof (guard) - 1,
> > +  (grub_efi_uint8_t *) );
> >if (status == GRUB_EFI_SUCCESS)
> > - grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof 
> > (__stack_chk_guard));
> > + return guard;
> >  }
> > -}
> > -#else
> > -static void
> > -stack_protector_init (void)
> > -{
> > +  return 0;
> >  }
> >  #endif
> >
> >  grub_addr_t grub_modbase;
> >
> > -__attribute__ ((__optimize__ ("-fno-stack-protector"))) void
> > +void
> >  grub_efi_init (void)
> >  {
> >grub_modbase = grub_efi_section_addr ("mods");
> > @@ -111,8 +102,6 @@ grub_efi_init (void)
> >   messages.  */
> >grub_console_init ();
> >
> > -  stack_protector_init ();
> > -
> >/* Initialize the memory management system.  */
> >grub_efi_mm_init ();
> >
> > diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
> > index 731c07c29..1244fa84f 100644
> > --- a/grub-core/kern/main.c
> > +++ b/grub-core/kern/main.c
> > @@ -270,6 +270,11 @@ grub_main (void)
> >
> >grub_boot_time ("After machine init.");
> >
> > +#ifdef GRUB_STACK_PROTECTOR
> > +  /* This call can only be made from a function that does not return. */
> > +  grub_update_stack_guard ();
> > +#endif
> >

[PATCH] efi: Fix stack protector issues

2023-12-23 Thread Ard Biesheuvel via Grub-devel
From: Ard Biesheuvel 

The 'ground truth' stack protector cookie value is kept in a global
variable, and loaded in every function prologue and epilogue to store
it into resp. compare it with the stack slot holding the cookie.

If the comparison fails, the program aborts, and this might occur
spuriously when the global variable changes values between the entry and
exit of a function. This implies that assigning the global variable at
boot must not involve any instrumented function calls.

So avoid any function calls, including grub_memcpy(), which is
unnecessary given that the stack cookie is always a suitably aligned
variable of the native word size.

While at it, leave the last byte 0x0 to avoid inadvertent unbounded
strings on the stack.

Note that the use of __attribute__((optimize)) is described as
unsuitable for production use in the GCC documentation, so let's drop
this as well now that it is no longer needed.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/kern/efi/init.c  | 27 ---
 grub-core/kern/main.c  |  5 +
 include/grub/stack_protector.h | 13 +
 3 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 6c54af6e7..1637077e1 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -39,12 +39,6 @@ static grub_efi_char16_t stack_chk_fail_msg[] =
 
 static grub_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
 
-/*
- * Don't put this on grub_efi_init()'s local stack to avoid it
- * getting a stack check.
- */
-static grub_efi_uint8_t stack_chk_guard_buf[32];
-
 /* Initialize canary in case there is no RNG protocol. */
 grub_addr_t __stack_chk_guard = (grub_addr_t) GRUB_STACK_PROTECTOR_INIT;
 
@@ -77,8 +71,8 @@ __stack_chk_fail (void)
   while (1);
 }
 
-static void
-stack_protector_init (void)
+grub_addr_t
+grub_stack_protector_init (void)
 {
   grub_efi_rng_protocol_t *rng;
 
@@ -87,23 +81,20 @@ stack_protector_init (void)
   if (rng != NULL)
 {
   grub_efi_status_t status;
+  grub_addr_t guard = 0;
 
-  status = rng->get_rng (rng, NULL, sizeof (stack_chk_guard_buf),
-stack_chk_guard_buf);
+  status = rng->get_rng (rng, NULL, sizeof (guard) - 1,
+(grub_efi_uint8_t *) );
   if (status == GRUB_EFI_SUCCESS)
-   grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof 
(__stack_chk_guard));
+   return guard;
 }
-}
-#else
-static void
-stack_protector_init (void)
-{
+  return 0;
 }
 #endif
 
 grub_addr_t grub_modbase;
 
-__attribute__ ((__optimize__ ("-fno-stack-protector"))) void
+void
 grub_efi_init (void)
 {
   grub_modbase = grub_efi_section_addr ("mods");
@@ -111,8 +102,6 @@ grub_efi_init (void)
  messages.  */
   grub_console_init ();
 
-  stack_protector_init ();
-
   /* Initialize the memory management system.  */
   grub_efi_mm_init ();
 
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
index 731c07c29..1244fa84f 100644
--- a/grub-core/kern/main.c
+++ b/grub-core/kern/main.c
@@ -270,6 +270,11 @@ grub_main (void)
 
   grub_boot_time ("After machine init.");
 
+#ifdef GRUB_STACK_PROTECTOR
+  /* This call can only be made from a function that does not return. */
+  grub_update_stack_guard ();
+#endif
+
   /* This breaks flicker-free boot on EFI systems, so disable it there. */
 #ifndef GRUB_MACHINE_EFI
   /* Hello.  */
diff --git a/include/grub/stack_protector.h b/include/grub/stack_protector.h
index c88dc00b5..9212bb4a6 100644
--- a/include/grub/stack_protector.h
+++ b/include/grub/stack_protector.h
@@ -25,6 +25,19 @@
 #ifdef GRUB_STACK_PROTECTOR
 extern grub_addr_t EXPORT_VAR (__stack_chk_guard);
 extern void __attribute__ ((noreturn)) EXPORT_FUNC (__stack_chk_fail) (void);
+
+grub_addr_t
+grub_stack_protector_init (void);
+
+static inline __attribute__((__always_inline__))
+void grub_update_stack_guard (void)
+{
+  grub_addr_t guard;
+
+  guard = grub_stack_protector_init ();
+  if (guard)
+ __stack_chk_guard = guard;
+}
 #endif
 
 #endif /* GRUB_STACK_PROTECTOR_H */
-- 
2.43.0.472.g3155946c3a-goog


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] loader/i386/linux: Prefer entry in long mode when booting via EFI

2023-09-17 Thread Ard Biesheuvel
On Thu, 3 Aug 2023 at 15:24, Ard Biesheuvel  wrote:
>
> The x86_64 Linux kernel can be booted in 32-bit mode, in which case the
> startup code creates a set of preliminary page tables that map the first
> 1GiB of physical memory 1:1, and enables paging. This is a prerequisite

this should be '4 GiB'

> for 64-bit execution, and can therefore only be implemented in 32-bit
> code.
>
> The x86_64 Linux kernel can also be booted in 64-bit mode directly: this
> implies that paging is already enabled, and it is the responsibility of
> the bootloader to ensure that the the active page tables cover the
> entire loaded image, including its BSS space, the size of which is
> described in the image's setup header.
>
> Given that the EFI spec mandates execution in long mode for x86_64, and
> stipulates that all system memory is mapped 1:1, the Linux/x86
> requirements for 64-bit entry can be met trivially when booting on
> x86_64 via EFI. So enter via the 64-bit entrypoint in this case.
>
> This involves inspecting the xloadflags field in the setup header to
> check whether the 64-bit entrypoint is supported. This field was
> introduced in Linux version v3.8 (early 2013)
>

> This change ensures that all EFI firmware tables and other assets passed
> by the firmware or bootloader in memory remain mapped and accessible
> throughout the early startup code.

The part between the () should just be dropped entirely: I
misunderstood the code when I was reading it/

The early code just maps the first 4 GiB 1:1

> (Note that Linux's 32-bit startup
> code creates multiple shadow mappings of the first 1GiB of physical
> memory up to the 4 GiB mark so anything that resides there becomes
> inaccessible until the 64-bit startup code replaces the preliminary
> mappings with more accurate ones)
>


> Avoiding the drop out of long mode will also be needed to support
> upcoming CPU designs that no longer implement 32-bit mode at all (as
> recently announced by Intel [0])
>
> [0] 
> https://www.intel.com/content/www/us/en/developer/articles/technical/envisioning-future-simplified-architecture.html
>
> Cc: Daniel Kiper 
> Cc: Julian Andres Klode 
> Signed-off-by: Ard Biesheuvel 
> ---
>  grub-core/loader/i386/linux.c | 12 
>  include/grub/i386/linux.h | 15 +--
>  2 files changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
> index 997647a33326eeb8..a83cc52a656d587b 100644
> --- a/grub-core/loader/i386/linux.c
> +++ b/grub-core/loader/i386/linux.c
> @@ -624,6 +624,18 @@ grub_linux_boot (void)
>}
>  #endif
>
> +#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
> +  if (grub_le_to_cpu16 (ctx.params->version) >= 0x020c &&
> +  (linux_params.xloadflags & LINUX_X86_XLF_KERNEL_64) != 0)
> +{
> +  struct grub_relocator64_efi_state state64;
> +
> +  state64.rsi = ctx.real_mode_target;
> +  state64.rip = ctx.params->code32_start + LINUX_X86_STARTUP64_OFFSET;
> +  return grub_relocator64_efi_boot (relocator, state64);
> +}
> +#endif
> +
>/* FIXME.  */
>/*  asm volatile ("lidt %0" : : "m" (idt_desc)); */
>state.ebp = state.edi = state.ebx = 0;
> diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
> index 0fd6e1212fd2fa86..d4b550869534e255 100644
> --- a/include/grub/i386/linux.h
> +++ b/include/grub/i386/linux.h
> @@ -69,6 +69,16 @@
>  #define GRUB_LINUX_OFW_SIGNATURE   \
>(' ' << 24 | 'W' << 16 | 'F' << 8 | 'O')
>
> +#define LINUX_X86_XLF_KERNEL_64(1<<0)
> +#define LINUX_X86_XLF_CAN_BE_LOADED_ABOVE_4G   (1<<1)
> +#define LINUX_X86_XLF_EFI_HANDOVER_32  (1<<2)
> +#define LINUX_X86_XLF_EFI_HANDOVER_64  (1<<3)
> +#define LINUX_X86_XLF_EFI_KEXEC(1<<4)
> +#define LINUX_X86_XLF_5LEVEL   (1<<5)
> +#define LINUX_X86_XLF_5LEVEL_ENABLED   (1<<6)
> +
> +#define LINUX_X86_STARTUP64_OFFSET 0x200
> +
>  #ifndef ASM_FILE
>
>  #define GRUB_E820_RAM1
> @@ -138,7 +148,7 @@ struct linux_i386_kernel_header
>grub_uint32_t kernel_alignment;
>grub_uint8_t relocatable;
>grub_uint8_t min_alignment;
> -  grub_uint8_t pad[2];
> +  grub_uint16_t xloadflags;
>grub_uint32_t cmdline_size;
>grub_uint32_t hardware_subarch;
>grub_uint64_t hardware_subarch_data;
> @@ -315,7 +325,8 @@ struct linux_kernel_params
>grub_uint32_t initrd_addr_max;   /* Maximum initrd address */
>grub_uint32_t kernel_alignment;  /* Alignment of the kernel */
>grub_uint8_t r

Re: [PATCH] loader/i386/linux: Prefer entry in long mode when booting via EFI

2023-09-14 Thread Ard Biesheuvel
On Thu, 14 Sept 2023 at 18:31, Daniel Kiper  wrote:
>
> On Mon, Aug 21, 2023 at 09:51:13PM +0200, Vladimir 'phcoder' Serbinenko wrote:
> > I think we need to start having options to specify which entry to use. E.g
> > linux --no-efi-stub /vmlinuz
> > This is probably needed to support other users of Linux protocol
>
> If somebody needs that thing they can add it later.
>
> For now Reviewed-by: Daniel Kiper ...
>
> Though...
>
> > Le lun. 21 août 2023, 20:12, Ard Biesheuvel  a écrit :
> >  On Thu, 3 Aug 2023 at 15:24, Ard Biesheuvel  wrote:
> >  >
> >  > The x86_64 Linux kernel can be booted in 32-bit mode, in which case
> >  the
> >  > startup code creates a set of preliminary page tables that map the
> >  first
> >  > 1GiB of physical memory 1:1, and enables paging. This is a
> >  prerequisite
> >  > for 64-bit execution, and can therefore only be implemented in 32-
> >  bit
> >  > code.
> >  >
> >  > The x86_64 Linux kernel can also be booted in 64-bit mode directly:
> >  this
> >  > implies that paging is already enabled, and it is the
> >  responsibility of
> >  > the bootloader to ensure that the the active page tables cover the
> >  > entire loaded image, including its BSS space, the size of which is
> >  > described in the image's setup header.
> >  >
> >  > Given that the EFI spec mandates execution in long mode for x86_64,
> >  and
> >  > stipulates that all system memory is mapped 1:1, the Linux/x86
> >  > requirements for 64-bit entry can be met trivially when booting on
> >  > x86_64 via EFI. So enter via the 64-bit entrypoint in this case.
> >  >
> >  > This involves inspecting the xloadflags field in the setup header
> >  to
> >  > check whether the 64-bit entrypoint is supported. This field was
> >  > introduced in Linux version v3.8 (early 2013)
> >  >
> >  > This change ensures that all EFI firmware tables and other assets
> >  passed
> >  > by the firmware or bootloader in memory remain mapped and
> >  accessible
> >  > throughout the early startup code. (Note that Linux's 32-bit
> >  startup
> >  > code creates multiple shadow mappings of the first 1GiB of physical
> >  > memory up to the 4 GiB mark so anything that resides there becomes
> >  > inaccessible until the 64-bit startup code replaces the preliminary
> >  > mappings with more accurate ones)
> >  >
> >  > Avoiding the drop out of long mode will also be needed to support
> >  > upcoming CPU designs that no longer implement 32-bit mode at all
> >  (as
> >  > recently announced by Intel [0])
> >  >
> >  > [0] https://www.intel.com/content/www/us/en/developer/articles/
> >  technical/envisioning-future-simplified-architecture.html
> >  >
> >  > Cc: Daniel Kiper 
> >  > Cc: Julian Andres Klode 
> >  > Signed-off-by: Ard Biesheuvel 
> >
> >  Ping?
> >
> >  > ---
> >  >  grub-core/loader/i386/linux.c | 12 
> >  >  include/grub/i386/linux.h | 15 +--
> >  >  2 files changed, 25 insertions(+), 2 deletions(-)
> >  >
> >  > diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/
> >  linux.c
> >  > index 997647a33326eeb8..a83cc52a656d587b 100644
> >  > --- a/grub-core/loader/i386/linux.c
> >  > +++ b/grub-core/loader/i386/linux.c
> >  > @@ -624,6 +624,18 @@ grub_linux_boot (void)
> >  >}
> >  >  #endif
> >  >
> >  > +#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
>
> ... I would put "defined (__x86_64__)" first in the condition. I can
> make it for you before push.
>

That's fine.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v9 02/11] Unify GUID types

2023-09-13 Thread Ard Biesheuvel
On Wed, 13 Sept 2023 at 13:42, Vladimir 'phcoder' Serbinenko
 wrote:
>
>
>
> Le mer. 13 sept. 2023, 12:33, Ard Biesheuvel  a écrit :
>>
>> On Wed, 13 Sept 2023 at 12:18, John Paul Adrian Glaubitz
>>  wrote:
>> >
>> > Hi Oliver!
>> >
>> > On Wed, 2023-09-13 at 12:14 +0200, Oliver Steffen wrote:
>> > > On Wed, Sep 13, 2023 at 6:10 AM Pedro Miguel Justo  
>> > > wrote:
>> > > >
>> > > >
>> > > > I can confirm that, taking [1][2] and making [3] on top of it, my 
>> > > > Montvale-based rx2660 machine still boots fine.
>> > >
>> > > Wonderful! Thanks for testing!
>> >
>> > Are you going to submit a patch to fix the issue with the new information?
>> >
>> > Would be great if the bug could be fixed before the 2.12 release.
>> >
>>
>> Yes, this needs to be fixed. The EFI GUID type should not have the
>> packed attribute in the general case, only in places where it could
>> really appear misaligned (e.g., in device path nodes), although I
>> suspect that adding the packed attribute to the outer struct would be
>> sufficient there (given that the guid struct has no internal padding
>> so the attribute only affects its minimum alignment)
>>
>> E.g,
>>
>> struct grub_efi_vendor_device_path
>> {
>>   grub_efi_device_path_t header;
>>   grub_guid_t vendor_guid;
>>   grub_efi_uint8_t vendor_defined_data[0];
>> } GRUB_PACKED;
>
> Tried this. Compiler doesn't allow it

Tried what exactly? This is just copy/paste from the existing tree

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v9 02/11] Unify GUID types

2023-09-13 Thread Ard Biesheuvel
On Wed, 13 Sept 2023 at 12:18, John Paul Adrian Glaubitz
 wrote:
>
> Hi Oliver!
>
> On Wed, 2023-09-13 at 12:14 +0200, Oliver Steffen wrote:
> > On Wed, Sep 13, 2023 at 6:10 AM Pedro Miguel Justo  wrote:
> > >
> > >
> > > I can confirm that, taking [1][2] and making [3] on top of it, my 
> > > Montvale-based rx2660 machine still boots fine.
> >
> > Wonderful! Thanks for testing!
>
> Are you going to submit a patch to fix the issue with the new information?
>
> Would be great if the bug could be fixed before the 2.12 release.
>

Yes, this needs to be fixed. The EFI GUID type should not have the
packed attribute in the general case, only in places where it could
really appear misaligned (e.g., in device path nodes), although I
suspect that adding the packed attribute to the outer struct would be
sufficient there (given that the guid struct has no internal padding
so the attribute only affects its minimum alignment)

E.g,

struct grub_efi_vendor_device_path
{
  grub_efi_device_path_t header;
  grub_guid_t vendor_guid;
  grub_efi_uint8_t vendor_defined_data[0];
} GRUB_PACKED;

Here the GUID is already 32-bit aligned due to the size of the preceding field

I think simply dropping the PACKED attribute from grub_guid_t should
be sufficient here - this will affect the placement of all the
grub_guid_t global and automatic variables that are passed to the
firmware APIs by reference. If needed we could bring back the
efi_packed_guid_t as well, but I'm not sure it is necessary.


Note that this affects 32-bit ARM as well: GRUB may pass misaligned
GUIDs to APIs such as Get/SetVariable and this could crash the
firmware if it assumes GUIDs are 32-bit aligned.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] loader/i386/linux: Prefer entry in long mode when booting via EFI

2023-09-06 Thread Ard Biesheuvel
On Mon, 21 Aug 2023 at 20:10, Ard Biesheuvel  wrote:
>
> On Thu, 3 Aug 2023 at 15:24, Ard Biesheuvel  wrote:
> >
> > The x86_64 Linux kernel can be booted in 32-bit mode, in which case the
> > startup code creates a set of preliminary page tables that map the first
> > 1GiB of physical memory 1:1, and enables paging. This is a prerequisite
> > for 64-bit execution, and can therefore only be implemented in 32-bit
> > code.
> >
> > The x86_64 Linux kernel can also be booted in 64-bit mode directly: this
> > implies that paging is already enabled, and it is the responsibility of
> > the bootloader to ensure that the the active page tables cover the
> > entire loaded image, including its BSS space, the size of which is
> > described in the image's setup header.
> >
> > Given that the EFI spec mandates execution in long mode for x86_64, and
> > stipulates that all system memory is mapped 1:1, the Linux/x86
> > requirements for 64-bit entry can be met trivially when booting on
> > x86_64 via EFI. So enter via the 64-bit entrypoint in this case.
> >
> > This involves inspecting the xloadflags field in the setup header to
> > check whether the 64-bit entrypoint is supported. This field was
> > introduced in Linux version v3.8 (early 2013)
> >
> > This change ensures that all EFI firmware tables and other assets passed
> > by the firmware or bootloader in memory remain mapped and accessible
> > throughout the early startup code. (Note that Linux's 32-bit startup
> > code creates multiple shadow mappings of the first 1GiB of physical
> > memory up to the 4 GiB mark so anything that resides there becomes
> > inaccessible until the 64-bit startup code replaces the preliminary
> > mappings with more accurate ones)
> >
> > Avoiding the drop out of long mode will also be needed to support
> > upcoming CPU designs that no longer implement 32-bit mode at all (as
> > recently announced by Intel [0])
> >
> > [0] 
> > https://www.intel.com/content/www/us/en/developer/articles/technical/envisioning-future-simplified-architecture.html
> >
> > Cc: Daniel Kiper 
> > Cc: Julian Andres Klode 
> > Signed-off-by: Ard Biesheuvel 
>
> Ping?
>

Ping?

This should preferably be part of the release so we avoid failing back
to 32-bit entry for configurations that may have been using the
handover protocol in the past.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v9 02/11] Unify GUID types

2023-08-31 Thread Ard Biesheuvel
On Wed, 30 Aug 2023 at 21:07, Vladimir 'phcoder' Serbinenko
 wrote:
>
>
>
> Le mer. 30 août 2023, 16:38, Daniel Kiper  a écrit :
>>
>> On Wed, Aug 30, 2023 at 04:23:36PM +0200, Ard Biesheuvel wrote:
>> > On Wed, 30 Aug 2023 at 16:18, Daniel Kiper  wrote:
>> > >
>> > > On Fri, Aug 25, 2023 at 05:50:58AM -0700, Oliver Steffen wrote:
>> > > > Quoting Vladimir 'phcoder' Serbinenko (2023-08-15 18:14:11)
>> > >
>> > > [...]
>> > >
>> > > > I am not sure what the best way forward is now, but we at least have 
>> > > > the
>> > > > patches from Vladimir (thanks!).
>> > > >
>> > > > Pedro, Adrian, could you - if you get a chance - try them with a 4 byte
>> > > > alignment too?
>> > >
>> > > Yes, that would be perfect. If Itanium works then I suggest to align
>> > > GUIDs to 4 bytes. This alignment is used in the kernel for more than
>> > > 4 years and it looks nobody complains...
>> > >
>> > > Pedro, Adrian, could you change GUIDs alignment in Vladimir's patches to
>> > > 4 and test them on Itanium?
>> > >
>> >
>> > Note that itanium is a 64-bit architecture, whereas the potential
>> > alignment/padding issue I raised only occurs on 32-bit systems.
>>
>> Yeah, I know. But IIRC your Linux kernel patch aligns GUIDs to 4 bytes
>> even on Itanium. So, how does it work on 64-bit architecture and nobody
>> complained for more than 4 years... Hmmm...
>
>
> Unaligned access causes an exception. In GRUB it leads to unhandled 
> exception. Linux catches exception and emulates unaligned access. It's 
> typical for RISC platforms

No it does not, at least not in the general case.

Every Linux arch except IA-64 supports booting via the EFI stub, which
is Linux kernel code that executes in the context of the EFI boot
services. Any unaligned accesses occurring in this phase will be
handled by the system firmware in the exact same way as an unaligned
access caused by a misaligned GUID provided by GRUB. This is why the
Linux EFI code needed to be fixed.

IA-64 deviates in this regard because it predates the introduction of
the EFI stub, and the only EFI calls that occur from Linux are runtime
services calls. Any unaligned traps occurring in that context will
indeed be fixed up by the kernel, and this explains why neither the
original unaligned GUIDs nor the 4-byte aligned ones Linux has been
using for the past four years ever created any problems on IA-64

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v9 02/11] Unify GUID types

2023-08-30 Thread Ard Biesheuvel
On Wed, 30 Aug 2023 at 16:18, Daniel Kiper  wrote:
>
> On Fri, Aug 25, 2023 at 05:50:58AM -0700, Oliver Steffen wrote:
> > Quoting Vladimir 'phcoder' Serbinenko (2023-08-15 18:14:11)
>
> [...]
>
> > I am not sure what the best way forward is now, but we at least have the
> > patches from Vladimir (thanks!).
> >
> > Pedro, Adrian, could you - if you get a chance - try them with a 4 byte
> > alignment too?
>
> Yes, that would be perfect. If Itanium works then I suggest to align
> GUIDs to 4 bytes. This alignment is used in the kernel for more than
> 4 years and it looks nobody complains...
>
> Pedro, Adrian, could you change GUIDs alignment in Vladimir's patches to
> 4 and test them on Itanium?
>

Note that itanium is a 64-bit architecture, whereas the potential
alignment/padding issue I raised only occurs on 32-bit systems.

So another option is to align GUIDs to __alignof__(void*)

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] loader/i386/linux: Prefer entry in long mode when booting via EFI

2023-08-21 Thread Ard Biesheuvel
On Thu, 3 Aug 2023 at 15:24, Ard Biesheuvel  wrote:
>
> The x86_64 Linux kernel can be booted in 32-bit mode, in which case the
> startup code creates a set of preliminary page tables that map the first
> 1GiB of physical memory 1:1, and enables paging. This is a prerequisite
> for 64-bit execution, and can therefore only be implemented in 32-bit
> code.
>
> The x86_64 Linux kernel can also be booted in 64-bit mode directly: this
> implies that paging is already enabled, and it is the responsibility of
> the bootloader to ensure that the the active page tables cover the
> entire loaded image, including its BSS space, the size of which is
> described in the image's setup header.
>
> Given that the EFI spec mandates execution in long mode for x86_64, and
> stipulates that all system memory is mapped 1:1, the Linux/x86
> requirements for 64-bit entry can be met trivially when booting on
> x86_64 via EFI. So enter via the 64-bit entrypoint in this case.
>
> This involves inspecting the xloadflags field in the setup header to
> check whether the 64-bit entrypoint is supported. This field was
> introduced in Linux version v3.8 (early 2013)
>
> This change ensures that all EFI firmware tables and other assets passed
> by the firmware or bootloader in memory remain mapped and accessible
> throughout the early startup code. (Note that Linux's 32-bit startup
> code creates multiple shadow mappings of the first 1GiB of physical
> memory up to the 4 GiB mark so anything that resides there becomes
> inaccessible until the 64-bit startup code replaces the preliminary
> mappings with more accurate ones)
>
> Avoiding the drop out of long mode will also be needed to support
> upcoming CPU designs that no longer implement 32-bit mode at all (as
> recently announced by Intel [0])
>
> [0] 
> https://www.intel.com/content/www/us/en/developer/articles/technical/envisioning-future-simplified-architecture.html
>
> Cc: Daniel Kiper 
> Cc: Julian Andres Klode 
> Signed-off-by: Ard Biesheuvel 

Ping?

> ---
>  grub-core/loader/i386/linux.c | 12 
>  include/grub/i386/linux.h | 15 +--
>  2 files changed, 25 insertions(+), 2 deletions(-)
>
> diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
> index 997647a33326eeb8..a83cc52a656d587b 100644
> --- a/grub-core/loader/i386/linux.c
> +++ b/grub-core/loader/i386/linux.c
> @@ -624,6 +624,18 @@ grub_linux_boot (void)
>}
>  #endif
>
> +#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
> +  if (grub_le_to_cpu16 (ctx.params->version) >= 0x020c &&
> +  (linux_params.xloadflags & LINUX_X86_XLF_KERNEL_64) != 0)
> +{
> +  struct grub_relocator64_efi_state state64;
> +
> +  state64.rsi = ctx.real_mode_target;
> +  state64.rip = ctx.params->code32_start + LINUX_X86_STARTUP64_OFFSET;
> +  return grub_relocator64_efi_boot (relocator, state64);
> +}
> +#endif
> +
>/* FIXME.  */
>/*  asm volatile ("lidt %0" : : "m" (idt_desc)); */
>state.ebp = state.edi = state.ebx = 0;
> diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
> index 0fd6e1212fd2fa86..d4b550869534e255 100644
> --- a/include/grub/i386/linux.h
> +++ b/include/grub/i386/linux.h
> @@ -69,6 +69,16 @@
>  #define GRUB_LINUX_OFW_SIGNATURE   \
>(' ' << 24 | 'W' << 16 | 'F' << 8 | 'O')
>
> +#define LINUX_X86_XLF_KERNEL_64(1<<0)
> +#define LINUX_X86_XLF_CAN_BE_LOADED_ABOVE_4G   (1<<1)
> +#define LINUX_X86_XLF_EFI_HANDOVER_32  (1<<2)
> +#define LINUX_X86_XLF_EFI_HANDOVER_64  (1<<3)
> +#define LINUX_X86_XLF_EFI_KEXEC(1<<4)
> +#define LINUX_X86_XLF_5LEVEL   (1<<5)
> +#define LINUX_X86_XLF_5LEVEL_ENABLED   (1<<6)
> +
> +#define LINUX_X86_STARTUP64_OFFSET 0x200
> +
>  #ifndef ASM_FILE
>
>  #define GRUB_E820_RAM1
> @@ -138,7 +148,7 @@ struct linux_i386_kernel_header
>grub_uint32_t kernel_alignment;
>grub_uint8_t relocatable;
>grub_uint8_t min_alignment;
> -  grub_uint8_t pad[2];
> +  grub_uint16_t xloadflags;
>grub_uint32_t cmdline_size;
>grub_uint32_t hardware_subarch;
>grub_uint64_t hardware_subarch_data;
> @@ -315,7 +325,8 @@ struct linux_kernel_params
>grub_uint32_t initrd_addr_max;   /* Maximum initrd address */
>grub_uint32_t kernel_alignment;  /* Alignment of the kernel */
>grub_uint8_t relocatable_kernel; /* Is the kernel relocatable */
> -  grub_uint8_t pad1[3];
> +  grub_uint8_t min_alignment;
> +  grub_uint16_t xloadflags;
>grub_uint32_t cmdline_size;  /* Size of the kernel command line */
>grub_uint32_t hardware_subarch;
>grub_uint64_t hardware_subarch_data;
> --
> 2.39.2
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v9 02/11] Unify GUID types

2023-08-15 Thread Ard Biesheuvel
On Tue, 15 Aug 2023 at 05:42, Vladimir 'phcoder' Serbinenko
 wrote:
>>
>> .
>>
>> Ard thinks that a 64 bit alignment for EFI GUIDs is a mistake - see [1]
>> and [2]. Hence Linux uses `__aligned(__alignof__(u32))` for "efi_guid_t"
>> since 2019.
>
>
> My patch presents a reliability paradigm: accept all inputs, produce outputs 
> that are always aligned to 8-byte. It can make sense even though I agree that 
> requiring 8-byte alignment for UUID is weird. Yet it's difficult to know if 
> some obscure firmware does rely on it in some one in a thousand edge case

+1

The Linux side change ensures that the OS does not present misaligned
GUIDs to the firmware.

The problem with 8-byte alignment is that it deviates from EDK2, and
could result in struct layout changes due to padding. Given that EDK2
uses 32-bit alignment only, some of the struct types it defines might
suddenly need the __packed attribute on 32-bit builds if the alignment
of the GUID type is increased to 64 bits.

E.g.,

struct {
  void *
  guid
}

will have no padding in 32-bit EDK2 based firmware builds, even if the
spec claims that GUIDs are 64-bit aligned.

So the lowest risk change for Linux was to increase to 32-bit
alignment, as it fixes any potential issues with misaligned
load-multiple instructions on ARM, and other architectures don't care
that much about alignment anyway.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot

2023-08-08 Thread Ard Biesheuvel
On Tue, 8 Aug 2023 at 17:34, Dimitri John Ledkov
 wrote:
>
> On Mon, 7 Aug 2023, 13:23 Ard Biesheuvel,  wrote:
> >
> > Recent mixed-mode Linux kernels (i.e., v4.0 or newer) can access EFI
> > runtime services at OS runtime even when the OS was not entered via the
> > EFI stub. This is because, instead of reverting back to the firmware's
> > segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit
> > runtime services using compatilibity mode (i.e., the same mode used for
> > 32-bit user space) without taking down all interrupt handling, exception
> > handling etc.
> >
> > This means that GRUB's legacy x86 boot mode is sufficient to make use of
> > this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI
> > enlightened mode (but without going via the EFI stub), and provide all
> > the metadata that the OS needs to map the EFI runtime regions and call
> > EFI runtime services successfully.
>
> I'm not sure I understand the target combination here, and I'm not
> sure we want to support it.
>

The point is not what we /want/ to support - it is what we already
supported in the past, and the recent EFI changes result in
regressions for those scenarios.

> For now, we keep shipping both 32bit and 64bit x86 revocations
> together. However, the time will come that we will want or need to
> drop the 32bit revocations. Ubuntu has never signed a 32bit build of
> grub for secureboot, nor have we ever signed 32bit kernels to boot
> either. Most distributions have also stopped 32bit x86 builds, and/or
> don't support them to the same feature level (there are some that
> enable lots of combinations, i.e. debian, but even there i am not sure
> such hardware exists).
>
> I see this as a bug that 32-bit i686 build of Grub can launch 64-bit
> kernels - potentially without using shim / shim-lock / sbat
> verification.
>

A 32-bit *EFI* build of GRUB, which you will never be able to boot on
anything other than 32-bit EFI, i.e., systems that nobody cares about
wrt secure boot.

> I would feel much better if under shim-lock/secureboot only matching
> bitness was allowed to be booted and supported. Meaning no mixing &
> matching i686 grub builds launching x86_64 kernels, or vice versa, and
> ditoo on any other arches too (i.e. no mixing between
> riscv32/riscv64/riscv128, nor armhf/arm64).
>

AFAICT, the non-EFIstub x86 boot path in GRUB has always supported
booting kernels of any bitness (provided, of course, that the CPU is
long mode capable)

With adding the EFI support, we broke this which may potentially harm users.

> I am impressed it is technologically possible, but do we really want
> to implement/design/support/encourage that?
>

Distros already do, that is the whole point. It is called mixed mode,
and it is something I am trying to get rid of.

The current mixed-mode implementation has elaborate plumbing so that
the 64-bit EFI stub can make use of 32-bit boot services. This was
presented to me in the past as a prerequisite for being able to
support mixed mode (and therefore a justification for upstreaming the
EFI handover protocol). However, I realized that the current mixed
mode support in Linux does not actually rely on this: the only thing
you need is a bootloader that implements the x86 Linux boot protocol
directly but also passes EFI memory map, system table, etc. GRUB
already did this. IOW, mainline i386-efi GRUB already supported mixed
mode, and the recent EFI changes broke that.

> I'm not even sure if 32-bit x86 EFI grub platform even makes sense
> anymore, and maybe it should be ripped out altogether? and leave i686
> boot to pc-bios only. i686 EFI was a short lived experiment that died
> without ever taking off.
>

Not for mixed-mode - i.e., 'netbooks' with 64-bit Atom CPUs that
shipped with 32-bit Windows and therefore 32-bit EFI. Not sure how
many are still in circulation running Linux.

Ideally, we'd drop this altogether. However, by making this change,
which is arguably a regression fix, we can phase out the EFI stub part
of mixed mode, and only retain the EFI runtime support.

> >
> > It does mean that GRUB should not attempt to invoke the firmware's
> > LoadImage/StartImage methods on kernel builds that it knows cannot be
> > started natively. So add a check for this in the native EFI boot path,
> > and fall back to legacy x86 mode in such cases.
> >
> > Note that in the general case, booting non-native images of the same
> > native word size (e.g., X64 EFI apps on arm64 firmware) might be
> > supported by means of emulation, so let's only disallow images that use
> > a non-native word size. This will also permit booting i686 kernels on
> > x86_64 builds, although without access to runtime services, as this is
> > n

[PATCH] loader/efi/linux: Implement x86 mixed mode using legacy boot

2023-08-07 Thread Ard Biesheuvel
Recent mixed-mode Linux kernels (i.e., v4.0 or newer) can access EFI
runtime services at OS runtime even when the OS was not entered via the
EFI stub. This is because, instead of reverting back to the firmware's
segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit
runtime services using compatilibity mode (i.e., the same mode used for
32-bit user space) without taking down all interrupt handling, exception
handling etc.

This means that GRUB's legacy x86 boot mode is sufficient to make use of
this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI
enlightened mode (but without going via the EFI stub), and provide all
the metadata that the OS needs to map the EFI runtime regions and call
EFI runtime services successfully.

It does mean that GRUB should not attempt to invoke the firmware's
LoadImage/StartImage methods on kernel builds that it knows cannot be
started natively. So add a check for this in the native EFI boot path,
and fall back to legacy x86 mode in such cases.

Note that in the general case, booting non-native images of the same
native word size (e.g., X64 EFI apps on arm64 firmware) might be
supported by means of emulation, so let's only disallow images that use
a non-native word size. This will also permit booting i686 kernels on
x86_64 builds, although without access to runtime services, as this is
not supported by Linux.

This change on top of 2.12-rc1 is sufficient to boot ordinary Linux
mixed mode builds and get full access to the EFI runtime services.

Cc: Daniel Kiper 
Cc: Steve McIntyre 
Cc: Julian Andres Klode 
Signed-off-by: Ard Biesheuvel 
---
 grub-core/loader/efi/linux.c | 5 +
 include/grub/efi/pe32.h  | 6 ++
 2 files changed, 11 insertions(+)

diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index ed325f2b0aae2d6f..1d0734e295043df7 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -120,6 +120,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
 return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF 
image header");
 }
 
+  if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC)
+{
+  return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not 
supported");
+}
+
   /*
* Linux kernels built for any architecture are guaranteed to support the
* LoadFile2 based initrd loading protocol if the image version is >= 1.
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 101859af1ea64237..4e6e9d254bd35c9b 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -267,6 +267,12 @@ struct grub_pe32_section_table
 
 #define GRUB_PE32_SIGNATURE_SIZE 4
 
+#if GRUB_TARGET_SIZEOF_VOID_P == 8
+#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC
+#else
+#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC
+#endif
+
 struct grub_pe_image_header
 {
   /* This is always PE\0\0.  */
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH] loader/i386/linux: Prefer entry in long mode when booting via EFI

2023-08-03 Thread Ard Biesheuvel
The x86_64 Linux kernel can be booted in 32-bit mode, in which case the
startup code creates a set of preliminary page tables that map the first
1GiB of physical memory 1:1, and enables paging. This is a prerequisite
for 64-bit execution, and can therefore only be implemented in 32-bit
code.

The x86_64 Linux kernel can also be booted in 64-bit mode directly: this
implies that paging is already enabled, and it is the responsibility of
the bootloader to ensure that the the active page tables cover the
entire loaded image, including its BSS space, the size of which is
described in the image's setup header.

Given that the EFI spec mandates execution in long mode for x86_64, and
stipulates that all system memory is mapped 1:1, the Linux/x86
requirements for 64-bit entry can be met trivially when booting on
x86_64 via EFI. So enter via the 64-bit entrypoint in this case.

This involves inspecting the xloadflags field in the setup header to
check whether the 64-bit entrypoint is supported. This field was
introduced in Linux version v3.8 (early 2013)

This change ensures that all EFI firmware tables and other assets passed
by the firmware or bootloader in memory remain mapped and accessible
throughout the early startup code. (Note that Linux's 32-bit startup
code creates multiple shadow mappings of the first 1GiB of physical
memory up to the 4 GiB mark so anything that resides there becomes
inaccessible until the 64-bit startup code replaces the preliminary
mappings with more accurate ones)

Avoiding the drop out of long mode will also be needed to support
upcoming CPU designs that no longer implement 32-bit mode at all (as
recently announced by Intel [0])

[0] 
https://www.intel.com/content/www/us/en/developer/articles/technical/envisioning-future-simplified-architecture.html

Cc: Daniel Kiper 
Cc: Julian Andres Klode 
Signed-off-by: Ard Biesheuvel 
---
 grub-core/loader/i386/linux.c | 12 
 include/grub/i386/linux.h | 15 +--
 2 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
index 997647a33326eeb8..a83cc52a656d587b 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -624,6 +624,18 @@ grub_linux_boot (void)
   }
 #endif
 
+#if defined (GRUB_MACHINE_EFI) && defined (__x86_64__)
+  if (grub_le_to_cpu16 (ctx.params->version) >= 0x020c &&
+  (linux_params.xloadflags & LINUX_X86_XLF_KERNEL_64) != 0)
+{
+  struct grub_relocator64_efi_state state64;
+
+  state64.rsi = ctx.real_mode_target;
+  state64.rip = ctx.params->code32_start + LINUX_X86_STARTUP64_OFFSET;
+  return grub_relocator64_efi_boot (relocator, state64);
+}
+#endif
+
   /* FIXME.  */
   /*  asm volatile ("lidt %0" : : "m" (idt_desc)); */
   state.ebp = state.edi = state.ebx = 0;
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
index 0fd6e1212fd2fa86..d4b550869534e255 100644
--- a/include/grub/i386/linux.h
+++ b/include/grub/i386/linux.h
@@ -69,6 +69,16 @@
 #define GRUB_LINUX_OFW_SIGNATURE   \
   (' ' << 24 | 'W' << 16 | 'F' << 8 | 'O')
 
+#define LINUX_X86_XLF_KERNEL_64(1<<0)
+#define LINUX_X86_XLF_CAN_BE_LOADED_ABOVE_4G   (1<<1)
+#define LINUX_X86_XLF_EFI_HANDOVER_32  (1<<2)
+#define LINUX_X86_XLF_EFI_HANDOVER_64  (1<<3)
+#define LINUX_X86_XLF_EFI_KEXEC(1<<4)
+#define LINUX_X86_XLF_5LEVEL   (1<<5)
+#define LINUX_X86_XLF_5LEVEL_ENABLED   (1<<6)
+
+#define LINUX_X86_STARTUP64_OFFSET 0x200
+
 #ifndef ASM_FILE
 
 #define GRUB_E820_RAM1
@@ -138,7 +148,7 @@ struct linux_i386_kernel_header
   grub_uint32_t kernel_alignment;
   grub_uint8_t relocatable;
   grub_uint8_t min_alignment;
-  grub_uint8_t pad[2];
+  grub_uint16_t xloadflags;
   grub_uint32_t cmdline_size;
   grub_uint32_t hardware_subarch;
   grub_uint64_t hardware_subarch_data;
@@ -315,7 +325,8 @@ struct linux_kernel_params
   grub_uint32_t initrd_addr_max;   /* Maximum initrd address */
   grub_uint32_t kernel_alignment;  /* Alignment of the kernel */
   grub_uint8_t relocatable_kernel; /* Is the kernel relocatable */
-  grub_uint8_t pad1[3];
+  grub_uint8_t min_alignment;
+  grub_uint16_t xloadflags;
   grub_uint32_t cmdline_size;  /* Size of the kernel command line */
   grub_uint32_t hardware_subarch;
   grub_uint64_t hardware_subarch_data;
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [RFC PATCH] efi: Add build error for new EFI arches that do not specify INITRD_MAX_ADDRESS_OFFSET

2023-07-11 Thread Ard Biesheuvel
On Mon, 10 Jul 2023 at 20:33, Glenn Washburn
 wrote:
>
> Non-x86 EFI architectures were using a INITRD_MAX_ADDRESS_OFFSET defined
> by the aarch64 architecture. This seems to generally work, as in no one
> has complained about this. However, the code is misleading. Architectures
> should explicitly set INITRD_MAX_ADDRESS_OFFSET. To avoid breaking current
> EFI architectures, set to GRUB_EFI_MAX_USABLE_ADDRESS, effectively allowing
> the entire address range. New architectures will fail to build until this
> macro is set.
>
> Signed-off-by: Glenn Washburn 
> ---
> My reading of a reply on the list[1] is that RISCV has no limit for the
> initrd. But I think it would be good to point to documentation describing
> limitations as in the ARM comments.
>

AIUI, RISC-V may support 3, 4 or 5 levels of paging, and it may depend
on the kernel configuration which of those are actually supported.
This may affect the addressability of the linear region, and given
EDK2's tendency to allocate from the top of memory downwards, imposing
no limit at all may result allocations that the kernel cannot access.

That said, is this even an issue for RISC-V? As far as I remember, the
LoadFile2 based initrd loading method was supported from the
beginning, and so this is mostly dead code anyway on RISC-V, and
perhaps it would be better to simply disable it.



>
> [1] https://lists.gnu.org/archive/html/grub-devel/2021-07/msg1.html
> ---
>  grub-core/loader/efi/linux.c | 18 ++
>  1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> index ab8fb35adb05..8f5460ba11e0 100644
> --- a/grub-core/loader/efi/linux.c
> +++ b/grub-core/loader/efi/linux.c
> @@ -28,6 +28,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -290,21 +291,30 @@ grub_linux_unload (void)
>  }
>
>  #if !defined(__i386__) && !defined(__x86_64__)
> +#if defined (__arm__)
>  /*
>   * As per linux/Documentation/arm/Booting
>   * ARM initrd needs to be covered by kernel linear mapping,
>   * so place it in the first 512MB of DRAM.
> - *
> + */
> +#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
> +#elif defined (__aarch64__)
> +/*
>   * As per linux/Documentation/arm64/booting.txt
>   * ARM64 initrd needs to be contained entirely within a 1GB aligned window
>   * of up to 32GB of size that covers the kernel image as well.
>   * Since the EFI stub loader will attempt to load the kernel near start of
>   * RAM, place the buffer in the first 32GB of RAM.
>   */
> -#ifdef __arm__
> -#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
> -#else /* __aarch64__ */
>  #define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024)
> +#elif defined (__ia64__) || defined (__riscv) || defined (__loongarch_lp64)
> +/*
> + * There has been no investigation into constraints on the initrd address
> + * for these platforms. Allow all the available address space for now.
> + */
> +#define INITRD_MAX_ADDRESS_OFFSET GRUB_EFI_MAX_USABLE_ADDRESS
> +#else
> +#error "Unknown INITRD_MAX_ADDRESS_OFFSET for architecture"
>  #endif
>
>  /*
> --
> 2.34.1
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v3 0/2] efi: Secure Boot fixes

2023-07-03 Thread Ard Biesheuvel
On Fri, 30 Jun 2023 at 16:02, Daniel Kiper  wrote:
>
> Hi,
>
> Here are two fixes for Secure Boot issues reported recently. This version of
> patch set adds comment to shim_lock->verify() function prototype and updates
> patch #1 commit message as it was suggested by Glenn. Please review and test.
>
> Daniel
>
> Daniel Kiper (2):
>   efi: Drop __grub_efi_api attribute from shim_lock->verify() function
>   efi: Fallback to legacy mode if shim is loaded on x86 archs
>

For the series,

Reviewed-by: Ard Biesheuvel 


>  grub-core/kern/efi/sb.c  | 10 ++
>  grub-core/loader/efi/linux.c | 17 +
>  include/grub/efi/api.h   |  6 +-
>  include/grub/efi/sb.h|  5 -
>  4 files changed, 36 insertions(+), 2 deletions(-)
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v2 1/2] efi: Drop __grub_efi_api attribute from shim_lock->verify() call

2023-06-30 Thread Ard Biesheuvel
On Fri, 30 Jun 2023 at 03:35, Glenn Washburn
 wrote:
>
> On Thu, 29 Jun 2023 20:02:31 +0200
> Daniel Kiper  wrote:
>
> > ... because (surprisingly) it uses System V AMD64 ABI on x86-64
> > architecture...
> >
> > Fixes: 6a080b9cd (efi: Add calling convention annotation to all prototypes)
> >
> > Signed-off-by: Daniel Kiper 
> > Acked-by: Ard Biesheuvel 
> > ---
> >  include/grub/efi/api.h | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
> > index 16161e1f0..f3c50ed5d 100644
> > --- a/include/grub/efi/api.h
> > +++ b/include/grub/efi/api.h
> > @@ -1777,7 +1777,7 @@ typedef struct grub_efi_block_io grub_efi_block_io_t;
> >
> >  struct grub_efi_shim_lock_protocol
> >  {
> > -  grub_efi_status_t (__grub_efi_api *verify) (void *buffer, grub_uint32_t 
> > size);
> > +  grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
>
> I would suggest adding a comment above this line, something like:
>
>   The shim_lock_protcol uses System V AMD64 ABI on x86-64 as specified
>   in __insert specification reference here__, unlike most UEFI protocol
>   methods, which use the MSABI calling convention.
>
> I may have some details wrong in the above, so change as needed. Also,
> I'm confused by your commit message. If this is only on x86-64, what
> about the other EFI architectures? This change's contents suggest it
> applies to all of them. Or is the shim lock protocol itself limited to
> x86-64 architectures?
>


Conceptually, it applies to all architectures. However, x86_64 is the
only architecture where the EFI calling convention deviates from the
Linux/SysV calling convention, which is what GRUB uses internally.

For this reason, __grub_efi_api expands to an empty string on non-x86
architectures (on 32-bit x86, it expands to regparm(0) but this should
be the default in any case)

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH 2/2] efi: Fallback to legacy mode if shim is loaded on x86 archs

2023-06-28 Thread Ard Biesheuvel
On Wed, 28 Jun 2023 at 15:29, Daniel Kiper  wrote:
>
> The LoadImage() provided by the shim does not consult MOK when loading
> an image. So, simply signature verification fails when it should not.
> This means we cannot use Linux EFI stub to start the kernel when the
> shim is loaded. We have to fallback to legacy mode on x86 architectures.
> This is not possible on other architectures due to lack of legacy mode.
>
> This is workaround which should disappear when the shim provides
> LoadImage() which looks up MOK during signature verification.
>
> On the occasion align constants in include/grub/efi/sb.h.
>
> Signed-off-by: Daniel Kiper 
> ---
>  grub-core/kern/efi/sb.c  | 10 ++
>  grub-core/loader/efi/linux.c | 13 +
>  include/grub/efi/sb.h|  5 -
>  3 files changed, 27 insertions(+), 1 deletion(-)
>
> diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
> index 80cfa0888..60550a6da 100644
> --- a/grub-core/kern/efi/sb.c
> +++ b/grub-core/kern/efi/sb.c
> @@ -32,6 +32,8 @@
>
>  static grub_guid_t shim_lock_guid = GRUB_EFI_SHIM_LOCK_GUID;
>
> +static bool shim_lock_enabled = false;
> +
>  /*
>   * Determine whether we're in secure boot mode.
>   *
> @@ -215,6 +217,14 @@ grub_shim_lock_verifier_setup (void)
>/* Enforce shim_lock_verifier. */
>grub_verifier_register (_lock_verifier);
>
> +  shim_lock_enabled = true;
> +
>grub_env_set ("shim_lock", "y");
>grub_env_export ("shim_lock");
>  }
> +
> +bool
> +grub_is_shim_lock_enabled (void)
> +{
> +  return shim_lock_enabled;
> +}
> diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> index c1eef7c98..5fb2ad01f 100644
> --- a/grub-core/loader/efi/linux.c
> +++ b/grub-core/loader/efi/linux.c
> @@ -29,6 +29,7 @@
>  #include 
>  #include 
>  #include 
> +#include 
>  #include 
>  #include 
>  #include 
> @@ -458,6 +459,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
> ((unused)),
>
>grub_dl_ref (my_mod);
>
> +#if defined(__i386__) || defined(__x86_64__)
> +  if (grub_is_shim_lock_enabled () == true)
> +{
> +  err = grub_cmd_linux_x86_legacy (cmd, argc, argv);
> +

Even if we only have a fallback on x86, we may encounter this
condition on other architectures too, so I think the check should be
generic, and only the fallback specific.

Not sure what to do on other architecures, though - there is no
backward compatibility concern here (at least not wrt users of
mainline GRUB), so we could still *try* to use the firmware's
loadimage/startimage, but perhaps issue a diagnostic message at the
very least?


> +  if (err == GRUB_ERR_NONE)
> +   return GRUB_ERR_NONE;
> +  else
> +   goto fail;
> +}
> +#endif
> +
>if (argc == 0)
>  {
>grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
> diff --git a/include/grub/efi/sb.h b/include/grub/efi/sb.h
> index 30c4335bb..49a9ad01c 100644
> --- a/include/grub/efi/sb.h
> +++ b/include/grub/efi/sb.h
> @@ -22,7 +22,7 @@
>  #include 
>  #include 
>
> -#define GRUB_EFI_SECUREBOOT_MODE_UNSET 0
> +#define GRUB_EFI_SECUREBOOT_MODE_UNSET 0
>  #define GRUB_EFI_SECUREBOOT_MODE_UNKNOWN   1
>  #define GRUB_EFI_SECUREBOOT_MODE_DISABLED  2
>  #define GRUB_EFI_SECUREBOOT_MODE_ENABLED   3
> @@ -31,6 +31,9 @@
>  extern grub_uint8_t
>  EXPORT_FUNC (grub_efi_get_secureboot) (void);
>
> +extern bool
> +EXPORT_FUNC (grub_is_shim_lock_enabled) (void);
> +
>  extern void
>  grub_shim_lock_verifier_setup (void);
>  #else
> --
> 2.11.0
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH 1/2] efi: Drop __grub_efi_api attribute from shim_lock->verify() call

2023-06-28 Thread Ard Biesheuvel
On Wed, 28 Jun 2023 at 15:29, Daniel Kiper  wrote:
>
> ... because (surprisingly) it uses System V AMD64 ABI on x86-64
> architecture...
>
> Fixes: 6a080b9cd (efi: Add calling convention annotation to all prototypes)
>
> Signed-off-by: Daniel Kiper 

Acked-by: Ard Biesheuvel 

> ---
>  include/grub/efi/api.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
> index 16161e1f0..f3c50ed5d 100644
> --- a/include/grub/efi/api.h
> +++ b/include/grub/efi/api.h
> @@ -1777,7 +1777,7 @@ typedef struct grub_efi_block_io grub_efi_block_io_t;
>
>  struct grub_efi_shim_lock_protocol
>  {
> -  grub_efi_status_t (__grub_efi_api *verify) (void *buffer, grub_uint32_t 
> size);
> +  grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
>  };
>  typedef struct grub_efi_shim_lock_protocol grub_efi_shim_lock_protocol_t;
>
> --
> 2.11.0
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] efi: Print EFI status as hex number instead of uint

2023-06-27 Thread Ard Biesheuvel
On Tue, 27 Jun 2023 at 21:19, Glenn Washburn
 wrote:
>
> EFI status codes are of different classes depending on the first byte and
> all error status codes defined in appendix D of the main spec start from 1
> and have the high bit set. When printing as a uint, the decimal is a very
> large number that needs have the high bit cleared get the spec error code.
> This can be easily visually done by a human if the number is printed as hex.
>
> Signed-off-by: Glenn Washburn 
> ---
>  grub-core/loader/efi/linux.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> index c1eef7c9865f..ca6f60519d73 100644
> --- a/grub-core/loader/efi/linux.c
> +++ b/grub-core/loader/efi/linux.c
> @@ -234,7 +234,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
> grub_size_t size, char *args)
>status = b->start_image (image_handle, 0, NULL);
>
>/* When successful, not reached */
> -  grub_error (GRUB_ERR_BAD_OS, "start_image() returned %" 
> PRIuGRUB_EFI_UINTN_T, status);
> +  grub_error (GRUB_ERR_BAD_OS, "start_image() returned %" 
> PRIxGRUB_EFI_UINTN_T, status);

Maybe add the 0x prefix to the format string as well?

>grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
>GRUB_EFI_BYTES_TO_PAGES 
> (loaded_image->load_options_size));
>  unload:
> --
> 2.34.1
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: Bad shim signature on kernel loading with patchset from 25.05.2023 and up

2023-06-26 Thread Ard Biesheuvel
On Mon, 26 Jun 2023 at 16:14, Daniel Kiper  wrote:
>
> On Mon, Jun 26, 2023 at 03:58:15PM +0200, Ard Biesheuvel wrote:
> > On Mon, 26 Jun 2023 at 15:56, Daniel Kiper  wrote:
> > >
> > > On Mon, Jun 26, 2023 at 03:14:18PM +0200, Tobias Powalowski via 
> > > Grub-devel wrote:
> > > > Am Mo., 26. Juni 2023 um 14:28 Uhr schrieb Daniel Kiper 
> > > > :
> > > >  Hey,
> > > >
> > > >  Thomas, good point. I completely missed that.
> > > >
> > > >  Tobias, please try Ard patch with the change suggested by Thomas. 
> > > > If
> > > >  you
> > > >  have not done that yet...
> > > >
> >
> > Which change is that? I am seeing only half of the discussion.
>
> Sorry, removal of unnecessary __grub_efi_api from the verify function of
> grub_efi_shim_lock_protocol. Here are details [1].
>

Ugh, really? EFI protocols using SysV calling convention? What a mess.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: Bad shim signature on kernel loading with patchset from 25.05.2023 and up

2023-06-26 Thread Ard Biesheuvel
On Mon, 26 Jun 2023 at 15:56, Daniel Kiper  wrote:
>
> On Mon, Jun 26, 2023 at 03:14:18PM +0200, Tobias Powalowski via Grub-devel 
> wrote:
> > Am Mo., 26. Juni 2023 um 14:28 Uhr schrieb Daniel Kiper 
> > :
> >  Hey,
> >
> >  Thomas, good point. I completely missed that.
> >
> >  Tobias, please try Ard patch with the change suggested by Thomas. If
> >  you
> >  have not done that yet...
> >

Which change is that? I am seeing only half of the discussion.


> >  Daniel
> >
> > Hi Daniel, Thomas and Ard,
> > yes both together work :)
>
> Great! Thanks a lot for the report and testing. I will prepare fixes in
> the following days. They can be different then the ones proposed here
> due to other reports about LoadFile2 failures. You will be CC-ed.
>
> > Sorry haven't tested it earlier with both enabled.
>
> No worries.
>
> Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: Bad shim signature on kernel loading with patchset from 25.05.2023 and up

2023-06-23 Thread Ard Biesheuvel
On Fri, 23 Jun 2023 at 16:18, Tobias Powalowski
 wrote:
>
> Am Fr., 23. Juni 2023 um 16:02 Uhr schrieb Daniel Kiper :
>>
>> On Thu, Jun 22, 2023 at 11:40:47AM +0200, Tobias Powalowski via Grub-devel 
>> wrote:
>> > Hi tackled it down to this commit:
>> > https://git.savannah.gnu.org/cgit/grub.git/commit/
>> > ?id=6a080b9cde0be5d08b71daf17a806067e32fc13f
>>
>> I hope you run the GRUB with this [1] patch. If not please use the
>> latest upstream master. It has the patch in.
>>
>> It would be nice if you could give us more information about your shim,
>> GRUB and kernel versions too.
>>
>> Daniel
>>
>> [1] https://lists.gnu.org/archive/html/grub-devel/2023-06/msg00092.html
>
> Hi,
> shim and mokmanager is from fedora's signed shim 15.4/15.6 (does not matter 
> both versions don't work) from here:
> https://kojipkgs.fedoraproject.org/packages/shim/
>
> Kernel is our latest Arch Linux linux 6.3.9-arch1-1
> The kernel image is not signed. Enrolling the kernel hash through MOK manager 
> does not make it bootable anymore,
> reverting back to grub version grub-2.06.r533.g78bc9a9b2 makes it bootable.
>
> Current broken grub is in our core repository:
> grub 2.06.r566.g857af0e17-1
> All git compiled versions after my mentioned commit are not working, Daniel 
> your mentioned patch was always applied.

Could you please try applying the hunk below?

diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index c1eef7c9865f5d0d..49b16933809dbf44 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -18,6 +18,7 @@

 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -458,6 +459,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__
((unused)),

   grub_dl_ref (my_mod);

+#if defined(__i386__)  || defined(__x86_64__)
+  if (grub_env_get ("shim_lock") != NULL)
+return grub_cmd_linux_x86_legacy (cmd, argc, argv);
+#endif
+
   if (argc == 0)
 {
   grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: Bad shim signature on kernel loading with patchset from 25.05.2023 and up

2023-06-23 Thread Ard Biesheuvel
On Fri, 23 Jun 2023 at 15:46, Tobias Powalowski
 wrote:
>
>
>
> Am Fr., 23. Juni 2023 um 15:41 Uhr schrieb Ard Biesheuvel :
>>
>> On Thu, 22 Jun 2023 at 11:41, Tobias Powalowski
>>  wrote:
>> >
>> > Hi tackled it down to this commit:
>> > https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6a080b9cde0be5d08b71daf17a806067e32fc13f
>> > starting with this commit shim verification fails for kernel hash with bad 
>> > shim verification and makes Secure Boot impossible.
>>
>> Could you elaborate on your setup? How are you signing and
>> authenticating the kernel image?
>>
>> GRUB calls LoadImage/StartImage, and these calls will be intercepted
>> by shim to implement its own authentication. The expectation here is
>> that the kernel's PE image is signed with a MOK key.
>
> Hi,
> here is  how it worked before:
> Add the kernel and grub hashes through MOK manager. After adding those grub 
> was able to boot the hashed kernel.
> On the installation medium I cannot expect someone already has a MOK 
> certificate, though hashes needs to be used in first place.

Apparently, SHIM hooks LoadImage and StartImage, but does not actually
perform any verification against the MOK db in this case.

This probably implies that upstream GRUB in its current state (without
the EFI stub boot patches that the distros are carrying) should
fallback to 'legacy' x86 EFI boot when secure boot is enabled and the
shim lock verifier is active.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: Bad shim signature on kernel loading with patchset from 25.05.2023 and up

2023-06-23 Thread Ard Biesheuvel
On Thu, 22 Jun 2023 at 11:41, Tobias Powalowski
 wrote:
>
> Hi tackled it down to this commit:
> https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6a080b9cde0be5d08b71daf17a806067e32fc13f
> starting with this commit shim verification fails for kernel hash with bad 
> shim verification and makes Secure Boot impossible.

Could you elaborate on your setup? How are you signing and
authenticating the kernel image?

GRUB calls LoadImage/StartImage, and these calls will be intercepted
by shim to implement its own authentication. The expectation here is
that the kernel's PE image is signed with a MOK key.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v2 0/2] EFI chainloader improvement

2023-06-01 Thread Ard Biesheuvel
On Thu, 1 Jun 2023 at 06:17, Glenn Washburn  wrote:
>
> Changes since v1:
>  * Rebase onto latest master
>  * Change logic: The device path argument to image load changed back to the 
> way
>it was originally where the argument is set to the device path that $root
>resolves to. If $root does not resolve or is not a device, the argument
>will be NULL as allowed for in the spec. By setting $root to the device of
>the chainloaded file, v1 behavior can be had. So this is more versatile
>behavior.
>  * Minor rewording of metadata.
>
> This series improves the EFI chainloader. I've noticed for a while now that
> chainloading would fail when root=memdisk. It didn't really make sense because
> I was specifying the image to chainload as device+path, so why would it care
> about what my root was. But I noticed that if I changed the root to the device
> the image file was located on, then chainloading worked. The second patch
> fixes this by removing some previous assumptions that I don't believe are
> valid (eg. that LoadImage needs a valid device path).
>

I don't think it ultimately matters that much what the device path is
when you provide the image via buffer+size, but I will note that the
generic EFI linux loader handles this case by constructing a 'memory
mapped' device path (in grub_arch_efi_linux_boot_image()), which just
describes a range of memory.

However, given that the device path in question is not installed on a
handle, I'm not even sure whether creating that memory mapped device
path serves any purpose tbh.

So this approach seems perfectly reasonable to me.

Reviewed-by: Ard Biesheuvel 

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v2] efi: Handle NULL return value when getting loaded image protocol

2023-05-24 Thread Ard Biesheuvel
The EFI spec mandates that the handle produced by the LoadImage boot
service has a LoadedImage protocol instance installed on it, but for
robustness, we should still deal with a NULL return value from the
helper routine that obtains this protocol pointer.

If this happens, don't try to start the image but unload it and return
an error.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/loader/efi/linux.c | 9 -
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 90ad1a7b82a76066..8211f7892ad391f1 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -214,6 +214,11 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
 
   /* Convert command line to UCS-2 */
   loaded_image = grub_efi_get_loaded_image (image_handle);
+  if (loaded_image == NULL)
+{
+  grub_error (GRUB_ERR_BAD_FIRMWARE, "missing loaded_image proto");
+  goto unload;
+}
   loaded_image->load_options_size = len =
 (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
   loaded_image->load_options =
@@ -229,9 +234,11 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
   status = b->start_image (image_handle, 0, NULL);
 
   /* When successful, not reached */
-  b->unload_image (image_handle);
+  grub_error (GRUB_ERR_BAD_OS, "start_image() returned %" 
PRIuGRUB_EFI_UINTN_T, status);
   grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
   GRUB_EFI_BYTES_TO_PAGES 
(loaded_image->load_options_size));
+unload:
+  b->unload_image (image_handle);
 
   return grub_errno;
 }
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH] efi: Handle NULL return value when getting loaded image protocol

2023-05-24 Thread Ard Biesheuvel
On Wed, 24 May 2023 at 19:15, Ard Biesheuvel  wrote:
>
> The EFI spec mandates that the handle produced by the LoadImage boot
> service has a LoadedImage protocol instance installed on it, but for
> robustness, we should still deal with a NULL return value from the
> helper routine that obtains this protocol pointer.
>
> If this happens, don't try to start the image but unload it and return
> an error.
>
> Signed-off-by: Ard Biesheuvel 
> ---
>  grub-core/loader/efi/linux.c | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> index 90ad1a7b82a76066..b434c56ae67d665e 100644
> --- a/grub-core/loader/efi/linux.c
> +++ b/grub-core/loader/efi/linux.c
> @@ -214,6 +214,11 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
> grub_size_t size, char *args)
>
>/* Convert command line to UCS-2 */
>loaded_image = grub_efi_get_loaded_image (image_handle);
> +  if (loaded_image == NULL)
> +{
> +  grub_error (GRUB_ERR_BAD_FIRMWARE, "missing loaded_image proto");
> +  goto unload;
> +}
>loaded_image->load_options_size = len =
>  (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
>loaded_image->load_options =
> @@ -228,6 +233,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
> grub_size_t size, char *args)
>grub_dprintf ("linux", "starting image %p\n", image_handle);
>status = b->start_image (image_handle, 0, NULL);
>
> +unload:

Uhm this is slightly bogus - apologies. The free_pages call still
dereferences loaded_image

I'll send a v2 right away.

>/* When successful, not reached */
>b->unload_image (image_handle);
>grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
> --
> 2.39.2
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH] efi: Handle NULL return value when getting loaded image protocol

2023-05-24 Thread Ard Biesheuvel
The EFI spec mandates that the handle produced by the LoadImage boot
service has a LoadedImage protocol instance installed on it, but for
robustness, we should still deal with a NULL return value from the
helper routine that obtains this protocol pointer.

If this happens, don't try to start the image but unload it and return
an error.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/loader/efi/linux.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 90ad1a7b82a76066..b434c56ae67d665e 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -214,6 +214,11 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
 
   /* Convert command line to UCS-2 */
   loaded_image = grub_efi_get_loaded_image (image_handle);
+  if (loaded_image == NULL)
+{
+  grub_error (GRUB_ERR_BAD_FIRMWARE, "missing loaded_image proto");
+  goto unload;
+}
   loaded_image->load_options_size = len =
 (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t);
   loaded_image->load_options =
@@ -228,6 +233,7 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
   grub_dprintf ("linux", "starting image %p\n", image_handle);
   status = b->start_image (image_handle, 0, NULL);
 
+unload:
   /* When successful, not reached */
   b->unload_image (image_handle);
   grub_efi_free_pages ((grub_addr_t) loaded_image->load_options,
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v4 5/5] efi: Use generic EFI loader for x86_64 and i386

2023-05-23 Thread Ard Biesheuvel
On Tue, 23 May 2023 at 17:32, Ard Biesheuvel  wrote:
>
> Switch the x86 based EFI platform builds to the generic EFI loader,
> which exposes the initrd via the LoadFile2 protocol instead of the
> x86-specific setup header. This will launch the Linux kernel via its EFI
> stub, which performs its own initialization in the EFI boot services
> context before calling ExitBootServices() and performing the bare metal
> Linux boot.
>
> Given that only Linux kernel versions v5.8 and later support this initrd
> loading method, the existing x86 loader is retained as a fallback, which
> will also be used for Linux kernels built without the EFI stub. In this
> case, GRUB calls ExitBootServices() before entering the Linux kernel,
> and all EFI related information is provided to the kernel via struct
> boot_params in the setup header, as before.
>
> Note that this means that booting EFI stub kernels older than v5.8 is
> not supported even when not using an initrd at all. Also, the EFI
> handover protocol, which has no basis in the UEFI specification, is not
> implemented.
>
> Signed-off-by: Ard Biesheuvel 

This patch needs the hunk below, which i failed to git add - apologies

--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -360,7 +360,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__
((unused)),
 int argc, char *argv[])
 {
   int __attribute__ ((unused)) initrd_size, initrd_pages;
-  void *initrd_mem = NULL;
+  void *__attribute__ ((unused)) initrd_mem = NULL;
   grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
   grub_efi_status_t status;

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v4 2/5] efi: Add calling convention annotation to all prototypes

2023-05-23 Thread Ard Biesheuvel
UEFI mandates MS calling convention on x86_64, which was not supported
on GCC when UEFI support was first introduced into GRUB. However, now we
can use the ms_abi function type attribute to annotate functions and
function pointers as adhering to the MS calling convention, and the
compiler will generate the correct instruction sequence for us.

So let's add the appropriate annotation to all the function prototypes.
This will allow us to drop the special call wrappers in a subsequent
patch.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/efiemu/runtime/efiemu.c |  48 +-
 grub-core/kern/arm/efi/init.c |   2 +-
 include/grub/efi/api.h| 569 ++--
 include/grub/efi/tpm.h| 149 +++--
 4 files changed, 397 insertions(+), 371 deletions(-)

diff --git a/grub-core/efiemu/runtime/efiemu.c 
b/grub-core/efiemu/runtime/efiemu.c
index 5db1f347b5db54cc..53b3cce7b0c2ecf8 100644
--- a/grub-core/efiemu/runtime/efiemu.c
+++ b/grub-core/efiemu/runtime/efiemu.c
@@ -32,17 +32,17 @@
 #include 
 #include 
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_get_time (grub_efi_time_t *time,
 grub_efi_time_capabilities_t *capabilities);
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_set_time (grub_efi_time_t *time);
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_get_wakeup_time (grub_efi_boolean_t *enabled,
grub_efi_boolean_t *pending,
grub_efi_time_t *time);
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_set_wakeup_time (grub_efi_boolean_t enabled,
grub_efi_time_t *time);
 
@@ -52,51 +52,51 @@ efiemu_set_wakeup_time (grub_efi_boolean_t enabled,
 #define PHYSICAL_ATTRIBUTE __attribute__ ((section(".text-physical")));
 #endif
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_set_virtual_address_map (grub_efi_uintn_t memory_map_size,
grub_efi_uintn_t descriptor_size,
grub_efi_uint32_t descriptor_version,
grub_efi_memory_descriptor_t *virtual_map)
   PHYSICAL_ATTRIBUTE;
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_convert_pointer (grub_efi_uintn_t debug_disposition,
void **address)
   PHYSICAL_ATTRIBUTE;
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_get_variable (grub_efi_char16_t *variable_name,
 const grub_efi_guid_t *vendor_guid,
 grub_efi_uint32_t *attributes,
 grub_efi_uintn_t *data_size,
 void *data);
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_get_next_variable_name (grub_efi_uintn_t *variable_name_size,
   grub_efi_char16_t *variable_name,
   grub_efi_guid_t *vendor_guid);
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_set_variable (grub_efi_char16_t *variable_name,
 const grub_efi_guid_t *vendor_guid,
 grub_efi_uint32_t attributes,
 grub_efi_uintn_t data_size,
 void *data);
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 efiemu_get_next_high_monotonic_count (grub_efi_uint32_t *high_count);
-void
+void __grub_efi_api
 efiemu_reset_system (grub_efi_reset_type_t reset_type,
 grub_efi_status_t reset_status,
 grub_efi_uintn_t data_size,
 grub_efi_char16_t *reset_data);
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 EFI_FUNC (efiemu_set_virtual_address_map) (grub_efi_uintn_t,
  grub_efi_uintn_t,
  grub_efi_uint32_t,
  grub_efi_memory_descriptor_t *)
  PHYSICAL_ATTRIBUTE;
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 EFI_FUNC (efiemu_convert_pointer) (grub_efi_uintn_t debug_disposition,
  void **address)
  PHYSICAL_ATTRIBUTE;
@@ -202,7 +202,7 @@ bcd_to_hex (grub_uint8_t in)
   return 10 * ((in & 0xf0) >> 4) + (in & 0x0f);
 }
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time,
   grub_efi_time_capabilities_t *capabilities)
 {
@@ -246,7 +246,7 @@ EFI_FUNC (efiemu_get_time) (grub_efi_time_t *time,
   return GRUB_EFI_SUCCESS;
 }
 
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time)
 {
   LOG ('b');
@@ -265,7 +265,7 @@ EFI_FUNC (efiemu_set_time) (grub_efi_time_t *time)
 }
 
 /* Following 2 functions are vendor specific. So announce it as unsupported */
-grub_efi_status_t
+grub_efi_status_t __grub_efi_api
 EFI_FUNC (efiemu_get_wakeup_time) (grub_efi_boolean_t *enabled,
  gru

[PATCH v4 4/5] efi: Remove x86_64 call wrappers

2023-05-23 Thread Ard Biesheuvel
The call wrappers are no longer needed now that GCC can generate
function calls using MS calling convention, so let's get rid of them.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def  |   1 -
 grub-core/kern/x86_64/efi/callwrap.S | 129 
 include/grub/efi/api.h   |  73 ---
 3 files changed, 203 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index c69c4a3321d27ecd..1d88c4d1c2555f7f 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -236,7 +236,6 @@ kernel = {
 
   x86_64 = kern/x86_64/dl.c;
   x86_64_xen = kern/x86_64/dl.c;
-  x86_64_efi = kern/x86_64/efi/callwrap.S;
   x86_64_efi = kern/i386/efi/init.c;
   x86_64_efi = bus/pci.c;
 
diff --git a/grub-core/kern/x86_64/efi/callwrap.S 
b/grub-core/kern/x86_64/efi/callwrap.S
deleted file mode 100644
index 1337fd9fc823f8a4..
--- a/grub-core/kern/x86_64/efi/callwrap.S
+++ /dev/null
@@ -1,129 +0,0 @@
-/* callwrap.S - wrapper for x86_64 efi calls */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include 
-#include 
-
-/*
- * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
- * different call conversion, so we need to do some conversion.
- *
- * gcc:
- *   %rdi,  %rsi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
- *
- * efi:
- *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
- *
- */
-
-.file   "callwrap.S"
-.text
-
-FUNCTION(efi_wrap_0)
-   subq $40, %rsp
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_1)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_2)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_3)
-   subq $40, %rsp
-   mov  %rcx, %r8
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_4)
-   subq $40, %rsp
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_5)
-   subq $40, %rsp
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_6)
-   subq $56, %rsp
-   mov 56+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $56, %rsp
-   ret
-
-FUNCTION(efi_wrap_7)
-   subq $88, %rsp
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
-
-FUNCTION(efi_wrap_10)
-   subq $88, %rsp
-   mov 88+40(%rsp), %rax
-   mov %rax, 72(%rsp)
-   mov 88+32(%rsp), %rax
-   mov %rax, 64(%rsp)
-   mov 88+24(%rsp), %rax
-   mov %rax, 56(%rsp)
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index ebfa6c40fba34eae..fb881ae12d5ae73a 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1824,77 +1824,4 @@ struct initrd_media_device_path {
 } GRUB_PACKED;
 typedef struct initrd_media_device_path initrd_media_device_path_t;
 
-#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
-  || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
-  || defined(__riscv) || defined (__loongarch__)
-
-#define efi_call_0(func)   (func)()
-#define efi_call_1(func, a)(func)(a)
-#define efi_call_2(func, a, b) (func)(a, b)
-#define efi_call_3(func, a, b, c)  (func)(a, b, c)
-#define efi_call_4(func, a, b, c, d)   (func)(a, b, c, d)
-#define efi_call_5(func, a, b, c, d, e)(func)(a, b, c, d, e)
-#define efi_call_6(func, a, b, c, d, e, f) (func)(

[PATCH v4 3/5] efi: Drop all uses of efi_call_XX wrappers

2023-05-23 Thread Ard Biesheuvel
Now that GCC can generate function calls using the correct calling
convention for us, we can stop using the efi_call_XX () wrappers, and
just dereference the function pointers directly.

This avoids the untyped variadic wrapper routines, which means better
type checking for the method calls.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/commands/acpi.c |  8 +--
 grub-core/commands/efi/efitextmode.c  |  8 ++-
 grub-core/commands/efi/lsefi.c|  5 +-
 grub-core/commands/efi/tpm.c  | 21 
 grub-core/disk/efi/efidisk.c  |  7 +--
 grub-core/kern/arm/efi/init.c | 10 ++--
 grub-core/kern/efi/efi.c  | 56 ++--
 grub-core/kern/efi/init.c | 15 +++---
 grub-core/kern/efi/mm.c   | 17 +++---
 grub-core/kern/i386/efi/tsc.c |  2 +-
 grub-core/kern/ia64/efi/init.c| 14 ++---
 grub-core/kern/loongarch64/efi/init.c | 10 ++--
 grub-core/lib/efi/datetime.c  |  9 ++--
 grub-core/lib/efi/halt.c  |  4 +-
 grub-core/lib/efi/relocator.c |  6 +--
 grub-core/loader/efi/appleloader.c|  8 +--
 grub-core/loader/efi/chainloader.c| 20 +++
 grub-core/mmap/efi/mmap.c | 16 +++---
 grub-core/net/drivers/efi/efinet.c| 26 -
 grub-core/term/efi/console.c  | 29 +-
 grub-core/term/efi/serial.c   | 18 +++
 grub-core/video/efi_gop.c | 18 +++
 grub-core/video/efi_uga.c |  8 +--
 23 files changed, 165 insertions(+), 170 deletions(-)

diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index fda62f4ea98a6da8..ab067ae6e51d43af 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -762,10 +762,10 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int 
argc, char **args)
 struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
 struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
 
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv2 ());
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv1 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv2 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv1 ());
   }
 #endif
 
diff --git a/grub-core/commands/efi/efitextmode.c 
b/grub-core/commands/efi/efitextmode.c
index 3679f6b4d8028bc7..198bc694d3fc3c3b 100644
--- a/grub-core/commands/efi/efitextmode.c
+++ b/grub-core/commands/efi/efitextmode.c
@@ -36,7 +36,7 @@ grub_efi_set_mode (grub_efi_simple_text_output_interface_t *o,
 
   if (mode != o->mode->mode)
 {
-  status = efi_call_2 (o->set_mode, o, mode);
+  status = o->set_mode (o, mode);
   if (status == GRUB_EFI_SUCCESS)
;
   else if (status == GRUB_EFI_DEVICE_ERROR)
@@ -79,8 +79,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   grub_printf_ (N_("Available modes for console output device.\n"));
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  grub_printf_ (N_(" [%" PRIuGRUB_EFI_UINT32_T "]  Col %5"
   PRIuGRUB_EFI_UINTN_T " Row %5" PRIuGRUB_EFI_UINTN_T
   " %c\n"),
@@ -129,8 +128,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   N_("non-numeric or invalid rows number `%s'"), 
args[1]);
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  if (u_columns == columns && u_rows == rows)
return grub_efi_set_mode (o, (grub_efi_int32_t) i);
 
diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
index c304d25ccdd6f32b..53970149785a28f8 100644
--- a/grub-core/commands/efi/lsefi.c
+++ b/grub-core/commands/efi/lsefi.c
@@ -108,8 +108,9 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
  grub_efi_print_device_path (dp);
}
 
-  status = efi_call_3 
(grub_efi_system_table->boot_services->protocols_per_handle,
-  handle, , _protocols);
+  status = grub_efi_system_table->boot_services->protocols_per_handle 
(handle,
+  
,
+   

[PATCH v4 1/5] efi: Make EFI PXE protocol methods non-callable

2023-05-23 Thread Ard Biesheuvel
The grub_efi_pxe_t struct definition has placeholders for the various
protocol method pointers, given that they are never called in the code,
and the prototypes have been omitted, and therefore do not comply with
the UEFI spec.

So let's convert them into void* pointers, so they cannot be called
inadvertently.

Signed-off-by: Ard Biesheuvel 
---
 include/grub/efi/api.h | 24 ++--
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index 4ae5e51c9013ceb3..7077d2265df9b20a 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1539,18 +1539,18 @@ typedef struct grub_efi_pxe_mode
 typedef struct grub_efi_pxe
 {
   grub_uint64_t rev;
-  void (*start) (void);
-  void (*stop) (void);
-  void (*dhcp) (void);
-  void (*discover) (void);
-  void (*mftp) (void);
-  void (*udpwrite) (void);
-  void (*udpread) (void);
-  void (*setipfilter) (void);
-  void (*arp) (void);
-  void (*setparams) (void);
-  void (*setstationip) (void);
-  void (*setpackets) (void);
+  void *start;
+  void *stop;
+  void *dhcp;
+  void *discover;
+  void *mftp;
+  void *udpwrite;
+  void *udpread;
+  void *setipfilter;
+  void *arp;
+  void *setparams;
+  void *setstationip;
+  void *setpackets;
   struct grub_efi_pxe_mode *mode;
 } grub_efi_pxe_t;
 
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v4 0/5] efi: Implement generic EFI boot for x86

2023-05-23 Thread Ard Biesheuvel
Switch the i386-efi and x86_64-efi builds to the generic EFI loader,
which enters the Linux kernel via the EFI stub and provides the initrd
via the LoadFile2 protocol. This unifies x86 with other EFI
architectures, and removes the dependency on the setup header and struct
bootparams.

Do some preparatory cleanup first, so we no longer need to rely on the
MS to SysV calling convention translation code.

Changes since v3:
- add missing efiapi annotations to efiemu routines
- work around dead code warning from Coverity by making unnecessary
  changes to the initrd loading logic in the generic EFI loader

Changes since v2:
- rebase onto latest master, which has the Loongarch changes
- retain Itanium support for now
- simplify the fallback logic - attempt to load the image as usual, and
  fallback on failure or if the image does not implement LoadFile2

Changes since v1:
- drop Itanium support, which is a maintenance burden as it shares the
  EFI code with other architectures, but does not have a EFI stub in
  Linux, and there is no way to test whether our changes break the boot
  for it or not;
- enable generic EFI for i386 as well
- wire up the existing x86 code as a fallback for kernels that lack EFI
  stub or LoadFile2 support. This removes the need for additional
  changes to support v5.8 or older kernels.

Cc: Daniel Kiper 
Cc: Glenn Washburn 

Ard Biesheuvel (5):
  efi: Make EFI PXE protocol methods non-callable
  efi: Add calling convention annotation to all prototypes
  efi: Drop all uses of efi_call_XX wrappers
  efi: Remove x86_64 call wrappers
  efi: Use generic EFI loader for x86_64 and i386

 grub-core/Makefile.core.def   |   3 +-
 grub-core/commands/acpi.c |   8 +-
 grub-core/commands/efi/efitextmode.c  |   8 +-
 grub-core/commands/efi/lsefi.c|   5 +-
 grub-core/commands/efi/tpm.c  |  21 +-
 grub-core/disk/efi/efidisk.c  |   7 +-
 grub-core/efiemu/runtime/efiemu.c |  48 +-
 grub-core/kern/arm/efi/init.c |  12 +-
 grub-core/kern/efi/efi.c  |  56 +-
 grub-core/kern/efi/init.c |  15 +-
 grub-core/kern/efi/mm.c   |  17 +-
 grub-core/kern/i386/efi/tsc.c |   2 +-
 grub-core/kern/ia64/efi/init.c|  14 +-
 grub-core/kern/loongarch64/efi/init.c |  10 +-
 grub-core/kern/x86_64/efi/callwrap.S  | 129 
 grub-core/lib/efi/datetime.c  |   9 +-
 grub-core/lib/efi/halt.c  |   4 +-
 grub-core/lib/efi/relocator.c |   6 +-
 grub-core/loader/efi/appleloader.c|   8 +-
 grub-core/loader/efi/chainloader.c|  20 +-
 grub-core/loader/efi/linux.c  |  47 +-
 grub-core/loader/i386/linux.c |   8 +
 grub-core/mmap/efi/mmap.c |  16 +-
 grub-core/net/drivers/efi/efinet.c|  26 +-
 grub-core/term/efi/console.c  |  29 +-
 grub-core/term/efi/serial.c   |  18 +-
 grub-core/video/efi_gop.c |  18 +-
 grub-core/video/efi_uga.c |   8 +-
 include/grub/efi/api.h| 666 +---
 include/grub/efi/efi.h|   2 +-
 include/grub/efi/tpm.h| 149 +++--
 31 files changed, 628 insertions(+), 761 deletions(-)
 delete mode 100644 grub-core/kern/x86_64/efi/callwrap.S

-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v4 5/5] efi: Use generic EFI loader for x86_64 and i386

2023-05-23 Thread Ard Biesheuvel
Switch the x86 based EFI platform builds to the generic EFI loader,
which exposes the initrd via the LoadFile2 protocol instead of the
x86-specific setup header. This will launch the Linux kernel via its EFI
stub, which performs its own initialization in the EFI boot services
context before calling ExitBootServices() and performing the bare metal
Linux boot.

Given that only Linux kernel versions v5.8 and later support this initrd
loading method, the existing x86 loader is retained as a fallback, which
will also be used for Linux kernels built without the EFI stub. In this
case, GRUB calls ExitBootServices() before entering the Linux kernel,
and all EFI related information is provided to the kernel via struct
boot_params in the setup header, as before.

Note that this means that booting EFI stub kernels older than v5.8 is
not supported even when not using an initrd at all. Also, the EFI
handover protocol, which has no basis in the UEFI specification, is not
implemented.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def   |  2 +
 grub-core/loader/efi/linux.c  | 47 ++--
 grub-core/loader/i386/linux.c |  8 
 include/grub/efi/efi.h|  2 +-
 4 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 1d88c4d1c2555f7f..e58b511242618df7 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1853,6 +1853,8 @@ module = {
   loongarch64 = loader/efi/linux.c;
   riscv32 = loader/efi/linux.c;
   riscv64 = loader/efi/linux.c;
+  i386_efi = loader/efi/linux.c;
+  x86_64_efi = loader/efi/linux.c;
   emu = loader/emu/linux.c;
   common = loader/linux.c;
   common = lib/cmdline.c;
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 15e0686549d7ecca..90ad1a7b82a76066 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -69,6 +69,12 @@ static initrd_media_device_path_t initrd_lf2_device_path = {
   }
 };
 
+extern grub_err_t
+grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
+
+extern grub_err_t
+grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
+
 static grub_efi_status_t __grub_efi_api
 grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
 grub_efi_device_path_t *device_path,
@@ -125,6 +131,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
 static grub_err_t
 finalize_params_linux (void)
 {
@@ -169,6 +176,7 @@ failure:
   grub_fdt_unload();
   return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
 }
+#endif
 
 grub_err_t
 grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
@@ -231,8 +239,10 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
 static grub_err_t
 grub_linux_boot (void)
 {
+#if !defined(__i386__) && !defined(__x86_64__)
   if (finalize_params_linux () != GRUB_ERR_NONE)
 return grub_errno;
+#endif
 
   return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
   kernel_size, linux_args));
@@ -253,7 +263,9 @@ grub_linux_unload (void)
   if (kernel_addr)
 grub_efi_free_pages ((grub_addr_t) kernel_addr,
 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+#if !defined(__i386__) && !defined(__x86_64__)
   grub_fdt_unload ();
+#endif
 
   if (initrd_lf2_handle != NULL)
 {
@@ -269,6 +281,7 @@ grub_linux_unload (void)
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
 /*
  * As per linux/Documentation/arm/Booting
  * ARM initrd needs to be covered by kernel linear mapping,
@@ -304,6 +317,7 @@ allocate_initrd_mem (int initrd_pages)
   GRUB_EFI_ALLOCATE_MAX_ADDRESS,
   GRUB_EFI_LOADER_DATA);
 }
+#endif
 
 static grub_efi_status_t __grub_efi_api
 grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
@@ -345,7 +359,7 @@ static grub_err_t
 grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 int argc, char *argv[])
 {
-  int initrd_size, initrd_pages;
+  int __attribute__ ((unused)) initrd_size, initrd_pages;
   void *initrd_mem = NULL;
   grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
   grub_efi_status_t status;
@@ -356,6 +370,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
((unused)),
   goto fail;
 }
 
+#if defined(__i386__) || defined(__x86_64__)
+  if (!initrd_use_loadfile2)
+return grub_cmd_initrd_x86_legacy (cmd, argc, argv);
+#endif
+
   if (!loaded)
 {
   grub_error (GRUB_ERR_BAD_ARGUMENT,
@@ -391,6 +410,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
((unused)),
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
   initrd_size = grub_get_initrd_siz

[PATCH v3 1/5] efi: Make EFI PXE protocol methods non-callable

2023-05-23 Thread Ard Biesheuvel
The grub_efi_pxe_t struct definition has placeholders for the various
protocol method pointers, given that they are never called in the code,
and the prototypes have been omitted, and therefore do not comply with
the UEFI spec.

So let's convert them into void* pointers, so they cannot be called
inadvertently.

Signed-off-by: Ard Biesheuvel 
---
 include/grub/efi/api.h | 24 ++--
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index 4ae5e51c9013ceb3..7077d2265df9b20a 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1539,18 +1539,18 @@ typedef struct grub_efi_pxe_mode
 typedef struct grub_efi_pxe
 {
   grub_uint64_t rev;
-  void (*start) (void);
-  void (*stop) (void);
-  void (*dhcp) (void);
-  void (*discover) (void);
-  void (*mftp) (void);
-  void (*udpwrite) (void);
-  void (*udpread) (void);
-  void (*setipfilter) (void);
-  void (*arp) (void);
-  void (*setparams) (void);
-  void (*setstationip) (void);
-  void (*setpackets) (void);
+  void *start;
+  void *stop;
+  void *dhcp;
+  void *discover;
+  void *mftp;
+  void *udpwrite;
+  void *udpread;
+  void *setipfilter;
+  void *arp;
+  void *setparams;
+  void *setstationip;
+  void *setpackets;
   struct grub_efi_pxe_mode *mode;
 } grub_efi_pxe_t;
 
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v3 5/5] efi: Use generic EFI loader for x86_64 and i386

2023-05-23 Thread Ard Biesheuvel
Switch the x86 based EFI platform builds to the generic EFI loader,
which exposes the initrd via the LoadFile2 protocol instead of the
x86-specific setup header. This will launch the Linux kernel via its EFI
stub, which performs its own initialization in the EFI boot services
context before calling ExitBootServices() and performing the bare metal
Linux boot.

Given that only Linux kernel versions v5.8 and later support this initrd
loading method, the existing x86 loader is retained as a fallback, which
will also be used for Linux kernels built without the EFI stub. In this
case, GRUB calls ExitBootServices() before entering the Linux kernel,
and all EFI related information is provided to the kernel via struct
boot_params in the setup header, as before.

Note that this means that booting EFI stub kernels older than v5.8 is
not supported even when not using an initrd at all. Also, the EFI
handover protocol, which has no basis in the UEFI specification, is not
implemented.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def   |  2 +
 grub-core/loader/efi/linux.c  | 40 +++-
 grub-core/loader/i386/linux.c |  8 
 include/grub/efi/efi.h|  2 +-
 4 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 1d88c4d1c2555f7f..e58b511242618df7 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1853,6 +1853,8 @@ module = {
   loongarch64 = loader/efi/linux.c;
   riscv32 = loader/efi/linux.c;
   riscv64 = loader/efi/linux.c;
+  i386_efi = loader/efi/linux.c;
+  x86_64_efi = loader/efi/linux.c;
   emu = loader/emu/linux.c;
   common = loader/linux.c;
   common = lib/cmdline.c;
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 15e0686549d7ecca..bb44de6beec73378 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -69,6 +69,12 @@ static initrd_media_device_path_t initrd_lf2_device_path = {
   }
 };
 
+extern grub_err_t
+grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
+
+extern grub_err_t
+grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
+
 static grub_efi_status_t __grub_efi_api
 grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
 grub_efi_device_path_t *device_path,
@@ -125,6 +131,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
 static grub_err_t
 finalize_params_linux (void)
 {
@@ -169,6 +176,7 @@ failure:
   grub_fdt_unload();
   return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
 }
+#endif
 
 grub_err_t
 grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
@@ -231,8 +239,10 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
 static grub_err_t
 grub_linux_boot (void)
 {
+#if !defined(__i386__) && !defined(__x86_64__)
   if (finalize_params_linux () != GRUB_ERR_NONE)
 return grub_errno;
+#endif
 
   return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
   kernel_size, linux_args));
@@ -253,7 +263,9 @@ grub_linux_unload (void)
   if (kernel_addr)
 grub_efi_free_pages ((grub_addr_t) kernel_addr,
 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+#if !defined(__i386__) && !defined(__x86_64__)
   grub_fdt_unload ();
+#endif
 
   if (initrd_lf2_handle != NULL)
 {
@@ -269,6 +281,7 @@ grub_linux_unload (void)
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
 /*
  * As per linux/Documentation/arm/Booting
  * ARM initrd needs to be covered by kernel linear mapping,
@@ -304,6 +317,7 @@ allocate_initrd_mem (int initrd_pages)
   GRUB_EFI_ALLOCATE_MAX_ADDRESS,
   GRUB_EFI_LOADER_DATA);
 }
+#endif
 
 static grub_efi_status_t __grub_efi_api
 grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
@@ -345,7 +359,7 @@ static grub_err_t
 grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
 int argc, char *argv[])
 {
-  int initrd_size, initrd_pages;
+  int __attribute__ ((unused)) initrd_size, initrd_pages;
   void *initrd_mem = NULL;
   grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
   grub_efi_status_t status;
@@ -356,6 +370,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
((unused)),
   goto fail;
 }
 
+#if defined(__i386__) || defined(__x86_64__)
+  if (!initrd_use_loadfile2)
+return grub_cmd_initrd_x86_legacy (cmd, argc, argv);
+#endif
+
   if (!loaded)
 {
   grub_error (GRUB_ERR_BAD_ARGUMENT,
@@ -391,6 +410,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
((unused)),
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
   initrd_size = grub_get_initrd_siz

[PATCH v3 2/5] efi: Add calling convention annotation to all prototypes

2023-05-23 Thread Ard Biesheuvel
UEFI mandates MS calling convention on x86_64, which was not supported
on GCC when UEFI support was first introduced into GRUB. However, now we
can use the ms_abi function type attribute to annotate functions and
function pointers as adhering to the MS calling convention, and the
compiler will generate the correct instruction sequence for us.

So let's add the appropriate annotation to all the function prototypes.
This will allow us to drop the special call wrappers in a subsequent
patch.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/kern/arm/efi/init.c |   2 +-
 include/grub/efi/api.h| 569 ++--
 include/grub/efi/tpm.h| 149 +++--
 3 files changed, 373 insertions(+), 347 deletions(-)

diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
index 7fcf91bf41168d4a..ab48342f3cda116d 100644
--- a/grub-core/kern/arm/efi/init.c
+++ b/grub-core/kern/arm/efi/init.c
@@ -34,7 +34,7 @@ grub_efi_get_time_ms (void)
   return tmr;
 }
 
-static void
+static void __grub_efi_api
 increment_timer (grub_efi_event_t event __attribute__ ((unused)),
 void *context __attribute__ ((unused)))
 {
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index 7077d2265df9b20a..ebfa6c40fba34eae 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1127,209 +1127,210 @@ struct grub_efi_boot_services
   grub_efi_table_header_t hdr;
 
   grub_efi_tpl_t
-  (*raise_tpl) (grub_efi_tpl_t new_tpl);
+  (__grub_efi_api *raise_tpl) (grub_efi_tpl_t new_tpl);
 
   void
-  (*restore_tpl) (grub_efi_tpl_t old_tpl);
+  (__grub_efi_api *restore_tpl) (grub_efi_tpl_t old_tpl);
 
   grub_efi_status_t
-  (*allocate_pages) (grub_efi_allocate_type_t type,
-grub_efi_memory_type_t memory_type,
-grub_efi_uintn_t pages,
-grub_efi_physical_address_t *memory);
+  (__grub_efi_api *allocate_pages) (grub_efi_allocate_type_t type,
+   grub_efi_memory_type_t memory_type,
+   grub_efi_uintn_t pages,
+   grub_efi_physical_address_t *memory);
 
   grub_efi_status_t
-  (*free_pages) (grub_efi_physical_address_t memory,
-grub_efi_uintn_t pages);
+  (__grub_efi_api *free_pages) (grub_efi_physical_address_t memory,
+   grub_efi_uintn_t pages);
 
   grub_efi_status_t
-  (*get_memory_map) (grub_efi_uintn_t *memory_map_size,
-grub_efi_memory_descriptor_t *memory_map,
-grub_efi_uintn_t *map_key,
-grub_efi_uintn_t *descriptor_size,
-grub_efi_uint32_t *descriptor_version);
+  (__grub_efi_api *get_memory_map) (grub_efi_uintn_t *memory_map_size,
+   grub_efi_memory_descriptor_t *memory_map,
+   grub_efi_uintn_t *map_key,
+   grub_efi_uintn_t *descriptor_size,
+   grub_efi_uint32_t *descriptor_version);
 
   grub_efi_status_t
-  (*allocate_pool) (grub_efi_memory_type_t pool_type,
-   grub_efi_uintn_t size,
-   void **buffer);
+  (__grub_efi_api *allocate_pool) (grub_efi_memory_type_t pool_type,
+  grub_efi_uintn_t size,
+  void **buffer);
 
   grub_efi_status_t
-  (*free_pool) (void *buffer);
+  (__grub_efi_api *free_pool) (void *buffer);
 
   grub_efi_status_t
-  (*create_event) (grub_efi_uint32_t type,
-  grub_efi_tpl_t notify_tpl,
-  void (*notify_function) (grub_efi_event_t event,
-   void *context),
-  void *notify_context,
-  grub_efi_event_t *event);
+  (__grub_efi_api *create_event) (grub_efi_uint32_t type,
+ grub_efi_tpl_t notify_tpl,
+ void (__grub_efi_api *notify_function) 
(grub_efi_event_t,
+ void 
*context),
+ void *notify_context,
+ grub_efi_event_t *event);
 
   grub_efi_status_t
-  (*set_timer) (grub_efi_event_t event,
-   grub_efi_timer_delay_t type,
-   grub_efi_uint64_t trigger_time);
+  (__grub_efi_api *set_timer) (grub_efi_event_t event,
+  grub_efi_timer_delay_t type,
+  grub_efi_uint64_t trigger_time);
 
   grub_efi_status_t
-  (*wait_for_event) (grub_efi_uintn_t num_events,
-grub_efi_event_t *event,
-grub_efi_uintn_t *index);
+  (__grub_efi_api *wait_for_event) (grub_efi_uintn_t num_events,
+   grub_efi_event_t *event,
+   grub_efi_uintn_t *index);
 
   grub_efi_status_t
-  (*signal_event

[PATCH v3 0/5] efi: Implement generic EFI boot for x86

2023-05-23 Thread Ard Biesheuvel
Switch the i386-efi and x86_64-efi builds to the generic EFI loader,
which enters the Linux kernel via the EFI stub and provides the initrd
via the LoadFile2 protocol. This unifies x86 with other EFI
architectures, and removes the dependency on the setup header and struct
bootparams.

Do some preparatory cleanup first, so we no longer need to rely on the
MS to SysV calling convention translation code.

Changes since v2:
- rebase onto latest master, which has the Loongarch changes
- retain Itanium support for now
- simplify the fallback logic - attempt to load the image as usual, and
  fallback on failure or if the image does not implement LoadFile2

Changes since v1:
- drop Itanium support, which is a maintenance burden as it shares the
  EFI code with other architectures, but does not have a EFI stub in
  Linux, and there is no way to test whether our changes break the boot
  for it or not;
- enable generic EFI for i386 as well
- wire up the existing x86 code as a fallback for kernels that lack EFI
  stub or LoadFile2 support. This removes the need for additional
  changes to support v5.8 or older kernels.

Cc: Daniel Kiper 
Cc: Glenn Washburn 

Ard Biesheuvel (5):
  efi: Make EFI PXE protocol methods non-callable
  efi: Add calling convention annotation to all prototypes
  efi: Drop all uses of efi_call_XX wrappers
  efi: Remove x86_64 call wrappers
  efi: Use generic EFI loader for x86_64 and i386

 grub-core/Makefile.core.def   |   3 +-
 grub-core/commands/acpi.c |   8 +-
 grub-core/commands/efi/efitextmode.c  |   8 +-
 grub-core/commands/efi/lsefi.c|   5 +-
 grub-core/commands/efi/tpm.c  |  21 +-
 grub-core/disk/efi/efidisk.c  |   7 +-
 grub-core/kern/arm/efi/init.c |  12 +-
 grub-core/kern/efi/efi.c  |  56 +-
 grub-core/kern/efi/init.c |  15 +-
 grub-core/kern/efi/mm.c   |  17 +-
 grub-core/kern/i386/efi/tsc.c |   2 +-
 grub-core/kern/ia64/efi/init.c|  14 +-
 grub-core/kern/loongarch64/efi/init.c |  10 +-
 grub-core/kern/x86_64/efi/callwrap.S  | 129 
 grub-core/lib/efi/datetime.c  |   9 +-
 grub-core/lib/efi/halt.c  |   4 +-
 grub-core/lib/efi/relocator.c |   6 +-
 grub-core/loader/efi/appleloader.c|   8 +-
 grub-core/loader/efi/chainloader.c|  20 +-
 grub-core/loader/efi/linux.c  |  40 +-
 grub-core/loader/i386/linux.c |   8 +
 grub-core/mmap/efi/mmap.c |  16 +-
 grub-core/net/drivers/efi/efinet.c|  26 +-
 grub-core/term/efi/console.c  |  29 +-
 grub-core/term/efi/serial.c   |  18 +-
 grub-core/video/efi_gop.c |  18 +-
 grub-core/video/efi_uga.c |   8 +-
 include/grub/efi/api.h| 666 +---
 include/grub/efi/efi.h|   2 +-
 include/grub/efi/tpm.h| 149 +++--
 30 files changed, 600 insertions(+), 734 deletions(-)
 delete mode 100644 grub-core/kern/x86_64/efi/callwrap.S

-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v3 3/5] efi: Drop all uses of efi_call_XX wrappers

2023-05-23 Thread Ard Biesheuvel
Now that GCC can generate function calls using the correct calling
convention for us, we can stop using the efi_call_XX () wrappers, and
just dereference the function pointers directly.

This avoids the untyped variadic wrapper routines, which means better
type checking for the method calls.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/commands/acpi.c |  8 +--
 grub-core/commands/efi/efitextmode.c  |  8 ++-
 grub-core/commands/efi/lsefi.c|  5 +-
 grub-core/commands/efi/tpm.c  | 21 
 grub-core/disk/efi/efidisk.c  |  7 +--
 grub-core/kern/arm/efi/init.c | 10 ++--
 grub-core/kern/efi/efi.c  | 56 ++--
 grub-core/kern/efi/init.c | 15 +++---
 grub-core/kern/efi/mm.c   | 17 +++---
 grub-core/kern/i386/efi/tsc.c |  2 +-
 grub-core/kern/ia64/efi/init.c| 14 ++---
 grub-core/kern/loongarch64/efi/init.c | 10 ++--
 grub-core/lib/efi/datetime.c  |  9 ++--
 grub-core/lib/efi/halt.c  |  4 +-
 grub-core/lib/efi/relocator.c |  6 +--
 grub-core/loader/efi/appleloader.c|  8 +--
 grub-core/loader/efi/chainloader.c| 20 +++
 grub-core/mmap/efi/mmap.c | 16 +++---
 grub-core/net/drivers/efi/efinet.c| 26 -
 grub-core/term/efi/console.c  | 29 +-
 grub-core/term/efi/serial.c   | 18 +++
 grub-core/video/efi_gop.c | 18 +++
 grub-core/video/efi_uga.c |  8 +--
 23 files changed, 165 insertions(+), 170 deletions(-)

diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index fda62f4ea98a6da8..ab067ae6e51d43af 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -762,10 +762,10 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int 
argc, char **args)
 struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
 struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
 
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv2 ());
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv1 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv2 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv1 ());
   }
 #endif
 
diff --git a/grub-core/commands/efi/efitextmode.c 
b/grub-core/commands/efi/efitextmode.c
index 3679f6b4d8028bc7..198bc694d3fc3c3b 100644
--- a/grub-core/commands/efi/efitextmode.c
+++ b/grub-core/commands/efi/efitextmode.c
@@ -36,7 +36,7 @@ grub_efi_set_mode (grub_efi_simple_text_output_interface_t *o,
 
   if (mode != o->mode->mode)
 {
-  status = efi_call_2 (o->set_mode, o, mode);
+  status = o->set_mode (o, mode);
   if (status == GRUB_EFI_SUCCESS)
;
   else if (status == GRUB_EFI_DEVICE_ERROR)
@@ -79,8 +79,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   grub_printf_ (N_("Available modes for console output device.\n"));
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  grub_printf_ (N_(" [%" PRIuGRUB_EFI_UINT32_T "]  Col %5"
   PRIuGRUB_EFI_UINTN_T " Row %5" PRIuGRUB_EFI_UINTN_T
   " %c\n"),
@@ -129,8 +128,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   N_("non-numeric or invalid rows number `%s'"), 
args[1]);
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  if (u_columns == columns && u_rows == rows)
return grub_efi_set_mode (o, (grub_efi_int32_t) i);
 
diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
index c304d25ccdd6f32b..53970149785a28f8 100644
--- a/grub-core/commands/efi/lsefi.c
+++ b/grub-core/commands/efi/lsefi.c
@@ -108,8 +108,9 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
  grub_efi_print_device_path (dp);
}
 
-  status = efi_call_3 
(grub_efi_system_table->boot_services->protocols_per_handle,
-  handle, , _protocols);
+  status = grub_efi_system_table->boot_services->protocols_per_handle 
(handle,
+  
,
+   

[PATCH v3 4/5] efi: Remove x86_64 call wrappers

2023-05-23 Thread Ard Biesheuvel
The call wrappers are no longer needed now that GCC can generate
function calls using MS calling convention, so let's get rid of them.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def  |   1 -
 grub-core/kern/x86_64/efi/callwrap.S | 129 
 include/grub/efi/api.h   |  73 ---
 3 files changed, 203 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index c69c4a3321d27ecd..1d88c4d1c2555f7f 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -236,7 +236,6 @@ kernel = {
 
   x86_64 = kern/x86_64/dl.c;
   x86_64_xen = kern/x86_64/dl.c;
-  x86_64_efi = kern/x86_64/efi/callwrap.S;
   x86_64_efi = kern/i386/efi/init.c;
   x86_64_efi = bus/pci.c;
 
diff --git a/grub-core/kern/x86_64/efi/callwrap.S 
b/grub-core/kern/x86_64/efi/callwrap.S
deleted file mode 100644
index 1337fd9fc823f8a4..
--- a/grub-core/kern/x86_64/efi/callwrap.S
+++ /dev/null
@@ -1,129 +0,0 @@
-/* callwrap.S - wrapper for x86_64 efi calls */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include 
-#include 
-
-/*
- * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
- * different call conversion, so we need to do some conversion.
- *
- * gcc:
- *   %rdi,  %rsi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
- *
- * efi:
- *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
- *
- */
-
-.file   "callwrap.S"
-.text
-
-FUNCTION(efi_wrap_0)
-   subq $40, %rsp
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_1)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_2)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_3)
-   subq $40, %rsp
-   mov  %rcx, %r8
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_4)
-   subq $40, %rsp
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_5)
-   subq $40, %rsp
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_6)
-   subq $56, %rsp
-   mov 56+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $56, %rsp
-   ret
-
-FUNCTION(efi_wrap_7)
-   subq $88, %rsp
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
-
-FUNCTION(efi_wrap_10)
-   subq $88, %rsp
-   mov 88+40(%rsp), %rax
-   mov %rax, 72(%rsp)
-   mov 88+32(%rsp), %rax
-   mov %rax, 64(%rsp)
-   mov 88+24(%rsp), %rax
-   mov %rax, 56(%rsp)
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index ebfa6c40fba34eae..fb881ae12d5ae73a 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1824,77 +1824,4 @@ struct initrd_media_device_path {
 } GRUB_PACKED;
 typedef struct initrd_media_device_path initrd_media_device_path_t;
 
-#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
-  || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
-  || defined(__riscv) || defined (__loongarch__)
-
-#define efi_call_0(func)   (func)()
-#define efi_call_1(func, a)(func)(a)
-#define efi_call_2(func, a, b) (func)(a, b)
-#define efi_call_3(func, a, b, c)  (func)(a, b, c)
-#define efi_call_4(func, a, b, c, d)   (func)(a, b, c, d)
-#define efi_call_5(func, a, b, c, d, e)(func)(a, b, c, d, e)
-#define efi_call_6(func, a, b, c, d, e, f) (func)(

Re: [PATCH v2 6/6] efi: Use generic EFI loader for x86_64 and i386

2023-05-16 Thread Ard Biesheuvel
On Sun, 14 May 2023 at 07:12, Glenn Washburn
 wrote:
>
> On Thu, 11 May 2023 14:06:40 +0200
> Ard Biesheuvel  wrote:
>
> > Switch the x86 based EFI platform builds to the generic EFI loader,
> > which exposes the initrd via the LoadFile2 protocol instead of the
> > x86-specific setup header. This will launch the Linux kernel via its
> > EFI stub, which performs its own initialization in the EFI boot
> > services context before calling ExitBootServices() and performing the
> > bare metal Linux boot.
> >
> > Given that only Linux kernel versions v5.8 and later support this
> > initrd loading method, the existing x86 loader is retained as a
> > fallback, which will also be used for Linux kernels built without the
> > EFI stub. In this case, GRUB calls ExitBootServices() before entering
> > the Linux kernel, and all EFI related information is provided to the
> > kernel via struct boot_params in the setup header, as before.
> >
> > Note that this means that booting EFI stub kernels older than v5.8 is
> > not supported even when not using an initrd at all. Also, the EFI
> > handover protocol, which has no basis in the UEFI specification, is
> > not implemented.
> >
> > Signed-off-by: Ard Biesheuvel 
> > ---
> >  grub-core/Makefile.core.def   |  5 +-
> >  grub-core/loader/efi/linux.c  | 51 ++--
> >  grub-core/loader/i386/linux.c |  8 +++
> >  include/grub/efi/efi.h|  2 +-
> >  4 files changed, 56 insertions(+), 10 deletions(-)
> >
> > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> > index 8ee2bd89c4205761..bc08955ac791241a 100644
> > --- a/grub-core/Makefile.core.def
> > +++ b/grub-core/Makefile.core.def
> > @@ -1818,11 +1818,8 @@ module = {
> >powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
> >sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
> >arm_coreboot = loader/arm/linux.c;
> > -  arm_efi = loader/efi/linux.c;
> >arm_uboot = loader/arm/linux.c;
> > -  arm64 = loader/efi/linux.c;
> > -  riscv32 = loader/efi/linux.c;
> > -  riscv64 = loader/efi/linux.c;
> > +  efi = loader/efi/linux.c;
> >emu = loader/emu/linux.c;
> >common = loader/linux.c;
> >common = lib/cmdline.c;
> > diff --git a/grub-core/loader/efi/linux.c
> > b/grub-core/loader/efi/linux.c index
> > 15e0686549d7ecca..970a4d7a5d4d464f 100644 ---
> > a/grub-core/loader/efi/linux.c +++ b/grub-core/loader/efi/linux.c
> > @@ -69,6 +69,12 @@ static initrd_media_device_path_t
> > initrd_lf2_device_path = { }
> >  };
> >
> > +extern grub_err_t
> > +grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char
> > *argv[]); +
> > +extern grub_err_t
> > +grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char
> > *argv[]); +
> >  static grub_efi_status_t __grub_efi_api
> >  grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
> >  grub_efi_device_path_t *device_path,
> > @@ -89,8 +95,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t
> > file, return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read
> > Linux image header");
> >if ((lh->code0 & 0x) != GRUB_PE32_MAGIC)
> > -return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
> > -N_("plain image kernel not supported -
> > rebuild with CONFIG_(U)EFI_STUB enabled"));
> > +return GRUB_ERR_NOT_IMPLEMENTED_YET;
> >
> >grub_dprintf ("linux", "UEFI stub kernel:\n");
> >grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
> > @@ -117,7 +122,11 @@ grub_arch_efi_linux_load_image_header
> > (grub_file_t file, if
> > (lh->pe_image_header.optional_header.major_image_version >= 1)
> > initrd_use_loadfile2 = true; else
> > +#if defined(__i386__) || defined(__x86_64__)
> > +return GRUB_ERR_NOT_IMPLEMENTED_YET;
>
> Is this for the unimplemented EFI handover protocol?

No. This forces the caller (below) to take the x86 legacy fallback
path, which we need to use in 2 cases:
- no EFI stub support
- no LoadFile2 support

The former implies the latter for non-EFI stub kernels, which GRUB
supports today, and should remain supported imo. When booting EFI stub
kernels older than v5.8, we fall back to the legacy boot as well, as
it is the only way to boot with EFI support (at runtime) and with
initrd support.

The EFI handover protocol should remain unimplemented.

> Regardless, I think
> a comment above this line indicating what would be implemented here
> would be nice for others look

Re: [PATCH v2 1/6] ia64: Remove support

2023-05-12 Thread Ard Biesheuvel
On Fri, 12 May 2023 at 12:42, John Paul Adrian Glaubitz
 wrote:
>
> Hello Ard!
>
> On Thu, 2023-05-11 at 16:29 +0200, Ard Biesheuvel wrote:
> > > > Feel free to keep using it, but please stop demanding that our people
> > > > keep wasting their time on it. If you want to support it in Debian,
> > > > you can carry it as a downstream patch and shoulder the maintenance
> > > > burden.
> > >
> > > Who is "our people"? Do you think that you are part of the community and
> > > I am not? I don't think this kind of hostility is justified. Neither you
> > > nor I own this project.
> > >
> >
> > Apologies - I had meant to type 'other people' not 'our people'. I
> > rarely contribute to GRUB myself, so I wouldn't consider myself more a
> > part of this community than anyone else.
> >
> > But my point remains: I have inferred from your response (and your
> > involvement in similar discussions around the Linux kernel) that you
> > would prefer Itanium support to be retained, right?
>
> Not necessarily. I am generally not opposed to removing ia64 support, but it
> should happen in a coordinated form where downstreams and users are involved.
>

Are you aware of any actual users?

> Just dropping support from random projects without prior coordination seems
> like the wrong approach to me. I would suggest posting your plans to the
> distributions mailing list [1], Debian's ia64 mailing list [2], the Gentoo
> developer mailing list [3], the Linux ia64 mailing list [4] and maybe the
> NetBSD ia64 mailing list [5].
>

Fair enough

> If you don't get any objections there, I am not going to object either. I just
> want this to happen in an ordered manner.
>

I already sent a similar patch to the linux-ia64 a while ago, and the
only person that objected was you :-)

> > So could you explain who you think should carry the maintenance
> > burden? IA64 will be the only EFI architecture in GRUB that does not
> > boot via an EFI stub in Linux, and this deviation means that retaining
> > support for it is going to take actual developer and maintainer
> > bandwidth. GRUB gets very little of that as it is, which means that
> > keeping IA64 support alive comes at the cost of worse support for
> > other architectures and platforms. (The series that this patch is part
> > of breaks the ia64 build, and i i struggle to see why i should care
> > about that)
> >
> > Very few of those people have access to such systems to begin with
> > (probably none), and the companies that manufactured them stopped
> > supporting them in the open source years ago, so testing these changes
> > is not straight-forward, making it unreasonable to demand this from
> > contributors. Also, it is unclear to me why the needs of the few
> > people that do still run such a system are not served by a build based
> > on today's GRUB tree, and why ia64 support needs to be retained going
> > forward.
>
> Well, that's why I am suggesting to coordinate this properly and ask potential
> users of the code whether they are okay with the removal.
>

That is reasonable - let's see how other people feel about this.

-- 
Ard.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v2 1/6] ia64: Remove support

2023-05-12 Thread Ard Biesheuvel
On Fri, 12 May 2023 at 00:41, matoro
 wrote:
>
> On 2023-05-11 18:09, Ard Biesheuvel wrote:
> > On Thu, 11 May 2023 at 20:59, matoro
> >  wrote:
> >>
> >> On 2023-05-11 10:29, Ard Biesheuvel wrote:
> >> > On Thu, 11 May 2023 at 15:34, John Paul Adrian Glaubitz
> >> >  wrote:
> >> >>
> >> >> On Thu, 2023-05-11 at 14:17 +0200, Ard Biesheuvel wrote:
> >> >> > On Thu, 11 May 2023 at 14:14, John Paul Adrian Glaubitz
> >> >> >  wrote:
> >> >> > >
> >> >> > > On Thu, 2023-05-11 at 14:06 +0200, Ard Biesheuvel wrote:
> >> >> > > > Itanium IA-64 support is obsolete, and implements its own flavor 
> >> >> > > > of EFI
> >> >> > > > boot that deviates from other architectures. Given that IA64 is 
> >> >> > > > unused
> >> >> > > > and unmaintained, it makes no sense to pretend that the EFI 
> >> >> > > > changes we
> >> >> > > > are making are tested or supported on IA64, so let's just get rid 
> >> >> > > > of it.
> >> >> > >
> >> >> > > But I just recently tested GRUB from git on IA64 and it worked 
> >> >> > > without
> >> >> > > any problems. We're using GRUB to boot Debian on IA64.
> >> >> > >
> >> >> >
> >> >> > IA-64 is a dead platform, and a waste of electricity.
> >> >>
> >> >> I was just making a statement regarding the testability of the code.
> >> >> That's all.
> >> >>
> >> >
> >> > Fair enough. That is good to know actually - that way, we have a known
> >> > working state right before we remove it.
> >> >
> >> >> > Feel free to keep using it, but please stop demanding that our people
> >> >> > keep wasting their time on it. If you want to support it in Debian,
> >> >> > you can carry it as a downstream patch and shoulder the maintenance
> >> >> > burden.
> >> >>
> >> >> Who is "our people"? Do you think that you are part of the community
> >> >> and
> >> >> I am not? I don't think this kind of hostility is justified. Neither
> >> >> you
> >> >> nor I own this project.
> >> >>
> >> >
> >> > Apologies - I had meant to type 'other people' not 'our people'. I
> >> > rarely contribute to GRUB myself, so I wouldn't consider myself more a
> >> > part of this community than anyone else.
> >> >
> >> > But my point remains: I have inferred from your response (and your
> >> > involvement in similar discussions around the Linux kernel) that you
> >> > would prefer Itanium support to be retained, right?
> >> >
> >> > So could you explain who you think should carry the maintenance
> >> > burden? IA64 will be the only EFI architecture in GRUB that does not
> >> > boot via an EFI stub in Linux, and this deviation means that retaining
> >> > support for it is going to take actual developer and maintainer
> >> > bandwidth. GRUB gets very little of that as it is, which means that
> >> > keeping IA64 support alive comes at the cost of worse support for
> >> > other architectures and platforms. (The series that this patch is part
> >> > of breaks the ia64 build, and i i struggle to see why i should care
> >> > about that)
> >> >
> >> > Very few of those people have access to such systems to begin with
> >> > (probably none), and the companies that manufactured them stopped
> >> > supporting them in the open source years ago, so testing these changes
> >> > is not straight-forward, making it unreasonable to demand this from
> >> > contributors. Also, it is unclear to me why the needs of the few
> >> > people that do still run such a system are not served by a build based
> >> > on today's GRUB tree, and why ia64 support needs to be retained going
> >> > forward.
> >> >
> >> > I'll leave it to the maintainers whether to merge this patch or not,
> >> > but if this needs to keep working on ia64 as well, someone else will
> >> > have to step up.
> >>
> >> Hi, I also have a functioning GRUB install on ia64 EFI.  My machine is
> >> fully open and available f

Re: [PATCH v2 1/6] ia64: Remove support

2023-05-11 Thread Ard Biesheuvel
On Thu, 11 May 2023 at 20:59, matoro
 wrote:
>
> On 2023-05-11 10:29, Ard Biesheuvel wrote:
> > On Thu, 11 May 2023 at 15:34, John Paul Adrian Glaubitz
> >  wrote:
> >>
> >> On Thu, 2023-05-11 at 14:17 +0200, Ard Biesheuvel wrote:
> >> > On Thu, 11 May 2023 at 14:14, John Paul Adrian Glaubitz
> >> >  wrote:
> >> > >
> >> > > On Thu, 2023-05-11 at 14:06 +0200, Ard Biesheuvel wrote:
> >> > > > Itanium IA-64 support is obsolete, and implements its own flavor of 
> >> > > > EFI
> >> > > > boot that deviates from other architectures. Given that IA64 is 
> >> > > > unused
> >> > > > and unmaintained, it makes no sense to pretend that the EFI changes 
> >> > > > we
> >> > > > are making are tested or supported on IA64, so let's just get rid of 
> >> > > > it.
> >> > >
> >> > > But I just recently tested GRUB from git on IA64 and it worked without
> >> > > any problems. We're using GRUB to boot Debian on IA64.
> >> > >
> >> >
> >> > IA-64 is a dead platform, and a waste of electricity.
> >>
> >> I was just making a statement regarding the testability of the code.
> >> That's all.
> >>
> >
> > Fair enough. That is good to know actually - that way, we have a known
> > working state right before we remove it.
> >
> >> > Feel free to keep using it, but please stop demanding that our people
> >> > keep wasting their time on it. If you want to support it in Debian,
> >> > you can carry it as a downstream patch and shoulder the maintenance
> >> > burden.
> >>
> >> Who is "our people"? Do you think that you are part of the community
> >> and
> >> I am not? I don't think this kind of hostility is justified. Neither
> >> you
> >> nor I own this project.
> >>
> >
> > Apologies - I had meant to type 'other people' not 'our people'. I
> > rarely contribute to GRUB myself, so I wouldn't consider myself more a
> > part of this community than anyone else.
> >
> > But my point remains: I have inferred from your response (and your
> > involvement in similar discussions around the Linux kernel) that you
> > would prefer Itanium support to be retained, right?
> >
> > So could you explain who you think should carry the maintenance
> > burden? IA64 will be the only EFI architecture in GRUB that does not
> > boot via an EFI stub in Linux, and this deviation means that retaining
> > support for it is going to take actual developer and maintainer
> > bandwidth. GRUB gets very little of that as it is, which means that
> > keeping IA64 support alive comes at the cost of worse support for
> > other architectures and platforms. (The series that this patch is part
> > of breaks the ia64 build, and i i struggle to see why i should care
> > about that)
> >
> > Very few of those people have access to such systems to begin with
> > (probably none), and the companies that manufactured them stopped
> > supporting them in the open source years ago, so testing these changes
> > is not straight-forward, making it unreasonable to demand this from
> > contributors. Also, it is unclear to me why the needs of the few
> > people that do still run such a system are not served by a build based
> > on today's GRUB tree, and why ia64 support needs to be retained going
> > forward.
> >
> > I'll leave it to the maintainers whether to merge this patch or not,
> > but if this needs to keep working on ia64 as well, someone else will
> > have to step up.
>
> Hi, I also have a functioning GRUB install on ia64 EFI.  My machine is
> fully open and available for debugging work, including on kernel and
> bootloader (hard resets can be done via management console).
>
> If there is any way this support can be saved or at least delayed by
> providing real hardware to work on, please reach out.  The environment
> is completely remote and available for anybody who would like to give it
> a try.

Thanks, this could be helpful if we manage to find people that have
the bandwidth to keep working on this. Would you be willing to spend
time and development effort yourself on building and installing GRUB
from the upstream repository on this machine (which is a bit more
complicated than running kernels or user space programs)? Which distro
and version are you using btw?

And just out of curiosity, why does this matter to you? Given that the
ia64 firmware, the hardware and the 

Re: [PATCH v2 1/6] ia64: Remove support

2023-05-11 Thread Ard Biesheuvel
On Thu, 11 May 2023 at 15:34, John Paul Adrian Glaubitz
 wrote:
>
> On Thu, 2023-05-11 at 14:17 +0200, Ard Biesheuvel wrote:
> > On Thu, 11 May 2023 at 14:14, John Paul Adrian Glaubitz
> >  wrote:
> > >
> > > On Thu, 2023-05-11 at 14:06 +0200, Ard Biesheuvel wrote:
> > > > Itanium IA-64 support is obsolete, and implements its own flavor of EFI
> > > > boot that deviates from other architectures. Given that IA64 is unused
> > > > and unmaintained, it makes no sense to pretend that the EFI changes we
> > > > are making are tested or supported on IA64, so let's just get rid of it.
> > >
> > > But I just recently tested GRUB from git on IA64 and it worked without
> > > any problems. We're using GRUB to boot Debian on IA64.
> > >
> >
> > IA-64 is a dead platform, and a waste of electricity.
>
> I was just making a statement regarding the testability of the code. That's 
> all.
>

Fair enough. That is good to know actually - that way, we have a known
working state right before we remove it.

> > Feel free to keep using it, but please stop demanding that our people
> > keep wasting their time on it. If you want to support it in Debian,
> > you can carry it as a downstream patch and shoulder the maintenance
> > burden.
>
> Who is "our people"? Do you think that you are part of the community and
> I am not? I don't think this kind of hostility is justified. Neither you
> nor I own this project.
>

Apologies - I had meant to type 'other people' not 'our people'. I
rarely contribute to GRUB myself, so I wouldn't consider myself more a
part of this community than anyone else.

But my point remains: I have inferred from your response (and your
involvement in similar discussions around the Linux kernel) that you
would prefer Itanium support to be retained, right?

So could you explain who you think should carry the maintenance
burden? IA64 will be the only EFI architecture in GRUB that does not
boot via an EFI stub in Linux, and this deviation means that retaining
support for it is going to take actual developer and maintainer
bandwidth. GRUB gets very little of that as it is, which means that
keeping IA64 support alive comes at the cost of worse support for
other architectures and platforms. (The series that this patch is part
of breaks the ia64 build, and i i struggle to see why i should care
about that)

Very few of those people have access to such systems to begin with
(probably none), and the companies that manufactured them stopped
supporting them in the open source years ago, so testing these changes
is not straight-forward, making it unreasonable to demand this from
contributors. Also, it is unclear to me why the needs of the few
people that do still run such a system are not served by a build based
on today's GRUB tree, and why ia64 support needs to be retained going
forward.

I'll leave it to the maintainers whether to merge this patch or not,
but if this needs to keep working on ia64 as well, someone else will
have to step up.

-- 
Ard.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v2 1/6] ia64: Remove support

2023-05-11 Thread Ard Biesheuvel
On Thu, 11 May 2023 at 14:14, John Paul Adrian Glaubitz
 wrote:
>
> On Thu, 2023-05-11 at 14:06 +0200, Ard Biesheuvel wrote:
> > Itanium IA-64 support is obsolete, and implements its own flavor of EFI
> > boot that deviates from other architectures. Given that IA64 is unused
> > and unmaintained, it makes no sense to pretend that the EFI changes we
> > are making are tested or supported on IA64, so let's just get rid of it.
>
> But I just recently tested GRUB from git on IA64 and it worked without
> any problems. We're using GRUB to boot Debian on IA64.
>

IA-64 is a dead platform, and a waste of electricity.

Feel free to keep using it, but please stop demanding that our people
keep wasting their time on it. If you want to support it in Debian,
you can carry it as a downstream patch and shoulder the maintenance
burden.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v2 6/6] efi: Use generic EFI loader for x86_64 and i386

2023-05-11 Thread Ard Biesheuvel
On Thu, 11 May 2023 at 14:06, Ard Biesheuvel  wrote:
>
> Switch the x86 based EFI platform builds to the generic EFI loader,
> which exposes the initrd via the LoadFile2 protocol instead of the
> x86-specific setup header. This will launch the Linux kernel via its EFI
> stub, which performs its own initialization in the EFI boot services
> context before calling ExitBootServices() and performing the bare metal
> Linux boot.
>
> Given that only Linux kernel versions v5.8 and later support this initrd
> loading method, the existing x86 loader is retained as a fallback, which
> will also be used for Linux kernels built without the EFI stub. In this
> case, GRUB calls ExitBootServices() before entering the Linux kernel,
> and all EFI related information is provided to the kernel via struct
> boot_params in the setup header, as before.
>
> Note that this means that booting EFI stub kernels older than v5.8 is
> not supported even when not using an initrd at all.

Clarification: you /can/ boot EFI stub kernels older than v5.8 but
they will use the fallback, even though their lack of LoadFIle2
support is not strictly an impediment for booting via the EFI stub if
no initrd needs to be loaded.

> Also, the EFI
> handover protocol, which has no basis in the UEFI specification, is not
> implemented.
>
> Signed-off-by: Ard Biesheuvel 
> ---
>  grub-core/Makefile.core.def   |  5 +-
>  grub-core/loader/efi/linux.c  | 51 ++--
>  grub-core/loader/i386/linux.c |  8 +++
>  include/grub/efi/efi.h|  2 +-
>  4 files changed, 56 insertions(+), 10 deletions(-)
>
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index 8ee2bd89c4205761..bc08955ac791241a 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -1818,11 +1818,8 @@ module = {
>powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
>sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
>arm_coreboot = loader/arm/linux.c;
> -  arm_efi = loader/efi/linux.c;
>arm_uboot = loader/arm/linux.c;
> -  arm64 = loader/efi/linux.c;
> -  riscv32 = loader/efi/linux.c;
> -  riscv64 = loader/efi/linux.c;
> +  efi = loader/efi/linux.c;
>emu = loader/emu/linux.c;
>common = loader/linux.c;
>common = lib/cmdline.c;
> diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> index 15e0686549d7ecca..970a4d7a5d4d464f 100644
> --- a/grub-core/loader/efi/linux.c
> +++ b/grub-core/loader/efi/linux.c
> @@ -69,6 +69,12 @@ static initrd_media_device_path_t initrd_lf2_device_path = 
> {
>}
>  };
>
> +extern grub_err_t
> +grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
> +
> +extern grub_err_t
> +grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
> +
>  static grub_efi_status_t __grub_efi_api
>  grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
>  grub_efi_device_path_t *device_path,
> @@ -89,8 +95,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
>  return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image 
> header");
>
>if ((lh->code0 & 0x) != GRUB_PE32_MAGIC)
> -return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
> -  N_("plain image kernel not supported - rebuild with 
> CONFIG_(U)EFI_STUB enabled"));
> +return GRUB_ERR_NOT_IMPLEMENTED_YET;
>
>grub_dprintf ("linux", "UEFI stub kernel:\n");
>grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
> @@ -117,7 +122,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
>if (lh->pe_image_header.optional_header.major_image_version >= 1)
>  initrd_use_loadfile2 = true;
>else
> +#if defined(__i386__) || defined(__x86_64__)
> +return GRUB_ERR_NOT_IMPLEMENTED_YET;
> +#else
>  initrd_use_loadfile2 = false;
> +#endif
>
>grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
>  initrd_use_loadfile2 ? "en" : "dis");
> @@ -125,6 +134,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
>return GRUB_ERR_NONE;
>  }
>
> +#if !defined(__i386__) && !defined(__x86_64__)
>  static grub_err_t
>  finalize_params_linux (void)
>  {
> @@ -169,6 +179,7 @@ failure:
>grub_fdt_unload();
>return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
>  }
> +#endif
>
>  grub_err_t
>  grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char 
> *args)
> @@ -231,8 +242,10 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
> grub_size_t size, char *args)
&

[PATCH v2 5/6] efi: Remove x86_64 call wrappers

2023-05-11 Thread Ard Biesheuvel
The call wrappers are no longer needed now that GCC can generate
function calls using MS calling convention, so let's get rid of them.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def  |   1 -
 grub-core/kern/x86_64/efi/callwrap.S | 129 
 include/grub/efi/api.h   |  73 ---
 3 files changed, 203 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 9194be1d4f796bd7..8ee2bd89c4205761 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -227,7 +227,6 @@ kernel = {
 
   x86_64 = kern/x86_64/dl.c;
   x86_64_xen = kern/x86_64/dl.c;
-  x86_64_efi = kern/x86_64/efi/callwrap.S;
   x86_64_efi = kern/i386/efi/init.c;
   x86_64_efi = bus/pci.c;
 
diff --git a/grub-core/kern/x86_64/efi/callwrap.S 
b/grub-core/kern/x86_64/efi/callwrap.S
deleted file mode 100644
index 1337fd9fc823f8a4..
--- a/grub-core/kern/x86_64/efi/callwrap.S
+++ /dev/null
@@ -1,129 +0,0 @@
-/* callwrap.S - wrapper for x86_64 efi calls */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include 
-#include 
-
-/*
- * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
- * different call conversion, so we need to do some conversion.
- *
- * gcc:
- *   %rdi,  %rsi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
- *
- * efi:
- *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
- *
- */
-
-.file   "callwrap.S"
-.text
-
-FUNCTION(efi_wrap_0)
-   subq $40, %rsp
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_1)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_2)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_3)
-   subq $40, %rsp
-   mov  %rcx, %r8
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_4)
-   subq $40, %rsp
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_5)
-   subq $40, %rsp
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_6)
-   subq $56, %rsp
-   mov 56+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $56, %rsp
-   ret
-
-FUNCTION(efi_wrap_7)
-   subq $88, %rsp
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
-
-FUNCTION(efi_wrap_10)
-   subq $88, %rsp
-   mov 88+40(%rsp), %rax
-   mov %rax, 72(%rsp)
-   mov 88+32(%rsp), %rax
-   mov %rax, 64(%rsp)
-   mov 88+24(%rsp), %rax
-   mov %rax, 56(%rsp)
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index b145211003954092..fb881ae12d5ae73a 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1824,77 +1824,4 @@ struct initrd_media_device_path {
 } GRUB_PACKED;
 typedef struct initrd_media_device_path initrd_media_device_path_t;
 
-#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
-  || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
-  || defined(__riscv)
-
-#define efi_call_0(func)   (func)()
-#define efi_call_1(func, a)(func)(a)
-#define efi_call_2(func, a, b) (func)(a, b)
-#define efi_call_3(func, a, b, c)  (func)(a, b, c)
-#define efi_call_4(func, a, b, c, d)   (func)(a, b, c, d)
-#define efi_call_5(func, a, b, c, d, e)(func)(a, b, c, d, e)
-#define efi_call_6(func, a, b, c, d, e, f) (func)(a, b, c, d, e, f)
-#define

[PATCH v2 2/6] efi: Make EFI PXE protocol methods non-callable

2023-05-11 Thread Ard Biesheuvel
The grub_efi_pxe_t struct definition has placeholders for the various
protocol method pointers, given that they are never called in the code,
and the prototypes have been omitted, and therefore do not comply with
the UEFI spec.

So let's convert them into void* pointers, so they cannot be called
inadvertently.

Signed-off-by: Ard Biesheuvel 
---
 include/grub/efi/api.h | 24 ++--
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index b4c4646651cd53f5..da1a80ca3a94fe1c 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1539,18 +1539,18 @@ typedef struct grub_efi_pxe_mode
 typedef struct grub_efi_pxe
 {
   grub_uint64_t rev;
-  void (*start) (void);
-  void (*stop) (void);
-  void (*dhcp) (void);
-  void (*discover) (void);
-  void (*mftp) (void);
-  void (*udpwrite) (void);
-  void (*udpread) (void);
-  void (*setipfilter) (void);
-  void (*arp) (void);
-  void (*setparams) (void);
-  void (*setstationip) (void);
-  void (*setpackets) (void);
+  void *start;
+  void *stop;
+  void *dhcp;
+  void *discover;
+  void *mftp;
+  void *udpwrite;
+  void *udpread;
+  void *setipfilter;
+  void *arp;
+  void *setparams;
+  void *setstationip;
+  void *setpackets;
   struct grub_efi_pxe_mode *mode;
 } grub_efi_pxe_t;
 
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v2 0/6] efi: Implement generic EFI boot for x86

2023-05-11 Thread Ard Biesheuvel
Switch the i386-efi and x86_64-efi builds to the generic EFI loader,
which enters the Linux kernel via the EFI stub and provides the initrd
via the LoadFile2 protocol. This unifies x86 with other EFI
architectures, and removes the dependency on the setup header and struct
bootparams.

Do some preparatory cleanup first, so we no longer need to rely on the
MS to SysV calling convention translation code.

Changes since v1:
- drop Itanium support, which is a maintenance burden as it shares the
  EFI code with other architectures, but does not have a EFI stub in
  Linux, and there is no way to test whether our changes break the boot
  for it or not;
- enable generic EFI for i386 as well
- wire up the existing x86 code as a fallback for kernels that lack EFI
  stub or LoadFile2 support. This removes the need for additional
  changes to support v5.8 or older kernels.

Ard Biesheuvel (6):
  ia64: Remove support
  efi: Make EFI PXE protocol methods non-callable
  efi: Add calling convention annotation to all prototypes
  efi: Drop all uses of efi_call_XX wrappers
  efi: Remove x86_64 call wrappers
  efi: Use generic EFI loader for x86_64 and i386

 .travis.yml  |   7 +-
 Makefile.util.def|   1 -
 configure.ac |   8 -
 docs/grub-dev.texi   |   2 +-
 docs/grub.texi   |   2 +-
 gentpl.py|   6 +-
 grub-core/Makefile.am|   6 -
 grub-core/Makefile.core.def  |  21 +-
 grub-core/commands/acpi.c|   8 +-
 grub-core/commands/efi/efitextmode.c |   8 +-
 grub-core/commands/efi/lsefi.c   |   5 +-
 grub-core/commands/efi/tpm.c |  21 +-
 grub-core/commands/file.c|  33 -
 grub-core/disk/efi/efidisk.c |   7 +-
 grub-core/kern/arm/efi/init.c|  12 +-
 grub-core/kern/dl.c  |  12 -
 grub-core/kern/efi/efi.c |  56 +-
 grub-core/kern/efi/init.c|  15 +-
 grub-core/kern/efi/mm.c  |  17 +-
 grub-core/kern/emu/cache.c   |   4 +-
 grub-core/kern/emu/cache_s.S |   2 +-
 grub-core/kern/emu/lite.c|   3 -
 grub-core/kern/i386/efi/tsc.c|   2 +-
 grub-core/kern/ia64/cache.c  |  35 -
 grub-core/kern/ia64/dl.c | 150 -
 grub-core/kern/ia64/dl_helper.c  | 241 ---
 grub-core/kern/ia64/efi/init.c   |  80 ---
 grub-core/kern/ia64/efi/startup.S|  44 --
 grub-core/kern/misc.c|   2 +-
 grub-core/kern/x86_64/efi/callwrap.S | 129 
 grub-core/lib/efi/datetime.c |   9 +-
 grub-core/lib/efi/halt.c |   6 +-
 grub-core/lib/efi/relocator.c|   6 +-
 grub-core/lib/ia64/longjmp.S | 162 -
 grub-core/lib/ia64/setjmp.S  | 177 --
 grub-core/lib/setjmp.S   |   3 -
 grub-core/loader/efi/appleloader.c   |   8 +-
 grub-core/loader/efi/chainloader.c   |  20 +-
 grub-core/loader/efi/linux.c |  51 +-
 grub-core/loader/i386/linux.c|   8 +
 grub-core/loader/ia64/efi/linux.c| 607 --
 grub-core/mmap/efi/mmap.c|  16 +-
 grub-core/net/drivers/efi/efinet.c   |  26 +-
 grub-core/term/efi/console.c |  29 +-
 grub-core/term/efi/serial.c  |  18 +-
 grub-core/video/efi_gop.c|  18 +-
 grub-core/video/efi_uga.c|   8 +-
 include/grub/cache.h |   2 +-
 include/grub/dl.h|  12 +-
 include/grub/efi/api.h   | 666 +---
 include/grub/efi/efi.h   |   2 +-
 include/grub/efi/pe32.h  |   2 -
 include/grub/efi/tpm.h   | 149 +++--
 include/grub/elf.h   | 109 
 include/grub/ia64/efi/memory.h   |   6 -
 include/grub/ia64/efi/time.h |  23 -
 include/grub/ia64/kernel.h   |  25 -
 include/grub/ia64/reloc.h|  44 --
 include/grub/ia64/setjmp.h   |  28 -
 include/grub/ia64/time.h |  28 -
 include/grub/ia64/types.h|  32 -
 include/grub/misc.h  |   2 +-
 include/grub/util/install.h  |   1 -
 include/grub/util/mkimage.h  |   2 -
 tests/core_compress_test.in  |   2 +-
 util/grub-install-common.c   |   1 -
 util/grub-install.c  |  16 -
 util/grub-mkimage.c  |   1 -
 util/grub-mkimagexx.c| 175 +
 util/grub-mknetdir.c |   1 -
 util/grub-mkrescue.c |   7 -
 util/grub-module-verifier.c  |  22 -
 util/mkimage.c   |  17 -
 73 files changed, 610 insertions(+), 2876 deletions(-)
 delete mode 100644 grub-core/kern/ia64/cache.c
 delete mode 100644 grub-core/kern/ia64/dl.c
 delete mode 100644 grub-core/kern/ia64/dl_helper.c
 delete mode 100644 grub-core/kern/ia64/efi/init.c
 delete mode 100644 grub-core/kern/ia64/efi/startup.S
 delete mode 100644 grub-core/kern/x86_64/efi/callwrap.S
 delete mode

[PATCH v2 1/6] ia64: Remove support

2023-05-11 Thread Ard Biesheuvel
Itanium IA-64 support is obsolete, and implements its own flavor of EFI
boot that deviates from other architectures. Given that IA64 is unused
and unmaintained, it makes no sense to pretend that the EFI changes we
are making are tested or supported on IA64, so let's just get rid of it.

Signed-off-by: Ard Biesheuvel 
---
 .travis.yml   |   7 +-
 Makefile.util.def |   1 -
 configure.ac  |   8 -
 docs/grub-dev.texi|   2 +-
 docs/grub.texi|   2 +-
 gentpl.py |   6 +-
 grub-core/Makefile.am |   6 -
 grub-core/Makefile.core.def   |  15 -
 grub-core/commands/file.c |  33 --
 grub-core/kern/dl.c   |  12 -
 grub-core/kern/emu/cache.c|   4 +-
 grub-core/kern/emu/cache_s.S  |   2 +-
 grub-core/kern/emu/lite.c |   3 -
 grub-core/kern/ia64/cache.c   |  35 --
 grub-core/kern/ia64/dl.c  | 150 -
 grub-core/kern/ia64/dl_helper.c   | 241 
 grub-core/kern/ia64/efi/init.c|  80 ---
 grub-core/kern/ia64/efi/startup.S |  44 --
 grub-core/kern/misc.c |   2 +-
 grub-core/lib/efi/halt.c  |   2 +-
 grub-core/lib/ia64/longjmp.S  | 162 --
 grub-core/lib/ia64/setjmp.S   | 177 --
 grub-core/lib/setjmp.S|   3 -
 grub-core/loader/ia64/efi/linux.c | 607 
 include/grub/cache.h  |   2 +-
 include/grub/dl.h |  12 +-
 include/grub/efi/pe32.h   |   2 -
 include/grub/elf.h| 109 
 include/grub/ia64/efi/memory.h|   6 -
 include/grub/ia64/efi/time.h  |  23 -
 include/grub/ia64/kernel.h|  25 -
 include/grub/ia64/reloc.h |  44 --
 include/grub/ia64/setjmp.h|  28 -
 include/grub/ia64/time.h  |  28 -
 include/grub/ia64/types.h |  32 --
 include/grub/misc.h   |   2 +-
 include/grub/util/install.h   |   1 -
 include/grub/util/mkimage.h   |   2 -
 tests/core_compress_test.in   |   2 +-
 util/grub-install-common.c|   1 -
 util/grub-install.c   |  16 -
 util/grub-mkimage.c   |   1 -
 util/grub-mkimagexx.c | 175 +-
 util/grub-mknetdir.c  |   1 -
 util/grub-mkrescue.c  |   7 -
 util/grub-module-verifier.c   |  22 -
 util/mkimage.c|  17 -
 47 files changed, 16 insertions(+), 2146 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 4bd05a30a27ad15c..7bea51b2f0c4da89 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,7 +23,7 @@ addons:
 env:
   global:
 # Include all cross toolchain paths, so we can just call them later down.
-- 
PATH=/tmp/qemu-install/bin:/tmp/grub/bin:/usr/bin:/bin:/tmp/cross/gcc-8.1.0-nolibc/aarch64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/arm-linux-gnueabi/bin:/tmp/cross/gcc-8.1.0-nolibc/ia64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/mips64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/powerpc64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv32-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/sparc64-linux/bin
+- 
PATH=/tmp/qemu-install/bin:/tmp/grub/bin:/usr/bin:/bin:/tmp/cross/gcc-8.1.0-nolibc/aarch64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/arm-linux-gnueabi/bin:/tmp/cross/gcc-8.1.0-nolibc/mips64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/powerpc64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv32-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/riscv64-linux/bin:/tmp/cross/gcc-8.1.0-nolibc/sparc64-linux/bin
 
 before_script:
   # Install necessary toolchains based on $CROSS_TARGETS variable.
@@ -44,7 +44,6 @@ script:
   arch=${target%-*};
   [ "$arch" = "arm64" ] && arch=aarch64-linux;
   [ "$arch" = "arm" ] && arch=arm-linux-gnueabi;
-  [ "$arch" = "ia64" ] && arch=ia64-linux;
   [ "$arch" = "mipsel" ] && arch=mips64-linux;
   [ "$arch" = "powerpc" ] && arch=powerpc64-linux;
   [ "$arch" = "riscv32" ] && arch=riscv32-linux;
@@ -83,10 +82,6 @@ matrix:
   env:
 - GRUB_TARGETS="sparc64-ieee1275"
 - CROSS_TARGETS="sparc64-linux"
-- name: "ia64"
-  env:
-- GRUB_TARGETS="ia64-efi"
-- CROSS_TARGETS="ia64-linux"
 - name: "mips"
   env:
 - GRUB_TARGETS="mips-arc mipsel-arc mipsel-qemu_mips mips-qemu_mips"
diff --git a/Makefile.util.def b/Makefile.util.def
index beaef1168f0d09b0..ae9e628e5c85b751 100644
--- a/Makefile.util.def
+++ b/Makefile.util.def
@@ -160,7 +160,6 @@ library = {
   common = grub-core/io/gzio.c;
   common = grub-core/io/xzio.c;
   common = grub-core/io/lzopio.c;
-  common = grub-core/kern/ia64/dl_helper.c;
   common = grub-core/kern/arm/dl_helper.c;
   common = grub-core/kern/arm64/dl_helper.c;
   common = gr

[PATCH v2 4/6] efi: Drop all uses of efi_call_XX wrappers

2023-05-11 Thread Ard Biesheuvel
Now that GCC can generate function calls using the correct calling
convention for us, we can stop using the efi_call_XX () wrappers, and
just dereference the function pointers directly.

This avoids the untyped variadic wrapper routines, which means better
type checking for the method calls.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/commands/acpi.c|  8 +--
 grub-core/commands/efi/efitextmode.c |  8 ++-
 grub-core/commands/efi/lsefi.c   |  5 +-
 grub-core/commands/efi/tpm.c | 21 
 grub-core/disk/efi/efidisk.c |  7 +--
 grub-core/kern/arm/efi/init.c| 10 ++--
 grub-core/kern/efi/efi.c | 56 ++--
 grub-core/kern/efi/init.c| 15 +++---
 grub-core/kern/efi/mm.c  | 17 +++---
 grub-core/kern/i386/efi/tsc.c|  2 +-
 grub-core/lib/efi/datetime.c |  9 ++--
 grub-core/lib/efi/halt.c |  4 +-
 grub-core/lib/efi/relocator.c|  6 +--
 grub-core/loader/efi/appleloader.c   |  8 +--
 grub-core/loader/efi/chainloader.c   | 20 +++
 grub-core/mmap/efi/mmap.c| 16 +++---
 grub-core/net/drivers/efi/efinet.c   | 26 -
 grub-core/term/efi/console.c | 29 +-
 grub-core/term/efi/serial.c  | 18 +++
 grub-core/video/efi_gop.c| 18 +++
 grub-core/video/efi_uga.c|  8 +--
 21 files changed, 153 insertions(+), 158 deletions(-)

diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index fda62f4ea98a6da8..ab067ae6e51d43af 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -762,10 +762,10 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int 
argc, char **args)
 struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
 struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
 
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv2 ());
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv1 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv2 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv1 ());
   }
 #endif
 
diff --git a/grub-core/commands/efi/efitextmode.c 
b/grub-core/commands/efi/efitextmode.c
index 3679f6b4d8028bc7..198bc694d3fc3c3b 100644
--- a/grub-core/commands/efi/efitextmode.c
+++ b/grub-core/commands/efi/efitextmode.c
@@ -36,7 +36,7 @@ grub_efi_set_mode (grub_efi_simple_text_output_interface_t *o,
 
   if (mode != o->mode->mode)
 {
-  status = efi_call_2 (o->set_mode, o, mode);
+  status = o->set_mode (o, mode);
   if (status == GRUB_EFI_SUCCESS)
;
   else if (status == GRUB_EFI_DEVICE_ERROR)
@@ -79,8 +79,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   grub_printf_ (N_("Available modes for console output device.\n"));
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  grub_printf_ (N_(" [%" PRIuGRUB_EFI_UINT32_T "]  Col %5"
   PRIuGRUB_EFI_UINTN_T " Row %5" PRIuGRUB_EFI_UINTN_T
   " %c\n"),
@@ -129,8 +128,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   N_("non-numeric or invalid rows number `%s'"), 
args[1]);
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  if (u_columns == columns && u_rows == rows)
return grub_efi_set_mode (o, (grub_efi_int32_t) i);
 
diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
index c304d25ccdd6f32b..53970149785a28f8 100644
--- a/grub-core/commands/efi/lsefi.c
+++ b/grub-core/commands/efi/lsefi.c
@@ -108,8 +108,9 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
  grub_efi_print_device_path (dp);
}
 
-  status = efi_call_3 
(grub_efi_system_table->boot_services->protocols_per_handle,
-  handle, , _protocols);
+  status = grub_efi_system_table->boot_services->protocols_per_handle 
(handle,
+  
,
+  
_protocols);
   if (status != GRUB_EFI_SUCCESS) {
grub_printf ("Unable to retrieve pr

[PATCH v2 6/6] efi: Use generic EFI loader for x86_64 and i386

2023-05-11 Thread Ard Biesheuvel
Switch the x86 based EFI platform builds to the generic EFI loader,
which exposes the initrd via the LoadFile2 protocol instead of the
x86-specific setup header. This will launch the Linux kernel via its EFI
stub, which performs its own initialization in the EFI boot services
context before calling ExitBootServices() and performing the bare metal
Linux boot.

Given that only Linux kernel versions v5.8 and later support this initrd
loading method, the existing x86 loader is retained as a fallback, which
will also be used for Linux kernels built without the EFI stub. In this
case, GRUB calls ExitBootServices() before entering the Linux kernel,
and all EFI related information is provided to the kernel via struct
boot_params in the setup header, as before.

Note that this means that booting EFI stub kernels older than v5.8 is
not supported even when not using an initrd at all. Also, the EFI
handover protocol, which has no basis in the UEFI specification, is not
implemented.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def   |  5 +-
 grub-core/loader/efi/linux.c  | 51 ++--
 grub-core/loader/i386/linux.c |  8 +++
 include/grub/efi/efi.h|  2 +-
 4 files changed, 56 insertions(+), 10 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 8ee2bd89c4205761..bc08955ac791241a 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1818,11 +1818,8 @@ module = {
   powerpc_ieee1275 = loader/powerpc/ieee1275/linux.c;
   sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
   arm_coreboot = loader/arm/linux.c;
-  arm_efi = loader/efi/linux.c;
   arm_uboot = loader/arm/linux.c;
-  arm64 = loader/efi/linux.c;
-  riscv32 = loader/efi/linux.c;
-  riscv64 = loader/efi/linux.c;
+  efi = loader/efi/linux.c;
   emu = loader/emu/linux.c;
   common = loader/linux.c;
   common = lib/cmdline.c;
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 15e0686549d7ecca..970a4d7a5d4d464f 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -69,6 +69,12 @@ static initrd_media_device_path_t initrd_lf2_device_path = {
   }
 };
 
+extern grub_err_t
+grub_cmd_linux_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
+
+extern grub_err_t
+grub_cmd_initrd_x86_legacy (grub_command_t cmd, int argc, char *argv[]);
+
 static grub_efi_status_t __grub_efi_api
 grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
 grub_efi_device_path_t *device_path,
@@ -89,8 +95,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
 return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image 
header");
 
   if ((lh->code0 & 0x) != GRUB_PE32_MAGIC)
-return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-  N_("plain image kernel not supported - rebuild with 
CONFIG_(U)EFI_STUB enabled"));
+return GRUB_ERR_NOT_IMPLEMENTED_YET;
 
   grub_dprintf ("linux", "UEFI stub kernel:\n");
   grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
@@ -117,7 +122,11 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
   if (lh->pe_image_header.optional_header.major_image_version >= 1)
 initrd_use_loadfile2 = true;
   else
+#if defined(__i386__) || defined(__x86_64__)
+return GRUB_ERR_NOT_IMPLEMENTED_YET;
+#else
 initrd_use_loadfile2 = false;
+#endif
 
   grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
 initrd_use_loadfile2 ? "en" : "dis");
@@ -125,6 +134,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
 static grub_err_t
 finalize_params_linux (void)
 {
@@ -169,6 +179,7 @@ failure:
   grub_fdt_unload();
   return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
 }
+#endif
 
 grub_err_t
 grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
@@ -231,8 +242,10 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
 static grub_err_t
 grub_linux_boot (void)
 {
+#if !defined(__i386__) && !defined(__x86_64__)
   if (finalize_params_linux () != GRUB_ERR_NONE)
 return grub_errno;
+#endif
 
   return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
   kernel_size, linux_args));
@@ -253,7 +266,9 @@ grub_linux_unload (void)
   if (kernel_addr)
 grub_efi_free_pages ((grub_addr_t) kernel_addr,
 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+#if !defined(__i386__) && !defined(__x86_64__)
   grub_fdt_unload ();
+#endif
 
   if (initrd_lf2_handle != NULL)
 {
@@ -269,6 +284,7 @@ grub_linux_unload (void)
   return GRUB_ERR_NONE;
 }
 
+#if !defined(__i386__) && !defined(__x86_64__)
 /*
  *

[PATCH v2 3/6] efi: Add calling convention annotation to all prototypes

2023-05-11 Thread Ard Biesheuvel
UEFI mandates MS calling convention on x86_64, which was not supported
on GCC when UEFI support was first introduced into GRUB. However, now we
can use the ms_abi function type attribute to annotate functions and
function pointers as adhering to the MS calling convention, and the
compiler will generate the correct instruction sequence for us.

So let's add the appropriate annotation to all the function prototypes.
This will allow us to drop the special call wrappers in a subsequent
patch.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/kern/arm/efi/init.c |   2 +-
 include/grub/efi/api.h| 569 ++--
 include/grub/efi/tpm.h| 149 +++--
 3 files changed, 373 insertions(+), 347 deletions(-)

diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
index 7fcf91bf41168d4a..ab48342f3cda116d 100644
--- a/grub-core/kern/arm/efi/init.c
+++ b/grub-core/kern/arm/efi/init.c
@@ -34,7 +34,7 @@ grub_efi_get_time_ms (void)
   return tmr;
 }
 
-static void
+static void __grub_efi_api
 increment_timer (grub_efi_event_t event __attribute__ ((unused)),
 void *context __attribute__ ((unused)))
 {
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index da1a80ca3a94fe1c..b145211003954092 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1127,209 +1127,210 @@ struct grub_efi_boot_services
   grub_efi_table_header_t hdr;
 
   grub_efi_tpl_t
-  (*raise_tpl) (grub_efi_tpl_t new_tpl);
+  (__grub_efi_api *raise_tpl) (grub_efi_tpl_t new_tpl);
 
   void
-  (*restore_tpl) (grub_efi_tpl_t old_tpl);
+  (__grub_efi_api *restore_tpl) (grub_efi_tpl_t old_tpl);
 
   grub_efi_status_t
-  (*allocate_pages) (grub_efi_allocate_type_t type,
-grub_efi_memory_type_t memory_type,
-grub_efi_uintn_t pages,
-grub_efi_physical_address_t *memory);
+  (__grub_efi_api *allocate_pages) (grub_efi_allocate_type_t type,
+   grub_efi_memory_type_t memory_type,
+   grub_efi_uintn_t pages,
+   grub_efi_physical_address_t *memory);
 
   grub_efi_status_t
-  (*free_pages) (grub_efi_physical_address_t memory,
-grub_efi_uintn_t pages);
+  (__grub_efi_api *free_pages) (grub_efi_physical_address_t memory,
+   grub_efi_uintn_t pages);
 
   grub_efi_status_t
-  (*get_memory_map) (grub_efi_uintn_t *memory_map_size,
-grub_efi_memory_descriptor_t *memory_map,
-grub_efi_uintn_t *map_key,
-grub_efi_uintn_t *descriptor_size,
-grub_efi_uint32_t *descriptor_version);
+  (__grub_efi_api *get_memory_map) (grub_efi_uintn_t *memory_map_size,
+   grub_efi_memory_descriptor_t *memory_map,
+   grub_efi_uintn_t *map_key,
+   grub_efi_uintn_t *descriptor_size,
+   grub_efi_uint32_t *descriptor_version);
 
   grub_efi_status_t
-  (*allocate_pool) (grub_efi_memory_type_t pool_type,
-   grub_efi_uintn_t size,
-   void **buffer);
+  (__grub_efi_api *allocate_pool) (grub_efi_memory_type_t pool_type,
+  grub_efi_uintn_t size,
+  void **buffer);
 
   grub_efi_status_t
-  (*free_pool) (void *buffer);
+  (__grub_efi_api *free_pool) (void *buffer);
 
   grub_efi_status_t
-  (*create_event) (grub_efi_uint32_t type,
-  grub_efi_tpl_t notify_tpl,
-  void (*notify_function) (grub_efi_event_t event,
-   void *context),
-  void *notify_context,
-  grub_efi_event_t *event);
+  (__grub_efi_api *create_event) (grub_efi_uint32_t type,
+ grub_efi_tpl_t notify_tpl,
+ void (__grub_efi_api *notify_function) 
(grub_efi_event_t,
+ void 
*context),
+ void *notify_context,
+ grub_efi_event_t *event);
 
   grub_efi_status_t
-  (*set_timer) (grub_efi_event_t event,
-   grub_efi_timer_delay_t type,
-   grub_efi_uint64_t trigger_time);
+  (__grub_efi_api *set_timer) (grub_efi_event_t event,
+  grub_efi_timer_delay_t type,
+  grub_efi_uint64_t trigger_time);
 
   grub_efi_status_t
-  (*wait_for_event) (grub_efi_uintn_t num_events,
-grub_efi_event_t *event,
-grub_efi_uintn_t *index);
+  (__grub_efi_api *wait_for_event) (grub_efi_uintn_t num_events,
+   grub_efi_event_t *event,
+   grub_efi_uintn_t *index);
 
   grub_efi_status_t
-  (*signal_event

Re: [PATCH 5/5] efi: Use generic EFI loader for x86_64

2023-05-11 Thread Ard Biesheuvel
On Wed, 10 May 2023 at 19:40, Ard Biesheuvel  wrote:
>
> On Wed, 10 May 2023 at 15:15, Daniel Kiper  wrote:
> >
> > On Wed, May 10, 2023 at 12:40:30PM +0200, Ard Biesheuvel wrote:
> > > On Tue, 9 May 2023 at 18:53, Ard Biesheuvel  wrote:
> > > >
> > > > Switch the x86_64 build to the generic EFI loader, which exposes the
> > > > initrd via the LoadFile2 protocol instead of the x86-specific setup
> > > > header. This will launch the Linux kernel via its EFI stub, which
> > > > performs its own initialization in the EFI boot services context before
> > > > calling ExitBootServices() and performing the bare metal Linux boot.
> > > >
> > > > Signed-off-by: Ard Biesheuvel 
> > > > ---
> > > >  grub-core/Makefile.core.def  |  6 +-
> > > >  grub-core/kern/efi/mm.c  |  2 +-
> > > >  grub-core/loader/efi/linux.c | 12 
> > > >  include/grub/efi/efi.h   |  2 ++
> > > >  4 files changed, 16 insertions(+), 6 deletions(-)
> > > >
> > > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> > > > index c17d022195b3fdca..f9e89a0cc4389dd0 100644
> > > > --- a/grub-core/Makefile.core.def
> > > > +++ b/grub-core/Makefile.core.def
> > > > @@ -1822,7 +1822,6 @@ module = {
> > > >
> > > >  module = {
> > > >name = linux;
> > > > -  x86 = loader/i386/linux.c;
> > > >i386_xen_pvh = loader/i386/linux.c;
> > > >xen = loader/i386/xen.c;
> > > >i386_pc = lib/i386/pc/vesa_modes_table.c;
> > > > @@ -1832,11 +1831,8 @@ module = {
> > > >sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
> > > >ia64_efi = loader/ia64/efi/linux.c;
> > > >arm_coreboot = loader/arm/linux.c;
> > > > -  arm_efi = loader/efi/linux.c;
> > > > +  efi = loader/efi/linux.c;
> > >
> > > This change breaks the build for i386_efi. Any suggestions on how to
> > > rephrase this?
>
> Also, I think the command line piece is missing - I'll fix that up for v2.
>

Never mind - I was looking at distro GRUB, which looks quite different :-)

I'll replace this hunk with

--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1809,7 +1809,7 @@ module = {

 module = {
   name = linux;
-  x86 = loader/i386/linux.c;
+  i386 = loader/i386/linux.c;
   i386_xen_pvh = loader/i386/linux.c;
   xen = loader/i386/xen.c;
   i386_pc = lib/i386/pc/vesa_modes_table.c;
@@ -1823,6 +1823,7 @@ module = {
   arm64 = loader/efi/linux.c;
   riscv32 = loader/efi/linux.c;
   riscv64 = loader/efi/linux.c;
+  x86_64_efi = loader/efi/linux.c;
   emu = loader/emu/linux.c;
   common = loader/linux.c;
   common = lib/cmdline.c;

and we can always consolidate it later if we figure out how

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH 5/5] efi: Use generic EFI loader for x86_64

2023-05-10 Thread Ard Biesheuvel
On Wed, 10 May 2023 at 15:15, Daniel Kiper  wrote:
>
> On Wed, May 10, 2023 at 12:40:30PM +0200, Ard Biesheuvel wrote:
> > On Tue, 9 May 2023 at 18:53, Ard Biesheuvel  wrote:
> > >
> > > Switch the x86_64 build to the generic EFI loader, which exposes the
> > > initrd via the LoadFile2 protocol instead of the x86-specific setup
> > > header. This will launch the Linux kernel via its EFI stub, which
> > > performs its own initialization in the EFI boot services context before
> > > calling ExitBootServices() and performing the bare metal Linux boot.
> > >
> > > Signed-off-by: Ard Biesheuvel 
> > > ---
> > >  grub-core/Makefile.core.def  |  6 +-
> > >  grub-core/kern/efi/mm.c  |  2 +-
> > >  grub-core/loader/efi/linux.c | 12 
> > >  include/grub/efi/efi.h   |  2 ++
> > >  4 files changed, 16 insertions(+), 6 deletions(-)
> > >
> > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> > > index c17d022195b3fdca..f9e89a0cc4389dd0 100644
> > > --- a/grub-core/Makefile.core.def
> > > +++ b/grub-core/Makefile.core.def
> > > @@ -1822,7 +1822,6 @@ module = {
> > >
> > >  module = {
> > >name = linux;
> > > -  x86 = loader/i386/linux.c;
> > >i386_xen_pvh = loader/i386/linux.c;
> > >xen = loader/i386/xen.c;
> > >i386_pc = lib/i386/pc/vesa_modes_table.c;
> > > @@ -1832,11 +1831,8 @@ module = {
> > >sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
> > >ia64_efi = loader/ia64/efi/linux.c;
> > >arm_coreboot = loader/arm/linux.c;
> > > -  arm_efi = loader/efi/linux.c;
> > > +  efi = loader/efi/linux.c;
> >
> > This change breaks the build for i386_efi. Any suggestions on how to
> > rephrase this?

Also, I think the command line piece is missing - I'll fix that up for v2.

>
> I will do more test builds in the following days and get back to you
> with results. And probably some fixes...
>
> Anyway, thank you for making this patch set.
>
> Daniel

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH 5/5] efi: Use generic EFI loader for x86_64

2023-05-10 Thread Ard Biesheuvel
On Tue, 9 May 2023 at 18:53, Ard Biesheuvel  wrote:
>
> Switch the x86_64 build to the generic EFI loader, which exposes the
> initrd via the LoadFile2 protocol instead of the x86-specific setup
> header. This will launch the Linux kernel via its EFI stub, which
> performs its own initialization in the EFI boot services context before
> calling ExitBootServices() and performing the bare metal Linux boot.
>
> Signed-off-by: Ard Biesheuvel 
> ---
>  grub-core/Makefile.core.def  |  6 +-
>  grub-core/kern/efi/mm.c  |  2 +-
>  grub-core/loader/efi/linux.c | 12 
>  include/grub/efi/efi.h   |  2 ++
>  4 files changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
> index c17d022195b3fdca..f9e89a0cc4389dd0 100644
> --- a/grub-core/Makefile.core.def
> +++ b/grub-core/Makefile.core.def
> @@ -1822,7 +1822,6 @@ module = {
>
>  module = {
>name = linux;
> -  x86 = loader/i386/linux.c;
>i386_xen_pvh = loader/i386/linux.c;
>xen = loader/i386/xen.c;
>i386_pc = lib/i386/pc/vesa_modes_table.c;
> @@ -1832,11 +1831,8 @@ module = {
>sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
>ia64_efi = loader/ia64/efi/linux.c;
>arm_coreboot = loader/arm/linux.c;
> -  arm_efi = loader/efi/linux.c;
> +  efi = loader/efi/linux.c;

This change breaks the build for i386_efi. Any suggestions on how to
rephrase this?

>arm_uboot = loader/arm/linux.c;
> -  arm64 = loader/efi/linux.c;
> -  riscv32 = loader/efi/linux.c;
> -  riscv64 = loader/efi/linux.c;
>emu = loader/emu/linux.c;
>common = loader/linux.c;
>common = lib/cmdline.c;
> diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
> index 09225a7c08e4d066..9ba0b8814fe16cc9 100644
> --- a/grub-core/kern/efi/mm.c
> +++ b/grub-core/kern/efi/mm.c
> @@ -653,7 +653,7 @@ grub_efi_mm_init (void)
>grub_mm_add_region_fn = grub_efi_mm_add_regions;
>  }
>
> -#if defined (__aarch64__) || defined (__arm__) || defined (__riscv)
> +#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) || 
> defined(__x86_64__)
>  grub_err_t
>  grub_efi_get_ram_base(grub_addr_t *base_addr)
>  {
> diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
> index 15e0686549d7ecca..3cf596f56e8eac4f 100644
> --- a/grub-core/loader/efi/linux.c
> +++ b/grub-core/loader/efi/linux.c
> @@ -125,6 +125,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
>return GRUB_ERR_NONE;
>  }
>
> +#ifndef __x86_64__
>  static grub_err_t
>  finalize_params_linux (void)
>  {
> @@ -169,6 +170,7 @@ failure:
>grub_fdt_unload();
>return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
>  }
> +#endif
>
>  grub_err_t
>  grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char 
> *args)
> @@ -231,8 +233,10 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
> grub_size_t size, char *args)
>  static grub_err_t
>  grub_linux_boot (void)
>  {
> +#ifndef __x86_64__
>if (finalize_params_linux () != GRUB_ERR_NONE)
>  return grub_errno;
> +#endif
>
>return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
>kernel_size, linux_args));
> @@ -253,7 +257,9 @@ grub_linux_unload (void)
>if (kernel_addr)
>  grub_efi_free_pages ((grub_addr_t) kernel_addr,
>  GRUB_EFI_BYTES_TO_PAGES (kernel_size));
> +#ifndef __x86_64__
>grub_fdt_unload ();
> +#endif
>
>if (initrd_lf2_handle != NULL)
>  {
> @@ -391,6 +397,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
> ((unused)),
>return GRUB_ERR_NONE;
>  }
>
> +#ifdef __x86_64__
> +  grub_error (GRUB_ERR_INVALID_COMMAND,
> +  N_("selected Linux kernel does not support loadfile2 initrd 
> loading"));
> +  goto fail;
> +#endif
> +
>initrd_size = grub_get_initrd_size (_ctx);
>grub_dprintf ("linux", "Loading initrd\n");
>
> diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
> index 444bf5b0b53e31fe..c56abfbd6ba45ab8 100644
> --- a/include/grub/efi/efi.h
> +++ b/include/grub/efi/efi.h
> @@ -112,6 +112,8 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) 
> (grub_efi_handle_t hnd,
>
>  #if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
>  void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
> +#endif
> +#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || 
> defined(__x86_64__)
>  grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
>  #include 
>  grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file,
> --
> 2.39.2
>

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH 3/5] efi: Drop all uses of efi_call_XX wrappers

2023-05-09 Thread Ard Biesheuvel
Now that GCC can generate function calls using the correct calling
convention for us, we can stop using the efi_call_XX () wrappers, and
just dereference the function pointers directly.

This avoids the untyped variadic wrapper routines, which means better
type checking for the method calls.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/commands/acpi.c|  8 +--
 grub-core/commands/efi/efitextmode.c |  8 ++-
 grub-core/commands/efi/lsefi.c   |  5 +-
 grub-core/commands/efi/tpm.c | 21 
 grub-core/disk/efi/efidisk.c |  7 +--
 grub-core/kern/arm/efi/init.c| 10 ++--
 grub-core/kern/efi/efi.c | 56 ++--
 grub-core/kern/efi/init.c| 15 +++---
 grub-core/kern/efi/mm.c  | 17 +++---
 grub-core/kern/i386/efi/tsc.c|  2 +-
 grub-core/kern/ia64/efi/init.c   | 15 +++---
 grub-core/lib/efi/datetime.c |  9 ++--
 grub-core/lib/efi/halt.c |  4 +-
 grub-core/lib/efi/relocator.c|  6 +--
 grub-core/loader/efi/appleloader.c   |  8 +--
 grub-core/loader/efi/chainloader.c   | 20 +++
 grub-core/mmap/efi/mmap.c| 16 +++---
 grub-core/net/drivers/efi/efinet.c   | 26 -
 grub-core/term/efi/console.c | 29 +-
 grub-core/term/efi/serial.c  | 18 +++
 grub-core/video/efi_gop.c| 18 +++
 grub-core/video/efi_uga.c|  8 +--
 22 files changed, 161 insertions(+), 165 deletions(-)

diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index fda62f4ea98a6da8..ab067ae6e51d43af 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -762,10 +762,10 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int 
argc, char **args)
 struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
 struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
 
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv2 ());
-efi_call_2 
(grub_efi_system_table->boot_services->install_configuration_table,
-  , grub_acpi_get_rsdpv1 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv2 ());
+grub_efi_system_table->boot_services->install_configuration_table (,
+  
grub_acpi_get_rsdpv1 ());
   }
 #endif
 
diff --git a/grub-core/commands/efi/efitextmode.c 
b/grub-core/commands/efi/efitextmode.c
index 3679f6b4d8028bc7..198bc694d3fc3c3b 100644
--- a/grub-core/commands/efi/efitextmode.c
+++ b/grub-core/commands/efi/efitextmode.c
@@ -36,7 +36,7 @@ grub_efi_set_mode (grub_efi_simple_text_output_interface_t *o,
 
   if (mode != o->mode->mode)
 {
-  status = efi_call_2 (o->set_mode, o, mode);
+  status = o->set_mode (o, mode);
   if (status == GRUB_EFI_SUCCESS)
;
   else if (status == GRUB_EFI_DEVICE_ERROR)
@@ -79,8 +79,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   grub_printf_ (N_("Available modes for console output device.\n"));
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  grub_printf_ (N_(" [%" PRIuGRUB_EFI_UINT32_T "]  Col %5"
   PRIuGRUB_EFI_UINTN_T " Row %5" PRIuGRUB_EFI_UINTN_T
   " %c\n"),
@@ -129,8 +128,7 @@ grub_cmd_efitextmode (grub_command_t cmd __attribute__ 
((unused)),
   N_("non-numeric or invalid rows number `%s'"), 
args[1]);
 
   for (i = 0; i < o->mode->max_mode; i++)
-   if (GRUB_EFI_SUCCESS == efi_call_4 (o->query_mode, o, i,
-   , ))
+   if (GRUB_EFI_SUCCESS == o->query_mode (o, i, , ))
  if (u_columns == columns && u_rows == rows)
return grub_efi_set_mode (o, (grub_efi_int32_t) i);
 
diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
index c304d25ccdd6f32b..53970149785a28f8 100644
--- a/grub-core/commands/efi/lsefi.c
+++ b/grub-core/commands/efi/lsefi.c
@@ -108,8 +108,9 @@ grub_cmd_lsefi (grub_command_t cmd __attribute__ ((unused)),
  grub_efi_print_device_path (dp);
}
 
-  status = efi_call_3 
(grub_efi_system_table->boot_services->protocols_per_handle,
-  handle, , _protocols);
+  status = grub_efi_system_table->boot_services->protocols_per_handle 
(handle,
+  
,
+  
_protocols);
   if (status != GRUB_EFI_SUCCESS) {

[PATCH 4/5] efi: Remove x86_64 call wrappers

2023-05-09 Thread Ard Biesheuvel
The call wrappers are no longer needed now that GCC can generate
function calls using MS calling convention, so let's get rid of them.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def  |   1 -
 grub-core/kern/x86_64/efi/callwrap.S | 129 
 include/grub/efi/api.h   |  73 ---
 3 files changed, 203 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index 801df7c21de663ec..c17d022195b3fdca 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -231,7 +231,6 @@ kernel = {
 
   x86_64 = kern/x86_64/dl.c;
   x86_64_xen = kern/x86_64/dl.c;
-  x86_64_efi = kern/x86_64/efi/callwrap.S;
   x86_64_efi = kern/i386/efi/init.c;
   x86_64_efi = bus/pci.c;
 
diff --git a/grub-core/kern/x86_64/efi/callwrap.S 
b/grub-core/kern/x86_64/efi/callwrap.S
deleted file mode 100644
index 1337fd9fc823f8a4..
--- a/grub-core/kern/x86_64/efi/callwrap.S
+++ /dev/null
@@ -1,129 +0,0 @@
-/* callwrap.S - wrapper for x86_64 efi calls */
-/*
- *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2006,2007,2009  Free Software Foundation, Inc.
- *
- *  GRUB is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation, either version 3 of the License, or
- *  (at your option) any later version.
- *
- *  GRUB is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include 
-#include 
-
-/*
- * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
- * different call conversion, so we need to do some conversion.
- *
- * gcc:
- *   %rdi,  %rsi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
- *
- * efi:
- *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
- *
- */
-
-.file   "callwrap.S"
-.text
-
-FUNCTION(efi_wrap_0)
-   subq $40, %rsp
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_1)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_2)
-   subq $40, %rsp
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_3)
-   subq $40, %rsp
-   mov  %rcx, %r8
-   mov  %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_4)
-   subq $40, %rsp
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_5)
-   subq $40, %rsp
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $40, %rsp
-   ret
-
-FUNCTION(efi_wrap_6)
-   subq $56, %rsp
-   mov 56+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $56, %rsp
-   ret
-
-FUNCTION(efi_wrap_7)
-   subq $88, %rsp
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
-
-FUNCTION(efi_wrap_10)
-   subq $88, %rsp
-   mov 88+40(%rsp), %rax
-   mov %rax, 72(%rsp)
-   mov 88+32(%rsp), %rax
-   mov %rax, 64(%rsp)
-   mov 88+24(%rsp), %rax
-   mov %rax, 56(%rsp)
-   mov 88+16(%rsp), %rax
-   mov %rax, 48(%rsp)
-   mov 88+8(%rsp), %rax
-   mov %rax, 40(%rsp)
-   mov %r9, 32(%rsp)
-   mov %r8, %r9
-   mov %rcx, %r8
-   mov %rsi, %rcx
-   call *%rdi
-   addq $88, %rsp
-   ret
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index b145211003954092..fb881ae12d5ae73a 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1824,77 +1824,4 @@ struct initrd_media_device_path {
 } GRUB_PACKED;
 typedef struct initrd_media_device_path initrd_media_device_path_t;
 
-#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
-  || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
-  || defined(__riscv)
-
-#define efi_call_0(func)   (func)()
-#define efi_call_1(func, a)(func)(a)
-#define efi_call_2(func, a, b) (func)(a, b)
-#define efi_call_3(func, a, b, c)  (func)(a, b, c)
-#define efi_call_4(func, a, b, c, d)   (func)(a, b, c, d)
-#define efi_call_5(func, a, b, c, d, e)(func)(a, b, c, d, e)
-#define efi_call_6(func, a, b, c, d, e, f) (func)(a, b, c, d, e, f)
-#define

[PATCH 1/5] efi: Make EFI PXE protocol methods non-callable

2023-05-09 Thread Ard Biesheuvel
The grub_efi_pxe_t struct definition has placeholders for the various
protocol method pointers, given that they are never called in the code,
and the prototypes have been omitted, and therefore do not comply with
the UEFI spec.

So let's convert them into void* pointers, so they cannot be called
inadvertently.

Signed-off-by: Ard Biesheuvel 
---
 include/grub/efi/api.h | 24 ++--
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index b4c4646651cd53f5..da1a80ca3a94fe1c 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1539,18 +1539,18 @@ typedef struct grub_efi_pxe_mode
 typedef struct grub_efi_pxe
 {
   grub_uint64_t rev;
-  void (*start) (void);
-  void (*stop) (void);
-  void (*dhcp) (void);
-  void (*discover) (void);
-  void (*mftp) (void);
-  void (*udpwrite) (void);
-  void (*udpread) (void);
-  void (*setipfilter) (void);
-  void (*arp) (void);
-  void (*setparams) (void);
-  void (*setstationip) (void);
-  void (*setpackets) (void);
+  void *start;
+  void *stop;
+  void *dhcp;
+  void *discover;
+  void *mftp;
+  void *udpwrite;
+  void *udpread;
+  void *setipfilter;
+  void *arp;
+  void *setparams;
+  void *setstationip;
+  void *setpackets;
   struct grub_efi_pxe_mode *mode;
 } grub_efi_pxe_t;
 
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH 5/5] efi: Use generic EFI loader for x86_64

2023-05-09 Thread Ard Biesheuvel
Switch the x86_64 build to the generic EFI loader, which exposes the
initrd via the LoadFile2 protocol instead of the x86-specific setup
header. This will launch the Linux kernel via its EFI stub, which
performs its own initialization in the EFI boot services context before
calling ExitBootServices() and performing the bare metal Linux boot.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/Makefile.core.def  |  6 +-
 grub-core/kern/efi/mm.c  |  2 +-
 grub-core/loader/efi/linux.c | 12 
 include/grub/efi/efi.h   |  2 ++
 4 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
index c17d022195b3fdca..f9e89a0cc4389dd0 100644
--- a/grub-core/Makefile.core.def
+++ b/grub-core/Makefile.core.def
@@ -1822,7 +1822,6 @@ module = {
 
 module = {
   name = linux;
-  x86 = loader/i386/linux.c;
   i386_xen_pvh = loader/i386/linux.c;
   xen = loader/i386/xen.c;
   i386_pc = lib/i386/pc/vesa_modes_table.c;
@@ -1832,11 +1831,8 @@ module = {
   sparc64_ieee1275 = loader/sparc64/ieee1275/linux.c;
   ia64_efi = loader/ia64/efi/linux.c;
   arm_coreboot = loader/arm/linux.c;
-  arm_efi = loader/efi/linux.c;
+  efi = loader/efi/linux.c;
   arm_uboot = loader/arm/linux.c;
-  arm64 = loader/efi/linux.c;
-  riscv32 = loader/efi/linux.c;
-  riscv64 = loader/efi/linux.c;
   emu = loader/emu/linux.c;
   common = loader/linux.c;
   common = lib/cmdline.c;
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index 09225a7c08e4d066..9ba0b8814fe16cc9 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -653,7 +653,7 @@ grub_efi_mm_init (void)
   grub_mm_add_region_fn = grub_efi_mm_add_regions;
 }
 
-#if defined (__aarch64__) || defined (__arm__) || defined (__riscv)
+#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) || 
defined(__x86_64__)
 grub_err_t
 grub_efi_get_ram_base(grub_addr_t *base_addr)
 {
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index 15e0686549d7ecca..3cf596f56e8eac4f 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -125,6 +125,7 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
   return GRUB_ERR_NONE;
 }
 
+#ifndef __x86_64__
 static grub_err_t
 finalize_params_linux (void)
 {
@@ -169,6 +170,7 @@ failure:
   grub_fdt_unload();
   return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
 }
+#endif
 
 grub_err_t
 grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args)
@@ -231,8 +233,10 @@ grub_arch_efi_linux_boot_image (grub_addr_t addr, 
grub_size_t size, char *args)
 static grub_err_t
 grub_linux_boot (void)
 {
+#ifndef __x86_64__
   if (finalize_params_linux () != GRUB_ERR_NONE)
 return grub_errno;
+#endif
 
   return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
   kernel_size, linux_args));
@@ -253,7 +257,9 @@ grub_linux_unload (void)
   if (kernel_addr)
 grub_efi_free_pages ((grub_addr_t) kernel_addr,
 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
+#ifndef __x86_64__
   grub_fdt_unload ();
+#endif
 
   if (initrd_lf2_handle != NULL)
 {
@@ -391,6 +397,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ 
((unused)),
   return GRUB_ERR_NONE;
 }
 
+#ifdef __x86_64__
+  grub_error (GRUB_ERR_INVALID_COMMAND,
+  N_("selected Linux kernel does not support loadfile2 initrd 
loading"));
+  goto fail;
+#endif
+
   initrd_size = grub_get_initrd_size (_ctx);
   grub_dprintf ("linux", "Loading initrd\n");
 
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index 444bf5b0b53e31fe..c56abfbd6ba45ab8 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -112,6 +112,8 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) 
(grub_efi_handle_t hnd,
 
 #if defined(__arm__) || defined(__aarch64__) || defined(__riscv)
 void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
+#endif
+#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || 
defined(__x86_64__)
 grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
 #include 
 grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file,
-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH 0/5] efi: Implement generic EFI boot for x86_64

2023-05-09 Thread Ard Biesheuvel
Switch the x86_64-efi build to the generic EFI loader, which enters the
Linux kernel via the EFI stub and provides the initrd via the LoadFile2
protocol. This unifies x86_64 with other EFI architectures, and removes
the dependency on the setup header and struct bootparams.

Do some preparatory cleanup first, so we no longer need to rely on the
MS to SysV calling convention translation code.

Ard Biesheuvel (5):
  efi: Make EFI PXE protocol methods non-callable
  efi: Add calling convention annotation to all prototypes
  efi: Drop all uses of efi_call_XX wrappers
  efi: Remove x86_64 call wrappers
  efi: Use generic EFI loader for x86_64

 grub-core/Makefile.core.def  |   7 +-
 grub-core/commands/acpi.c|   8 +-
 grub-core/commands/efi/efitextmode.c |   8 +-
 grub-core/commands/efi/lsefi.c   |   5 +-
 grub-core/commands/efi/tpm.c |  21 +-
 grub-core/disk/efi/efidisk.c |   7 +-
 grub-core/kern/arm/efi/init.c|  12 +-
 grub-core/kern/efi/efi.c |  56 +-
 grub-core/kern/efi/init.c|  15 +-
 grub-core/kern/efi/mm.c  |  19 +-
 grub-core/kern/i386/efi/tsc.c|   2 +-
 grub-core/kern/ia64/efi/init.c   |  15 +-
 grub-core/kern/x86_64/efi/callwrap.S | 129 
 grub-core/lib/efi/datetime.c |   9 +-
 grub-core/lib/efi/halt.c |   4 +-
 grub-core/lib/efi/relocator.c|   6 +-
 grub-core/loader/efi/appleloader.c   |   8 +-
 grub-core/loader/efi/chainloader.c   |  20 +-
 grub-core/loader/efi/linux.c |  12 +
 grub-core/mmap/efi/mmap.c|  16 +-
 grub-core/net/drivers/efi/efinet.c   |  26 +-
 grub-core/term/efi/console.c |  29 +-
 grub-core/term/efi/serial.c  |  18 +-
 grub-core/video/efi_gop.c|  18 +-
 grub-core/video/efi_uga.c|   8 +-
 include/grub/efi/api.h   | 666 +---
 include/grub/efi/efi.h   |   2 +
 include/grub/efi/tpm.h   | 149 +++--
 28 files changed, 562 insertions(+), 733 deletions(-)
 delete mode 100644 grub-core/kern/x86_64/efi/callwrap.S

-- 
2.39.2


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH 2/5] efi: Add calling convention annotation to all prototypes

2023-05-09 Thread Ard Biesheuvel
UEFI mandates MS calling convention on x86_64, which was not supported
on GCC when UEFI support was first introduced into GRUB. However, now we
can use the ms_abi function type attribute to annotate functions and
function pointers as adhering to the MS calling convention, and the
compiler will generate the correct instruction sequence for us.

So let's add the appropriate annotation to all the function prototypes.
This will allow us to drop the special call wrappers in a subsequent
patch.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/kern/arm/efi/init.c |   2 +-
 include/grub/efi/api.h| 569 ++--
 include/grub/efi/tpm.h| 149 +++--
 3 files changed, 373 insertions(+), 347 deletions(-)

diff --git a/grub-core/kern/arm/efi/init.c b/grub-core/kern/arm/efi/init.c
index 7fcf91bf41168d4a..ab48342f3cda116d 100644
--- a/grub-core/kern/arm/efi/init.c
+++ b/grub-core/kern/arm/efi/init.c
@@ -34,7 +34,7 @@ grub_efi_get_time_ms (void)
   return tmr;
 }
 
-static void
+static void __grub_efi_api
 increment_timer (grub_efi_event_t event __attribute__ ((unused)),
 void *context __attribute__ ((unused)))
 {
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index da1a80ca3a94fe1c..b145211003954092 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -1127,209 +1127,210 @@ struct grub_efi_boot_services
   grub_efi_table_header_t hdr;
 
   grub_efi_tpl_t
-  (*raise_tpl) (grub_efi_tpl_t new_tpl);
+  (__grub_efi_api *raise_tpl) (grub_efi_tpl_t new_tpl);
 
   void
-  (*restore_tpl) (grub_efi_tpl_t old_tpl);
+  (__grub_efi_api *restore_tpl) (grub_efi_tpl_t old_tpl);
 
   grub_efi_status_t
-  (*allocate_pages) (grub_efi_allocate_type_t type,
-grub_efi_memory_type_t memory_type,
-grub_efi_uintn_t pages,
-grub_efi_physical_address_t *memory);
+  (__grub_efi_api *allocate_pages) (grub_efi_allocate_type_t type,
+   grub_efi_memory_type_t memory_type,
+   grub_efi_uintn_t pages,
+   grub_efi_physical_address_t *memory);
 
   grub_efi_status_t
-  (*free_pages) (grub_efi_physical_address_t memory,
-grub_efi_uintn_t pages);
+  (__grub_efi_api *free_pages) (grub_efi_physical_address_t memory,
+   grub_efi_uintn_t pages);
 
   grub_efi_status_t
-  (*get_memory_map) (grub_efi_uintn_t *memory_map_size,
-grub_efi_memory_descriptor_t *memory_map,
-grub_efi_uintn_t *map_key,
-grub_efi_uintn_t *descriptor_size,
-grub_efi_uint32_t *descriptor_version);
+  (__grub_efi_api *get_memory_map) (grub_efi_uintn_t *memory_map_size,
+   grub_efi_memory_descriptor_t *memory_map,
+   grub_efi_uintn_t *map_key,
+   grub_efi_uintn_t *descriptor_size,
+   grub_efi_uint32_t *descriptor_version);
 
   grub_efi_status_t
-  (*allocate_pool) (grub_efi_memory_type_t pool_type,
-   grub_efi_uintn_t size,
-   void **buffer);
+  (__grub_efi_api *allocate_pool) (grub_efi_memory_type_t pool_type,
+  grub_efi_uintn_t size,
+  void **buffer);
 
   grub_efi_status_t
-  (*free_pool) (void *buffer);
+  (__grub_efi_api *free_pool) (void *buffer);
 
   grub_efi_status_t
-  (*create_event) (grub_efi_uint32_t type,
-  grub_efi_tpl_t notify_tpl,
-  void (*notify_function) (grub_efi_event_t event,
-   void *context),
-  void *notify_context,
-  grub_efi_event_t *event);
+  (__grub_efi_api *create_event) (grub_efi_uint32_t type,
+ grub_efi_tpl_t notify_tpl,
+ void (__grub_efi_api *notify_function) 
(grub_efi_event_t,
+ void 
*context),
+ void *notify_context,
+ grub_efi_event_t *event);
 
   grub_efi_status_t
-  (*set_timer) (grub_efi_event_t event,
-   grub_efi_timer_delay_t type,
-   grub_efi_uint64_t trigger_time);
+  (__grub_efi_api *set_timer) (grub_efi_event_t event,
+  grub_efi_timer_delay_t type,
+  grub_efi_uint64_t trigger_time);
 
   grub_efi_status_t
-  (*wait_for_event) (grub_efi_uintn_t num_events,
-grub_efi_event_t *event,
-grub_efi_uintn_t *index);
+  (__grub_efi_api *wait_for_event) (grub_efi_uintn_t num_events,
+   grub_efi_event_t *event,
+   grub_efi_uintn_t *index);
 
   grub_efi_status_t
-  (*signal_event

Re: Handling large allocations (bypassing mm?)

2022-12-22 Thread Ard Biesheuvel
On Fri, 16 Dec 2022 at 18:55, Robbie Harwood  wrote:
>
> Ard Biesheuvel  writes:
>
> > As for supporing kernels from 2012: I don't see why upstream GRUB
> > should care about that. If your distro fork supports those today, you
> > will simply need to carry those patches out of tree a bit longer.
>
> No, it's not a question of distros supporting themselves like this.  For
> better or worse, people expect to be able to install many OSs on their
> drive and have any grub be able to boot any of them.
>
> One such use case I've seen is hardware testing: someone will install
> all the operating systems they care about on a drive, then plug it in to
> the machine with the hardware and try all of them in sequence.  And of
> course there're always hobbyists who just think it's fun to do things
> like that - they file bugs too :)
>
> In any case, it's not a little bit of time we're talking about here -
> even though RHEL 6 is only guaranteed into 2024 right now, RHEL 8 is
> slated to be here until at least 2031.  (Source:
> https://access.redhat.com/support/policy/updates/errata/ )
>

Fair enough.

So are you saying that all downstream GRUBs are mutually compatible,
and can boot other distro kernel images, and it is simply mainline
GRUB that needs to be modified to incorporate those existing
out-of-tree changes?

My stake in this is mainly from the opposite side, i.e., avoiding
pointless per-arch deviations when doing EFI boot from any bootloader.
Upstreaming the EFI handover protocol and other x86 quirks into GRUB
while we already have all the pieces we need to make EFI boot almost
entirely arch-agnostic seems like a mistake to me. And given that the
x86 EFI handover protocol is not in mainline GRUB at the moment, I
wonder how this all fits with your (plural) assertion that older
kernels must be supported by mainline GRUB, as it doesn't support any
of those today.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: Handling large allocations (bypassing mm?)

2022-12-15 Thread Ard Biesheuvel
On Thu, 15 Dec 2022 at 15:29, Julian Andres Klode
 wrote:
>
> On Wed, Dec 14, 2022 at 04:11:18PM +0100, Daniel Kiper wrote:
> > Adding a few folks who may be interested in this discussion too...
> >
> > On Wed, Dec 14, 2022 at 02:21:49PM +0100, Julian Andres Klode wrote:
> > > Hi,
> > >
> > > so I want to bring this discussion here that I had mostly with myself
> > > in the past days on IRC.
> > >
> > > As some of you know, we had a couple issues with large initrds in
> > > Ubuntu, Jeremy posted a patch series earlier about mmunlimited.
> >
> > I skimmed through it but at first sight I do not like it. I will comment
> > the patches more extensively in the following days.
> >
> > > I wanted to propose a more fine-grained approach, as well as a
> > > more generic approach to handling large allocations.
> > >
> > > The first issue one experiences when opening large initrds is
> > > that grub_file_open() calls grub_verifier_open() which simply
> > > grub_malloc()s a buffer for the size of the file.
> > >
> > > Later, for initrd, we have to allocate it a second time, in
> > > the upstream tree that happens via relocator, in the rhboot
> > > tree it allocates directly from EFI.
> > >
> > > Now my basic proposal is quite simple: We make grub_malloc()
> > > and that relocator allocation code bypass the grub memory
> > > management altogether and just do raw EFI page allocations
> > > (provide two function pointers grub_mm_allocate_pages and
> > > grub_mm_free_pages, and just call them if allocation size
> > > is large[1]). e.g. at the start of grub_malloc:
> >
> > In general I think we should stop using legacy Linux loader on UEFI
> > platforms and migrate to LoadFile2 protocol. Relevant patches for ARM64
> > are in master now. We are waiting for patches from Atish which will
> > merge ARM64 implementation into RISC-V (you can find earlier version
> > of the patch set here [1]). Then it could be extended into other
> > architectures including AMD64. Of course this will not solve problem
> > with extra allocation in verifiers. However, at least we should not
> > have problems with large initrds and we will not deal with relocator
> > on EFI platforms.
> >
> > WRT verifiers extra allocation, as you said, this is a problem but it can
> > be solved later. Now at least we should be sure it is possible to load
> > big initrds with LoadFile2 protocol and there are no obstacles in the
> > GRUB code for this thing.
>
> To my knowledge, that is incorrect and LoadFile2 suppoort does nothing
> to address the issue of large initrds:
>

It does.

You should only need 1x the space for the initrd with LoadFile2(), and
given that it is the EFI stub itself that performs the allocation,
whether or not it is above 4 GB or meets some other arch-specific
requirement is completely immaterial to GRUB.

The initrd data will only be loaded once, when the EFI stub asks for
it, and if it doesn't, GRUB will never access the file (or more
accurately, never call grub_file_read() on it).

For verification and other purposes, GRUB is free to authenticate,
decompress or do other things to the payload after loading it into the
buffer but before returning from the callback, and if needed, it can
wipe the buffer again and return an error code to the EFI stub, which
will cause it to give up and return back to GRUB (provided that you
are not using the terminally broken EFI handover protocol)

As for supporing kernels from 2012: I don't see why upstream GRUB
should care about that. If your distro fork supports those today, you
will simply need to carry those patches out of tree a bit longer.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v2 2/2] efi: Put Linux specific magic number in the DOS header

2022-12-07 Thread Ard Biesheuvel
On Wed, 7 Dec 2022 at 11:36, Xiaotian Wu  wrote:
>
> 在 2022-12-07星期三的 09:06 +0100,Ard Biesheuvel写道:
> > On Wed, 7 Dec 2022 at 08:51, Xiaotian Wu 
> > wrote:
> > >
> > > 在 2022-11-29星期二的 18:56 +0100,Ard Biesheuvel写道:
> > > > GRUB currently relies on the magic number in the image header of
> > > > ARM
> > > > and
> > > > arm64 EFI kernel images to decide whether or not the image in
> > > > question
> > > > is a bootable kernel.
> > > >
> > > > However, the purpose of the magic number is to identify the image
> > > > as
> > > > one
> > > > that implements the bare metal boot protocol, and so GRUB, which
> > > > only
> > > > does EFI boot, can only boot images that could potentially be
> > > > booted
> > > > in
> > > > a non-EFI manner as well.
> > > >
> > > > This is problematic for the new zboot decompressor image format,
> > > > as
> > > > it
> > > > can only boot in EFI mode, and must therefore not use the bare
> > > > metal
> > > > boot magic number in its header.
> > > >
> > > > For this reason, the strict magic number was dropped from GRUB,
> > > > to
> > > > permit essentially any kind of EFI executable to be booted via
> > > > the
> > > > 'linux' command, blurring the line between the linux loader and
> > > > the
> > > > chainloader.
> > > >
> > > > So let's use the same field in the DOS header that RISC-V and
> > > > arm64
> > > > already use for their 'bare metal' magic numbers to store a
> > > > 'generic
> > > > Linux kernel' magic number, which can be used to identify
> > > > bootable
> > > > kernel images in PE format which don't necessarily implement a
> > > > bare
> > > > metal boot protocol in the same binary. Note that, in the context
> > > > of
> > > > EFI, the MSDOS header is only described in terms of the fields
> > > > that
> > > > it
> > > > shares with the hybrid PE/COFF image format, (i.e., the magic
> > > > number
> > > > at
> > > > offset #0 and the PE header offset at byte offset #0x3c). Since
> > > > we
> > > > aim
> > > > for compatibility with EFI only, and not with MS-DOS or MS-
> > > > Windows,
> > > > we
> > > > can use the remaining space in the MS-DOS header however we want.
> > > >
> > > > Let's set the generic magic number for x86 images as well:
> > > > existing
> > > > bootloaders already have their own methods to identify x86 Linux
> > > > images
> > > > that can be booted in a non-EFI manner, and having the magic
> > > > number
> > > > in
> > > > place there will ease any future transitions in loader
> > > > implementations
> > > > to merge the x86 and non-x86 EFI boot paths.
> > > >
> > > > Note that 32-bit ARM already uses the same location in the header
> > > > for
> > > > a
> > > > different purpose, but the ARM support is already widely
> > > > implemented
> > > > and
> > > > the EFI zboot decompressor is not available on ARM anyway, so we
> > > > just
> > > > disregard it here.
> > > >
> > > > Cc: Huacai Chen 
> > > > Cc: Atish Patra 
> > > > Cc: Heinrich Schuchardt 
> > > > Cc: Daniel Kiper 
> > > > Cc: Leif Lindholm 
> > > > Signed-off-by: Ard Biesheuvel 
> > > > ---
> > > >  arch/loongarch/kernel/head.S| 3 ++-
> > > >  arch/x86/boot/header.S  | 3 ++-
> > > >  drivers/firmware/efi/libstub/zboot-header.S | 3 ++-
> > > >  include/linux/pe.h  | 7 +++
> > > >  4 files changed, 13 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git a/arch/loongarch/kernel/head.S
> > > > b/arch/loongarch/kernel/head.S
> > > > index 84970e2666588963..caa74439700eee93 100644
> > > > --- a/arch/loongarch/kernel/head.S
> > > > +++ b/arch/loongarch/kernel/head.S
> > > > @@ -25,7 +25,8 @@ _head:
> > > > .dword  kernel_entry/* Kernel entry point */
> > > > .dword  _end - _text/* Kern

Re: [PATCH v2 2/2] efi: Put Linux specific magic number in the DOS header

2022-12-07 Thread Ard Biesheuvel
On Wed, 7 Dec 2022 at 08:51, Xiaotian Wu  wrote:
>
> 在 2022-11-29星期二的 18:56 +0100,Ard Biesheuvel写道:
> > GRUB currently relies on the magic number in the image header of ARM
> > and
> > arm64 EFI kernel images to decide whether or not the image in
> > question
> > is a bootable kernel.
> >
> > However, the purpose of the magic number is to identify the image as
> > one
> > that implements the bare metal boot protocol, and so GRUB, which only
> > does EFI boot, can only boot images that could potentially be booted
> > in
> > a non-EFI manner as well.
> >
> > This is problematic for the new zboot decompressor image format, as
> > it
> > can only boot in EFI mode, and must therefore not use the bare metal
> > boot magic number in its header.
> >
> > For this reason, the strict magic number was dropped from GRUB, to
> > permit essentially any kind of EFI executable to be booted via the
> > 'linux' command, blurring the line between the linux loader and the
> > chainloader.
> >
> > So let's use the same field in the DOS header that RISC-V and arm64
> > already use for their 'bare metal' magic numbers to store a 'generic
> > Linux kernel' magic number, which can be used to identify bootable
> > kernel images in PE format which don't necessarily implement a bare
> > metal boot protocol in the same binary. Note that, in the context of
> > EFI, the MSDOS header is only described in terms of the fields that
> > it
> > shares with the hybrid PE/COFF image format, (i.e., the magic number
> > at
> > offset #0 and the PE header offset at byte offset #0x3c). Since we
> > aim
> > for compatibility with EFI only, and not with MS-DOS or MS-Windows,
> > we
> > can use the remaining space in the MS-DOS header however we want.
> >
> > Let's set the generic magic number for x86 images as well: existing
> > bootloaders already have their own methods to identify x86 Linux
> > images
> > that can be booted in a non-EFI manner, and having the magic number
> > in
> > place there will ease any future transitions in loader
> > implementations
> > to merge the x86 and non-x86 EFI boot paths.
> >
> > Note that 32-bit ARM already uses the same location in the header for
> > a
> > different purpose, but the ARM support is already widely implemented
> > and
> > the EFI zboot decompressor is not available on ARM anyway, so we just
> > disregard it here.
> >
> > Cc: Huacai Chen 
> > Cc: Atish Patra 
> > Cc: Heinrich Schuchardt 
> > Cc: Daniel Kiper 
> > Cc: Leif Lindholm 
> > Signed-off-by: Ard Biesheuvel 
> > ---
> >  arch/loongarch/kernel/head.S| 3 ++-
> >  arch/x86/boot/header.S  | 3 ++-
> >  drivers/firmware/efi/libstub/zboot-header.S | 3 ++-
> >  include/linux/pe.h  | 7 +++
> >  4 files changed, 13 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/loongarch/kernel/head.S
> > b/arch/loongarch/kernel/head.S
> > index 84970e2666588963..caa74439700eee93 100644
> > --- a/arch/loongarch/kernel/head.S
> > +++ b/arch/loongarch/kernel/head.S
> > @@ -25,7 +25,8 @@ _head:
> > .dword  kernel_entry/* Kernel entry point */
> > .dword  _end - _text/* Kernel image effective
> > size */
> > .quad   0   /* Kernel image load offset
> > from start of RAM */
> > -   .org0x3c/* 0x20 ~ 0x3b reserved */
> > +   .org0x38/* 0x20 ~ 0x38 reserved */
> > +   .long   LINUX_PE_MAGIC
> > .long   pe_header - _head   /* Offset to the PE header */
> >
> >  pe_header:
> > diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
> > index f912d777013052ea..be8f78a7ee325475 100644
> > --- a/arch/x86/boot/header.S
> > +++ b/arch/x86/boot/header.S
> > @@ -80,10 +80,11 @@ bs_die:
> > ljmp$0xf000,$0xfff0
> >
> >  #ifdef CONFIG_EFI_STUB
> > -   .org0x3c
> > +   .org0x38
> > #
> > # Offset to the PE header.
> > #
> > +   .long   LINUX_PE_MAGIC
> > .long   pe_header
> >  #endif /* CONFIG_EFI_STUB */
> >
> > diff --git a/drivers/firmware/efi/libstub/zboot-header.S
> > b/drivers/firmware/efi/libstub/zboot-header.S
> > index bc2d7750d7f14174..ec4525d40e0cf6d6 100644
> > --- a/drivers/firmware/efi/libstub/zboot-header.S
> > +++ b/drivers/firmware/efi/libstub/zboot-heade

Re: [PATCH v2 2/2] efi: Put Linux specific magic number in the DOS header

2022-12-01 Thread Ard Biesheuvel
On Thu, 1 Dec 2022 at 15:30, Daniel Kiper  wrote:
>
> On Tue, Nov 29, 2022 at 06:56:16PM +0100, Ard Biesheuvel wrote:
> > GRUB currently relies on the magic number in the image header of ARM and
> > arm64 EFI kernel images to decide whether or not the image in question
> > is a bootable kernel.
> >
> > However, the purpose of the magic number is to identify the image as one
> > that implements the bare metal boot protocol, and so GRUB, which only
> > does EFI boot, can only boot images that could potentially be booted in
> > a non-EFI manner as well.
> >
> > This is problematic for the new zboot decompressor image format, as it
> > can only boot in EFI mode, and must therefore not use the bare metal
> > boot magic number in its header.
> >
> > For this reason, the strict magic number was dropped from GRUB, to
> > permit essentially any kind of EFI executable to be booted via the
> > 'linux' command, blurring the line between the linux loader and the
> > chainloader.
> >
> > So let's use the same field in the DOS header that RISC-V and arm64
> > already use for their 'bare metal' magic numbers to store a 'generic
> > Linux kernel' magic number, which can be used to identify bootable
> > kernel images in PE format which don't necessarily implement a bare
> > metal boot protocol in the same binary. Note that, in the context of
> > EFI, the MSDOS header is only described in terms of the fields that it
>
> s/MSDOS/MS-DOS/ to be consistent with other places in the patch...
>
> > shares with the hybrid PE/COFF image format, (i.e., the magic number at
> > offset #0 and the PE header offset at byte offset #0x3c). Since we aim
>
> s/the magic number at offset #0/MS-DOS EXE magic number at offset #0/?
>
> "the magic number at offset #0" itself is confusing in the context of
> number of "magic number" phrases in the patch... :-)
>
> > for compatibility with EFI only, and not with MS-DOS or MS-Windows, we
> > can use the remaining space in the MS-DOS header however we want.
> >
> > Let's set the generic magic number for x86 images as well: existing
> > bootloaders already have their own methods to identify x86 Linux images
> > that can be booted in a non-EFI manner, and having the magic number in
> > place there will ease any future transitions in loader implementations
> > to merge the x86 and non-x86 EFI boot paths.
> >
> > Note that 32-bit ARM already uses the same location in the header for a
> > different purpose, but the ARM support is already widely implemented and
> > the EFI zboot decompressor is not available on ARM anyway, so we just
> > disregard it here.
> >
> > Cc: Huacai Chen 
> > Cc: Atish Patra 
> > Cc: Heinrich Schuchardt 
> > Cc: Daniel Kiper 
> > Cc: Leif Lindholm 
> > Signed-off-by: Ard Biesheuvel 
> > ---
> >  arch/loongarch/kernel/head.S| 3 ++-
> >  arch/x86/boot/header.S  | 3 ++-
> >  drivers/firmware/efi/libstub/zboot-header.S | 3 ++-
> >  include/linux/pe.h  | 7 +++
> >  4 files changed, 13 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
> > index 84970e2666588963..caa74439700eee93 100644
> > --- a/arch/loongarch/kernel/head.S
> > +++ b/arch/loongarch/kernel/head.S
> > @@ -25,7 +25,8 @@ _head:
> >   .dword  kernel_entry/* Kernel entry point */
> >   .dword  _end - _text/* Kernel image effective size */
> >   .quad   0   /* Kernel image load offset from 
> > start of RAM */
> > - .org0x3c/* 0x20 ~ 0x3b reserved */
> > + .org0x38/* 0x20 ~ 0x38 reserved */
> > + .long   LINUX_PE_MAGIC
> >   .long   pe_header - _head   /* Offset to the PE header */
> >
> >  pe_header:
> > diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
> > index f912d777013052ea..be8f78a7ee325475 100644
> > --- a/arch/x86/boot/header.S
> > +++ b/arch/x86/boot/header.S
> > @@ -80,10 +80,11 @@ bs_die:
> >   ljmp$0xf000,$0xfff0
> >
> >  #ifdef CONFIG_EFI_STUB
> > - .org0x3c
> > + .org0x38
> >   #
> >   # Offset to the PE header.
> >   #
> > + .long   LINUX_PE_MAGIC
> >   .long   pe_header
> >  #endif /* CONFIG_EFI_STUB */
> >
> > diff --git a/drivers/firmware/efi/libstub/zboot-header.S 
> > b/drivers/firmware/efi/libstub/zboot-header.S
> > index bc2d7750d7f1417

[PATCH v2 2/2] efi: Put Linux specific magic number in the DOS header

2022-11-29 Thread Ard Biesheuvel
GRUB currently relies on the magic number in the image header of ARM and
arm64 EFI kernel images to decide whether or not the image in question
is a bootable kernel.

However, the purpose of the magic number is to identify the image as one
that implements the bare metal boot protocol, and so GRUB, which only
does EFI boot, can only boot images that could potentially be booted in
a non-EFI manner as well.

This is problematic for the new zboot decompressor image format, as it
can only boot in EFI mode, and must therefore not use the bare metal
boot magic number in its header.

For this reason, the strict magic number was dropped from GRUB, to
permit essentially any kind of EFI executable to be booted via the
'linux' command, blurring the line between the linux loader and the
chainloader.

So let's use the same field in the DOS header that RISC-V and arm64
already use for their 'bare metal' magic numbers to store a 'generic
Linux kernel' magic number, which can be used to identify bootable
kernel images in PE format which don't necessarily implement a bare
metal boot protocol in the same binary. Note that, in the context of
EFI, the MSDOS header is only described in terms of the fields that it
shares with the hybrid PE/COFF image format, (i.e., the magic number at
offset #0 and the PE header offset at byte offset #0x3c). Since we aim
for compatibility with EFI only, and not with MS-DOS or MS-Windows, we
can use the remaining space in the MS-DOS header however we want.

Let's set the generic magic number for x86 images as well: existing
bootloaders already have their own methods to identify x86 Linux images
that can be booted in a non-EFI manner, and having the magic number in
place there will ease any future transitions in loader implementations
to merge the x86 and non-x86 EFI boot paths.

Note that 32-bit ARM already uses the same location in the header for a
different purpose, but the ARM support is already widely implemented and
the EFI zboot decompressor is not available on ARM anyway, so we just
disregard it here.

Cc: Huacai Chen 
Cc: Atish Patra 
Cc: Heinrich Schuchardt 
Cc: Daniel Kiper 
Cc: Leif Lindholm 
Signed-off-by: Ard Biesheuvel 
---
 arch/loongarch/kernel/head.S| 3 ++-
 arch/x86/boot/header.S  | 3 ++-
 drivers/firmware/efi/libstub/zboot-header.S | 3 ++-
 include/linux/pe.h  | 7 +++
 4 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index 84970e2666588963..caa74439700eee93 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -25,7 +25,8 @@ _head:
.dword  kernel_entry/* Kernel entry point */
.dword  _end - _text/* Kernel image effective size */
.quad   0   /* Kernel image load offset from start 
of RAM */
-   .org0x3c/* 0x20 ~ 0x3b reserved */
+   .org0x38/* 0x20 ~ 0x38 reserved */
+   .long   LINUX_PE_MAGIC
.long   pe_header - _head   /* Offset to the PE header */
 
 pe_header:
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index f912d777013052ea..be8f78a7ee325475 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -80,10 +80,11 @@ bs_die:
ljmp$0xf000,$0xfff0
 
 #ifdef CONFIG_EFI_STUB
-   .org0x3c
+   .org0x38
#
# Offset to the PE header.
#
+   .long   LINUX_PE_MAGIC
.long   pe_header
 #endif /* CONFIG_EFI_STUB */
 
diff --git a/drivers/firmware/efi/libstub/zboot-header.S 
b/drivers/firmware/efi/libstub/zboot-header.S
index bc2d7750d7f14174..ec4525d40e0cf6d6 100644
--- a/drivers/firmware/efi/libstub/zboot-header.S
+++ b/drivers/firmware/efi/libstub/zboot-header.S
@@ -20,7 +20,8 @@ __efistub_efi_zboot_header:
.long   __efistub__gzdata_size - 12 // payload size
.long   0, 0// reserved
.asciz  COMP_TYPE   // compression 
type
-   .org.Ldoshdr + 0x3c
+   .org.Ldoshdr + 0x38
+   .long   LINUX_PE_MAGIC
.long   .Lpehdr - .Ldoshdr  // PE header 
offset
 
 .Lpehdr:
diff --git a/include/linux/pe.h b/include/linux/pe.h
index 056a1762de904fc1..1db4c944efd78f51 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -31,6 +31,13 @@
 #define LINUX_EFISTUB_MAJOR_VERSION0x1
 #define LINUX_EFISTUB_MINOR_VERSION0x1
 
+/*
+ * LINUX_PE_MAGIC appears at offset 0x38 into the MSDOS header of EFI bootable
+ * Linux kernel images that target the architecture as specified by the PE/COFF
+ * header machine type field.
+ */
+#define LINUX_PE_MAGIC 0x818223cd
+
 #define MZ_MAGIC   0x5a4d  /* "MZ" */
 
 #define PE_MAGIC   0x4550  /* "PE\0\0

[PATCH v2 0/2] efi: Add generic magic number in header

2022-11-29 Thread Ard Biesheuvel
This is a minimal respin of the RFC patch I sent out a few week ago. No
changes were applied except the /0x30/0x38 typo fix and some additional
wording in the commit log. I also added a patch to make the command line
initrd loader always built-in.

The purpose of all of this is to create *and document* a common baseline
for EFI booting of Linux. (I know I promised some documentation myself,
but I simply don't have time for that, so if anyone feels so inclined,
please go ahead).

The idea is that EFI images with the LINUX_PE_MAGIC number are
guaranteed to support:
- initrd loading via LoadFile2
- initrd loading via the command line
- (on x86) mixed mode boot via the .compat entry point
- other things I missed?

Architectures such as arm64 and RISC-V already have their own magic
numbers, in which case the PE/COFF major/minor image version should be
inspected, where 1.1 corresponds with the set described above.

If other architectures want to create hybrid images as well, it would be
better to use a different offset to store the magic number, so that the
generic EFI one can be carried as well. The reason for deviating from
this for arm64 and RISC-V is the simple fact that existing images
already exist, so for those architectures, we have to consider both
anyway.

Cc: Huacai Chen 
Cc: Atish Patra 
Cc: Heinrich Schuchardt 
Cc: Daniel Kiper 
Cc: Leif Lindholm 

Ard Biesheuvel (2):
  efi: libstub: Always enable initrd command line loader and bump
version
  efi: Put Linux specific magic number in the DOS header

 arch/loongarch/kernel/head.S   |  3 ++-
 arch/x86/boot/header.S |  3 ++-
 drivers/firmware/efi/Kconfig   | 15 ---
 drivers/firmware/efi/libstub/efi-stub-helper.c |  3 +--
 drivers/firmware/efi/libstub/zboot-header.S|  3 ++-
 include/linux/pe.h |  9 -
 6 files changed, 15 insertions(+), 21 deletions(-)

-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v2 1/2] efi: libstub: Always enable initrd command line loader and bump version

2022-11-29 Thread Ard Biesheuvel
In preparation for setting a cross-architecture baseline for EFI boot
support, remove the Kconfig option that permits the command line initrd
loader to be disabled. Also, bump the minor version so that any image
built with the new version can be identified as supporting this.

Signed-off-by: Ard Biesheuvel 
---
 drivers/firmware/efi/Kconfig   | 15 ---
 drivers/firmware/efi/libstub/efi-stub-helper.c |  3 +--
 include/linux/pe.h |  2 +-
 3 files changed, 2 insertions(+), 18 deletions(-)

diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 08ed88e49ea307b0..043ca31c114ebf2a 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -106,21 +106,6 @@ config EFI_ARMSTUB_DTB_LOADER
  functionality for bootloaders that do not have such support
  this option is necessary.
 
-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
-   help
- Select this config option to add support for the initrd= command
- line parameter, allowing an initrd to be loaded into memory that
- resides on a file system backed by an implementation of
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL.
-
- This method has been superseded by the simpler LoadFile2 based
- initrd loading method, but the initrd= loader is retained as it
- can be used from the UEFI Shell or other generic loaders that
- don't implement the Linux specific LoadFile2 method.
-
 config EFI_BOOTLOADER_CONTROL
tristate "EFI Bootloader Control"
select UCS2_STRING
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c 
b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 739454d8063af8b1..f5a4bdacac642846 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -538,8 +538,7 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t 
*image,
 unsigned long soft_limit,
 unsigned long hard_limit)
 {
-   if (!IS_ENABLED(CONFIG_EFI_GENERIC_STUB_INITRD_CMDLINE_LOADER) ||
-   (IS_ENABLED(CONFIG_X86) && image == NULL))
+   if (image == NULL)
return EFI_UNSUPPORTED;
 
return handle_cmdline_files(image, L"initrd=", sizeof(L"initrd=") - 2,
diff --git a/include/linux/pe.h b/include/linux/pe.h
index 1d3836ef9d92dcd8..056a1762de904fc1 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -29,7 +29,7 @@
  * handover_offset and xloadflags fields in the bootparams structure.
  */
 #define LINUX_EFISTUB_MAJOR_VERSION0x1
-#define LINUX_EFISTUB_MINOR_VERSION0x0
+#define LINUX_EFISTUB_MINOR_VERSION0x1
 
 #define MZ_MAGIC   0x5a4d  /* "MZ" */
 
-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [RFC PATCH] efi: Put Linux specific magic number in the DOS header

2022-11-10 Thread Ard Biesheuvel
On Thu, 10 Nov 2022 at 00:27, Daniel Kiper  wrote:
>
> On Wed, Nov 09, 2022 at 04:01:27PM +0100, Heinrich Schuchardt wrote:
> > On 11/9/22 15:16, Ard Biesheuvel wrote:
> > > GRUB currently relies on the magic number in the image header of ARM and
> > > arm64 EFI kernel images to decide whether or not the image in question
> > > is a bootable kernel.
> > >
> > > However, the purpose of the magic number is to identify the image as one
> > > that implements the bare metal boot protocol, and so GRUB, which only
> > > does EFI boot, can only boot images that could potentially be booted in
> > > a non-EFI manner as well.
> > >
> > > This is problematic for the new zboot decompressor image format, as it
> > > can only boot in EFI mode, and must therefore not use the bare metal
> > > boot magic number in its header.
> > >
> > > For this reason, the strict magic number was dropped from GRUB, to
> > > permit essentially any kind of EFI executable to be booted via the
> > > 'linux' command, blurring the line between the linux loader and the
> > > chainloader.
> > >
> > > So let's use the same field in the DOS header that RISC-V and arm64
> > > already use for their 'bare metal' magic numbers to store a 'generic
> > > Linux kernel' magic number, which can be used to identify bootable
> > > kernel images in PE format which don't necessarily implement a bare
> > > metal boot protocol in the same binary.
> > >
> > > Let's set the generic magic number for x86 images as well: existing
> > > bootloaders already have their own methods to identify x86 Linux images
> > > that can be booted in a non-EFI manner, and having the magic number in
> > > place there will ease any future transitions in loader implementations
> > > to merge the x86 and non-x86 EFI boot paths.
> > >
> > > Note that 32-bit ARM already uses the same location in the header for a
> > > different purpose, but the ARM support is already widely implemented and
> > > the EFI zboot decompressor is not available on ARM anyway, so we just
> > > disregard it here.
> > >
> > > Cc: Huacai Chen 
> > > Cc: Atish Patra 
> > > Cc: Heinrich Schuchardt 
> > > Cc: Daniel Kiper 
> > > Cc: Leif Lindholm 
> > > Signed-off-by: Ard Biesheuvel 
> > > ---
> > > The idea is that, with this in place, the existing arm64 support in GRUB
> > > can be made generic, with the arm64 variant of the arch image header
> > > typedef being made generic as well.
> > >
> > > Any code that attempts to identify EFI images as kernel images should
> > > check for the arm64, RISC-V and generic values, and if the latter, look
> > > at the PE machine type if it wants to know the architecture.
> > >
> > >   arch/loongarch/kernel/head.S| 3 ++-
> > >   arch/x86/boot/header.S  | 3 ++-
> > >   drivers/firmware/efi/libstub/zboot-header.S | 3 ++-
> > >   include/linux/pe.h  | 7 +++
> > >   4 files changed, 13 insertions(+), 3 deletions(-)
> >
> > We need files in Documentation/ that describes the meaning and value of the
> > field per architecture.
> >
> > We already have:
> >
> > riscv: Documentation/riscv/boot-image-header.rst
> > arm64: Documentation/arm64/booting.rst
>
> I think we should add something to the Documentation/x86/boot.rst too.
> Probably in or after "EFI Handover Protocol (deprecated)" section.
>

Point taken. I'll add some mention of this to the appropriate places
under Documentation/

> > But other UEFI architectures are missing.
> >
> > Otherwise I am fine with the change.
> >
> > Best regards
> >
> > Heinrich
> >
> > >
> > > diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
> > > index 97425779ce9f3499..e1deea93aaafa069 100644
> > > --- a/arch/loongarch/kernel/head.S
> > > +++ b/arch/loongarch/kernel/head.S
> > > @@ -25,7 +25,8 @@ _head:
> > > .dword  kernel_entry/* Kernel entry point */
> > > .dword  _end - _text/* Kernel image effective size */
> > > .quad   0   /* Kernel image load offset from 
> > > start of RAM */
> > > -   .org0x3c/* 0x20 ~ 0x3b reserved */
> > > +   .org0x38/* 0x20 ~ 0x38 reserved */
> > > +   .long   LINUX_PE_MAGIC
> > > .long   pe_hea

[RFC PATCH] efi: Put Linux specific magic number in the DOS header

2022-11-09 Thread Ard Biesheuvel
GRUB currently relies on the magic number in the image header of ARM and
arm64 EFI kernel images to decide whether or not the image in question
is a bootable kernel.

However, the purpose of the magic number is to identify the image as one
that implements the bare metal boot protocol, and so GRUB, which only
does EFI boot, can only boot images that could potentially be booted in
a non-EFI manner as well.

This is problematic for the new zboot decompressor image format, as it
can only boot in EFI mode, and must therefore not use the bare metal
boot magic number in its header.

For this reason, the strict magic number was dropped from GRUB, to
permit essentially any kind of EFI executable to be booted via the
'linux' command, blurring the line between the linux loader and the
chainloader.

So let's use the same field in the DOS header that RISC-V and arm64
already use for their 'bare metal' magic numbers to store a 'generic
Linux kernel' magic number, which can be used to identify bootable
kernel images in PE format which don't necessarily implement a bare
metal boot protocol in the same binary.

Let's set the generic magic number for x86 images as well: existing
bootloaders already have their own methods to identify x86 Linux images
that can be booted in a non-EFI manner, and having the magic number in
place there will ease any future transitions in loader implementations
to merge the x86 and non-x86 EFI boot paths.

Note that 32-bit ARM already uses the same location in the header for a
different purpose, but the ARM support is already widely implemented and
the EFI zboot decompressor is not available on ARM anyway, so we just
disregard it here.

Cc: Huacai Chen  
Cc: Atish Patra 
Cc: Heinrich Schuchardt 
Cc: Daniel Kiper 
Cc: Leif Lindholm 
Signed-off-by: Ard Biesheuvel 
---
The idea is that, with this in place, the existing arm64 support in GRUB
can be made generic, with the arm64 variant of the arch image header
typedef being made generic as well.

Any code that attempts to identify EFI images as kernel images should
check for the arm64, RISC-V and generic values, and if the latter, look
at the PE machine type if it wants to know the architecture.

 arch/loongarch/kernel/head.S| 3 ++-
 arch/x86/boot/header.S  | 3 ++-
 drivers/firmware/efi/libstub/zboot-header.S | 3 ++-
 include/linux/pe.h  | 7 +++
 4 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/loongarch/kernel/head.S b/arch/loongarch/kernel/head.S
index 97425779ce9f3499..e1deea93aaafa069 100644
--- a/arch/loongarch/kernel/head.S
+++ b/arch/loongarch/kernel/head.S
@@ -25,7 +25,8 @@ _head:
.dword  kernel_entry/* Kernel entry point */
.dword  _end - _text/* Kernel image effective size */
.quad   0   /* Kernel image load offset from start 
of RAM */
-   .org0x3c/* 0x20 ~ 0x3b reserved */
+   .org0x38/* 0x20 ~ 0x38 reserved */
+   .long   LINUX_PE_MAGIC
.long   pe_header - _head   /* Offset to the PE header */
 
 pe_header:
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index d31982509654dcb1..9338c68e7413d6e6 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -80,10 +80,11 @@ bs_die:
ljmp$0xf000,$0xfff0
 
 #ifdef CONFIG_EFI_STUB
-   .org0x3c
+   .org0x38
#
# Offset to the PE header.
#
+   .long   LINUX_PE_MAGIC
.long   pe_header
 #endif /* CONFIG_EFI_STUB */
 
diff --git a/drivers/firmware/efi/libstub/zboot-header.S 
b/drivers/firmware/efi/libstub/zboot-header.S
index 9e6fe061ab07a008..97c2637337d79913 100644
--- a/drivers/firmware/efi/libstub/zboot-header.S
+++ b/drivers/firmware/efi/libstub/zboot-header.S
@@ -20,7 +20,8 @@ __efistub_efi_zboot_header:
.long   __efistub__gzdata_size - ZBOOT_SIZE_LEN // payload size
.long   0, 0// reserved
.asciz  COMP_TYPE   // compression 
type
-   .org.Ldoshdr + 0x3c
+   .org.Ldoshdr + 0x38
+   .long   LINUX_PE_MAGIC
.long   .Lpehdr - .Ldoshdr  // PE header 
offset
 
 .Lpehdr:
diff --git a/include/linux/pe.h b/include/linux/pe.h
index 1d3836ef9d92dcd8..fa176c24167c301c 100644
--- a/include/linux/pe.h
+++ b/include/linux/pe.h
@@ -31,6 +31,13 @@
 #define LINUX_EFISTUB_MAJOR_VERSION0x1
 #define LINUX_EFISTUB_MINOR_VERSION0x0
 
+/*
+ * LINUX_PE_MAGIC appears at offset 0x30 into the MSDOS header of EFI bootable
+ * Linux kernel images that target the architecture as specified by the PE/COFF
+ * header machine type field.
+ */
+#define LINUX_PE_MAGIC 0x818223cd
+
 #define MZ_MAGIC   0x5a4d  /* "MZ" */
 
 #define PE_MAGIC   0x4550  /* "PE\0\0

Re: [v6 PATCH 2/3] RISC-V: Update image header

2022-11-09 Thread Ard Biesheuvel
On Wed, 9 Nov 2022 at 13:50, Ard Biesheuvel  wrote:
>
> On Wed, 9 Nov 2022 at 13:38, Leif Lindholm  wrote:
> >
> > On Wed, Nov 09, 2022 at 13:10:29 +0100, Ard Biesheuvel wrote:
> > > > > > The drawback to that is that not all EFI executables are destined 
> > > > > > for
> > > > > > the Linux loader. So while trying to boot them using the linux 
> > > > > > loader
> > > > > > is definitely user error, that change removed a potentially useful
> > > > > > user-visible error message.
> > > > >
> > > > > The new EFI zboot images don't have the arch specific magic numbers
> > > > > either, and those are Linux images too.
> > > > >
> > > > > So pretending that Linux EFI PE/COFF images are always hybrid images
> > > > > that could also boot in bare metal mode is no longer appropriate in
> > > > > any case,
> > > >
> > > > Is that true for arm32 as well?
> > >
> > > Is what true?
> >
> > That arm32 linux images containing an EFI stub do not always contain
> > the magic field?
> >
>
> No, but I'm not sure how that matters. We will have a generic EFI
> loader for arm64, ARM and RISC-V, and shortly also for LoongArch.
> Those images may not have magic numbers because they do not support
> bare metal boot only EFI boot.
>
> The fact that none of the images in the latter category happen to be
> arm32 seems hardly relevant to me.
>
> > > > Certainly for arm64, *a* change was needed.
> > >
> > > RISC-V, arm64 and LoongArch now all use the same compressed format,
> > > which can decompress itself when executed as a EFI binary, or be
> > > decompressed by a non-EFI loader using the metadata in the header.
> > >
> > > So it might make sense for GRUB to be able to identify this image type
> > > specifically as well, but only if that information is useful in some
> > > way.
> >
> > In order to be able to indicate to a user, who may *not* be a kernel
> > developer, or even be aware of the concept of different types of
> > kernel images, that they picked the wrong image some other way than
> > the boot failing.
> >
>
> OK, so that information *is* useful in some way. Fair enough.
>
> > > > > and we should really just deal with the fact that the linux
> > > > > loader and the chainloader are mostly the same thing on EFI-only
> > > > > architectures.
> > > >
> > > > Architectures that only support *linux* booting via EFI.
> > > > Which arm32 isn't.
> > >
> > > I am not following you here.
> > >
> > > > *Dealing* with that would mean merging the linux- and chain-
> > > > loaders. Not dropping sanity checks and keeping both.
> > >
> > > The sanity check had to be dropped because not all EFI Linux images
> > > carry the magic number.
> >
> > No, the sanity check had to be *changed* because not all EFI Linux
> > images carry the magic number.
> >
> > If there really is no way to tell the EFI xboot kernel from any other
> > EFI executable for the same architecture, then:
> > - that's going to be reasonably annoying also from within the OS when
> >   using the file command.
> > - we have lost the ability to warn users they (or their cross-upgrade)
> >   picked the wrong file.
> >
>
> There is. The zboot image header clearly spells out 'zimg', the
> compression type and the start and size of the compressed payload
> inside the EFI binary.
>
> > > Whether or not the chainloader and the linux loader are the same thing
> > > is a different matter.
> >
> > You brought that point up, not me.
> > I agree the chainloader should not go looking for further magic.
> >
>
> Ok, at least we agree on something :-)
>
> > > > The change may have been the appropriate compromise, but it wasn't
> > > > treated as one.
> > >
> > > It is not a compromise. GRUB should not reason about whether or not a
> > > Linux EFI image is also bootable via the bare metal boot protocol
> > > which it does not implement.
> >
> > GRUB should, where reasonable, provide helpful messages to end users.
> >
> > That means a loader for a specific operating system should do basic
> > sanity checks to verify that the image is for that operating system
> > where at all possible. Otherwise, it should not be using an
> > os-specific loader.

Re: [v6 PATCH 2/3] RISC-V: Update image header

2022-11-09 Thread Ard Biesheuvel
On Wed, 9 Nov 2022 at 13:38, Leif Lindholm  wrote:
>
> On Wed, Nov 09, 2022 at 13:10:29 +0100, Ard Biesheuvel wrote:
> > > > > The drawback to that is that not all EFI executables are destined for
> > > > > the Linux loader. So while trying to boot them using the linux loader
> > > > > is definitely user error, that change removed a potentially useful
> > > > > user-visible error message.
> > > >
> > > > The new EFI zboot images don't have the arch specific magic numbers
> > > > either, and those are Linux images too.
> > > >
> > > > So pretending that Linux EFI PE/COFF images are always hybrid images
> > > > that could also boot in bare metal mode is no longer appropriate in
> > > > any case,
> > >
> > > Is that true for arm32 as well?
> >
> > Is what true?
>
> That arm32 linux images containing an EFI stub do not always contain
> the magic field?
>

No, but I'm not sure how that matters. We will have a generic EFI
loader for arm64, ARM and RISC-V, and shortly also for LoongArch.
Those images may not have magic numbers because they do not support
bare metal boot only EFI boot.

The fact that none of the images in the latter category happen to be
arm32 seems hardly relevant to me.

> > > Certainly for arm64, *a* change was needed.
> >
> > RISC-V, arm64 and LoongArch now all use the same compressed format,
> > which can decompress itself when executed as a EFI binary, or be
> > decompressed by a non-EFI loader using the metadata in the header.
> >
> > So it might make sense for GRUB to be able to identify this image type
> > specifically as well, but only if that information is useful in some
> > way.
>
> In order to be able to indicate to a user, who may *not* be a kernel
> developer, or even be aware of the concept of different types of
> kernel images, that they picked the wrong image some other way than
> the boot failing.
>

OK, so that information *is* useful in some way. Fair enough.

> > > > and we should really just deal with the fact that the linux
> > > > loader and the chainloader are mostly the same thing on EFI-only
> > > > architectures.
> > >
> > > Architectures that only support *linux* booting via EFI.
> > > Which arm32 isn't.
> >
> > I am not following you here.
> >
> > > *Dealing* with that would mean merging the linux- and chain-
> > > loaders. Not dropping sanity checks and keeping both.
> >
> > The sanity check had to be dropped because not all EFI Linux images
> > carry the magic number.
>
> No, the sanity check had to be *changed* because not all EFI Linux
> images carry the magic number.
>
> If there really is no way to tell the EFI xboot kernel from any other
> EFI executable for the same architecture, then:
> - that's going to be reasonably annoying also from within the OS when
>   using the file command.
> - we have lost the ability to warn users they (or their cross-upgrade)
>   picked the wrong file.
>

There is. The zboot image header clearly spells out 'zimg', the
compression type and the start and size of the compressed payload
inside the EFI binary.

> > Whether or not the chainloader and the linux loader are the same thing
> > is a different matter.
>
> You brought that point up, not me.
> I agree the chainloader should not go looking for further magic.
>

Ok, at least we agree on something :-)

> > > The change may have been the appropriate compromise, but it wasn't
> > > treated as one.
> >
> > It is not a compromise. GRUB should not reason about whether or not a
> > Linux EFI image is also bootable via the bare metal boot protocol
> > which it does not implement.
>
> GRUB should, where reasonable, provide helpful messages to end users.
>
> That means a loader for a specific operating system should do basic
> sanity checks to verify that the image is for that operating system
> where at all possible. Otherwise, it should not be using an
> os-specific loader.
>
> Of course, if the operating system decides that's an antifeature, it
> can always choose to not provide identifiable images.
>

In that case, we should add something to the PE headers of Linux
kernels built for any architecture to identify it as such. And we
should add the same thing to the zboot images, so they are
identifiable both as a zboot image and as a linux kernel.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [v6 PATCH 2/3] RISC-V: Update image header

2022-11-09 Thread Ard Biesheuvel
On Wed, 9 Nov 2022 at 13:01, Leif Lindholm  wrote:
>
> On Wed, Nov 09, 2022 at 12:33:58 +0100, Ard Biesheuvel wrote:
> > > > Can we get rid of these header definitions entirely?
> > > >
> > > > The only GRUB code that seems to care about the fields that are not
> > > > defined in the PE/COFF spec is grub_cmd_file(), which currently parses
> > > > the magic field, but given that we only support EFI boot anyway, that
> > > > code should just parse the PE machine type instead.
> > >
> > > Right, so your patch from August dropped that check in the loader
> > > itself. I missed that one.
> > >
> > > The drawback to that is that not all EFI executables are destined for
> > > the Linux loader. So while trying to boot them using the linux loader
> > > is definitely user error, that change removed a potentially useful
> > > user-visible error message.
> >
> > The new EFI zboot images don't have the arch specific magic numbers
> > either, and those are Linux images too.
> >
> > So pretending that Linux EFI PE/COFF images are always hybrid images
> > that could also boot in bare metal mode is no longer appropriate in
> > any case,
>
> Is that true for arm32 as well?
>

Is what true?

> Certainly for arm64, *a* change was needed.
>

RISC-V, arm64 and LoongArch now all use the same compressed format,
which can decompress itself when executed as a EFI binary, or be
decompressed by a non-EFI loader using the metadata in the header.

So it might make sense for GRUB to be able to identify this image type
specifically as well, but only if that information is useful in some
way.

> > and we should really just deal with the fact that the linux
> > loader and the chainloader are mostly the same thing on EFI-only
> > architectures.
>
> Architectures that only support *linux* booting via EFI.
> Which arm32 isn't.
>

I am not following you here.

> *Dealing* with that would mean merging the linux- and chain-
> loaders. Not dropping sanity checks and keeping both.
>

The sanity check had to be dropped because not all EFI Linux images
carry the magic number.

Whether or not the chainloader and the linux loader are the same thing
is a different matter.

> The change may have been the appropriate compromise, but it wasn't
> treated as one.
>

It is not a compromise. GRUB should not reason about whether or not a
Linux EFI image is also bootable via the bare metal boot protocol
which it does not implement.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [v6 PATCH 2/3] RISC-V: Update image header

2022-11-09 Thread Ard Biesheuvel
On Wed, 9 Nov 2022 at 12:21, Leif Lindholm  wrote:
>
> On Tue, Nov 08, 2022 at 17:36:51 +0100, Ard Biesheuvel wrote:
> > > I can agree that hdr_offset makes more sense but
> > > Documentation/riscv/boot-image-header.rst names this member as res3.
> > > So, I would rename hdr_offset to res3 too. Or fix
> > > Documentation/riscv/boot-image-header.rst in the kernel. Or, least
> > > preferred, explain in the commit message why you do not rename this
> > > member and add to the comment that this member is named res3 in the
> > > documentation.
> >
> > Can we get rid of these header definitions entirely?
> >
> > The only GRUB code that seems to care about the fields that are not
> > defined in the PE/COFF spec is grub_cmd_file(), which currently parses
> > the magic field, but given that we only support EFI boot anyway, that
> > code should just parse the PE machine type instead.
>
> Right, so your patch from August dropped that check in the loader
> itself. I missed that one.
>
> The drawback to that is that not all EFI executables are destined for
> the Linux loader. So while trying to boot them using the linux loader
> is definitely user error, that change removed a potentially useful
> user-visible error message.
>

The new EFI zboot images don't have the arch specific magic numbers
either, and those are Linux images too.

So pretending that Linux EFI PE/COFF images are always hybrid images
that could also boot in bare metal mode is no longer appropriate in
any case, and we should really just deal with the fact that the linux
loader and the chainloader are mostly the same thing on EFI-only
architectures.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [v6 PATCH 2/3] RISC-V: Update image header

2022-11-09 Thread Ard Biesheuvel
On Wed, 9 Nov 2022 at 09:13, Atish Kumar Patra  wrote:
>
>
>
> On Tue, Nov 8, 2022 at 8:37 AM Ard Biesheuvel  wrote:
>>
>> On Tue, 8 Nov 2022 at 16:59, Daniel Kiper  wrote:
>> >
>> > On Fri, Nov 04, 2022 at 04:26:06PM -0700, Atish Patra wrote:
>> > > Update the RISC-V Linux kernel image headers as per the current header.
>> > >
>> > > Reference:
>> > > /Documentation/riscv/boot-image-header.rst
>> > >
>> > > 474efecb65dc: ("riscv: modify the Image header to improve compatibility 
>> > > with the ARM64 header")
>> >
>> > The latest commit which updates Documentation/riscv/boot-image-header.rst 
>> > is
>> > 1d5c17e47028 (RISC-V: Typo fixes in image header and documentation).
>> >
>> > > Acked-by: Heinrich Schuchardt 
>> > > Signed-off-by: Atish Patra 
>> >
>> > The order of these lines should be reversed...
>> >
>> > > ---
>> > >  include/grub/riscv32/linux.h | 19 ++-
>> > >  include/grub/riscv64/linux.h | 19 +++
>> > >  2 files changed, 21 insertions(+), 17 deletions(-)
>> > >
>> > > diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h
>> > > index 512b777c8a41..a884d4f4760c 100644
>> > > --- a/include/grub/riscv32/linux.h
>> > > +++ b/include/grub/riscv32/linux.h
>> > > @@ -19,21 +19,22 @@
>> > >  #ifndef GRUB_RISCV32_LINUX_HEADER
>> > >  #define GRUB_RISCV32_LINUX_HEADER 1
>> > >
>> > > -#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
>> > > -
>> > > -/* From linux/Documentation/riscv/booting.txt */
>> > > +/* From linux/Documentation/riscv/boot-image-header.rst */
>> > >  struct linux_riscv_kernel_header
>> > >  {
>> > >grub_uint32_t code0;   /* Executable code */
>> > >grub_uint32_t code1;   /* Executable code */
>> > > -  grub_uint64_t text_offset; /* Image load offset */
>> > > -  grub_uint64_t res0;/* reserved */
>> > > -  grub_uint64_t res1;/* reserved */
>> > > +  grub_uint64_t text_offset; /* Image load offset, little endian */
>> > > +  grub_uint64_t image_size;  /* Effective Image size, little endian */
>> > > +  grub_uint64_t flags;   /* kernel flags, little endian */
>> > > +  grub_uint32_t version; /* Version of this header */
>> > > +  grub_uint32_t res1;/* reserved */
>> > >grub_uint64_t res2;/* reserved */
>> > > -  grub_uint64_t res3;/* reserved */
>> > > -  grub_uint64_t res4;/* reserved */
>> > > -  grub_uint32_t magic;   /* Magic number, little endian, 
>> > > "RSCV" */
>> > > +  grub_uint64_t magic;   /* magic (RISC-V specifc, 
>> > > deprecated)*/
>> > > +  grub_uint32_t magic2;  /* Magic number 2 (to match the 
>> > > ARM64 'magic' field pos) */
>> > >grub_uint32_t hdr_offset;  /* Offset of PE/COFF header */
>> >
>> > I can agree that hdr_offset makes more sense but
>> > Documentation/riscv/boot-image-header.rst names this member as res3.
>> > So, I would rename hdr_offset to res3 too. Or fix
>> > Documentation/riscv/boot-image-header.rst in the kernel. Or, least
>> > preferred, explain in the commit message why you do not rename this
>> > member and add to the comment that this member is named res3 in the
>> > documentation.
>> >
>>
>> Can we get rid of these header definitions entirely?
>>
>> The only GRUB code that seems to care about the fields that are not
>> defined in the PE/COFF spec is grub_cmd_file(), which currently parses
>> the magic field, but given that we only support EFI boot anyway, that
>> code should just parse the PE machine type instead.
>
>
> If I understand you correctly, you are suggesting to remove the 
> linux_arm64_kernel_header/linux_riscv_kernel_header
> and just define a generic linux_arch_kernel_header which has pe_image_header 
> at the correct offset.
> grub_cmd_file() can just compare the machine type instead of the magic number 
> for the IS_ARM64_LINUX case.
> The other places using linux_arm64_kernel_header will just use the generic 
> structure to compute the section_alignment field from the PE header.
>

Exactly.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [v6 PATCH 2/3] RISC-V: Update image header

2022-11-08 Thread Ard Biesheuvel
On Tue, 8 Nov 2022 at 16:59, Daniel Kiper  wrote:
>
> On Fri, Nov 04, 2022 at 04:26:06PM -0700, Atish Patra wrote:
> > Update the RISC-V Linux kernel image headers as per the current header.
> >
> > Reference:
> > /Documentation/riscv/boot-image-header.rst
> >
> > 474efecb65dc: ("riscv: modify the Image header to improve compatibility 
> > with the ARM64 header")
>
> The latest commit which updates Documentation/riscv/boot-image-header.rst is
> 1d5c17e47028 (RISC-V: Typo fixes in image header and documentation).
>
> > Acked-by: Heinrich Schuchardt 
> > Signed-off-by: Atish Patra 
>
> The order of these lines should be reversed...
>
> > ---
> >  include/grub/riscv32/linux.h | 19 ++-
> >  include/grub/riscv64/linux.h | 19 +++
> >  2 files changed, 21 insertions(+), 17 deletions(-)
> >
> > diff --git a/include/grub/riscv32/linux.h b/include/grub/riscv32/linux.h
> > index 512b777c8a41..a884d4f4760c 100644
> > --- a/include/grub/riscv32/linux.h
> > +++ b/include/grub/riscv32/linux.h
> > @@ -19,21 +19,22 @@
> >  #ifndef GRUB_RISCV32_LINUX_HEADER
> >  #define GRUB_RISCV32_LINUX_HEADER 1
> >
> > -#define GRUB_LINUX_RISCV_MAGIC_SIGNATURE 0x52534356 /* 'RSCV' */
> > -
> > -/* From linux/Documentation/riscv/booting.txt */
> > +/* From linux/Documentation/riscv/boot-image-header.rst */
> >  struct linux_riscv_kernel_header
> >  {
> >grub_uint32_t code0;   /* Executable code */
> >grub_uint32_t code1;   /* Executable code */
> > -  grub_uint64_t text_offset; /* Image load offset */
> > -  grub_uint64_t res0;/* reserved */
> > -  grub_uint64_t res1;/* reserved */
> > +  grub_uint64_t text_offset; /* Image load offset, little endian */
> > +  grub_uint64_t image_size;  /* Effective Image size, little endian */
> > +  grub_uint64_t flags;   /* kernel flags, little endian */
> > +  grub_uint32_t version; /* Version of this header */
> > +  grub_uint32_t res1;/* reserved */
> >grub_uint64_t res2;/* reserved */
> > -  grub_uint64_t res3;/* reserved */
> > -  grub_uint64_t res4;/* reserved */
> > -  grub_uint32_t magic;   /* Magic number, little endian, 
> > "RSCV" */
> > +  grub_uint64_t magic;   /* magic (RISC-V specifc, 
> > deprecated)*/
> > +  grub_uint32_t magic2;  /* Magic number 2 (to match the ARM64 
> > 'magic' field pos) */
> >grub_uint32_t hdr_offset;  /* Offset of PE/COFF header */
>
> I can agree that hdr_offset makes more sense but
> Documentation/riscv/boot-image-header.rst names this member as res3.
> So, I would rename hdr_offset to res3 too. Or fix
> Documentation/riscv/boot-image-header.rst in the kernel. Or, least
> preferred, explain in the commit message why you do not rename this
> member and add to the comment that this member is named res3 in the
> documentation.
>

Can we get rid of these header definitions entirely?

The only GRUB code that seems to care about the fields that are not
defined in the PE/COFF spec is grub_cmd_file(), which currently parses
the magic field, but given that we only support EFI boot anyway, that
code should just parse the PE machine type instead.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v5 0/6] linux: implement LoadFile2 initrd loading

2022-10-21 Thread Ard Biesheuvel
On Fri, 21 Oct 2022 at 14:51, Daniel Kiper  wrote:
>
> On Tue, Oct 18, 2022 at 09:05:01PM +0200, Ard Biesheuvel wrote:
> > This implements the LoadFile2 initrd loading protocol, which is
> > essentially a callback interface into the bootloader to load the initrd
> > data into a caller provided buffer. This means the bootloader no longer
> > has to contain any policy regarding where to load the initrd (which
> > differs between architectures and kernel versions) and no longer has to
> > manipulate arch specific data structures such as DT or struct bootparams
> > to inform the OS where the initrd resides in memory. This is especially
> > relevant for the upcoming LoongArch support, which does not use either
> > DT or struct bootparams, and would have to rely on the initrd= command
> > line interface, which is deprecated and of limited utility [0].
> >
> > Sample output from booting a recent Linux/arm64 kernel:
> >
> >   grub> insmod part_msdos
> >   grub> linux (hd0,msdos1)/Image
> >   grub> initrd (hd0,msdos1)/initrd.img
> >   grub> boot
> >   EFI stub: Booting Linux Kernel...
> >   EFI stub: EFI_RNG_PROTOCOL unavailable
> >   EFI stub: Generating empty DTB
> >   EFI stub: Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path
> >   EFI stub: Exiting boot services...
> >   [0.00] Booting Linux on physical CPU 0x00 [0x411fd070]
> >
> > Changes since v4:
> > - incorporate review feedback from Daniel regarding whitespace and other
> >   minor style deviations
> >
> > Changes since v3:
> > - drop a couple of patches that have been merged independently in the
> >   meantime
> > - update patch #1 to read the PE image header offset from the file
> >   instead of using the harcoded offset
> > - add acks from Heinrich and Ilias
> >
> > Changes since v2:
> > - incorporate some ancient feedback from Daniel that I never saw until
> >   today. (this is why I am sending two versions of the same series on
> >   the same day - apologies for the spam)
> >
> > [0] The initrd= command line loader can only access files that reside on
> > the same volume as the loaded image, which means GRUB would have to
> > present this volume abstraction in order to serve the initrd file.
> >
> > Cc: Daniel Kiper 
> > Cc: Leif Lindholm 
> > Cc: Nikita Ermakov 
> > Cc: Atish Patra 
> > Cc: Huacai Chen 
> > Cc: Heinrich Schuchardt 
> > Cc: dann frazier 
> > Cc: Julian Andres Klode 
> > Cc: Ilias Apalodimas 
> >
> > Ard Biesheuvel (6):
> >   efi: move MS-DOS stub out of generic PE header definition
> >   linux/arm: unify ARM/arm64 vs Xen PE/COFF header handling
> >   linux/arm: account for COFF headers appearing at unexpected offsets
> >   efi/efinet: Don't close connections at fini_hw() time
> >   efi: implement LoadFile2 initrd loading protocol for Linux
> >   linux: ignore FDT unless we need to modify it
>
> Reviewed-by: Daniel Kiper  for all patches...
>

Thanks

> Though one comment. Probably I would pull stdbool.h into include/grub/types.h
> in the patch #5. If I do not hear any objections I will do that for you before
> merging the patches.
>

Sure

> Thank you for doing this work guys! And sorry it took so long to review
> all these patches...
>

No worries

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v5 5/6] efi: implement LoadFile2 initrd loading protocol for Linux

2022-10-18 Thread Ard Biesheuvel
Recent Linux kernels will invoke the LoadFile2 protocol installed on
a well-known vendor media path to load the initrd if it is exposed by
the firmware. Using this method is preferred for two reasons:
- the Linux kernel is in charge of allocating the memory, and so it can
  implement any placement policy it wants (given that these tend to
  change between kernel versions),
- it is no longer necessary to modify the device tree provided by the
  firmware.

So let's install this protocol when handling the 'initrd' command if
such a recent kernel was detected (based on the PE/COFF image version),
and defer loading the initrd contents until the point where the kernel
invokes the LoadFile2 protocol.

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Heinrich Schuchardt 
Tested-by: Ilias Apalodimas 
Reviewed-by: Ilias Apalodimas 
---
 grub-core/commands/efi/lsefi.c |   1 +
 grub-core/loader/arm64/linux.c | 124 +++-
 include/grub/efi/api.h |  40 +++
 3 files changed, 164 insertions(+), 1 deletion(-)

diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
index f46ba3b49384..c304d25ccdd6 100644
--- a/grub-core/commands/efi/lsefi.c
+++ b/grub-core/commands/efi/lsefi.c
@@ -55,6 +55,7 @@ struct known_protocol
 { GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" },
 { GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID, "EFI driver binding" },
 { GRUB_EFI_LOAD_FILE_PROTOCOL_GUID, "load file" },
+{ GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID, "load file2" },
 { GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "simple FS" },
 { GRUB_EFI_TAPE_IO_PROTOCOL_GUID, "tape I/O" },
 { GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID, "unicode collation" },
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 754db84a96cf..9a4522d2f7bf 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -33,6 +33,7 @@
 #include 
 #include 
 #include 
+#include 
 
 GRUB_MOD_LICENSE ("GPLv3+");
 
@@ -48,6 +49,39 @@ static grub_uint32_t cmdline_size;
 static grub_addr_t initrd_start;
 static grub_addr_t initrd_end;
 
+static struct grub_linux_initrd_context initrd_ctx = {0, 0, 0};
+static grub_efi_handle_t initrd_lf2_handle = NULL;
+static bool initrd_use_loadfile2 = false;
+
+static grub_efi_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
+static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
+
+static initrd_media_device_path_t initrd_lf2_device_path = {
+  {
+{
+  GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
+  GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE,
+  sizeof(grub_efi_vendor_media_device_path_t),
+},
+LINUX_EFI_INITRD_MEDIA_GUID
+  }, {
+GRUB_EFI_END_DEVICE_PATH_TYPE,
+GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
+sizeof(grub_efi_device_path_t)
+  }
+};
+
+static grub_efi_status_t __grub_efi_api
+grub_efi_initrd_load_file2 (grub_efi_load_file2_t *this,
+grub_efi_device_path_t *device_path,
+grub_efi_boolean_t boot_policy,
+grub_efi_uintn_t *buffer_size,
+void *buffer);
+
+static grub_efi_load_file2_t initrd_lf2 = {
+  grub_efi_initrd_load_file2
+};
+
 grub_err_t
 grub_arch_efi_linux_load_image_header (grub_file_t file,
   struct linux_arch_kernel_header * lh)
@@ -78,6 +112,18 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
 return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF 
image header");
 }
 
+  /*
+   * Linux kernels built for any architecture are guaranteed to support the
+   * LoadFile2 based initrd loading protocol if the image version is >= 1.
+   */
+  if (lh->pe_image_header.optional_header.major_image_version >= 1)
+initrd_use_loadfile2 = true;
+  else
+initrd_use_loadfile2 = false;
+
+  grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
+initrd_use_loadfile2 ? "en" : "dis");
+
   return GRUB_ERR_NONE;
 }
 
@@ -197,6 +243,8 @@ grub_linux_boot (void)
 static grub_err_t
 grub_linux_unload (void)
 {
+  grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
+
   grub_dl_unref (my_mod);
   loaded = 0;
   if (initrd_start)
@@ -208,6 +256,18 @@ grub_linux_unload (void)
 grub_efi_free_pages ((grub_addr_t) kernel_addr,
 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
   grub_fdt_unload ();
+
+  if (initrd_lf2_handle != NULL)
+{
+  b->uninstall_multiple_protocol_interfaces (initrd_lf2_handle,
+ _file2_guid,
+ _lf2,
+ _path_guid,
+ _lf2_device_path,
+

[PATCH v5 1/6] efi: move MS-DOS stub out of generic PE header definition

2022-10-18 Thread Ard Biesheuvel
The PE/COFF spec permits the COFF signature and file header to appear
anywhere in the file, and the actual offset is recorded in 4 byte
little endian field at offset 0x3c of the image.

When GRUB is emitted as a PE/COFF binary, we reuse the 128 byte MS-DOS
stub (even for non-x86 architectures), putting the COFF signature and
file header at offset 0x80. However, other PE/COFF images may use
different values, and non-x86 Linux kernels use an offset of 0x40
instead.

So let's get rid of the grub_pe32_header struct from pe32.h, given that
it does not represent anything defined by the PE/COFF spec. Instead,
introduce a minimal struct grub_msdos_image_header type based on the
PE/COFF spec's description of the image header, and use the offset
recorded at file position 0x3c to discover the actual location of the PE
signature and the COFF image header.

The remaining fields are moved into a struct grub_pe_image_header,
which we will use later to access COFF header fields of arbitrary
images (and which may therefore appear at different offsets)

Signed-off-by: Ard Biesheuvel 
---
 grub-core/kern/efi/efi.c |  8 ++--
 include/grub/efi/pe32.h  | 16 
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index e8a976a22f15..cf49d6357e00 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -302,7 +302,8 @@ grub_addr_t
 grub_efi_modules_addr (void)
 {
   grub_efi_loaded_image_t *image;
-  struct grub_pe32_header *header;
+  struct grub_msdos_image_header *header;
+  struct grub_pe_image_header *pe_image_header;
   struct grub_pe32_coff_header *coff_header;
   struct grub_pe32_section_table *sections;
   struct grub_pe32_section_table *section;
@@ -314,7 +315,10 @@ grub_efi_modules_addr (void)
 return 0;
 
   header = image->image_base;
-  coff_header = &(header->coff_header);
+  pe_image_header
+= (struct grub_pe_image_header *) ((char *) header
+   + header->pe_image_header_offset);
+  coff_header = &(pe_image_header->coff_header);
   sections
 = (struct grub_pe32_section_table *) ((char *) coff_header
  + sizeof (*coff_header)
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 0ed8781f0376..98c4ff177e19 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -48,6 +48,17 @@
 
 #define GRUB_PE32_MAGIC0x5a4d
 
+struct grub_msdos_image_header
+{
+  /* This is always 'MZ'. (GRUB_PE32_MAGIC)  */
+  grub_uint16_t msdos_magic;
+
+  grub_uint16_t reserved[29];
+
+  /* The file offset of the PE image header. */
+  grub_uint32_t pe_image_header_offset;
+};
+
 /* According to the spec, the minimal alignment is 512 bytes...
But some examples (such as EFI drivers in the Intel
Sample Implementation) use 32 bytes (0x20) instead, and it seems
@@ -254,11 +265,8 @@ struct grub_pe32_section_table
 
 #define GRUB_PE32_SIGNATURE_SIZE 4
 
-struct grub_pe32_header
+struct grub_pe_image_header
 {
-  /* This should be filled in with GRUB_PE32_MSDOS_STUB.  */
-  grub_uint8_t msdos_stub[GRUB_PE32_MSDOS_STUB_SIZE];
-
   /* This is always PE\0\0.  */
   char signature[GRUB_PE32_SIGNATURE_SIZE];
 
-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v5 4/6] efi/efinet: Don't close connections at fini_hw() time

2022-10-18 Thread Ard Biesheuvel
When GRUB runs on top of EFI firmware, it only has access to block and
network device abstractions exposed by the firmware, and it is up to the
firmware to quiesce the underlying hardware when exiting boot services
and handing over to the OS.

This is especially important for network devices, to prevent incoming
packets from being DMA'd straight into memory after the OS has taken
over but before it has managed to reconfigure the network hardware.

GRUB handles this by means of the grub_net_fini_hw() preboot hook, which
is executed before calling into the booted image. This means that all
network devices disappear or become inoperable before the EFI stub
executes on EFI targeted builds. This is problematic as it prevents the
EFI stub from calling back into GRUB provided protocols such as
LoadFile2 for the initrd, which we will provide in a subsequent patch.

So add a flag that indicates to the network core that EFI network
devices should not be closed when grub_net_fini_hw() is called.

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Heinrich Schuchardt 
Reviewed-by: Daniel Kiper 
---
 grub-core/net/drivers/efi/efinet.c | 10 +-
 grub-core/net/net.c|  2 +-
 include/grub/net.h |  3 ++-
 3 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/grub-core/net/drivers/efi/efinet.c 
b/grub-core/net/drivers/efi/efinet.c
index 73343d26d9e1..5adf5f40f492 100644
--- a/grub-core/net/drivers/efi/efinet.c
+++ b/grub-core/net/drivers/efi/efinet.c
@@ -320,7 +320,15 @@ grub_efinet_findcards (void)
 
   card->name = grub_xasprintf ("efinet%d", i++);
   card->driver = 
-  card->flags = 0;
+  /*
+   * EFI network devices are abstract SNP protocol instances, and the
+   * firmware is in charge of ensuring that they will be torn down when the
+   * OS loader hands off to the OS proper. Closing them as part of the
+   * preboot cleanup is therefore unnecessary, and undesirable, as it
+   * prevents us from using the network connection in a protocal callback
+   * such as LoadFile2 for initrd loading.
+   */
+  card->flags = GRUB_NET_CARD_NO_CLOSE_ON_FINI_HW;
   card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET;
   grub_memcpy (card->default_address.mac,
   net->mode->current_address,
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 064e7114e012..7046dc57890a 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -1787,7 +1787,7 @@ grub_net_fini_hw (int noreturn __attribute__ ((unused)))
 {
   struct grub_net_card *card;
   FOR_NET_CARDS (card)
-if (card->opened)
+if (card->opened && !(card->flags & GRUB_NET_CARD_NO_CLOSE_ON_FINI_HW))
   {
if (card->driver->close)
  card->driver->close (card);
diff --git a/include/grub/net.h b/include/grub/net.h
index a64a04cc80b1..79cba357ae6a 100644
--- a/include/grub/net.h
+++ b/include/grub/net.h
@@ -64,7 +64,8 @@ typedef enum grub_net_interface_flags
 typedef enum grub_net_card_flags
   {
 GRUB_NET_CARD_HWADDRESS_IMMUTABLE = 1,
-GRUB_NET_CARD_NO_MANUAL_INTERFACES = 2
+GRUB_NET_CARD_NO_MANUAL_INTERFACES = 2,
+GRUB_NET_CARD_NO_CLOSE_ON_FINI_HW = 4
   } grub_net_card_flags_t;
 
 struct grub_net_card;
-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v5 6/6] linux: ignore FDT unless we need to modify it

2022-10-18 Thread Ard Biesheuvel
Now that we implemented support for the LoadFile2 protocol for initrd
loading, there is no longer a need to pass the initrd parameters via
the device tree. This means that when the LoadFile2 protocol is being
used, there is no reason to update the device tree in the first place,
and so we can ignore it entirely.

The only remaining reason to deal with the devicetree is if we are
using the 'devicetree' command to load one from disk, so tweak the
logic in grub_fdt_install() to take that into account.

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Leif Lindholm 
Reviewed-by: Daniel Kiper 
---
 grub-core/loader/arm64/linux.c | 22 ++--
 grub-core/loader/efi/fdt.c |  7 +--
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 9a4522d2f7bf..9d0bacc85419 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -134,21 +134,21 @@ finalize_params_linux (void)
 
   void *fdt;
 
-  fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
+  /* Set initrd info */
+  if (initrd_start && initrd_end > initrd_start)
+{
+  fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
 
-  if (!fdt)
-goto failure;
+  if (!fdt)
+   goto failure;
 
-  node = grub_fdt_find_subnode (fdt, 0, "chosen");
-  if (node < 0)
-node = grub_fdt_add_subnode (fdt, 0, "chosen");
+  node = grub_fdt_find_subnode (fdt, 0, "chosen");
+  if (node < 0)
+   node = grub_fdt_add_subnode (fdt, 0, "chosen");
 
-  if (node < 1)
-goto failure;
+  if (node < 1)
+   goto failure;
 
-  /* Set initrd info */
-  if (initrd_start && initrd_end > initrd_start)
-{
   grub_dprintf ("linux", "Initrd @ %p-%p\n",
(void *) initrd_start, (void *) initrd_end);
 
diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
index 80d70887474a..35a3be2e5cda 100644
--- a/grub-core/loader/efi/fdt.c
+++ b/grub-core/loader/efi/fdt.c
@@ -89,13 +89,16 @@ grub_fdt_install (void)
   static grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
   grub_efi_status_t status;
 
+  if (fdt == NULL && loaded_fdt == NULL)
+return GRUB_ERR_NONE;
+
   b = grub_efi_system_table->boot_services;
-  status = b->install_configuration_table (_guid, fdt);
+  status = b->install_configuration_table (_guid, fdt ? fdt : loaded_fdt);
   if (status != GRUB_EFI_SUCCESS)
 return grub_error (GRUB_ERR_IO, "failed to install FDT");
 
   grub_dprintf ("fdt", "Installed/updated FDT configuration table @ %p\n",
-   fdt);
+   fdt ? fdt : loaded_fdt);
   return GRUB_ERR_NONE;
 }
 
-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v5 2/6] linux/arm: unify ARM/arm64 vs Xen PE/COFF header handling

2022-10-18 Thread Ard Biesheuvel
Xen has its own version of the image header, to account for the
additional PE/COFF header fields. Since we are adding references to
those in the shared EFI loader code, update the common definitions
and drop the Xen specific one which no longer has a purpose.

Since in both cases, the call to grub_arch_efi_linux_check_image() is
preceded by a load of the image header, let's move the load into that
function, and rename it to grub_arch_efi_linux_load_image_header()/

Signed-off-by: Ard Biesheuvel 
---
 grub-core/loader/arm64/linux.c| 12 +-
 grub-core/loader/arm64/xen_boot.c | 23 
 include/grub/arm/linux.h  |  5 +
 include/grub/arm64/linux.h|  2 ++
 include/grub/efi/efi.h|  4 +++-
 5 files changed, 21 insertions(+), 25 deletions(-)

diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index b5b559c236e0..3733a69d6e36 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -49,8 +49,13 @@ static grub_addr_t initrd_start;
 static grub_addr_t initrd_end;
 
 grub_err_t
-grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
+grub_arch_efi_linux_load_image_header (grub_file_t file,
+  struct linux_arch_kernel_header * lh)
 {
+  grub_file_seek (file, 0);
+  if (grub_file_read (file, lh, sizeof (*lh)) < (grub_ssize_t) sizeof (*lh))
+return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image 
header");
+
   if ((lh->code0 & 0x) != GRUB_PE32_MAGIC)
 return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
   N_("plain image kernel not supported - rebuild with 
CONFIG_(U)EFI_STUB enabled"));
@@ -301,10 +306,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
((unused)),
 
   kernel_size = grub_file_size (file);
 
-  if (grub_file_read (file, , sizeof (lh)) < (long) sizeof (lh))
-return grub_errno;
-
-  if (grub_arch_efi_linux_check_image () != GRUB_ERR_NONE)
+  if (grub_arch_efi_linux_load_image_header (file, ) != GRUB_ERR_NONE)
 goto fail;
 
   grub_loader_unset();
diff --git a/grub-core/loader/arm64/xen_boot.c 
b/grub-core/loader/arm64/xen_boot.c
index 22cc25eccd9d..763d87dcde5b 100644
--- a/grub-core/loader/arm64/xen_boot.c
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -31,7 +31,6 @@
 #include 
 #include 
 #include 
-#include  /* required by struct xen_hypervisor_header */
 #include 
 #include 
 
@@ -65,18 +64,6 @@ enum module_type
 };
 typedef enum module_type module_type_t;
 
-struct xen_hypervisor_header
-{
-  struct linux_arm64_kernel_header efi_head;
-
-  /* This is always PE\0\0.  */
-  grub_uint8_t signature[GRUB_PE32_SIGNATURE_SIZE];
-  /* The COFF file header.  */
-  struct grub_pe32_coff_header coff_header;
-  /* The Optional header.  */
-  struct grub_pe64_optional_header optional_header;
-};
-
 struct xen_boot_binary
 {
   struct xen_boot_binary *next;
@@ -452,7 +439,7 @@ static grub_err_t
 grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)),
 int argc, char *argv[])
 {
-  struct xen_hypervisor_header sh;
+  struct linux_arm64_kernel_header lh;
   grub_file_t file = NULL;
 
   grub_dl_ref (my_mod);
@@ -467,10 +454,7 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ 
((unused)),
   if (!file)
 goto fail;
 
-  if (grub_file_read (file, , sizeof (sh)) != (long) sizeof (sh))
-goto fail;
-  if (grub_arch_efi_linux_check_image
-  ((struct linux_arch_kernel_header *) ) != GRUB_ERR_NONE)
+  if (grub_arch_efi_linux_load_image_header (file, ) != GRUB_ERR_NONE)
 goto fail;
   grub_file_seek (file, 0);
 
@@ -484,7 +468,8 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ 
((unused)),
 return grub_errno;
 
   xen_hypervisor->is_hypervisor = 1;
-  xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
+  xen_hypervisor->align
+= (grub_size_t) lh.pe_image_header.optional_header.section_alignment;
 
   xen_boot_binary_load (xen_hypervisor, file, argc, argv);
   if (grub_errno == GRUB_ERR_NONE)
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index bcd5a7eb186e..f38e695b1408 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -22,6 +22,8 @@
 
 #include "system.h"
 
+#include 
+
 #define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818
 
 struct linux_arm_kernel_header {
@@ -32,6 +34,9 @@ struct linux_arm_kernel_header {
   grub_uint32_t end;   /* _edata */
   grub_uint32_t reserved2[3];
   grub_uint32_t hdr_offset;
+#if defined GRUB_MACHINE_EFI
+  struct grub_pe_image_header pe_image_header;
+#endif
 };
 
 #if defined(__arm__)
diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
index 7e22b4ab6990..3da71a51256f 100644
--- a/include/grub/arm64/linux.h
+++ b/include/grub/arm64/linux.h
@@ -20,6 +20,7 @@
 #define GRUB_ARM64_LINUX_HEADER 1
 
 #include 
+#include 
 
 #define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0

[PATCH v5 3/6] linux/arm: account for COFF headers appearing at unexpected offsets

2022-10-18 Thread Ard Biesheuvel
The way we load the Linux and PE/COFF image headers depends on a fixed
placement of the COFF header at offset 0x40 into the file. This is a
reasonable default, given that this is where Linux emits it today.
However, in order to comply with the PE/COFF spec, which allows this
header to appear anywhere in the file, let's ensure that we read the
header from where it actually appears in the file if it is not located
at offset 0x40.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/loader/arm64/linux.c | 15 +++
 1 file changed, 15 insertions(+)

diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 3733a69d6e36..754db84a96cf 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -63,6 +63,21 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
   grub_dprintf ("linux", "UEFI stub kernel:\n");
   grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
 
+  /*
+   * The PE/COFF spec permits the COFF header to appear anywhere in the file, 
so
+   * we need to double check whether it was where we expected it, and if not, 
we
+   * must load it from the correct offset into the pe_image_header field of
+   * struct linux_arch_kernel_header.
+   */
+  if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) 
>pe_image_header)
+{
+  if (grub_file_seek (file, lh->hdr_offset) == (grub_off_t) -1
+  || grub_file_read (file, >pe_image_header,
+ sizeof (struct grub_pe_image_header))
+ != sizeof (struct grub_pe_image_header))
+return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF 
image header");
+}
+
   return GRUB_ERR_NONE;
 }
 
-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


[PATCH v5 0/6] linux: implement LoadFile2 initrd loading

2022-10-18 Thread Ard Biesheuvel
This implements the LoadFile2 initrd loading protocol, which is
essentially a callback interface into the bootloader to load the initrd
data into a caller provided buffer. This means the bootloader no longer
has to contain any policy regarding where to load the initrd (which
differs between architectures and kernel versions) and no longer has to
manipulate arch specific data structures such as DT or struct bootparams
to inform the OS where the initrd resides in memory. This is especially
relevant for the upcoming LoongArch support, which does not use either
DT or struct bootparams, and would have to rely on the initrd= command
line interface, which is deprecated and of limited utility [0].

Sample output from booting a recent Linux/arm64 kernel:

  grub> insmod part_msdos
  grub> linux (hd0,msdos1)/Image
  grub> initrd (hd0,msdos1)/initrd.img
  grub> boot
  EFI stub: Booting Linux Kernel...
  EFI stub: EFI_RNG_PROTOCOL unavailable
  EFI stub: Generating empty DTB
  EFI stub: Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path
  EFI stub: Exiting boot services...
  [0.00] Booting Linux on physical CPU 0x00 [0x411fd070]

Changes since v4:
- incorporate review feedback from Daniel regarding whitespace and other
  minor style deviations

Changes since v3:
- drop a couple of patches that have been merged independently in the
  meantime
- update patch #1 to read the PE image header offset from the file
  instead of using the harcoded offset
- add acks from Heinrich and Ilias

Changes since v2:
- incorporate some ancient feedback from Daniel that I never saw until
  today. (this is why I am sending two versions of the same series on
  the same day - apologies for the spam)

[0] The initrd= command line loader can only access files that reside on
the same volume as the loaded image, which means GRUB would have to
present this volume abstraction in order to serve the initrd file.

Cc: Daniel Kiper 
Cc: Leif Lindholm 
Cc: Nikita Ermakov 
Cc: Atish Patra 
Cc: Huacai Chen 
Cc: Heinrich Schuchardt 
Cc: dann frazier 
Cc: Julian Andres Klode 
Cc: Ilias Apalodimas 

Ard Biesheuvel (6):
  efi: move MS-DOS stub out of generic PE header definition
  linux/arm: unify ARM/arm64 vs Xen PE/COFF header handling
  linux/arm: account for COFF headers appearing at unexpected offsets
  efi/efinet: Don't close connections at fini_hw() time
  efi: implement LoadFile2 initrd loading protocol for Linux
  linux: ignore FDT unless we need to modify it

 grub-core/commands/efi/lsefi.c |   1 +
 grub-core/kern/efi/efi.c   |   8 +-
 grub-core/loader/arm64/linux.c | 173 ++--
 grub-core/loader/arm64/xen_boot.c  |  23 +--
 grub-core/loader/efi/fdt.c |   7 +-
 grub-core/net/drivers/efi/efinet.c |  10 +-
 grub-core/net/net.c|   2 +-
 include/grub/arm/linux.h   |   5 +
 include/grub/arm64/linux.h |   2 +
 include/grub/efi/api.h |  40 +
 include/grub/efi/efi.h |   4 +-
 include/grub/efi/pe32.h|  16 +-
 include/grub/net.h |   3 +-
 13 files changed, 246 insertions(+), 48 deletions(-)

-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [v5 PATCH 0/3] Unify ARM64 & RISC-V Linux Loader

2022-10-10 Thread Ard Biesheuvel
On Mon, 10 Oct 2022 at 16:58, Daniel Kiper  wrote:
>
> On Fri, Oct 07, 2022 at 01:50:27AM -0700, Atish Patra wrote:
> > This series unifies the linux loader for ARM64 & RISC-V. The linux loader
> > for ARM64 is pretty much arch independent. Thus, this series just moves
> > it to the common directory and update the make files.
> >
> > This series is rebased on top of Ard's LoadFile2 series[1].
> >
> > The unification effort was a little mess and I was to blame :(.
> > I started the effort but couldn't follow up after. Nikita picked it up
> > and rebased all the patches along with LoadFile2.
> >
> > However, Nikita did not follow up after v3 as well. Ard revised his
> > LoadFile2 series few weeks back. As the ocotober deadline for next grub
> > release is closing, I decided to rebase the patches so that RISC-V support
> > can be officially part of the release. Sorry for the mess/confusion.
>
> No worries, I know how it works. Thank you for rebase.
>
> Ard, Atish, your patch series seem to conflict. I think I would review
> and take Atish first. Then Ard would need to rebase. Any objections?
>

Why would you do that? You told me 2 months ago that you were going to
review the patches in september. Now you are telling me you are first
going to review and merge a series that Atish sent out on 7 october,
forcing me to put in additional work to do the rebase?

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


Re: [PATCH v4 1/6] efi: move MS-DOS stub out of generic PE header definition

2022-09-15 Thread Ard Biesheuvel
On Thu, 15 Sept 2022 at 14:21, Leif Lindholm  wrote:
>
> On Thu, Sep 08, 2022 at 15:30:12 +0200, Ard Biesheuvel wrote:
> > The PE/COFF spec permits the COFF signature and file header to appear
> > anywhere in the file, and the actual offset is recorded in 4 byte
> > little endian field at offset 0x3c of the image.
> >
> > When GRUB is emitted as a PE/COFF binary, we reuse the 128 byte MS-DOS
> > stub (even for non-x86 architectures), putting the COFF signature and
> > file header at offset 0x80. However, other PE/COFF images may use
> > different values, and non-x86 Linux kernels use an offset of 0x40
> > instead.
> >
> > So let's get rid of the grub_pe32_header struct from pe32.h, given that
> > it does not represent anything defined by the PE/COFF spec. Instead,
> > introduce a minimal struct grub_msdos_image_header type based on the
> > PE/COFF spec's description of the image header, and use the offset
> > recorded at file position 0x3c to discover the actual location of the PE
> > signature and the COFF image header.
> >
> > The remaining fields are moved into a struct grub_coff_image_header,
> > which we will use later to access COFF header fields of arbitrary
> > images (and which may therefore appear at different offsets)
> >
> > Signed-off-by: Ard Biesheuvel 
> > ---
> >  grub-core/kern/efi/efi.c |  8 ++--
> >  include/grub/efi/pe32.h  | 16 
> >  2 files changed, 18 insertions(+), 6 deletions(-)
> >
> > diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
> > index e8a976a22f15..f85587d66635 100644
> > --- a/grub-core/kern/efi/efi.c
> > +++ b/grub-core/kern/efi/efi.c
> > @@ -302,7 +302,8 @@ grub_addr_t
> >  grub_efi_modules_addr (void)
> >  {
> >grub_efi_loaded_image_t *image;
> > -  struct grub_pe32_header *header;
> > +  struct grub_msdos_image_header *dos_header;
> > +  struct grub_coff_image_header *header;
> >struct grub_pe32_coff_header *coff_header;
> >struct grub_pe32_section_table *sections;
> >struct grub_pe32_section_table *section;
> > @@ -313,7 +314,10 @@ grub_efi_modules_addr (void)
> >if (! image)
> >  return 0;
> >
> > -  header = image->image_base;
> > +  dos_header = (struct grub_msdos_image_header *)image->image_base;
> > +
> > +  header = (struct grub_coff_image_header *) ((char *) dos_header
> > +  + 
> > dos_header->pe_signature_offset);
> >coff_header = &(header->coff_header);
>
> This is where I get semantically confused.
> We now have a coff_image_header called header (pointing at the space
> for the PE\0\0 signature, which comes immediately before the COFF
> header, and isn't part of it).
>
> And then we have a pe32_coff_header called coff_header, pointing at
> the machine field (the start) of the COFF header.
>
> Since "header" is no longer referring to an image header, could we
> chuck out the signature as well from the structure and add
> GRUB_PE32_SIGNATURE_SIZE when calculating?
>
> I.e. drop "header" altogether and do:
>
>   dos_header = (struct grub_msdos_image_header *)image->image_base;
>
>   coff_header = (struct grub_coff_image_header *) ((char *) dos_header
>   + 
> dos_header->pe_signature_offset
>   + GRUB_PE32_SIGNATURE_SIZE
>   );
> ?
>

I suppose that should work, but it does mean we have to add  a 'char
signature[GRUB_PE32_SIGNATURE_SIZE];' member to the existing structs
that incorporate grub_coff_image_header, along with adding
GRUB_PE32_SIGNATURE_SIZE every time we refer to the PE header offset.


> >sections
> >  = (struct grub_pe32_section_table *) ((char *) coff_header
> > diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
> > index 0ed8781f0376..6688d96c0046 100644
> > --- a/include/grub/efi/pe32.h
> > +++ b/include/grub/efi/pe32.h
> > @@ -48,6 +48,17 @@
> >
> >  #define GRUB_PE32_MAGIC  0x5a4d
> >
> > +struct grub_msdos_image_header
> > +{
> > +  /* This is always 'MZ'. (GRUB_PE32_MAGIC)  */
> > +  grub_uint16_t msdos_magic;
> > +
> > +  grub_uint16_t reserved[29];
> > +
> > +  /* The file offset of the PE signature and COFF image header. */
> > +  grub_uint32_t pe_signature_offset;
> > +};
> > +
> >  /* According to the spec, the minimal alignment is 512 bytes...
> > But some examples (such as EFI drivers in the

[PATCH v4 2/6] linux/arm: unify ARM/arm64 vs Xen PE/COFF header handling

2022-09-08 Thread Ard Biesheuvel
Xen has its own version of the image header, to account for the
additional PE/COFF header fields. Since we are adding references to
those in the shared EFI loader code, update the common definitions
and drop the Xen specific one which no longer has a purpose.

Signed-off-by: Ard Biesheuvel 
---
 grub-core/loader/arm64/linux.c| 12 +-
 grub-core/loader/arm64/xen_boot.c | 23 
 include/grub/arm/linux.h  |  6 +
 include/grub/arm64/linux.h|  4 
 include/grub/efi/efi.h|  4 +++-
 5 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index b5b559c236e0..7c0f17cf933d 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -49,8 +49,13 @@ static grub_addr_t initrd_start;
 static grub_addr_t initrd_end;
 
 grub_err_t
-grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
+grub_arch_efi_linux_load_image_header (grub_file_t file,
+  struct linux_arch_kernel_header * lh)
 {
+  grub_file_seek (file, 0);
+  if (grub_file_read (file, lh, sizeof (*lh)) < (long) sizeof (*lh))
+return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image 
header");
+
   if ((lh->code0 & 0x) != GRUB_PE32_MAGIC)
 return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
   N_("plain image kernel not supported - rebuild with 
CONFIG_(U)EFI_STUB enabled"));
@@ -301,10 +306,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ 
((unused)),
 
   kernel_size = grub_file_size (file);
 
-  if (grub_file_read (file, , sizeof (lh)) < (long) sizeof (lh))
-return grub_errno;
-
-  if (grub_arch_efi_linux_check_image () != GRUB_ERR_NONE)
+  if (grub_arch_efi_linux_load_image_header (file, ) != GRUB_ERR_NONE)
 goto fail;
 
   grub_loader_unset();
diff --git a/grub-core/loader/arm64/xen_boot.c 
b/grub-core/loader/arm64/xen_boot.c
index 22cc25eccd9d..e5895ee78218 100644
--- a/grub-core/loader/arm64/xen_boot.c
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -31,7 +31,6 @@
 #include 
 #include 
 #include 
-#include  /* required by struct xen_hypervisor_header */
 #include 
 #include 
 
@@ -65,18 +64,6 @@ enum module_type
 };
 typedef enum module_type module_type_t;
 
-struct xen_hypervisor_header
-{
-  struct linux_arm64_kernel_header efi_head;
-
-  /* This is always PE\0\0.  */
-  grub_uint8_t signature[GRUB_PE32_SIGNATURE_SIZE];
-  /* The COFF file header.  */
-  struct grub_pe32_coff_header coff_header;
-  /* The Optional header.  */
-  struct grub_pe64_optional_header optional_header;
-};
-
 struct xen_boot_binary
 {
   struct xen_boot_binary *next;
@@ -452,7 +439,7 @@ static grub_err_t
 grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ ((unused)),
 int argc, char *argv[])
 {
-  struct xen_hypervisor_header sh;
+  struct linux_arm64_kernel_header lh;
   grub_file_t file = NULL;
 
   grub_dl_ref (my_mod);
@@ -467,10 +454,7 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ 
((unused)),
   if (!file)
 goto fail;
 
-  if (grub_file_read (file, , sizeof (sh)) != (long) sizeof (sh))
-goto fail;
-  if (grub_arch_efi_linux_check_image
-  ((struct linux_arch_kernel_header *) ) != GRUB_ERR_NONE)
+  if (grub_arch_efi_linux_load_image_header (file, ) != GRUB_ERR_NONE)
 goto fail;
   grub_file_seek (file, 0);
 
@@ -484,7 +468,8 @@ grub_cmd_xen_hypervisor (grub_command_t cmd __attribute__ 
((unused)),
 return grub_errno;
 
   xen_hypervisor->is_hypervisor = 1;
-  xen_hypervisor->align = (grub_size_t) sh.optional_header.section_alignment;
+  xen_hypervisor->align
+= (grub_size_t) lh.coff_image_header.optional_header.section_alignment;
 
   xen_boot_binary_load (xen_hypervisor, file, argc, argv);
   if (grub_errno == GRUB_ERR_NONE)
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
index bcd5a7eb186e..ea815db13417 100644
--- a/include/grub/arm/linux.h
+++ b/include/grub/arm/linux.h
@@ -22,6 +22,8 @@
 
 #include "system.h"
 
+#include 
+
 #define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818
 
 struct linux_arm_kernel_header {
@@ -32,6 +34,10 @@ struct linux_arm_kernel_header {
   grub_uint32_t end;   /* _edata */
   grub_uint32_t reserved2[3];
   grub_uint32_t hdr_offset;
+
+#if defined GRUB_MACHINE_EFI
+  struct grub_coff_image_header coff_image_header;
+#endif
 };
 
 #if defined(__arm__)
diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
index 7e22b4ab6990..c5ea9e8f503a 100644
--- a/include/grub/arm64/linux.h
+++ b/include/grub/arm64/linux.h
@@ -21,6 +21,8 @@
 
 #include 
 
+#include 
+
 #define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */
 
 /* From linux/Documentation/arm64/booting.txt */
@@ -36,6 +38,8 @@ struct linux_arm64_kernel_header
   grub_uint64_t res4;  /* reserved */
   grub_uint32_t magic; /* Magic number, little endian, &q

[PATCH v4 5/6] efi: implement LoadFile2 initrd loading protocol for Linux

2022-09-08 Thread Ard Biesheuvel
Recent Linux kernels will invoke the LoadFile2 protocol installed on
a well-known vendor media path to load the initrd if it is exposed by
the firmware. Using this method is preferred for two reasons:
- the Linux kernel is in charge of allocating the memory, and so it can
  implement any placement policy it wants (given that these tend to
  change between kernel versions),
- it is no longer necessary to modify the device tree provided by the
  firmware.

So let's install this protocol when handling the 'initrd' command if
such a recent kernel was detected (based on the PE/COFF image version),
and defer loading the initrd contents until the point where the kernel
invokes the LoadFile2 protocol.

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Heinrich Schuchardt 
Tested-by: Ilias Apalodimas 
Reviewed-by: Ilias Apalodimas 
---
 grub-core/commands/efi/lsefi.c |   1 +
 grub-core/loader/arm64/linux.c | 123 +++-
 include/grub/efi/api.h |  40 +++
 3 files changed, 163 insertions(+), 1 deletion(-)

diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c
index f46ba3b49384..c304d25ccdd6 100644
--- a/grub-core/commands/efi/lsefi.c
+++ b/grub-core/commands/efi/lsefi.c
@@ -55,6 +55,7 @@ struct known_protocol
 { GRUB_EFI_ABSOLUTE_POINTER_PROTOCOL_GUID, "absolute pointer" },
 { GRUB_EFI_DRIVER_BINDING_PROTOCOL_GUID, "EFI driver binding" },
 { GRUB_EFI_LOAD_FILE_PROTOCOL_GUID, "load file" },
+{ GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID, "load file2" },
 { GRUB_EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID, "simple FS" },
 { GRUB_EFI_TAPE_IO_PROTOCOL_GUID, "tape I/O" },
 { GRUB_EFI_UNICODE_COLLATION_PROTOCOL_GUID, "unicode collation" },
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 56ba8d0a6ea3..8b7fbb35fb72 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -48,6 +48,39 @@ static grub_uint32_t cmdline_size;
 static grub_addr_t initrd_start;
 static grub_addr_t initrd_end;
 
+static struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
+static grub_efi_handle_t initrd_lf2_handle = NULL;
+static int initrd_use_loadfile2 = 0;
+
+static grub_efi_guid_t load_file2_guid = GRUB_EFI_LOAD_FILE2_PROTOCOL_GUID;
+static grub_efi_guid_t device_path_guid = GRUB_EFI_DEVICE_PATH_GUID;
+
+static initrd_media_device_path_t initrd_lf2_device_path = {
+  {
+{
+  GRUB_EFI_MEDIA_DEVICE_PATH_TYPE,
+  GRUB_EFI_VENDOR_MEDIA_DEVICE_PATH_SUBTYPE,
+  sizeof(grub_efi_vendor_media_device_path_t),
+},
+LINUX_EFI_INITRD_MEDIA_GUID
+  }, {
+GRUB_EFI_END_DEVICE_PATH_TYPE,
+GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE,
+sizeof(grub_efi_device_path_t)
+  }
+};
+
+static grub_efi_status_t __grub_efi_api
+grub_efi_initrd_load_file2(grub_efi_load_file2_t *this,
+   grub_efi_device_path_t *device_path,
+   grub_efi_boolean_t boot_policy,
+   grub_efi_uintn_t *buffer_size,
+   void *buffer);
+
+static grub_efi_load_file2_t initrd_lf2 = {
+  grub_efi_initrd_load_file2
+};
+
 grub_err_t
 grub_arch_efi_linux_load_image_header (grub_file_t file,
   struct linux_arch_kernel_header * lh)
@@ -78,6 +111,18 @@ grub_arch_efi_linux_load_image_header (grub_file_t file,
return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image 
header");
 }
 
+  /*
+   * Linux kernels built for any architecture are guaranteed to support the
+   * LoadFile2 based initrd loading protocol if the image version is >= 1.
+   */
+  if (lh->coff_image_header.optional_header.major_image_version >= 1)
+initrd_use_loadfile2 = 1;
+  else
+initrd_use_loadfile2 = 0;
+
+  grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
+initrd_use_loadfile2 ? "en" : "dis");
+
   return GRUB_ERR_NONE;
 }
 
@@ -197,6 +242,8 @@ grub_linux_boot (void)
 static grub_err_t
 grub_linux_unload (void)
 {
+  grub_efi_boot_services_t *b = grub_efi_system_table->boot_services;
+
   grub_dl_unref (my_mod);
   loaded = 0;
   if (initrd_start)
@@ -208,6 +255,18 @@ grub_linux_unload (void)
 grub_efi_free_pages ((grub_addr_t) kernel_addr,
 GRUB_EFI_BYTES_TO_PAGES (kernel_size));
   grub_fdt_unload ();
+
+  if (initrd_lf2_handle)
+{
+  b->uninstall_multiple_protocol_interfaces (initrd_lf2_handle,
+ _file2_guid,
+ _lf2,
+ _path_guid,
+ _lf2_device_path,
+ NULL);
+  initrd_lf2_handle = NULL;
+  initrd_use_loadfile2 = 0;
+}
   return GRUB_ERR_NONE;
 }
 
@@ -247,13 +306,50

[PATCH v4 6/6] linux: ignore FDT unless we need to modify it

2022-09-08 Thread Ard Biesheuvel
Now that we implemented support for the LoadFile2 protocol for initrd
loading, there is no longer a need to pass the initrd parameters via
the device tree. This means that when the LoadFile2 protocol is being
used, there is no reason to update the device tree in the first place,
and so we can ignore it entirely.

The only remaining reason to deal with the devicetree is if we are
using the 'devicetree' command to load one from disk, so tweak the
logic in grub_fdt_install() to take that into account.

Signed-off-by: Ard Biesheuvel 
Reviewed-by: Leif Lindholm 
---
 grub-core/loader/arm64/linux.c | 22 ++--
 grub-core/loader/efi/fdt.c |  7 +--
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
index 8b7fbb35fb72..36396e9f7ff5 100644
--- a/grub-core/loader/arm64/linux.c
+++ b/grub-core/loader/arm64/linux.c
@@ -133,21 +133,21 @@ finalize_params_linux (void)
 
   void *fdt;
 
-  fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
+  /* Set initrd info */
+  if (initrd_start && initrd_end > initrd_start)
+{
+  fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
 
-  if (!fdt)
-goto failure;
+  if (!fdt)
+   goto failure;
 
-  node = grub_fdt_find_subnode (fdt, 0, "chosen");
-  if (node < 0)
-node = grub_fdt_add_subnode (fdt, 0, "chosen");
+  node = grub_fdt_find_subnode (fdt, 0, "chosen");
+  if (node < 0)
+   node = grub_fdt_add_subnode (fdt, 0, "chosen");
 
-  if (node < 1)
-goto failure;
+  if (node < 1)
+   goto failure;
 
-  /* Set initrd info */
-  if (initrd_start && initrd_end > initrd_start)
-{
   grub_dprintf ("linux", "Initrd @ %p-%p\n",
(void *) initrd_start, (void *) initrd_end);
 
diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c
index 80d70887474a..fd8093ac83c9 100644
--- a/grub-core/loader/efi/fdt.c
+++ b/grub-core/loader/efi/fdt.c
@@ -89,13 +89,16 @@ grub_fdt_install (void)
   static grub_efi_guid_t fdt_guid = GRUB_EFI_DEVICE_TREE_GUID;
   grub_efi_status_t status;
 
+  if (!fdt && !loaded_fdt)
+return GRUB_ERR_NONE;
+
   b = grub_efi_system_table->boot_services;
-  status = b->install_configuration_table (_guid, fdt);
+  status = b->install_configuration_table (_guid, fdt ?: loaded_fdt);
   if (status != GRUB_EFI_SUCCESS)
 return grub_error (GRUB_ERR_IO, "failed to install FDT");
 
   grub_dprintf ("fdt", "Installed/updated FDT configuration table @ %p\n",
-   fdt);
+   fdt ?: loaded_fdt);
   return GRUB_ERR_NONE;
 }
 
-- 
2.35.1


___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel


  1   2   >