Re: [PATCH 1/3] efi/x86: simplify 64-bit EFI firmware call wrapper

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




> On Dec 28, 2019, at 2:13 AM, Ard Biesheuvel <ard.biesheuvel@xxxxxxxxxx> wrote:
> 
> On Fri, 27 Dec 2019 at 19:08, Arvind Sankar <nivedita@xxxxxxxxxxxx> wrote:
>> 
>>> On Fri, Dec 27, 2019 at 12:51:56PM -0500, Arvind Sankar wrote:
>>> On Thu, Dec 26, 2019 at 04:14:05PM +0100, Ard Biesheuvel wrote:
>>>> The efi_call() wrapper used to invoke EFI runtime services serves
>>>> a number of purposes:
>>>> - realign the stack to 16 bytes
>>>> - preserve FP register state
>>>> - translate from SysV to MS calling convention.
>>>> 
>>>> Preserving the FP register state is redundant in most cases, since
>>>> efi_call() is almost always used from within the scope of a pair of
>>>> kernel_fpu_begin()/_end() calls, with the exception of the early
>>>> call to SetVirtualAddressMap() and the SGI UV support code. So let's
>>>> add a pair of kernel_fpu_begin()/_end() calls there as well, and
>>>> remove the unnecessary code from the assembly implementation of
>>>> efi_call(), and only keep the pieces that deal with the stack
>>>> alignment and the ABI translation.
>>>> 
>>>> Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>
>>>> ---
>>>> arch/x86/platform/efi/efi_64.c      |  4 +++
>>>> arch/x86/platform/efi/efi_stub_64.S | 36 ++------------------
>>>> arch/x86/platform/uv/bios_uv.c      |  7 ++--
>>>> 3 files changed, 11 insertions(+), 36 deletions(-)
>>>> 
>>>> diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
>>>> index 03c2ed3c645c..3690df1d31c6 100644
>>>> --- a/arch/x86/platform/efi/efi_64.c
>>>> +++ b/arch/x86/platform/efi/efi_64.c
>>>> @@ -84,6 +84,7 @@ pgd_t * __init efi_call_phys_prolog(void)
>>>> 
>>>>    if (!efi_enabled(EFI_OLD_MEMMAP)) {
>>>>            efi_switch_mm(&efi_mm);
>>>> +           kernel_fpu_begin();
>>>>            return efi_mm.pgd;
>>>>    }
>>>> 
>>>> @@ -141,6 +142,7 @@ pgd_t * __init efi_call_phys_prolog(void)
>>>>    }
>>>> 
>>>>    __flush_tlb_all();
>>>> +   kernel_fpu_begin();
>>>>    return save_pgd;
>>>> out:
>>>>    efi_call_phys_epilog(save_pgd);
>>>> @@ -158,6 +160,8 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
>>>>    p4d_t *p4d;
>>>>    pud_t *pud;
>>>> 
>>>> +   kernel_fpu_end();
>>>> +
>>>>    if (!efi_enabled(EFI_OLD_MEMMAP)) {
>>>>            efi_switch_mm(efi_scratch.prev_mm);
>>>>            return;
>>> 
>>> Does kernel_fpu_begin/kernel_fpu_end need to be outside the efi_switch_mm?
>>> 
>>> If there's an error in efi_call_phys_prolog during the old memmap code,
>>> it will call efi_call_phys_epilog without having called
>>> kernel_fpu_begin, which will cause an unbalanced kernel_fpu_end. Looks
>>> like the next step will be a panic anyway though.
>> 
>> Do we even need to save/restore the fpu state at this point in boot? The
>> mixed-mode code path doesn't appear to be saving/restoring the XMM
>> registers during SetVirtualAddressMap.
> 
> That is an excellent question, and I was hoping Andy or Ingo could
> shed some light on that.
> 
> I tested without and it booted fine, and it does seem to me that there
> should be very little to preserve given how early this call happens
> (from efi_enter_virtual_mode() which gets called from start_kernel())


Unless you’re somehow calling it from interrupt context, I doubt saving FP regs is needed. Certainly kernel_fpu_begin() doesn’t do anything that matters if we’re in the (misnamed) init task. If you’re calling it really really early, there’s a different potential issue: FP might not be fully initialized. We could have CR0.TS still set, or we might not have all the various “OS supports such-and-such regs” flags set.

Does the UEFI spec explicitly state what FP state can be used by the EFI functions?



[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux