[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAMj1kXG0GZ8K4kVux3zQ6TXGoeQ8bwHq7JXbx-YXFbLSbD-6Gg@mail.gmail.com>
Date: Thu, 29 Jun 2023 23:42:49 +0200
From: Ard Biesheuvel <ardb@...nel.org>
To: Thomas Gleixner <tglx@...utronix.de>
Cc: LKML <linux-kernel@...r.kernel.org>,
Niklāvs Koļesņikovs
<pinkflames.linux@...il.com>, linux-efi@...r.kernel.org,
x86@...nel.org, regressions@...ts.linux.dev
Subject: Re: x86/efi: Make efi_set_virtual_address_map IBT safe
On Thu, 29 Jun 2023 at 21:35, Thomas Gleixner <tglx@...utronix.de> wrote:
>
> Niklāvs reported a boot regression on an Alderlake machine and bisected it
> to commit 9df9d2f0471b ("init: Invoke arch_cpu_finalize_init() earlier").
>
> By moving the invocation of arch_cpu_finalize_init() further down he
> identified that efi_enter_virtual_mode() is the function which causes
> the boot hang.
>
> The main difference of the earlier invocation is that the boot CPU is
> already fully initialized and mitigations and alternatives are applied.
>
> But the only really interesting change turned out to be IBT, which is
> now enabled before efi_enter_virtual_mode(). "ibt=off" on the kernel
> command line cured the problem.
>
> Inspection of the involved calls in efi_enter_virtual_mode() unearthed that
> efi_set_virtual_address_map() is the only place in the kernel which invokes
> an EFI call without the IBT safe wrapper. This went obviously unnoticed so
> far as IBT was enabled later.
>
> Use arch_efi_call_virt() instead of efi_call() to cure that.
>
> Fixes: fe379fa4d199 ("x86/ibt: Disable IBT around firmware")
> Fixes: 9df9d2f0471b ("init: Invoke arch_cpu_finalize_init() earlier")
> Reported-by: Niklāvs Koļesņikovs <pinkflames.linux@...il.com>
> Signed-off-by: Thomas Gleixner <tglx@...utronix.de>
> Link: https://bugzilla.kernel.org/show_bug.cgi?id=217602
Reviewed-by: Ard Biesheuvel <ardb@...nel.org>
I take it you'll send this straight to Linus?
> ---
> I put two fixes tags in as the IBT one missed that and the earlier
> invocation unearthed it and made it observable.
> ---
> arch/x86/platform/efi/efi_64.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> --- a/arch/x86/platform/efi/efi_64.c
> +++ b/arch/x86/platform/efi/efi_64.c
> @@ -853,9 +853,9 @@ efi_set_virtual_address_map(unsigned lon
>
> /* Disable interrupts around EFI calls: */
> local_irq_save(flags);
> - status = efi_call(efi.runtime->set_virtual_address_map,
> - memory_map_size, descriptor_size,
> - descriptor_version, virtual_map);
> + status = arch_efi_call_virt(efi.runtime, set_virtual_address_map,
> + memory_map_size, descriptor_size,
> + descriptor_version, virtual_map);
> local_irq_restore(flags);
>
> efi_fpu_end();
Powered by blists - more mailing lists