[PATCH 0/2] efi: Allow to auto-disable it on RT

2019-08-16 Thread Sebastian Andrzej Siewior
Hi,

since we have CONFIG_PREEMPT_RT these two patches allow to auto-disable
EFI runtime services on RT while it is still possible to override it and
use it if needed.

Sebastian



[PATCH 1/2] efi: Allow efi=runtime

2019-08-16 Thread Sebastian Andrzej Siewior
In case the option "efi=noruntime" is default at built-time, the user
could overwrite its state by `efi=runtime' and allow it again.

Acked-by: Ard Biesheuvel 
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/firmware/efi/efi.c |3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -114,6 +114,9 @@ static int __init parse_efi_cmdline(char
if (parse_option_str(str, "noruntime"))
disable_runtime = true;
 
+   if (parse_option_str(str, "runtime"))
+   disable_runtime = false;
+
return 0;
 }
 early_param("efi", parse_efi_cmdline);


[PATCH 2/2] efi: Disable runtime services on RT

2019-08-16 Thread Sebastian Andrzej Siewior
Based on meassurements the EFI functions get_variable /
get_next_variable take up to 2us which looks okay.
The functions get_time, set_time take around 10ms. Those 10ms are too
much. Even one ms would be too much.
Ard mentioned that SetVariable might even trigger larger latencies if
the firware will erase flash blocks on NOR.

The time-functions are used by efi-rtc and can be triggered during
runtimed (either via explicit read/write or ntp sync).

The variable write could be used by pstore.
These functions can be disabled without much of a loss. The poweroff /
reboot hooks may be provided by PSCI.

Disable EFI's runtime wrappers.

This was observed on "EFI v2.60 by SoftIron Overdrive 1000".

Acked-by: Ard Biesheuvel 
Signed-off-by: Sebastian Andrzej Siewior 
---
 drivers/firmware/efi/efi.c |2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -88,7 +88,7 @@ struct mm_struct efi_mm = {
 
 struct workqueue_struct *efi_rts_wq;
 
-static bool disable_runtime;
+static bool disable_runtime = IS_ENABLED(CONFIG_PREEMPT_RT);
 static int __init setup_noefi(char *arg)
 {
disable_runtime = true;


Early EFI-related boot freeze in parse_setup_data()

2019-08-16 Thread Daniel Drake
Hi,

We're working with a new consumer MiniPC based on AMD E1-7010.

It fails to boot Linux when booting in EFI mode - it hangs with
nothing on screen. earlycon=efifb doesn't show any output.

Looking closer, I was able to confirm that we reach EFI
ExitBootServices() via efi_printk in the efi stub. But you can't use
EFI's console functionality after that point, so I then resorted to
inserting calls to:

   idt_invalidate(NULL); __asm__ __volatile__("int3");

throughout the early boot code that follows in order to force a system
reset. That way I could deduce if execution was reaching that point
(system reset) or not (system hang as before). As a side-question I'd
be curious if there is any better way to debug such early boot
failures on consumer x86 hardware without a serial port...

Anyway, the system freeze occurs in parse_setup_data(), specifically:

data = early_memremap(pa_data, sizeof(*data));
data_len = data->len + sizeof(struct setup_data);

Dereferencing data->len causes the system to hang. I presume it
triggers an exception handler due to some kind of invalid memory
access.

By returning early in that function, boot continues basically fine. So
I could then log the details: pa_data has value 0x892bb018 and
early_memremap returns address 0xff200018. Accessing just a
single byte at that address causes the system hang.

This original pa_data value (from boot_params.hdr.setup_data) was set
by the EFI stub in setup_efi_pci(). I confirmed that the same
0x892bb018 value is set there, it is not being corrupted along the
way.

Any suggestions for how to diagnose further?

dmesg output:
https://gist.github.com/dsd/199bed7b590e90efdf73f9f6384ca551

Thanks
Daniel