Commit 17baa442 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'efi-urgent-2020-07-25' of...

Merge tag 'efi-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip into master

Pull EFI fixes from Ingo Molnar:
 "Various EFI fixes:

   - Fix the layering violation in the use of the EFI runtime services
     availability mask in users of the 'efivars' abstraction

   - Revert build fix for GCC v4.8 which is no longer supported

   - Clean up some x86 EFI stub details, some of which are borderline
     bugs that copy around garbage into padding fields - let's fix these
     out of caution.

   - Fix build issues while working on RISC-V support

   - Avoid --whole-archive when linking the stub on arm64"

* tag 'efi-urgent-2020-07-25' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  efi: Revert "efi/x86: Fix build with gcc 4"
  efi/efivars: Expose RT service availability via efivars abstraction
  efi/libstub: Move the function prototypes to header file
  efi/libstub: Fix gcc error around __umoddi3 for 32 bit builds
  efi/libstub/arm64: link stub lib.a conditionally
  efi/x86: Only copy upto the end of setup_header
  efi/x86: Remove unused variables
parents 7cb3a5c5 74f85551
...@@ -137,7 +137,7 @@ export TEXT_OFFSET ...@@ -137,7 +137,7 @@ export TEXT_OFFSET
core-y += arch/arm64/ core-y += arch/arm64/
libs-y := arch/arm64/lib/ $(libs-y) libs-y := arch/arm64/lib/ $(libs-y)
core-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a libs-$(CONFIG_EFI_STUB) += $(objtree)/drivers/firmware/efi/libstub/lib.a
# Default target when executing plain make # Default target when executing plain make
boot := arch/arm64/boot boot := arch/arm64/boot
......
...@@ -356,10 +356,7 @@ static struct pstore_info efi_pstore_info = { ...@@ -356,10 +356,7 @@ static struct pstore_info efi_pstore_info = {
static __init int efivars_pstore_init(void) static __init int efivars_pstore_init(void)
{ {
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) if (!efivars_kobject() || !efivar_supports_writes())
return 0;
if (!efivars_kobject())
return 0; return 0;
if (efivars_pstore_disable) if (efivars_pstore_disable)
......
...@@ -176,11 +176,13 @@ static struct efivar_operations generic_ops; ...@@ -176,11 +176,13 @@ static struct efivar_operations generic_ops;
static int generic_ops_register(void) static int generic_ops_register(void)
{ {
generic_ops.get_variable = efi.get_variable; generic_ops.get_variable = efi.get_variable;
generic_ops.set_variable = efi.set_variable;
generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
generic_ops.get_next_variable = efi.get_next_variable; generic_ops.get_next_variable = efi.get_next_variable;
generic_ops.query_variable_store = efi_query_variable_store; generic_ops.query_variable_store = efi_query_variable_store;
if (efi_rt_services_supported(EFI_RT_SUPPORTED_SET_VARIABLE)) {
generic_ops.set_variable = efi.set_variable;
generic_ops.set_variable_nonblocking = efi.set_variable_nonblocking;
}
return efivars_register(&generic_efivars, &generic_ops, efi_kobj); return efivars_register(&generic_efivars, &generic_ops, efi_kobj);
} }
...@@ -382,7 +384,8 @@ static int __init efisubsys_init(void) ...@@ -382,7 +384,8 @@ static int __init efisubsys_init(void)
return -ENOMEM; return -ENOMEM;
} }
if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) { if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME)) {
efivar_ssdt_load(); efivar_ssdt_load();
error = generic_ops_register(); error = generic_ops_register();
if (error) if (error)
...@@ -416,7 +419,8 @@ static int __init efisubsys_init(void) ...@@ -416,7 +419,8 @@ static int __init efisubsys_init(void)
err_remove_group: err_remove_group:
sysfs_remove_group(efi_kobj, &efi_subsys_attr_group); sysfs_remove_group(efi_kobj, &efi_subsys_attr_group);
err_unregister: err_unregister:
if (efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES)) if (efi_rt_services_supported(EFI_RT_SUPPORTED_GET_VARIABLE |
EFI_RT_SUPPORTED_GET_NEXT_VARIABLE_NAME))
generic_ops_unregister(); generic_ops_unregister();
err_put: err_put:
kobject_put(efi_kobj); kobject_put(efi_kobj);
......
...@@ -680,11 +680,8 @@ int efivars_sysfs_init(void) ...@@ -680,11 +680,8 @@ int efivars_sysfs_init(void)
struct kobject *parent_kobj = efivars_kobject(); struct kobject *parent_kobj = efivars_kobject();
int error = 0; int error = 0;
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES))
return -ENODEV;
/* No efivars has been registered yet */ /* No efivars has been registered yet */
if (!parent_kobj) if (!parent_kobj || !efivar_supports_writes())
return 0; return 0;
printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION, printk(KERN_INFO "EFI Variables Facility v%s %s\n", EFIVARS_VERSION,
......
...@@ -6,8 +6,7 @@ ...@@ -6,8 +6,7 @@
# enabled, even if doing so doesn't break the build. # enabled, even if doing so doesn't break the build.
# #
cflags-$(CONFIG_X86_32) := -march=i386 cflags-$(CONFIG_X86_32) := -march=i386
cflags-$(CONFIG_X86_64) := -mcmodel=small \ cflags-$(CONFIG_X86_64) := -mcmodel=small
$(call cc-option,-maccumulate-outgoing-args)
cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ \
-fPIC -fno-strict-aliasing -mno-red-zone \ -fPIC -fno-strict-aliasing -mno-red-zone \
-mno-mmx -mno-sse -fshort-wchar \ -mno-mmx -mno-sse -fshort-wchar \
......
...@@ -44,7 +44,7 @@ efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr, ...@@ -44,7 +44,7 @@ efi_status_t efi_allocate_pages_aligned(unsigned long size, unsigned long *addr,
*addr = ALIGN((unsigned long)alloc_addr, align); *addr = ALIGN((unsigned long)alloc_addr, align);
if (slack > 0) { if (slack > 0) {
int l = (alloc_addr % align) / EFI_PAGE_SIZE; int l = (alloc_addr & (align - 1)) / EFI_PAGE_SIZE;
if (l) { if (l) {
efi_bs_call(free_pages, alloc_addr, slack - l + 1); efi_bs_call(free_pages, alloc_addr, slack - l + 1);
......
...@@ -121,23 +121,6 @@ static unsigned long get_dram_base(void) ...@@ -121,23 +121,6 @@ static unsigned long get_dram_base(void)
return membase; return membase;
} }
/*
* This function handles the architcture specific differences between arm and
* arm64 regarding where the kernel image must be loaded and any memory that
* must be reserved. On failure it is required to free all
* all allocations it has made.
*/
efi_status_t handle_kernel_image(unsigned long *image_addr,
unsigned long *image_size,
unsigned long *reserve_addr,
unsigned long *reserve_size,
unsigned long dram_base,
efi_loaded_image_t *image);
asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint,
unsigned long fdt_addr,
unsigned long fdt_size);
/* /*
* EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint * EFI entry point for the arm/arm64 EFI stubs. This is the entrypoint
* that is described in the PE/COFF header. Most of the code is the same * that is described in the PE/COFF header. Most of the code is the same
......
...@@ -776,6 +776,22 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image, ...@@ -776,6 +776,22 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image,
unsigned long *load_size, unsigned long *load_size,
unsigned long soft_limit, unsigned long soft_limit,
unsigned long hard_limit); unsigned long hard_limit);
/*
* This function handles the architcture specific differences between arm and
* arm64 regarding where the kernel image must be loaded and any memory that
* must be reserved. On failure it is required to free all
* all allocations it has made.
*/
efi_status_t handle_kernel_image(unsigned long *image_addr,
unsigned long *image_size,
unsigned long *reserve_addr,
unsigned long *reserve_size,
unsigned long dram_base,
efi_loaded_image_t *image);
asmlinkage void __noreturn efi_enter_kernel(unsigned long entrypoint,
unsigned long fdt_addr,
unsigned long fdt_size);
void efi_handle_post_ebs_state(void); void efi_handle_post_ebs_state(void);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <linux/efi.h> #include <linux/efi.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/stddef.h>
#include <asm/efi.h> #include <asm/efi.h>
#include <asm/e820/types.h> #include <asm/e820/types.h>
...@@ -361,8 +362,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -361,8 +362,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
int options_size = 0; int options_size = 0;
efi_status_t status; efi_status_t status;
char *cmdline_ptr; char *cmdline_ptr;
unsigned long ramdisk_addr;
unsigned long ramdisk_size;
efi_system_table = sys_table_arg; efi_system_table = sys_table_arg;
...@@ -390,8 +389,9 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, ...@@ -390,8 +389,9 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
hdr = &boot_params->hdr; hdr = &boot_params->hdr;
/* Copy the second sector to boot_params */ /* Copy the setup header from the second sector to boot_params */
memcpy(&hdr->jump, image_base + 512, 512); memcpy(&hdr->jump, image_base + 512,
sizeof(struct setup_header) - offsetof(struct setup_header, jump));
/* /*
* Fill out some of the header fields ourselves because the * Fill out some of the header fields ourselves because the
......
...@@ -1229,3 +1229,9 @@ int efivars_unregister(struct efivars *efivars) ...@@ -1229,3 +1229,9 @@ int efivars_unregister(struct efivars *efivars)
return rv; return rv;
} }
EXPORT_SYMBOL_GPL(efivars_unregister); EXPORT_SYMBOL_GPL(efivars_unregister);
int efivar_supports_writes(void)
{
return __efivars && __efivars->ops->set_variable;
}
EXPORT_SYMBOL_GPL(efivar_supports_writes);
...@@ -201,6 +201,9 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc) ...@@ -201,6 +201,9 @@ static int efivarfs_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_d_op = &efivarfs_d_ops; sb->s_d_op = &efivarfs_d_ops;
sb->s_time_gran = 1; sb->s_time_gran = 1;
if (!efivar_supports_writes())
sb->s_flags |= SB_RDONLY;
inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true); inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0, true);
if (!inode) if (!inode)
return -ENOMEM; return -ENOMEM;
...@@ -252,9 +255,6 @@ static struct file_system_type efivarfs_type = { ...@@ -252,9 +255,6 @@ static struct file_system_type efivarfs_type = {
static __init int efivarfs_init(void) static __init int efivarfs_init(void)
{ {
if (!efi_rt_services_supported(EFI_RT_SUPPORTED_VARIABLE_SERVICES))
return -ENODEV;
if (!efivars_kobject()) if (!efivars_kobject())
return -ENODEV; return -ENODEV;
......
...@@ -994,6 +994,7 @@ int efivars_register(struct efivars *efivars, ...@@ -994,6 +994,7 @@ int efivars_register(struct efivars *efivars,
int efivars_unregister(struct efivars *efivars); int efivars_unregister(struct efivars *efivars);
struct kobject *efivars_kobject(void); struct kobject *efivars_kobject(void);
int efivar_supports_writes(void);
int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *), int efivar_init(int (*func)(efi_char16_t *, efi_guid_t, unsigned long, void *),
void *data, bool duplicates, struct list_head *head); void *data, bool duplicates, struct list_head *head);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment