mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 22:54:05 +08:00
x86/fpu: Make the EFI FPU calling convention explicit
EFI uses kernel_fpu_begin() to conform to the UEFI calling convention. This specifically requires initializing FCW (FPU Control Word), whereas no sane 64-bit kernel code should use legacy 387 operations that reference FCW. This should allow to safely change the default semantics of kernel_fpu_begin() to stop initializing FCW on 64-bit kernels. [ bp: Massage commit message a little. ] Signed-off-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lkml.kernel.org/r/25d392fff64680e0f4bb8cf0b1003314dc29eafe.1611205691.git.luto@kernel.org
This commit is contained in:
parent
6ee1d745b7
commit
b0dc553cfc
@ -68,17 +68,33 @@ extern unsigned long efi_fw_vendor, efi_config_table;
|
||||
#f " called with too many arguments (" #p ">" #n ")"); \
|
||||
})
|
||||
|
||||
static inline void efi_fpu_begin(void)
|
||||
{
|
||||
/*
|
||||
* The UEFI calling convention (UEFI spec 2.3.2 and 2.3.4) requires
|
||||
* that FCW and MXCSR (64-bit) must be initialized prior to calling
|
||||
* UEFI code. (Oddly the spec does not require that the FPU stack
|
||||
* be empty.)
|
||||
*/
|
||||
kernel_fpu_begin_mask(KFPU_387 | KFPU_MXCSR);
|
||||
}
|
||||
|
||||
static inline void efi_fpu_end(void)
|
||||
{
|
||||
kernel_fpu_end();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
#define arch_efi_call_virt_setup() \
|
||||
({ \
|
||||
kernel_fpu_begin(); \
|
||||
efi_fpu_begin(); \
|
||||
firmware_restrict_branch_speculation_start(); \
|
||||
})
|
||||
|
||||
#define arch_efi_call_virt_teardown() \
|
||||
({ \
|
||||
firmware_restrict_branch_speculation_end(); \
|
||||
kernel_fpu_end(); \
|
||||
efi_fpu_end(); \
|
||||
})
|
||||
|
||||
#define arch_efi_call_virt(p, f, args...) p->f(args)
|
||||
@ -107,7 +123,7 @@ struct efi_scratch {
|
||||
#define arch_efi_call_virt_setup() \
|
||||
({ \
|
||||
efi_sync_low_kernel_mappings(); \
|
||||
kernel_fpu_begin(); \
|
||||
efi_fpu_begin(); \
|
||||
firmware_restrict_branch_speculation_start(); \
|
||||
efi_switch_mm(&efi_mm); \
|
||||
})
|
||||
@ -119,7 +135,7 @@ struct efi_scratch {
|
||||
({ \
|
||||
efi_switch_mm(efi_scratch.prev_mm); \
|
||||
firmware_restrict_branch_speculation_end(); \
|
||||
kernel_fpu_end(); \
|
||||
efi_fpu_end(); \
|
||||
})
|
||||
|
||||
#ifdef CONFIG_KASAN
|
||||
|
@ -850,7 +850,7 @@ efi_set_virtual_address_map(unsigned long memory_map_size,
|
||||
virtual_map);
|
||||
efi_switch_mm(&efi_mm);
|
||||
|
||||
kernel_fpu_begin();
|
||||
efi_fpu_begin();
|
||||
|
||||
/* Disable interrupts around EFI calls: */
|
||||
local_irq_save(flags);
|
||||
@ -859,7 +859,7 @@ efi_set_virtual_address_map(unsigned long memory_map_size,
|
||||
descriptor_version, virtual_map);
|
||||
local_irq_restore(flags);
|
||||
|
||||
kernel_fpu_end();
|
||||
efi_fpu_end();
|
||||
|
||||
/* grab the virtually remapped EFI runtime services table pointer */
|
||||
efi.runtime = READ_ONCE(systab->runtime);
|
||||
|
Loading…
Reference in New Issue
Block a user