Skip to contentSkip to conversation

EFI_STUB fails to boot non-EFI on arm64

DISCUSSION Catalin Marinas 6 participants 15 messages May 23, 2014 – Jul 8, 2014

Subsystems (2)
lore
Share & tools
lore

Catalin Marinas

author maintainer
#0 lore raw

Hi,

As the EFI_STUB for arm64 got into tip and soon into -next, I thought about giving it a try (tip/arm64/efi). Using my boot-wrapper (non-EFI) is still supposed to work but I get the trace below. It looks like memmap.map is NULL but the code still assumes the kernel was started as an EFI app.

Have you guys tested these patches properly?

Linux version 3.15.0-rc1+ (cmarinas at e102109-lin) (gcc version 4.8.3 20140401 (prerelease) (0.12.310) ) #451 SMP PREEMPT Fri May 23 10:40:10 BST 2014
CPU: AArch64 Processor [410fd0f0] revision 0
bootconsole [earlycon0] enabled
efi: Getting parameters from FDT:
efi: Can't find System Table in device tree!
cma: CMA: reserved 16 MiB at 8ff000000
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.

Unable to handle kernel NULL pointer dereference at virtual address 00000020
pgd = ffffffc00007d000
[00000020] *pgd=0000000000000000
Internal error: Oops: 96000005 [#1] PREEMPT SMP
Modules linked in:
CPU: 0 PID: 0 Comm: swapper Not tainted 3.15.0-rc1+ #451
task: ffffffc0005f4890 ti: ffffffc0005e8000 task.ti: ffffffc0005e8000
PC is at efi_idmap_init+0x74/0xc8
LR is at efi_idmap_init+0x4c/0xc8
pc : [<ffffffc0005b7f54>] lr : [<ffffffc0005b7f2c>] pstate: 600002c5

sp : ffffffc0005ebee0
x29: ffffffc0005ebee0 x28: 0000004080000000
x27: ffffffc0005f60c8 x26: ffffffc0005f6000
x25: ffffffc00053f618 x24: ffffffc0005f8fa8
x23: ffffffc000600000 x22: ffffffc000629000
x21: ffffffc000600000 x20: ffffffc000629338
x19: 0000000000000000 x18: 0000000000000000
x17: ffffffc000635d48 x16: 0000000000000001
x15: 000000000000000a x14: 0000000900000000
x13: 0000000000000018 x12: 0000000880000000
x11: ffffffc000000000 x10: 0000004000000000
x9 : 02c0000000000713 x8 : 0000000040000000
x7 : 00000008ffffffff x6 : ffffffc000629390
x5 : ffffffc000629000 x4 : 0000000000000000
x3 : 00000008ffe00711 x2 : 0000000000000000
x1 : 0000000000000000 x0 : 0000000000000000

Process swapper (pid: 0, stack limit = 0xffffffc0005e8058)

Stack: (0xffffffc0005ebee0 to 0xffffffc0005ec000)

bee0: 005ebf10 ffffffc0 005b667c ffffffc0 7effdf80 ffffffc8 00635d78 ffffffc0
bf00: 005f6108 ffffffc0 005b65ec ffffffc0 005ebfa0 ffffffc0 005b4528 ffffffc0
bf20: 00629000 ffffffc0 00000001 00000000 005d7fd8 ffffffc0 410fd0f0 00000000
bf40: 805f6000 00000000 80000000 00000000 8007b000 00000000 8007d000 00000000
bf60: 00080590 ffffffc0 0044d088 ffffffc0 00000001 00000000 88000000 00000000
bf80: 0062f278 ffffffc0 00000002 00000000 0062ee32 ffffffc0 00000000 00000000
bfa0: 00000000 00000000 80080330 00000000 00000000 00000000 00000e12 00000000
bfc0: 88000000 00000000 410fd0f0 00000000 805f6000 00000000 00000000 00000000
bfe0: 00000000 00000000 005d7fd8 ffffffc0 00000000 00000000 00000000 00000000

Call trace:
[<ffffffc0005b7f54>] efi_idmap_init+0x74/0xc8
[<ffffffc0005b6678>] setup_arch+0x3d4/0x57c
[<ffffffc0005b4524>] start_kernel+0x88/0x364
Code: f9401a80 cb000020 eb00027f 54000248 (f9401260) 
---[ end trace f3ac502fe4422ad7 ]---
Kernel panic - not syncing: Attempted to kill the idle task!
---[ end Kernel panic - not syncing: Attempted to kill the idle task!
#1 lore raw
Quoted 7 lines · Catalin Marinas

As the EFI_STUB for arm64 got into tip and soon into -next, I thought about giving it a try (tip/arm64/efi). Using my boot-wrapper (non-EFI) is still supposed to work but I get the trace below. It looks like memmap.map is NULL but the code still assumes the kernel was started as an EFI app.

Have you guys tested these patches properly?

Apparently not sufficuently...
Sorry about that.

Fix appended:

Quoted 1 line

From 98433920394730d835f0061474832909c0740f29 Mon Sep 17 00:00:00 2001

From: Leif Lindholm <[email protected]>
Date: Fri, 23 May 2014 11:23:23 +0100
Subject: [PATCH] arm64: efi: only attempt efi map setup if booting via EFI

Booting a kernel with CONFIG_EFI enabled on a non-EFI system caused an oops with the current UEFI support code.
Add the required test to prevent this.

---
 arch/arm64/kernel/efi.c |    3 +++
 1 file changed, 3 insertions(+)
arch/arm64/kernel/efi.c +3 -0
index 7bfd650..14db1f6 100644
@@ -333,6 +333,9 @@ void __init efi_init(void)
 
 void __init efi_idmap_init(void)
 {
+	if (!efi_enabled(EFI_BOOT))
+		return;
+
 	/* boot time idmap_pg_dir is incomplete, so fill in missing parts */
 	efi_setup_idmap();
 }
Signature · 1 line
1.7.10.4
#2 lore raw
Quoted 7 lines · Leif Lindholm
Quoted 6 lines · Catalin Marinas

As the EFI_STUB for arm64 got into tip and soon into -next, I thought about giving it a try (tip/arm64/efi). Using my boot-wrapper (non-EFI) is still supposed to work but I get the trace below. It looks like memmap.map is NULL but the code still assumes the kernel was started as an EFI app.

Quoted 6 lines
Quoted 1 line

Have you guys tested these patches properly?

Apparently not sufficuently...
Sorry about that.

Fix appended:

This looks pretty straight forward. I've picked it up and shoved it on my arm64-efi branch.

Signature · 1 line
Matt Fleming, Intel Open Source Technology Center
author maintainer Acked-by
#3 lore raw
In reply to Leif Lindholm
Quoted 16 lines · Leif Lindholm

Subject: [PATCH] arm64: efi: only attempt efi map setup if booting via EFI

Booting a kernel with CONFIG_EFI enabled on a non-EFI system caused an oops with the current UEFI support code.
Add the required test to prevent this.

---
 arch/arm64/kernel/efi.c |    3 +++
 1 file changed, 3 insertions(+)
arch/arm64/kernel/efi.c +0 -0
index 7bfd650..14db1f6 100644

arch/arm64/kernel/efi.c void __init efi_init(void) · line 338

Quoted 6 lines
arch/arm64/kernel/efi.c +3 -0
@@ -333,6 +333,9 @@ void __init efi_init(void)
 
 void __init efi_idmap_init(void)
 {
+	if (!efi_enabled(EFI_BOOT))
+		return;
+

That's a first (possibly temporary) step and I think it's fine:

But we need some further tweaking to the way we call efi_init(). Currently it doesn't matter whether Linux booted as an EFI application or not and efi_init() is always called, causing some pr_err() in fdt_find_uefi_params(). It's not really an error as we support the same image booting non-EFI as well.

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Signature · 1 line
Catalin
#4 lore raw
Quoted 9 lines · Catalin Marinas

That's a first (possibly temporary) step and I think it's fine:

But we need some further tweaking to the way we call efi_init(). Currently it doesn't matter whether Linux booted as an EFI application or not and efi_init() is always called, causing some pr_err() in fdt_find_uefi_params(). It's not really an error as we support the same image booting non-EFI as well.

OK.

Quoted 4 lines

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

My view is that this should be fixed in fdt_find_uefi_params(). A single info message that we can't find evidence of UEFI should be printed in the non-error case.

Like below?

/
Leif

Quoted 1 line

From 67283e60923c14c024460b4512c49563a92acce7 Mon Sep 17 00:00:00 2001

From: Leif Lindholm <[email protected]>
Date: Fri, 23 May 2014 15:50:51 +0100
Subject: [PATCH] efi: fdt: Drop error messages for non-error case

Change fdt_find_uefi_params() to only write error messages if actual error encountered, rather than if no UEFI information is encountered. For the non-error case, print a single info message.

---
 drivers/firmware/efi/efi.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/firmware/efi/efi.c +10 -5
index cd36deb..4bb42e1e 100644
@@ -366,11 +366,8 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
 		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop) {
-			pr_err("Can't find %s in device tree!\n",
-			       dt_params[i].name);
-			return 0;
-		}
+		if (!prop)
+			goto fail;
 		dest = info->params + dt_params[i].offset;
 
 		val = of_read_number(prop, len / sizeof(u32));
@@ -385,6 +382,14 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 				dt_params[i].size * 2, val);
 	}
 	return 1;
+
+	fail:
+	if (i == 0)
+		pr_info("  UEFI not found.\n");
+	else
+		pr_err("Can't find %s in device tree!\n", dt_params[i].name);
+
+	return 0;
 }
 
 int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
Signature · 1 line
1.7.10.4
#5 lore raw
Quoted 18 lines · Leif Lindholm
Quoted 9 lines · Catalin Marinas

That's a first (possibly temporary) step and I think it's fine:

But we need some further tweaking to the way we call efi_init(). Currently it doesn't matter whether Linux booted as an EFI application or not and efi_init() is always called, causing some pr_err() in fdt_find_uefi_params(). It's not really an error as we support the same image booting non-EFI as well.

OK.

Quoted 4 lines

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Quoted 5 lines

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

Considering that

a) the raw Image loader and the stub enter the kernel through different entry points (i.e., offset #0 and whatever entry point is specified in the PE/COFF header, respectively), and
b) there is no decompressor etc involved so we jump straight into the kernel startup code
c) head.S already deals with a similar problem, i.e., storing the CPU boot mode

I would assume it shouldn't be so difficult to set a bit somewhere indicating which case we are dealing with?

Signature · 1 line
Ard.
Quoted 64 lines

My view is that this should be fixed in fdt_find_uefi_params(). A single info message that we can't find evidence of UEFI should be printed in the non-error case.

Like below?

/
Leif

From 67283e60923c14c024460b4512c49563a92acce7 Mon Sep 17 00:00:00 2001
From: Leif Lindholm <[email protected]>
Date: Fri, 23 May 2014 15:50:51 +0100
Subject: [PATCH] efi: fdt: Drop error messages for non-error case

Change fdt_find_uefi_params() to only write error messages if actual error encountered, rather than if no UEFI information is encountered. For the non-error case, print a single info message.

---
 drivers/firmware/efi/efi.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)
drivers/firmware/efi/efi.c +10 -6
index cd36deb..4bb42e1e 100644
@@ -366,11 +366,8 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 
        for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
                prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-               if (!prop) {
-                       pr_err("Can't find %s in device tree!\n",
-                              dt_params[i].name);
-                       return 0;
-               }
+               if (!prop)
+                       goto fail;
                dest = info->params + dt_params[i].offset;
 
                val = of_read_number(prop, len / sizeof(u32));
@@ -385,6 +382,14 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
                                dt_params[i].size * 2, val);
        }
        return 1;
+
+       fail:
+       if (i == 0)
+               pr_info("  UEFI not found.\n");
+       else
+               pr_err("Can't find %s in device tree!\n", dt_params[i].name);
+
+       return 0;
 }
 
 int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
--

1.7.10.4

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#6 lore raw
Quoted 20 lines · Ard Biesheuvel
Quoted 10 lines
Quoted 4 lines

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

Considering that

a) the raw Image loader and the stub enter the kernel through different entry points (i.e., offset #0 and whatever entry point is specified in the PE/COFF header, respectively), and
b) there is no decompressor etc involved so we jump straight into the kernel startup code
c) head.S already deals with a similar problem, i.e., storing the CPU boot mode

Quoted 2 lines

I would assume it shouldn't be so difficult to set a bit somewhere indicating which case we are dealing with?

That would certainly be possible, but what would be the benefit of having two separate mechanisms for determining whether we are booting via UEFI - which could potentially end up disagreeing?

/
Leif

#7 lore raw
Quoted 24 lines · Leif Lindholm
Quoted 20 lines · Ard Biesheuvel
Quoted 10 lines
Quoted 4 lines

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

Considering that

a) the raw Image loader and the stub enter the kernel through different entry points (i.e., offset #0 and whatever entry point is specified in the PE/COFF header, respectively), and
b) there is no decompressor etc involved so we jump straight into the kernel startup code
c) head.S already deals with a similar problem, i.e., storing the CPU boot mode

Quoted 2 lines

I would assume it shouldn't be so difficult to set a bit somewhere indicating which case we are dealing with?

Quoted 6 lines

That would certainly be possible, but what would be the benefit of having two separate mechanisms for determining whether we are booting via UEFI - which could potentially end up disagreeing?

/
Leif

Also, for arm32 the decompressor is still used, so the kernel proper only knows that it was started via the stub
based on device tree entries. In the arm32 case the stub load the initrd and sets up the device tree for the compressed kernel just like any linux loader.

(I had a previous response to Ard's message that was html and got bounced.)

Roy

#8 lore raw
In reply to Leif Lindholm
Quoted 22 lines · Leif Lindholm
Quoted 20 lines · Ard Biesheuvel
Quoted 10 lines
Quoted 4 lines

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

Considering that

a) the raw Image loader and the stub enter the kernel through different entry points (i.e., offset #0 and whatever entry point is specified in the PE/COFF header, respectively), and
b) there is no decompressor etc involved so we jump straight into the kernel startup code
c) head.S already deals with a similar problem, i.e., storing the CPU boot mode

Quoted 7 lines
Quoted 2 lines

I would assume it shouldn't be so difficult to set a bit somewhere indicating which case we are dealing with?

That would certainly be possible, but what would be the benefit of having two separate mechanisms for determining whether we are booting via UEFI - which could potentially end up disagreeing?

Yeah, you're right. Also, the ARM requirements are sufficiently different (as Roy points out) that the presence of the FDT nodes is the most reliable indicator of whether you can proceed booting in EFI mode.

Signature · 1 line
Ard.
#9 lore raw
In reply to Leif Lindholm
Quoted 11 lines · Leif Lindholm
Quoted 4 lines · Catalin Marinas

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

Quoted 5 lines

My view is that this should be fixed in fdt_find_uefi_params(). A single info message that we can't find evidence of UEFI should be printed in the non-error case.

Like below?

Why not move the efi_get_fdt_params call out of efi_init and into setup_arch via a wrapper? Then efi_get_fdt_params and efi_init can have useful return values, which allow us to distinguish between "My DT doesn't have the necessary UEFI properties" and "UEFI failed to initialise" without having to make some printks pr_info and others pr_err within efi_init itself..

Will

#10 lore raw
Quoted 14 lines · Will Deacon
Quoted 14 lines
Quoted 4 lines

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

My view is that this should be fixed in fdt_find_uefi_params(). A single info message that we can't find evidence of UEFI should be printed in the non-error case.

Quoted 8 lines
Quoted 1 line

Like below?

Why not move the efi_get_fdt_params call out of efi_init and into setup_arch via a wrapper? Then efi_get_fdt_params and efi_init can have useful return values, which allow us to distinguish between "My DT doesn't have the necessary UEFI properties" and "UEFI failed to initialise" without having to make some printks pr_info and others pr_err within efi_init itself..

Well, but (for the output part) my patch already did that? If the "Getting parameters from FDT:\n" was too verbose, we could just drop it, and have the same effect on output.

Thing is - there is not really any error case available anywhere during the execution of efi_init() and its branches other than:
- Information required for UEFI boot cannot be found.
- Information exists, but is invalid.
- Failed to early_memremap some UEFI regions into the kernel. which all amounts to "UEFI not available or something went wrong", rather than "UEFI failed to initialise".
If efi_init returns successfully, EFI_BOOT is set, and testable using the efi_enabled() macro.

The proper "UEFI failed to initialise" bit does not come until the early_initcall arm64_enter_virtual_mode(), and is indicated not by a return value, but by setting the flag indicating that EFI_RUNTIME_SERVICES are available, which is checked later in core code using the efi_enabled() macro.

So moving the call to efi_get_fdt_params() would have little effect other than adding a third call site for UEFI bits in setup_arch().

/
Leif

#11 lore raw
Quoted 24 lines · Leif Lindholm
Quoted 14 lines · Will Deacon
Quoted 14 lines
Quoted 4 lines

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

Well, I agree that we shouldn't be spewing error messages for expected operation, but efi_init() is the function we call to determine whether we _are_ booting via UEFI - and it sets flags accordingly for the efi_enabled() macro.

My view is that this should be fixed in fdt_find_uefi_params(). A single info message that we can't find evidence of UEFI should be printed in the non-error case.

Quoted 8 lines
Quoted 1 line

Like below?

Why not move the efi_get_fdt_params call out of efi_init and into setup_arch via a wrapper? Then efi_get_fdt_params and efi_init can have useful return values, which allow us to distinguish between "My DT doesn't have the necessary UEFI properties" and "UEFI failed to initialise" without having to make some printks pr_info and others pr_err within efi_init itself..

Quoted 3 lines

Well, but (for the output part) my patch already did that? If the "Getting parameters from FDT:\n" was too verbose, we could just drop it, and have the same effect on output.

It's the pr_err which is annoying, not the "Getting parameters from FDT:\n" message. Why should I have an error logged to my console when I was never intending to boot using EFI anyway?

Quoted 7 lines

Thing is - there is not really any error case available anywhere during the execution of efi_init() and its branches other than:
- Information required for UEFI boot cannot be found.
- Information exists, but is invalid.
- Failed to early_memremap some UEFI regions into the kernel. which all amounts to "UEFI not available or something went wrong", rather than "UEFI failed to initialise".

Fine, but in this case the DT had the relevant properties which is a good indication that the user was at least *trying* to boot using EFI, no?

Quoted 8 lines

If efi_init returns successfully, EFI_BOOT is set, and testable using the efi_enabled() macro.

The proper "UEFI failed to initialise" bit does not come until the early_initcall arm64_enter_virtual_mode(), and is indicated not by a return value, but by setting the flag indicating that EFI_RUNTIME_SERVICES are available, which is checked later in core code using the efi_enabled() macro.

Sorry, I naively assumed that with a name like efi_init it might, you know, initialise EFI? ;)

Quoted 2 lines

So moving the call to efi_get_fdt_params() would have little effect other than adding a third call site for UEFI bits in setup_arch().

I don't mind having the extra call site if it allows us to distinguish errors from information.

Will

#12 lore raw
Quoted 7 lines · Will Deacon
Quoted 3 lines

Well, but (for the output part) my patch already did that? If the "Getting parameters from FDT:\n" was too verbose, we could just drop it, and have the same effect on output.

It's the pr_err which is annoying, not the "Getting parameters from FDT:\n" message. Why should I have an error logged to my console when I was never intending to boot using EFI anyway?

The pr_err would now only be triggered if some UEFI properties were present and not others. I.e. if the UEFI stub loader failed miserably without detecting it, or something corrupted the DT later on. We would then be the proud owners of a system in an undefined state.

Quoted 10 lines
Quoted 7 lines

Thing is - there is not really any error case available anywhere during the execution of efi_init() and its branches other than:
- Information required for UEFI boot cannot be found.
- Information exists, but is invalid.
- Failed to early_memremap some UEFI regions into the kernel. which all amounts to "UEFI not available or something went wrong", rather than "UEFI failed to initialise".

Fine, but in this case the DT had the relevant properties which is a good indication that the user was at least *trying* to boot using EFI, no?

Having a partial/invalid DT is going to cause undefined behaviour regardless of your method of booting.

And if the data provided proved inaccessible or broken, the symptom would be a complete lack of memblocks. So it may in fact not be possible for that pr_err to ever make it to the console :)

Quoted 11 lines
Quoted 8 lines

If efi_init returns successfully, EFI_BOOT is set, and testable using the efi_enabled() macro.

The proper "UEFI failed to initialise" bit does not come until the early_initcall arm64_enter_virtual_mode(), and is indicated not by a return value, but by setting the flag indicating that EFI_RUNTIME_SERVICES are available, which is checked later in core code using the efi_enabled() macro.

Sorry, I naively assumed that with a name like efi_init it might, you know, initialise EFI? ;)

Name cargo-culted from ia64/x86 by me, and from me by Mark :)

Quoted 5 lines
Quoted 2 lines

So moving the call to efi_get_fdt_params() would have little effect other than adding a third call site for UEFI bits in setup_arch().

I don't mind having the extra call site if it allows us to distinguish errors from information.

And I still don't see how an extra call site in setup_arch would make this more possible than it already is (with my suggested patch to the current version of the code).

/
Leif

author maintainer
#13 lore raw
In reply to Leif Lindholm

I forgot about this thread. I think we need it sorted in some way.

Quoted 5 lines · Leif Lindholm
Quoted 4 lines · Catalin Marinas

Can we add another of detecting whether it's an EFI application and avoid calling efi_init()? I can see x86 sets some efi_loader_signature string in exit_boot() and checks against it later when calling efi_init().

So, to be in line with 32-bit arm, the only way to tell the uncompressed kernel image that it was started as an EFI application is via FDT.

Quoted 3 lines

My view is that this should be fixed in fdt_find_uefi_params(). A single info message that we can't find evidence of UEFI should be printed in the non-error case.

[...]

Quoted 20 lines
drivers/firmware/efi/efi.c +2 -5
index cd36deb..4bb42e1e 100644
@@ -366,11 +366,8 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
 		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop) {
-			pr_err("Can't find %s in device tree!\n",
-			       dt_params[i].name);
-			return 0;
-		}
+		if (!prop)
+			goto fail;
 		dest = info->params + dt_params[i].offset;
 
 		val = of_read_number(prop, len / sizeof(u32));
@@ -385,6 +382,14 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 				dt_params[i].size * 2, val);

drivers/firmware/efi/efi.c static int __init fdt_find_uefi_params(unsigned long node, const char *uname, · line 392

Quoted 10 lines
drivers/firmware/efi/efi.c +8 -0
 	}
 	return 1;
+
+	fail:
+	if (i == 0)
+		pr_info("  UEFI not found.\n");
+	else
+		pr_err("Can't find %s in device tree!\n", dt_params[i].name);
+
+	return 0;

I'm ok with the idea but I don't particularly like the implementation. Does this look any better (functionally the same as yours)?

drivers/firmware/efi/efi.c +15 -7
index eff1a2f22f09..dc79346689e6 100644
@@ -346,6 +346,7 @@ static __initdata struct {
 
 struct param_info {
 	int verbose;
+	int found;
 	void *params;
 };
 
@@ -362,16 +363,12 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen at 0") != 0))
 		return 0;
 
-	pr_info("Getting parameters from FDT:\n");
-
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
 		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop) {
-			pr_err("Can't find %s in device tree!\n",
-			       dt_params[i].name);
+		if (!prop)
 			return 0;
-		}
 		dest = info->params + dt_params[i].offset;
+		info->found++;
 
 		val = of_read_number(prop, len / sizeof(u32));
 
@@ -390,10 +387,21 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
 {
 	struct param_info info;
+	int ret;
+
+	pr_info("Getting EFI parameters from FDT:\n");
 
 	info.verbose = verbose;
+	info.found = 0;
 	info.params = params;
 
-	return of_scan_flat_dt(fdt_find_uefi_params, &info);
+	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
+	if (!info.found)
+		pr_info("UEFI not found.\n");
+	else if (!ret)
+		pr_err("Can't find '%s' in device tree!\n",
+		       dt_params[info.found].name);
+
+	return ret;
 }
 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
Acked-by Tested-by
#14 lore raw
Quoted 1 line · Catalin Marinas

I forgot about this thread. I think we need it sorted in some way.

Agreed.

Quoted 22 lines · Leif Lindholm
Quoted 3 lines

My view is that this should be fixed in fdt_find_uefi_params(). A single info message that we can't find evidence of UEFI should be printed in the non-error case.

[...]

Quoted 17 lines
drivers/firmware/efi/efi.c +2 -5
index cd36deb..4bb42e1e 100644
@@ -366,11 +366,8 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
 		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop) {
-			pr_err("Can't find %s in device tree!\n",
-			       dt_params[i].name);
-			return 0;
-		}
+		if (!prop)
+			goto fail;
 		dest = info->params + dt_params[i].offset;
 
Quoted 16 lines

drivers/firmware/efi/efi.c static int __init fdt_find_uefi_params(unsigned long node, const char *uname, · line 392

Quoted 13 lines
drivers/firmware/efi/efi.c +8 -0
 		val = of_read_number(prop, len / sizeof(u32));
@@ -385,6 +382,14 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 				dt_params[i].size * 2, val);
 	}
 	return 1;
+
+	fail:
+	if (i == 0)
+		pr_info("  UEFI not found.\n");
+	else
+		pr_err("Can't find %s in device tree!\n", dt_params[i].name);
+
+	return 0;

I'm ok with the idea but I don't particularly like the implementation. Does this look any better (functionally the same as yours)?

It solves the problem, so sure.

Quoted 58 lines
drivers/firmware/efi/efi.c +15 -8
index eff1a2f22f09..dc79346689e6 100644
@@ -346,6 +346,7 @@ static __initdata struct {
 
 struct param_info {
 	int verbose;
+	int found;
 	void *params;
 };
 
@@ -362,16 +363,12 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 	    (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen at 0") != 0))
 		return 0;
 
-	pr_info("Getting parameters from FDT:\n");
-
 	for (i = 0; i < ARRAY_SIZE(dt_params); i++) {
 		prop = of_get_flat_dt_prop(node, dt_params[i].propname, &len);
-		if (!prop) {
-			pr_err("Can't find %s in device tree!\n",
-			       dt_params[i].name);
+		if (!prop)
 			return 0;
-		}
 		dest = info->params + dt_params[i].offset;
+		info->found++;
 
 		val = of_read_number(prop, len / sizeof(u32));
 
@@ -390,10 +387,21 @@ static int __init fdt_find_uefi_params(unsigned long node, const char *uname,
 int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
 {
 	struct param_info info;
+	int ret;
+
+	pr_info("Getting EFI parameters from FDT:\n");
 
 	info.verbose = verbose;
+	info.found = 0;
 	info.params = params;
 
-	return of_scan_flat_dt(fdt_find_uefi_params, &info);
+	ret = of_scan_flat_dt(fdt_find_uefi_params, &info);
+	if (!info.found)
+		pr_info("UEFI not found.\n");
+	else if (!ret)
+		pr_err("Can't find '%s' in device tree!\n",
+		       dt_params[info.found].name);
+
+	return ret;
 }
 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */
--

To unsubscribe from this list: send the line "unsubscribe linux-efi" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html