ARM: bootm: Allow booting in secure mode on hyp capable systems
PATCH v2 1/1 ARM: bootm: Allow booting in secure mode on hyp capable systems
Older Linux kernels will not properly boot in hype mode, add support for a bootm_boot_mode environment variable, which when set to "sec" will cause u-boot to boot in secure mode even when build with non-sec (and hyp) support.
--
Changes in v2:
-Allow changing the default boot mode to secure through defining
CONFIG_ARMV7_SEC_BY_DEFAULT, this is useful for archs which have a Kconfig option for compatibility with older kernels
--- arch/arm/lib/bootm.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-)
arch/arm/lib/bootm.c +26 -5
@@ -235,6 +235,26 @@ static void boot_prep_linux(bootm_headers_t *images) } } +#if defined(CONFIG_ARMV7_NONSEC ) || defined(CONFIG_ARMV7_VIRT ) +static bool boot_nonsec (void ) +{ +char *s =getenv ("bootm_boot_mode" ); +#ifdef CONFIG_ARMV7_SEC_BY_DEFAULT +bool nonsec = false; +#else +bool nonsec = true; +#endif + +if (s && !strcmp (s,"sec" )) + nonsec = false; + +if (s && !strcmp (s,"nonsec" )) + nonsec = true; + +return nonsec; +} +#endif +/* Subcommand: GO */ static void boot_jump_linux (bootm_headers_t *images,int flag) {
@@ -283,12 +303,13 @@ static void boot_jump_linux(bootm_headers_t *images, int flag)if (!fake) {#if defined(CONFIG_ARMV7_NONSEC ) || defined(CONFIG_ARMV7_VIRT ) -armv7_init_nonsec (); -secure_ram_addr (_do_nonsec_entry)(kernel_entry, -0 , machid, r2); -#else -kernel_entry (0 , machid, r2); +if (boot_nonsec ()) { +armv7_init_nonsec (); +secure_ram_addr (_do_nonsec_entry)(kernel_entry, +0 , machid, r2); + }#endif +kernel_entry (0 , machid, r2); }#endif }
Signature · 1 line
2.1.0
PATCH v2 1/1 ARM: bootm: Allow booting in secure mode on hyp capable systems
Quoted 4 lines · Hans de Goede
if (!fake) {#if
defined(CONFIG_ARMV7_NONSEC)||defined(CONFIG_ARMV7_VIRT)arch/arm/lib/bootm.c +0
-2-armv7_init_nonsec (); - secure_ram_addr(_do_nonsec_entry)(kernel_entry,
arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t *images, int flag) · line 312
Quoted 10 lines
arch/arm/lib/bootm.c +6
-3- 0, machid, r2); -#else -kernel_entry (0 , machid, r2); +if (boot_nonsec ()) { +armv7_init_nonsec (); +secure_ram_addr (_do_nonsec_entry)(kernel_entry, +0 , machid, r2); + }#endif +kernel_entry (0 , machid, r2);
There's a subtle different here, which is that this final kernel_entry call used to be in the #else clause, and so emitted for the NONSEC || VIRT case. So if the _do_nonsec_entry call were to fail (not currently possible) and return you'd end up trying again via the sec path.
I'm not sure that's a bad thing, but it is a difference so it'd be good to know it was a deliberate choice (or not).
Ian.
PATCH v2 1/1 ARM: bootm: Allow booting in secure mode on hyp capable systems
Hi Ian,
Quoted 21 lines · Ian Campbell
Quoted 4 lines · Hans de Goede
if (!fake) {#if
defined(CONFIG_ARMV7_NONSEC)||defined(CONFIG_ARMV7_VIRT)arch/arm/lib/bootm.c +0
-2-armv7_init_nonsec (); - secure_ram_addr(_do_nonsec_entry)(kernel_entry,arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t *images, int flag) · line 312
Quoted 10 lines
arch/arm/lib/bootm.c +6
-3- 0, machid, r2); -#else -kernel_entry (0 , machid, r2); +if (boot_nonsec ()) { +armv7_init_nonsec (); +secure_ram_addr (_do_nonsec_entry)(kernel_entry, +0 , machid, r2); + }#endif +kernel_entry (0 , machid, r2);There's a subtle different here, which is that this final
kernel_entrycall used to be in the #else clause, and so emitted for the NONSEC || VIRT case. So if the_do_nonsec_entrycall were to fail (not currently possible) and return you'd end up trying again via the sec path.
Quoted 2 lines
I'm not sure that's a bad thing, but it is a difference so it'd be good to know it was a deliberate choice (or not).
I was under the assumption that do_nonsec_entry would never fail, and would not return, which is why I wrote this code the way I wrote it. I'm not sure if retrying in secure mode meets the principle of least surprise, so I guess the #if .. #endif block should probably get an "else" added before the #endif, do you agree?
Regards,
Hans
PATCH v2 1/1 ARM: bootm: Allow booting in secure mode on hyp capable systems
Quoted 24 lines · Hans de Goede
Hi Ian,
Quoted 21 lines · Ian Campbell
Quoted 4 lines · Hans de Goede
if (!fake) {#if
defined(CONFIG_ARMV7_NONSEC)||defined(CONFIG_ARMV7_VIRT)arch/arm/lib/bootm.c +0
-2-armv7_init_nonsec (); - secure_ram_addr(_do_nonsec_entry)(kernel_entry,arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t *images, int flag) · line 312
Quoted 10 lines
arch/arm/lib/bootm.c +6
-3- 0, machid, r2); -#else -kernel_entry (0 , machid, r2); +if (boot_nonsec ()) { +armv7_init_nonsec (); +secure_ram_addr (_do_nonsec_entry)(kernel_entry, +0 , machid, r2); + }#endif +kernel_entry (0 , machid, r2);There's a subtle different here, which is that this final
kernel_entrycall used to be in the #else clause, and so emitted for the NONSEC || VIRT case. So if the_do_nonsec_entrycall were to fail (not currently possible) and return you'd end up trying again via the sec path.
Quoted 5 lines
Quoted 2 lines
I'm not sure that's a bad thing, but it is a difference so it'd be good to know it was a deliberate choice (or not).
I was under the assumption that
do_nonsec_entrywould never fail, and would not return, which is why I wrote this code the way I wrote it.
AFAICT in practice it can't fail today, but if it were somehow modified in the future to do so this would expose some slightly surprising behaviour.
Quoted 4 lines
I'm not sure
if retrying in secure mode meets the principle of least surprise, so I guess the #if .. #endif block should probably get an "else" added before the #endif, do you agree?
Yes.
BTW, if you put the #ifdef around boot_nonsec() instead and make the #else case #define boot_nonsec() (0) then does that end up looking cleaner here at the caller? Maybe that causes knockons with the prototypes for the unused functions in that case, in which case I doubt it is worth it.
Ian.
PATCH v2 1/1 ARM: bootm: Allow booting in secure mode on hyp capable systems
Hi,
Quoted 40 lines · Ian Campbell
Quoted 24 lines · Hans de Goede
Hi Ian,
Quoted 21 lines · Ian Campbell
Quoted 4 lines · Hans de Goede
if (!fake) {#if
defined(CONFIG_ARMV7_NONSEC)||defined(CONFIG_ARMV7_VIRT)arch/arm/lib/bootm.c +0
-2-armv7_init_nonsec (); - secure_ram_addr(_do_nonsec_entry)(kernel_entry,arch/arm/lib/bootm.c static void boot_jump_linux(bootm_headers_t *images, int flag) · line 312
Quoted 10 lines
arch/arm/lib/bootm.c +6
-3- 0, machid, r2); -#else -kernel_entry (0 , machid, r2); +if (boot_nonsec ()) { +armv7_init_nonsec (); +secure_ram_addr (_do_nonsec_entry)(kernel_entry, +0 , machid, r2); + }#endif +kernel_entry (0 , machid, r2);There's a subtle different here, which is that this final
kernel_entrycall used to be in the #else clause, and so emitted for the NONSEC || VIRT case. So if the_do_nonsec_entrycall were to fail (not currently possible) and return you'd end up trying again via the sec path.Quoted 5 lines
Quoted 2 lines
I'm not sure that's a bad thing, but it is a difference so it'd be good to know it was a deliberate choice (or not).
I was under the assumption that
do_nonsec_entrywould never fail, and would not return, which is why I wrote this code the way I wrote it.AFAICT in practice it can't fail today, but if it were somehow modified in the future to do so this would expose some slightly surprising behaviour.
Quoted 4 lines
I'm not sure
if retrying in secure mode meets the principle of least surprise, so I guess the #if .. #endif block should probably get an "else" added before the #endif, do you agree?
Quoted 7 lines
Yes.
BTW, if you put the #ifdef around
boot_nonsec()instead and make the #else case #defineboot_nonsec()(0) then does that end up looking cleaner here at the caller? Maybe that causes knockons with the prototypes for the unused functions in that case, in which case I doubt it is worth it.
The problem there is that do_nonsec_entry is not defined in that case, so we really need an #ifdef there.
Regards,
Hans