All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [RFC] efi_loader: support for CONFIG_ARMV7_NONSEC
@ 2018-04-06  5:43 Heinrich Schuchardt
  2018-04-06  7:48 ` Alexander Graf
  0 siblings, 1 reply; 3+ messages in thread
From: Heinrich Schuchardt @ 2018-04-06  5:43 UTC (permalink / raw)
  To: u-boot

Booting with SMP fails on the Allwinner A20 CPU.
https://gist.github.com/xypron/2524ba898d6905d959c744c2b05da196

When executing bootefi we need to
* copy the Power State Coordination Interface (PSCI) code to its
  destination address
* switch between our hypervisor mode (HYP) and the supervisor mode (SVC)
  of the payload (http://linux-sunxi.org/PSCI)

This patch is incomplete. It is just meant to indicate where we could
change the entry point.

With the patch iPXE cannot get a network address.

Possibly a better moment for switching to SVC is ExitBootServices.

We also have to consider switching modes at EFI_ENTRY and EFI_EXIT.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 cmd/bootefi.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 85f7b42e76..af5adf8b29 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -17,8 +17,10 @@
 #include <linux/libfdt_env.h>
 #include <memalign.h>
 #include <asm/global_data.h>
+#include <asm/armv7.h>
 #include <asm-generic/sections.h>
 #include <asm-generic/unaligned.h>
+#include <asm/secure.h>
 #include <linux/linkage.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -176,8 +178,19 @@ static efi_status_t efi_do_enter(
 {
 	efi_status_t ret = EFI_LOAD_ERROR;
 
-	if (entry)
-		ret = entry(image_handle, st);
+	if (entry) {
+#ifdef CONFIG_ARMV7_NONSEC
+		if (armv7_boot_nonsec()) {
+			armv7_init_nonsec();
+			secure_ram_addr(_do_nonsec_entry)(entry,
+					(uintptr_t)image_handle,
+					(uintptr_t)st, 0);
+		} else
+#endif
+		{
+			ret = entry(image_handle, st);
+		}
+	}
 	st->boottime->exit(image_handle, ret, 0, NULL);
 	return ret;
 }
-- 
2.14.2

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [RFC] efi_loader: support for CONFIG_ARMV7_NONSEC
  2018-04-06  5:43 [U-Boot] [RFC] efi_loader: support for CONFIG_ARMV7_NONSEC Heinrich Schuchardt
@ 2018-04-06  7:48 ` Alexander Graf
  2018-06-12 17:42   ` Mark Kettenis
  0 siblings, 1 reply; 3+ messages in thread
From: Alexander Graf @ 2018-04-06  7:48 UTC (permalink / raw)
  To: u-boot



On 06.04.18 07:43, Heinrich Schuchardt wrote:
> Booting with SMP fails on the Allwinner A20 CPU.
> https://gist.github.com/xypron/2524ba898d6905d959c744c2b05da196
> 
> When executing bootefi we need to
> * copy the Power State Coordination Interface (PSCI) code to its
>   destination address
> * switch between our hypervisor mode (HYP) and the supervisor mode (SVC)
>   of the payload (http://linux-sunxi.org/PSCI)
> 
> This patch is incomplete. It is just meant to indicate where we could
> change the entry point.
> 
> With the patch iPXE cannot get a network address.
> 
> Possibly a better moment for switching to SVC is ExitBootServices.
> 
> We also have to consider switching modes at EFI_ENTRY and EFI_EXIT.
> 
> Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>

Well, I think it makes perfect sense to switch to HYP mode. We do the
same on AArch64 when we're in EL3 (MON). The fact that iPXE can not get
a network address then sounds weird - HYP should have the same privilege
level as Linux does eventually and there network probably works for you.

Maybe we also need to do the dcache flushing dance? See efi_run_in_el2().

Either way, here's a slightly more clean (untested!) version of your
patch. Because Thunderbird is very good at mangling patches, I'll also
give you a pastebin link[1].


Alex

[1] http://paste.opensuse.org/view/raw/69476551


diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 5a2a81005f..8107ada52c 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -20,6 +20,11 @@
 #include <asm-generic/sections.h>
 #include <linux/linkage.h>

+#ifdef CONFIG_ARM
+#include <asm/armv7.h>
+#include <asm/secure.h>
+#endif
+
 DECLARE_GLOBAL_DATA_PTR;

 #define OBJ_LIST_NOT_INITIALIZED 1
@@ -178,6 +183,15 @@ static efi_status_t efi_run_in_el2(EFIAPI
efi_status_t (*entry)(
 }
 #endif

+#ifdef CONFIG_ARMV7_NONSEC
+static efi_status_t efi_run_in_hyp(EFIAPI efi_status_t (*entry)(
+			efi_handle_t image_handle, struct efi_system_table *st),
+			efi_handle_t image_handle, struct efi_system_table *st)
+{
+	return efi_do_enter(image_handle, st, entry);
+}
+#endif
+
 /* Carve out DT reserved memory ranges */
 static efi_status_t efi_carve_out_dt_rsv(void *fdt)
 {
@@ -327,6 +341,19 @@ static efi_status_t do_bootefi_exec(void *efi,
 	}
 #endif

+#ifdef CONFIG_ARMV7_NONSEC
+	if (armv7_boot_nonsec()) {
+		armv7_init_nonsec();
+		secure_ram_addr(_do_nonsec_entry)(efi_run_in_hyp,
+				(uintptr_t)entry,
+				(uintptr_t)&loaded_image_info_obj.handle,
+				(uintptr_t)&systab);
+
+		/* Should never reach here, efi exits with longjmp */
+		while (1) { }
+	}
+#endif
+
 	ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry);

 exit:

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [U-Boot] [RFC] efi_loader: support for CONFIG_ARMV7_NONSEC
  2018-04-06  7:48 ` Alexander Graf
@ 2018-06-12 17:42   ` Mark Kettenis
  0 siblings, 0 replies; 3+ messages in thread
From: Mark Kettenis @ 2018-06-12 17:42 UTC (permalink / raw)
  To: u-boot

> From: Alexander Graf <agraf@suse.de>
> Date: Fri, 6 Apr 2018 09:48:06 +0200
> 
> On 06.04.18 07:43, Heinrich Schuchardt wrote:
> > Booting with SMP fails on the Allwinner A20 CPU.
> > https://gist.github.com/xypron/2524ba898d6905d959c744c2b05da196
> > 
> > When executing bootefi we need to
> > * copy the Power State Coordination Interface (PSCI) code to its
> >   destination address
> > * switch between our hypervisor mode (HYP) and the supervisor mode (SVC)
> >   of the payload (http://linux-sunxi.org/PSCI)
> > 
> > This patch is incomplete. It is just meant to indicate where we could
> > change the entry point.
> > 
> > With the patch iPXE cannot get a network address.
> > 
> > Possibly a better moment for switching to SVC is ExitBootServices.
> > 
> > We also have to consider switching modes at EFI_ENTRY and EFI_EXIT.
> > 
> > Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
> 
> Well, I think it makes perfect sense to switch to HYP mode. We do the
> same on AArch64 when we're in EL3 (MON). The fact that iPXE can not get
> a network address then sounds weird - HYP should have the same privilege
> level as Linux does eventually and there network probably works for you.
> 
> Maybe we also need to do the dcache flushing dance? See efi_run_in_el2().
> 
> Either way, here's a slightly more clean (untested!) version of your
> patch. Because Thunderbird is very good at mangling patches, I'll also
> give you a pastebin link[1].

Since OpenBSD/armv7 requires an EFI implementation I spent some time
investigating this approach.  I just posted a small patch series that
seems to work.  Turns out the dcache flushing dance is indeed
necessary.  Without it, the "global data" pointer sometimes ends up
being uninitialized after the switch into non-secure mode.  The
crucial fix though is making sure we have a usable stack when
returning from HYP mode.  That may very well be the issue that
Heinrich ran into.

> diff --git a/cmd/bootefi.c b/cmd/bootefi.c
> index 5a2a81005f..8107ada52c 100644
> --- a/cmd/bootefi.c
> +++ b/cmd/bootefi.c
> @@ -20,6 +20,11 @@
>  #include <asm-generic/sections.h>
>  #include <linux/linkage.h>
> 
> +#ifdef CONFIG_ARM
> +#include <asm/armv7.h>
> +#include <asm/secure.h>
> +#endif
> +
>  DECLARE_GLOBAL_DATA_PTR;
> 
>  #define OBJ_LIST_NOT_INITIALIZED 1
> @@ -178,6 +183,15 @@ static efi_status_t efi_run_in_el2(EFIAPI
> efi_status_t (*entry)(
>  }
>  #endif
> 
> +#ifdef CONFIG_ARMV7_NONSEC
> +static efi_status_t efi_run_in_hyp(EFIAPI efi_status_t (*entry)(
> +			efi_handle_t image_handle, struct efi_system_table *st),
> +			efi_handle_t image_handle, struct efi_system_table *st)
> +{
> +	return efi_do_enter(image_handle, st, entry);
> +}
> +#endif
> +
>  /* Carve out DT reserved memory ranges */
>  static efi_status_t efi_carve_out_dt_rsv(void *fdt)
>  {
> @@ -327,6 +341,19 @@ static efi_status_t do_bootefi_exec(void *efi,
>  	}
>  #endif
> 
> +#ifdef CONFIG_ARMV7_NONSEC
> +	if (armv7_boot_nonsec()) {
> +		armv7_init_nonsec();
> +		secure_ram_addr(_do_nonsec_entry)(efi_run_in_hyp,
> +				(uintptr_t)entry,
> +				(uintptr_t)&loaded_image_info_obj.handle,
> +				(uintptr_t)&systab);
> +
> +		/* Should never reach here, efi exits with longjmp */
> +		while (1) { }
> +	}
> +#endif
> +
>  	ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry);
> 
>  exit:
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot
> 

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-06-12 17:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-06  5:43 [U-Boot] [RFC] efi_loader: support for CONFIG_ARMV7_NONSEC Heinrich Schuchardt
2018-04-06  7:48 ` Alexander Graf
2018-06-12 17:42   ` Mark Kettenis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.