[PATCH 2/2] efi: implement mandatory locking for UEFI Runtime Services
According to section 7.1 of the UEFI spec, Runtime Services are not fully reentrant, and there are particular combinations of calls that need to be serialized. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org --- drivers/firmware/efi/runtime-wrappers.c | 109 +--- 1 file changed, 99 insertions(+), 10 deletions(-) diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c index 10daa4bbb258..6588d054af99 100644 --- a/drivers/firmware/efi/runtime-wrappers.c +++ b/drivers/firmware/efi/runtime-wrappers.c @@ -15,10 +15,50 @@ */ #include linux/efi.h -#include linux/spinlock.h /* spinlock_t */ +#include linux/mutex.h +#include linux/spinlock.h #include asm/efi.h /* + * According to section 7.1 of the UEFI spec, Runtime Services are not fully + * reentrant, and there are particular combinations of calls that need to be + * serialized. + * + * Table 31. Rules for Reentry Into Runtime Services + * ++---+ + * | If previous call is busy in | Forbidden to call | + * ++---+ + * | Any | SetVirtualAddressMap()| + * ++---+ + * | ConvertPointer() | ConvertPointer() | + * ++---+ + * | SetVariable() | ResetSystem() | + * | UpdateCapsule() | | + * | SetTime() | | + * | SetWakeupTime() | | + * | GetNextHighMonotonicCount() | | + * ++---+ + * | GetVariable() | GetVariable() | + * | GetNextVariableName() | GetNextVariableName() | + * | SetVariable() | SetVariable() | + * | QueryVariableInfo() | QueryVariableInfo() | + * | UpdateCapsule() | UpdateCapsule() | + * | QueryCapsuleCapabilities()| QueryCapsuleCapabilities() | + * | GetNextHighMonotonicCount() | GetNextHighMonotonicCount() | + * ++---+ + * | GetTime() | GetTime() | + * | SetTime() | SetTime() | + * | GetWakeupTime() | GetWakeupTime() | + * | SetWakeupTime() | SetWakeupTime() | + * ++---+ + * + * The first two are disregarded here, as SetVirtualAddressMap() is called + * only once, and very early, and ConvertPointer() is not exposed at all. + */ +static DEFINE_MUTEX(var_ro_mutex); +static DEFINE_MUTEX(var_rw_mutex); + +/* * As per commit ef68c8f87ed1 (x86: Serialize EFI time accesses on rtc_lock), * the EFI specification requires that callers of the time related runtime * functions serialize with other CMOS accesses in the kernel, as the EFI time @@ -78,14 +118,25 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name, unsigned long *data_size, void *data) { - return efi_call_virt(get_variable, name, vendor, attr, data_size, data); + efi_status_t status; + + mutex_lock(var_ro_mutex); + status = efi_call_virt(get_variable, name, vendor, attr, data_size, + data); + mutex_unlock(var_ro_mutex); + return status; } static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, efi_char16_t *name, efi_guid_t *vendor) { - return efi_call_virt(get_next_variable, name_size, name, vendor); + efi_status_t status; + + mutex_lock(var_ro_mutex); + status = efi_call_virt(get_next_variable, name_size, name, vendor); + mutex_unlock(var_ro_mutex); + return status; } static efi_status_t virt_efi_set_variable(efi_char16_t *name, @@ -94,7 +145,15 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name, unsigned long data_size, void *data) { - return efi_call_virt(set_variable, name, vendor, attr, data_size, data); + efi_status_t status; + + mutex_lock(var_ro_mutex); + mutex_lock(var_rw_mutex); + status = efi_call_virt(set_variable, name, vendor, attr, data_size, + data); +
[PATCH 1/2] efi/arm64: fix potential NULL dereference of efi.systab
We assign efi.systab using efi_lookup_mapped_addr(), and test for !NULL, but then go on an dereference it anyway. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org --- arch/arm64/kernel/efi.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 56c3327bbf79..e785f93f17cb 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -419,8 +419,11 @@ static int __init arm64_enter_virtual_mode(void) } efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table); - if (efi.systab) - set_bit(EFI_SYSTEM_TABLES, efi.flags); + if (!efi.systab) { + pr_err(Failed to remap EFI System Table!\n); + return -1; + } + set_bit(EFI_SYSTEM_TABLES, efi.flags); local_irq_save(flags); cpu_switch_mm(idmap_pg_dir, init_mm); -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/5] efi: efistub: convert into static library
On Thu, 26 Jun, at 04:23:37PM, Ard Biesheuvel wrote: This patch changes both x86 and arm64 efistub implementations from #including shared .c files under drivers/firmware/efi to building the shared code as a static library. The x86 code uses a stub built into the boot executable which uncompresses the kernel at boot time. In this case, the library is linked into the decompressor. In the arm64 case, the stub is part of the kernel proper so the library is linked into the kernel proper as well. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org OK, this breaks the ia64 build because of the following... /drivers/firmware/efi/libstub/efi-stub-helper.c:14:21: fatal error: asm/efi.h: No such file or directory diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index e1096539eedb..d9abdbc962f1 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -1,7 +1,7 @@ # # Makefile for linux kernel # -obj-$(CONFIG_EFI)+= efi.o vars.o +obj-$(CONFIG_EFI)+= efi.o vars.o libstub/ obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_VARS_PSTORE)+= efi-pstore.o obj-$(CONFIG_UEFI_CPER) += cper.o I guess what we need is CONFIG_EFI_LIBSTUB selected by both CONFIG_EFI_STUB (for x86) and CONFIG_EFI_ARMSTUB (for arm64)? e.g. obj-$(CONFIG_EFI_LIBSTUB) libstub/ -- Matt Fleming, Intel Open Source Technology Center -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/5] efi: efistub: convert into static library
On 2 July 2014 13:15, Matt Fleming m...@console-pimps.org wrote: On Thu, 26 Jun, at 04:23:37PM, Ard Biesheuvel wrote: This patch changes both x86 and arm64 efistub implementations from #including shared .c files under drivers/firmware/efi to building the shared code as a static library. The x86 code uses a stub built into the boot executable which uncompresses the kernel at boot time. In this case, the library is linked into the decompressor. In the arm64 case, the stub is part of the kernel proper so the library is linked into the kernel proper as well. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org OK, this breaks the ia64 build because of the following... /drivers/firmware/efi/libstub/efi-stub-helper.c:14:21: fatal error: asm/efi.h: No such file or directory diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index e1096539eedb..d9abdbc962f1 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -1,7 +1,7 @@ # # Makefile for linux kernel # -obj-$(CONFIG_EFI)+= efi.o vars.o +obj-$(CONFIG_EFI)+= efi.o vars.o libstub/ obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_VARS_PSTORE)+= efi-pstore.o obj-$(CONFIG_UEFI_CPER) += cper.o I guess what we need is CONFIG_EFI_LIBSTUB selected by both CONFIG_EFI_STUB (for x86) and CONFIG_EFI_ARMSTUB (for arm64)? e.g. obj-$(CONFIG_EFI_LIBSTUB) libstub/ Yes, that seems the appropriate way to deal with this. Let me respin so I can fix the other thing I mentioned yesterday as well. -- Ard. -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 5/5] efi: efistub: convert into static library
Would something like this ifneq ($(CONFIG_EFI_STUB)$(CONFIG_EFI_ARMSTUB),nn) obj-y += libstub/ endif be too hideous? On 2 July 2014 13:23, Ard Biesheuvel ard.biesheu...@linaro.org wrote: On 2 July 2014 13:15, Matt Fleming m...@console-pimps.org wrote: On Thu, 26 Jun, at 04:23:37PM, Ard Biesheuvel wrote: This patch changes both x86 and arm64 efistub implementations from #including shared .c files under drivers/firmware/efi to building the shared code as a static library. The x86 code uses a stub built into the boot executable which uncompresses the kernel at boot time. In this case, the library is linked into the decompressor. In the arm64 case, the stub is part of the kernel proper so the library is linked into the kernel proper as well. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org OK, this breaks the ia64 build because of the following... /drivers/firmware/efi/libstub/efi-stub-helper.c:14:21: fatal error: asm/efi.h: No such file or directory diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index e1096539eedb..d9abdbc962f1 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile @@ -1,7 +1,7 @@ # # Makefile for linux kernel # -obj-$(CONFIG_EFI)+= efi.o vars.o +obj-$(CONFIG_EFI)+= efi.o vars.o libstub/ obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_VARS_PSTORE)+= efi-pstore.o obj-$(CONFIG_UEFI_CPER) += cper.o I guess what we need is CONFIG_EFI_LIBSTUB selected by both CONFIG_EFI_STUB (for x86) and CONFIG_EFI_ARMSTUB (for arm64)? e.g. obj-$(CONFIG_EFI_LIBSTUB) libstub/ Yes, that seems the appropriate way to deal with this. Let me respin so I can fix the other thing I mentioned yesterday as well. -- Ard. -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/5] efi: efistub: refactor stub components
In order to move from the #include ../../../x.c anti-pattern used by both the x86 and arm64 versions of the stub to a static library linked into either the kernel proper (arm64) or a separate boot executable (x86), there is some prepatory work required. This patch does the following: - move forward declarations of functions shared between the arch specific and the generic parts of the stub to include/linux/efi.h - move forward declarations of functions shared between various .c files of the generic stub code to a new local header file called efistub.h - add #includes to all .c files which were formerly relying on the #includor to include the correct header files - remove all static modifiers from functions which will need to be externally visible once we move to a static library Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org --- arch/arm64/kernel/efi-stub.c | 29 - arch/x86/boot/compressed/eboot.c | 13 +++--- drivers/firmware/efi/arm-stub.c| 32 +-- drivers/firmware/efi/efi-stub-helper.c | 74 +- drivers/firmware/efi/efistub.h | 42 +++ drivers/firmware/efi/fdt.c | 20 + include/linux/efi.h| 42 +++ 7 files changed, 164 insertions(+), 88 deletions(-) create mode 100644 drivers/firmware/efi/efistub.h diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c index 23cbde4324b1..e4999021b07d 100644 --- a/arch/arm64/kernel/efi-stub.c +++ b/arch/arm64/kernel/efi-stub.c @@ -11,36 +11,21 @@ */ #include linux/efi.h #include asm/efi.h -#include linux/libfdt.h #include asm/sections.h -static void efi_char16_printk(efi_system_table_t *sys_table_arg, - efi_char16_t *str); - -static efi_status_t efi_open_volume(efi_system_table_t *sys_table, - void *__image, void **__fh); -static efi_status_t efi_file_close(void *handle); - -static efi_status_t -efi_file_read(void *handle, unsigned long *size, void *addr); - -static efi_status_t -efi_file_size(efi_system_table_t *sys_table, void *__fh, - efi_char16_t *filename_16, void **handle, u64 *file_sz); - /* Include shared EFI stub code */ #include ../../../drivers/firmware/efi/efi-stub-helper.c #include ../../../drivers/firmware/efi/fdt.c #include ../../../drivers/firmware/efi/arm-stub.c -static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, - 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) +efi_status_t handle_kernel_image(efi_system_table_t *sys_table, +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) { efi_status_t status; unsigned long kernel_size, kernel_memsize = 0; diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index c066bc4e3051..916bbdd7dd28 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -45,8 +45,7 @@ static void setup_boot_services##bits(struct efi_config *c) \ BOOT_SERVICES(32); BOOT_SERVICES(64); -static void efi_printk(efi_system_table_t *, char *); -static void efi_char16_printk(efi_system_table_t *, efi_char16_t *); +void efi_char16_printk(efi_system_table_t *, efi_char16_t *); static efi_status_t __file_size32(void *__fh, efi_char16_t *filename_16, @@ -153,7 +152,7 @@ grow: return status; } -static efi_status_t +efi_status_t efi_file_size(efi_system_table_t *sys_table, void *__fh, efi_char16_t *filename_16, void **handle, u64 *file_sz) { @@ -163,7 +162,7 @@ efi_file_size(efi_system_table_t *sys_table, void *__fh, return __file_size32(__fh, filename_16, handle, file_sz); } -static inline efi_status_t +efi_status_t efi_file_read(void *handle, unsigned long *size, void *addr) { unsigned long func; @@ -181,7 +180,7 @@ efi_file_read(void *handle, unsigned long *size, void *addr) } } -static inline efi_status_t efi_file_close(void *handle) +efi_status_t efi_file_close(void *handle) { if (efi_early-is64) { efi_file_handle_64_t *fh = handle; @@ -246,7 +245,7 @@ static inline efi_status_t __open_volume64(void *__image, void **__fh) return status; } -static inline efi_status_t +efi_status_t
[PATCH v3 0/5] efistub: convert into static library
This is v3 of the series to change the #include ../../../../xxx.c pattern into a static library linked into either the kernel (arm64) or a separate boot decompressor (x86, ARM). Changes since v2: - make sure that removals of 'static' modifiers occur in a way that doesn't break bisect (i.e., definition + all declarations in the same patch) - avoid ia64 breakage (which does not use the stub) by building it conditionally on CONFIG_EFI_STUB not CONFIG_EFI Changes since v1: - added patch #1 to change EFI_ERROR, it is not a result code defined by UEFI so it should only be returned by get_dram_base() and efi_entry() - added a section to libstub Makefile to clean CFLAGS of stack protecter and other options that are inappropriate for the stub - rebased onto the UEFI Runtime Services NEON patches (re)posted earlier today Ard Biesheuvel (5): efi/arm64: Avoid EFI_ERROR as a generic return code efi/x86: efistub: Move shared dependencies to asm/efi.h efi/arm64: efistub: Move shared dependencies to asm/efi.h efi: efistub: refactor stub components efi: efistub: convert into static library arch/arm64/Kconfig | 5 ++ arch/arm64/Makefile| 1 + arch/arm64/include/asm/efi.h | 12 arch/arm64/kernel/efi-stub.c | 48 +++--- arch/x86/boot/compressed/Makefile | 3 +- arch/x86/boot/compressed/eboot.c | 20 ++ arch/x86/boot/compressed/eboot.h | 16 - arch/x86/include/asm/efi.h | 25 drivers/firmware/efi/Kconfig | 3 + drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/libstub/Makefile | 26 drivers/firmware/efi/{ = libstub}/arm-stub.c | 32 ++ .../firmware/efi/{ = libstub}/efi-stub-helper.c | 74 +++--- drivers/firmware/efi/libstub/efistub.h | 42 drivers/firmware/efi/{ = libstub}/fdt.c | 20 +++--- include/linux/efi.h| 42 16 files changed, 242 insertions(+), 128 deletions(-) create mode 100644 drivers/firmware/efi/libstub/Makefile rename drivers/firmware/efi/{ = libstub}/arm-stub.c (93%) rename drivers/firmware/efi/{ = libstub}/efi-stub-helper.c (88%) create mode 100644 drivers/firmware/efi/libstub/efistub.h rename drivers/firmware/efi/{ = libstub}/fdt.c (94%) -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/5] efi/x86: efistub: Move shared dependencies to asm/efi.h
This moves definitions depended upon both by code under arch/x86/boot and under drivers/firmware/efi to asm/efi.h. This is in preparation of turning the stub code under drivers/firmware/efi into a static library. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org Signed-off-by: Matt Fleming matt.flem...@intel.com --- arch/x86/boot/compressed/eboot.c | 5 + arch/x86/boot/compressed/eboot.h | 16 arch/x86/include/asm/efi.h | 25 + 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 385f42c200bc..c066bc4e3051 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -19,10 +19,7 @@ static efi_system_table_t *sys_table; -static struct efi_config *efi_early; - -#define efi_call_early(f, ...) \ - efi_early-call(efi_early-f, __VA_ARGS__); +struct efi_config *efi_early; #define BOOT_SERVICES(bits)\ static void setup_boot_services##bits(struct efi_config *c)\ diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index c88c31ecad12..d487e727f1ec 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h @@ -103,20 +103,4 @@ struct efi_uga_draw_protocol { void *blt; }; -struct efi_config { - u64 image_handle; - u64 table; - u64 allocate_pool; - u64 allocate_pages; - u64 get_memory_map; - u64 free_pool; - u64 free_pages; - u64 locate_handle; - u64 handle_protocol; - u64 exit_boot_services; - u64 text_output; - efi_status_t (*call)(unsigned long, ...); - bool is64; -} __packed; - #endif /* BOOT_COMPRESSED_EBOOT_H */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 3dbf56eb540d..9043f365ebf5 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -158,6 +158,31 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( return EFI_SUCCESS; } #endif /* CONFIG_EFI_MIXED */ + + +/* arch specific definitions used by the stub code */ + +struct efi_config { + u64 image_handle; + u64 table; + u64 allocate_pool; + u64 allocate_pages; + u64 get_memory_map; + u64 free_pool; + u64 free_pages; + u64 locate_handle; + u64 handle_protocol; + u64 exit_boot_services; + u64 text_output; + efi_status_t (*call)(unsigned long, ...); + bool is64; +} __packed; + +extern struct efi_config *efi_early; + +#define efi_call_early(f, ...) \ + efi_early-call(efi_early-f, __VA_ARGS__); + #else /* * IF EFI is not configured, have the EFI calls return -ENOSYS. -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 5/5] efi: efistub: convert into static library
This patch changes both x86 and arm64 efistub implementations from #including shared .c files under drivers/firmware/efi to building the shared code as a static library. The x86 code uses a stub built into the boot executable which uncompresses the kernel at boot time. In this case, the library is linked into the decompressor. In the arm64 case, the stub is part of the kernel proper so the library is linked into the kernel proper as well. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org --- arch/arm64/Kconfig | 5 + arch/arm64/Makefile| 1 + arch/arm64/kernel/efi-stub.c | 6 - arch/x86/boot/compressed/Makefile | 3 ++- arch/x86/boot/compressed/eboot.c | 2 -- drivers/firmware/efi/Kconfig | 3 +++ drivers/firmware/efi/Makefile | 1 + drivers/firmware/efi/libstub/Makefile | 26 ++ drivers/firmware/efi/{ = libstub}/arm-stub.c | 0 .../firmware/efi/{ = libstub}/efi-stub-helper.c | 0 drivers/firmware/efi/{ = libstub}/efistub.h | 0 drivers/firmware/efi/{ = libstub}/fdt.c | 0 12 files changed, 38 insertions(+), 9 deletions(-) create mode 100644 drivers/firmware/efi/libstub/Makefile rename drivers/firmware/efi/{ = libstub}/arm-stub.c (100%) rename drivers/firmware/efi/{ = libstub}/efi-stub-helper.c (100%) rename drivers/firmware/efi/{ = libstub}/efistub.h (100%) rename drivers/firmware/efi/{ = libstub}/fdt.c (100%) diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 2cc14cef01bd..3a0a4ce4c751 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -292,6 +292,9 @@ config CMDLINE_FORCE This is useful if you cannot or don't want to change the command-line options your boot loader passes to the kernel. +config EFI_STUB + bool + config EFI bool UEFI runtime support depends on OF !CPU_BIG_ENDIAN @@ -299,6 +302,8 @@ config EFI select UCS2_STRING select EFI_PARAMS_FROM_FDT select EFI_RUNTIME_WRAPPERS + select EFI_STUB + select EFI_ARMSTUB default y help This option provides support for runtime services provided diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index 8185a913c5ed..5836717d2f66 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile @@ -48,6 +48,7 @@ core-$(CONFIG_XEN) += arch/arm64/xen/ core-$(CONFIG_CRYPTO) += arch/arm64/crypto/ libs-y := arch/arm64/lib/ $(libs-y) libs-y += $(LIBGCC) +libs-$(CONFIG_EFI_STUB) += drivers/firmware/efi/libstub/ # Default target when executing plain make KBUILD_IMAGE := Image.gz diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c index e4999021b07d..1317fef8dde9 100644 --- a/arch/arm64/kernel/efi-stub.c +++ b/arch/arm64/kernel/efi-stub.c @@ -13,12 +13,6 @@ #include asm/efi.h #include asm/sections.h -/* Include shared EFI stub code */ -#include ../../../drivers/firmware/efi/efi-stub-helper.c -#include ../../../drivers/firmware/efi/fdt.c -#include ../../../drivers/firmware/efi/arm-stub.c - - efi_status_t handle_kernel_image(efi_system_table_t *sys_table, unsigned long *image_addr, unsigned long *image_size, diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 0fcd9133790c..7a801a310e37 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -33,7 +33,8 @@ VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone ifeq ($(CONFIG_EFI_STUB), y) - VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o + VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \ + $(objtree)/drivers/firmware/efi/libstub/lib.a endif $(obj)/vmlinux: $(VMLINUX_OBJS) FORCE diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 916bbdd7dd28..3b5c66c8f749 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -280,8 +280,6 @@ void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) } } -#include ../../../../drivers/firmware/efi/efi-stub-helper.c - static void find_bits(unsigned long mask, u8 *pos, u8 *size) { u8 first, len; diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig index 588dc47e7075..f712d47f30d8 100644 --- a/drivers/firmware/efi/Kconfig +++ b/drivers/firmware/efi/Kconfig @@ -57,6 +57,9 @@ config EFI_PARAMS_FROM_FDT config EFI_RUNTIME_WRAPPERS bool +config EFI_ARMSTUB + bool + endmenu config UEFI_CPER diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index e1096539eedb..a204d1474cec 100644 --- a/drivers/firmware/efi/Makefile +++
[PATCH v3 1/5] efi/arm64: Avoid EFI_ERROR as a generic return code
As EFI_ERROR is not a UEFI result code but a local invention only intended to allow get_dram_base() to signal failure, we should not use it elsewhere. Replace with EFI_LOAD_ERROR. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org Signed-off-by: Matt Fleming matt.flem...@intel.com --- arch/arm64/kernel/efi-stub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c index e786e6cdc400..7aa7155a9740 100644 --- a/arch/arm64/kernel/efi-stub.c +++ b/arch/arm64/kernel/efi-stub.c @@ -69,7 +69,7 @@ static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, if (*image_addr != (dram_base + TEXT_OFFSET)) { pr_efi_err(sys_table, Failed to alloc kernel memory\n); efi_free(sys_table, kernel_memsize, *image_addr); - return EFI_ERROR; + return EFI_LOAD_ERROR; } *image_size = kernel_memsize; } -- 1.8.3.2 -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/5] efi/x86: efistub: move shared dependencies to asm/efi.h
On Thu, 2014-06-26 at 16:23 +0200, Ard Biesheuvel wrote: This moves definitions depended upon both by code under arch/x86/boot and under drivers/firmware/efi to asm/efi.h. This is in preparation of turning the stub code under drivers/firmware/efi into a static library. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org --- arch/x86/boot/compressed/eboot.c | 5 + arch/x86/boot/compressed/eboot.h | 16 arch/x86/include/asm/efi.h | 25 + 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 0331d765c2bb..2fd5e2643623 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -19,10 +19,7 @@ static efi_system_table_t *sys_table; -static struct efi_config *efi_early; - -#define efi_call_early(f, ...) \ - efi_early-call(efi_early-f, __VA_ARGS__); +struct efi_config *efi_early; #define BOOT_SERVICES(bits) \ static void setup_boot_services##bits(struct efi_config *c) \ diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index c88c31ecad12..d487e727f1ec 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h @@ -103,20 +103,4 @@ struct efi_uga_draw_protocol { void *blt; }; -struct efi_config { - u64 image_handle; - u64 table; - u64 allocate_pool; - u64 allocate_pages; - u64 get_memory_map; - u64 free_pool; - u64 free_pages; - u64 locate_handle; - u64 handle_protocol; - u64 exit_boot_services; - u64 text_output; - efi_status_t (*call)(unsigned long, ...); - bool is64; -} __packed; - #endif /* BOOT_COMPRESSED_EBOOT_H */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 1eb5f6433ad8..55059a50a01f 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -156,6 +156,31 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( return EFI_SUCCESS; } #endif /* CONFIG_EFI_MIXED */ + + +/* arch specific definitions used by the stub code */ + +struct efi_config { + u64 image_handle; + u64 table; + u64 allocate_pool; + u64 allocate_pages; + u64 get_memory_map; + u64 free_pool; + u64 free_pages; + u64 locate_handle; + u64 handle_protocol; + u64 exit_boot_services; + u64 text_output; + efi_status_t (*call)(unsigned long, ...); + bool is64; +} __packed; + +extern struct efi_config *efi_early; + +#define efi_call_early(f, ...) \ + efi_early-call(efi_early-f, __VA_ARGS__); That shouldn't have the trailing ; + #else /* * IF EFI is not configured, have the EFI calls return -ENOSYS. -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/5] efi/x86: efistub: move shared dependencies to asm/efi.h
On 2 July 2014 14:59, Mark Salter msal...@redhat.com wrote: On Thu, 2014-06-26 at 16:23 +0200, Ard Biesheuvel wrote: This moves definitions depended upon both by code under arch/x86/boot and under drivers/firmware/efi to asm/efi.h. This is in preparation of turning the stub code under drivers/firmware/efi into a static library. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org --- arch/x86/boot/compressed/eboot.c | 5 + arch/x86/boot/compressed/eboot.h | 16 arch/x86/include/asm/efi.h | 25 + 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 0331d765c2bb..2fd5e2643623 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -19,10 +19,7 @@ static efi_system_table_t *sys_table; -static struct efi_config *efi_early; - -#define efi_call_early(f, ...) \ - efi_early-call(efi_early-f, __VA_ARGS__); +struct efi_config *efi_early; #define BOOT_SERVICES(bits) \ static void setup_boot_services##bits(struct efi_config *c) \ diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index c88c31ecad12..d487e727f1ec 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h @@ -103,20 +103,4 @@ struct efi_uga_draw_protocol { void *blt; }; -struct efi_config { - u64 image_handle; - u64 table; - u64 allocate_pool; - u64 allocate_pages; - u64 get_memory_map; - u64 free_pool; - u64 free_pages; - u64 locate_handle; - u64 handle_protocol; - u64 exit_boot_services; - u64 text_output; - efi_status_t (*call)(unsigned long, ...); - bool is64; -} __packed; - #endif /* BOOT_COMPRESSED_EBOOT_H */ diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 1eb5f6433ad8..55059a50a01f 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h @@ -156,6 +156,31 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( return EFI_SUCCESS; } #endif /* CONFIG_EFI_MIXED */ + + +/* arch specific definitions used by the stub code */ + +struct efi_config { + u64 image_handle; + u64 table; + u64 allocate_pool; + u64 allocate_pages; + u64 get_memory_map; + u64 free_pool; + u64 free_pages; + u64 locate_handle; + u64 handle_protocol; + u64 exit_boot_services; + u64 text_output; + efi_status_t (*call)(unsigned long, ...); + bool is64; +} __packed; + +extern struct efi_config *efi_early; + +#define efi_call_early(f, ...) \ + efi_early-call(efi_early-f, __VA_ARGS__); That shouldn't have the trailing ; Hmm, perhaps not. This patch just moves stuff around, so fixing this should probably be done in a separate patch. -- Ard. -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v7 07/10] xen: Define EFI related stuff
On Mon, 30 Jun 2014, Daniel Kiper wrote: Define constants and structures which are needed to properly execute EFI related hypercall in Xen dom0. This patch is based on Jan Beulich and Tang Liang work. Signed-off-by: Jan Beulich jbeul...@suse.com Signed-off-by: Tang Liang liang.t...@oracle.com Signed-off-by: Daniel Kiper daniel.ki...@oracle.com Reviewed-by: David Vrabel david.vra...@citrix.com Acked-by: Stefano Stabellini stefano.stabell...@eu.citrix.com v6 - suggestions/fixes: - fix indentation (suggested by David Vrabel). v5 - suggestions/fixes: - improve commit message (suggested by David Vrabel). v4 - suggestions/fixes: - change some types from generic to Xen specific ones (suggested by Stefano Stabellini), - do some formating changes (suggested by Jan Beulich). --- include/xen/interface/platform.h | 123 ++ 1 file changed, 123 insertions(+) diff --git a/include/xen/interface/platform.h b/include/xen/interface/platform.h index f1331e3..5cc49ea 100644 --- a/include/xen/interface/platform.h +++ b/include/xen/interface/platform.h @@ -108,11 +108,113 @@ struct xenpf_platform_quirk { }; DEFINE_GUEST_HANDLE_STRUCT(xenpf_platform_quirk_t); +#define XENPF_efi_runtime_call49 +#define XEN_EFI_get_time 1 +#define XEN_EFI_set_time 2 +#define XEN_EFI_get_wakeup_time 3 +#define XEN_EFI_set_wakeup_time 4 +#define XEN_EFI_get_next_high_monotonic_count 5 +#define XEN_EFI_get_variable 6 +#define XEN_EFI_set_variable 7 +#define XEN_EFI_get_next_variable_name8 +#define XEN_EFI_query_variable_info 9 +#define XEN_EFI_query_capsule_capabilities 10 +#define XEN_EFI_update_capsule 11 + +struct xenpf_efi_runtime_call { + uint32_t function; + /* + * This field is generally used for per sub-function flags (defined + * below), except for the XEN_EFI_get_next_high_monotonic_count case, + * where it holds the single returned value. + */ + uint32_t misc; + xen_ulong_t status; + union { +#define XEN_EFI_GET_TIME_SET_CLEARS_NS 0x0001 + struct { + struct xenpf_efi_time { + uint16_t year; + uint8_t month; + uint8_t day; + uint8_t hour; + uint8_t min; + uint8_t sec; + uint32_t ns; + int16_t tz; + uint8_t daylight; + } time; + uint32_t resolution; + uint32_t accuracy; + } get_time; + + struct xenpf_efi_time set_time; + +#define XEN_EFI_GET_WAKEUP_TIME_ENABLED 0x0001 +#define XEN_EFI_GET_WAKEUP_TIME_PENDING 0x0002 + struct xenpf_efi_time get_wakeup_time; + +#define XEN_EFI_SET_WAKEUP_TIME_ENABLE 0x0001 +#define XEN_EFI_SET_WAKEUP_TIME_ENABLE_ONLY 0x0002 + struct xenpf_efi_time set_wakeup_time; + +#define XEN_EFI_VARIABLE_NON_VOLATILE 0x0001 +#define XEN_EFI_VARIABLE_BOOTSERVICE_ACCESS 0x0002 +#define XEN_EFI_VARIABLE_RUNTIME_ACCESS 0x0004 + struct { + GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */ + xen_ulong_t size; + GUEST_HANDLE(void) data; + struct xenpf_efi_guid { + uint32_t data1; + uint16_t data2; + uint16_t data3; + uint8_t data4[8]; + } vendor_guid; + } get_variable, set_variable; + + struct { + xen_ulong_t size; + GUEST_HANDLE(void) name; /* UCS-2/UTF-16 string */ + struct xenpf_efi_guid vendor_guid; + } get_next_variable_name; + + struct { + uint32_t attr; + uint64_t max_store_size; + uint64_t remain_store_size; + uint64_t max_size; + } query_variable_info; + + struct { + GUEST_HANDLE(void) capsule_header_array; + xen_ulong_t capsule_count; + uint64_t max_capsule_size; + uint32_t reset_type; + } query_capsule_capabilities; + + struct { + GUEST_HANDLE(void) capsule_header_array; + xen_ulong_t capsule_count; + uint64_t sg_list; /* machine address */ + } update_capsule; + } u; +};
Re: [PATCH v7 08/10] xen: Put EFI machinery in place
On Mon, 30 Jun 2014, Daniel Kiper wrote: This patch enables EFI usage under Xen dom0. Standard EFI Linux Kernel infrastructure cannot be used because it requires direct access to EFI data and code. However, in dom0 case it is not possible because above mentioned EFI stuff is fully owned and controlled by Xen hypervisor. In this case all calls from dom0 to EFI must be requested via special hypercall which in turn executes relevant EFI code in behalf of dom0. When dom0 kernel boots it checks for EFI availability on a machine. If it is detected then artificial EFI system table is filled. Native EFI callas are replaced by functions which mimics them by calling relevant hypercall. Later pointer to EFI system table is passed to standard EFI machinery and it continues EFI subsystem initialization taking into account that there is no direct access to EFI boot services, runtime, tables, structures, etc. After that system runs as usual. This patch is based on Jan Beulich and Tang Liang work. Signed-off-by: Jan Beulich jbeul...@suse.com Signed-off-by: Tang Liang liang.t...@oracle.com Signed-off-by: Daniel Kiper daniel.ki...@oracle.com Reviewed-by: David Vrabel david.vra...@citrix.com Acked-by: Stefano Stabellini stefano.stabell...@eu.citrix.com v7 - suggestions/fixes: - move xen_efi_probe() declaration to include/xen/xen-ops.h (suggested by Stefano Stabellini). v6 - suggestions/fixes: - remove unneeded BUG() call (suggested by Stefano Stabellini). v5 - suggestions/fixes: - improve macro usage readability (suggested by Andrew Cooper and David Vrabel), - conditions cleanup (suggested by David Vrabel), - use -fshort-wchar option (suggested by Jan Beulich), - Kconfig rule cleanup (suggested by Jan Beulich), - forward port fixes from SUSE kernel (suggested by Jan Beulich), - improve commit message (suggested by David Vrabel). v4 - suggestions/fixes: - just populate an efi_system_table_t object (suggested by Matt Fleming). --- arch/x86/xen/enlighten.c | 15 ++ drivers/xen/Kconfig |4 + drivers/xen/Makefile |3 + drivers/xen/efi.c| 368 ++ include/xen/xen-ops.h| 11 ++ 5 files changed, 401 insertions(+) create mode 100644 drivers/xen/efi.c diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ffb101e..e27d2fe 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -32,6 +32,7 @@ #include linux/gfp.h #include linux/memblock.h #include linux/edd.h +#include linux/efi.h #include xen/xen.h #include xen/events.h @@ -1520,6 +1521,7 @@ asmlinkage __visible void __init xen_start_kernel(void) { struct physdev_set_iopl set_iopl; int rc; + efi_system_table_t *efi_systab_xen; if (!xen_start_info) return; @@ -1718,6 +1720,19 @@ asmlinkage __visible void __init xen_start_kernel(void) xen_setup_runstate_info(0); + efi_systab_xen = xen_efi_probe(); + + if (efi_systab_xen) { + strncpy((char *)boot_params.efi_info.efi_loader_signature, Xen, + sizeof(boot_params.efi_info.efi_loader_signature)); + boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen); + boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) 32); + + set_bit(EFI_BOOT, efi.flags); + set_bit(EFI_PARAVIRT, efi.flags); + set_bit(EFI_64BIT, efi.flags); + } + /* Start the world */ #ifdef CONFIG_X86_32 i386_start_kernel(); diff --git a/drivers/xen/Kconfig b/drivers/xen/Kconfig index 38fb36e..8bc0183 100644 --- a/drivers/xen/Kconfig +++ b/drivers/xen/Kconfig @@ -240,4 +240,8 @@ config XEN_MCE_LOG config XEN_HAVE_PVMMU bool +config XEN_EFI + def_bool y + depends on X86_64 EFI + endmenu diff --git a/drivers/xen/Makefile b/drivers/xen/Makefile index 45e00af..84044b5 100644 --- a/drivers/xen/Makefile +++ b/drivers/xen/Makefile @@ -9,6 +9,8 @@ obj-y += xenbus/ nostackp := $(call cc-option, -fno-stack-protector) CFLAGS_features.o:= $(nostackp) +CFLAGS_efi.o += -fshort-wchar + dom0-$(CONFIG_PCI) += pci.o dom0-$(CONFIG_USB_SUPPORT) += dbgp.o dom0-$(CONFIG_ACPI) += acpi.o $(xen-pad-y) @@ -33,6 +35,7 @@ obj-$(CONFIG_XEN_STUB) += xen-stub.o obj-$(CONFIG_XEN_ACPI_HOTPLUG_MEMORY)+= xen-acpi-memhotplug.o obj-$(CONFIG_XEN_ACPI_HOTPLUG_CPU) += xen-acpi-cpuhotplug.o obj-$(CONFIG_XEN_ACPI_PROCESSOR) += xen-acpi-processor.o +obj-$(CONFIG_XEN_EFI)+= efi.o xen-evtchn-y := evtchn.o xen-gntdev-y := gntdev.o xen-gntalloc-y := gntalloc.o diff --git a/drivers/xen/efi.c
Re: [PATCH 1/2] efi/arm64: fix potential NULL dereference of efi.systab
On Wed, 2014-07-02 at 12:13 +0200, Ard Biesheuvel wrote: On 2 July 2014 12:10, Ard Biesheuvel ard.biesheu...@linaro.org wrote: We assign efi.systab using efi_lookup_mapped_addr(), and test for !NULL, but then go on an dereference it anyway. Signed-off-by: Ard Biesheuvel ard.biesheu...@linaro.org --- arch/arm64/kernel/efi.c | 7 +-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 56c3327bbf79..e785f93f17cb 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c @@ -419,8 +419,11 @@ static int __init arm64_enter_virtual_mode(void) } efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table); - if (efi.systab) - set_bit(EFI_SYSTEM_TABLES, efi.flags); + if (!efi.systab) { + pr_err(Failed to remap EFI System Table!\n); ... this needs a kfree(virtmap) as well. And probably should unmap all the remapped regions in virtmap first. Presumably the systab will be in a runtime memory region which gets virtual mapping from remap_region(). If that succeeds, then the efi_lookup_mapped_addr should always succeed. But to be careful, we should probably bail out earlier if remap_region() ever returns zero. If all remaps work and efi_lookup_mapped_addr() fails, then we should try ioremap_cache() directly. Or do what x86 does and make a local copy of the table earlier when we early_memremap() it in uefi_init(). -- To unsubscribe from this list: send the line unsubscribe linux-efi in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html