diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-04 20:13:50 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-04 20:13:50 -0400 |
commit | 76f09aa464a1913efd596dd0edbf88f932fde08c (patch) | |
tree | ce9aadc9a1c30597b9d61c7aac86bfb2e6caf961 /arch | |
parent | e9c9eecabaa898ff3fedd98813ee4ac1a00d006a (diff) | |
parent | 99a5603e2a1f146ac0c6414d8a3669aa749ccff8 (diff) |
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI changes from Ingo Molnar:
"Main changes in this cycle are:
- arm64 efi stub fixes, preservation of FP/SIMD registers across
firmware calls, and conversion of the EFI stub code into a static
library - Ard Biesheuvel
- Xen EFI support - Daniel Kiper
- Support for autoloading the efivars driver - Lee, Chun-Yi
- Use the PE/COFF headers in the x86 EFI boot stub to request that
the stub be loaded with CONFIG_PHYSICAL_ALIGN alignment - Michael
Brown
- Consolidate all the x86 EFI quirks into one file - Saurabh Tangri
- Additional error logging in x86 EFI boot stub - Ulf Winkelvos
- Support loading initrd above 4G in EFI boot stub - Yinghai Lu
- EFI reboot patches for ACPI hardware reduced platforms"
* 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (31 commits)
efi/arm64: Handle missing virtual mapping for UEFI System Table
arch/x86/xen: Silence compiler warnings
xen: Silence compiler warnings
x86/efi: Request desired alignment via the PE/COFF headers
x86/efi: Add better error logging to EFI boot stub
efi: Autoload efivars
efi: Update stale locking comment for struct efivars
arch/x86: Remove efi_set_rtc_mmss()
arch/x86: Replace plain strings with constants
xen: Put EFI machinery in place
xen: Define EFI related stuff
arch/x86: Remove redundant set_bit(EFI_MEMMAP) call
arch/x86: Remove redundant set_bit(EFI_SYSTEM_TABLES) call
efi: Introduce EFI_PARAVIRT flag
arch/x86: Do not access EFI memory map if it is not available
efi: Use early_mem*() instead of early_io*()
arch/ia64: Define early_memunmap()
x86/reboot: Add EFI reboot quirk for ACPI Hardware Reduced flag
efi/reboot: Allow powering off machines using EFI
efi/reboot: Add generic wrapper around EfiResetSystem()
...
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm64/Kconfig | 6 | ||||
-rw-r--r-- | arch/arm64/Makefile | 1 | ||||
-rw-r--r-- | arch/arm64/include/asm/efi.h | 33 | ||||
-rw-r--r-- | arch/arm64/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/arm64/kernel/efi-stub.c | 48 | ||||
-rw-r--r-- | arch/arm64/kernel/efi.c | 42 | ||||
-rw-r--r-- | arch/ia64/include/asm/io.h | 1 | ||||
-rw-r--r-- | arch/ia64/kernel/process.c | 2 | ||||
-rw-r--r-- | arch/x86/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/boot/compressed/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 48 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.h | 16 | ||||
-rw-r--r-- | arch/x86/boot/header.S | 2 | ||||
-rw-r--r-- | arch/x86/include/asm/efi.h | 33 | ||||
-rw-r--r-- | arch/x86/kernel/reboot.c | 24 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 4 | ||||
-rw-r--r-- | arch/x86/platform/efi/Makefile | 2 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 483 | ||||
-rw-r--r-- | arch/x86/platform/efi/quirks.c | 290 | ||||
-rw-r--r-- | arch/x86/xen/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/xen/efi.c | 43 | ||||
-rw-r--r-- | arch/x86/xen/enlighten.c | 2 | ||||
-rw-r--r-- | arch/x86/xen/xen-ops.h | 8 |
23 files changed, 553 insertions, 543 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index f3b584be76d7..b0f9c9db9590 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -347,12 +347,18 @@ config CMDLINE_FORCE | |||
347 | This is useful if you cannot or don't want to change the | 347 | This is useful if you cannot or don't want to change the |
348 | command-line options your boot loader passes to the kernel. | 348 | command-line options your boot loader passes to the kernel. |
349 | 349 | ||
350 | config EFI_STUB | ||
351 | bool | ||
352 | |||
350 | config EFI | 353 | config EFI |
351 | bool "UEFI runtime support" | 354 | bool "UEFI runtime support" |
352 | depends on OF && !CPU_BIG_ENDIAN | 355 | depends on OF && !CPU_BIG_ENDIAN |
353 | select LIBFDT | 356 | select LIBFDT |
354 | select UCS2_STRING | 357 | select UCS2_STRING |
355 | select EFI_PARAMS_FROM_FDT | 358 | select EFI_PARAMS_FROM_FDT |
359 | select EFI_RUNTIME_WRAPPERS | ||
360 | select EFI_STUB | ||
361 | select EFI_ARMSTUB | ||
356 | default y | 362 | default y |
357 | help | 363 | help |
358 | This option provides support for runtime services provided | 364 | This option provides support for runtime services provided |
diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile index e8d025c1459e..57833546bf00 100644 --- a/arch/arm64/Makefile +++ b/arch/arm64/Makefile | |||
@@ -52,6 +52,7 @@ core-$(CONFIG_XEN) += arch/arm64/xen/ | |||
52 | core-$(CONFIG_CRYPTO) += arch/arm64/crypto/ | 52 | core-$(CONFIG_CRYPTO) += arch/arm64/crypto/ |
53 | libs-y := arch/arm64/lib/ $(libs-y) | 53 | libs-y := arch/arm64/lib/ $(libs-y) |
54 | libs-y += $(LIBGCC) | 54 | libs-y += $(LIBGCC) |
55 | libs-$(CONFIG_EFI_STUB) += drivers/firmware/efi/libstub/ | ||
55 | 56 | ||
56 | # Default target when executing plain make | 57 | # Default target when executing plain make |
57 | KBUILD_IMAGE := Image.gz | 58 | KBUILD_IMAGE := Image.gz |
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h index 5a46c4e7f539..a34fd3b12e2b 100644 --- a/arch/arm64/include/asm/efi.h +++ b/arch/arm64/include/asm/efi.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_EFI_H | 2 | #define _ASM_EFI_H |
3 | 3 | ||
4 | #include <asm/io.h> | 4 | #include <asm/io.h> |
5 | #include <asm/neon.h> | ||
5 | 6 | ||
6 | #ifdef CONFIG_EFI | 7 | #ifdef CONFIG_EFI |
7 | extern void efi_init(void); | 8 | extern void efi_init(void); |
@@ -11,4 +12,36 @@ extern void efi_idmap_init(void); | |||
11 | #define efi_idmap_init() | 12 | #define efi_idmap_init() |
12 | #endif | 13 | #endif |
13 | 14 | ||
15 | #define efi_call_virt(f, ...) \ | ||
16 | ({ \ | ||
17 | efi_##f##_t *__f = efi.systab->runtime->f; \ | ||
18 | efi_status_t __s; \ | ||
19 | \ | ||
20 | kernel_neon_begin(); \ | ||
21 | __s = __f(__VA_ARGS__); \ | ||
22 | kernel_neon_end(); \ | ||
23 | __s; \ | ||
24 | }) | ||
25 | |||
26 | #define __efi_call_virt(f, ...) \ | ||
27 | ({ \ | ||
28 | efi_##f##_t *__f = efi.systab->runtime->f; \ | ||
29 | \ | ||
30 | kernel_neon_begin(); \ | ||
31 | __f(__VA_ARGS__); \ | ||
32 | kernel_neon_end(); \ | ||
33 | }) | ||
34 | |||
35 | /* arch specific definitions used by the stub code */ | ||
36 | |||
37 | /* | ||
38 | * AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from | ||
39 | * start of kernel and may not cross a 2MiB boundary. We set alignment to | ||
40 | * 2MiB so we know it won't cross a 2MiB boundary. | ||
41 | */ | ||
42 | #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ | ||
43 | #define MAX_FDT_OFFSET SZ_512M | ||
44 | |||
45 | #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) | ||
46 | |||
14 | #endif /* _ASM_EFI_H */ | 47 | #endif /* _ASM_EFI_H */ |
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 27c72ef4fd7a..df7ef8768fc2 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
@@ -4,8 +4,7 @@ | |||
4 | 4 | ||
5 | CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) | 5 | CPPFLAGS_vmlinux.lds := -DTEXT_OFFSET=$(TEXT_OFFSET) |
6 | AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) | 6 | AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET) |
7 | CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) \ | 7 | CFLAGS_efi-stub.o := -DTEXT_OFFSET=$(TEXT_OFFSET) |
8 | -I$(src)/../../../scripts/dtc/libfdt | ||
9 | 8 | ||
10 | CFLAGS_REMOVE_ftrace.o = -pg | 9 | CFLAGS_REMOVE_ftrace.o = -pg |
11 | CFLAGS_REMOVE_insn.o = -pg | 10 | CFLAGS_REMOVE_insn.o = -pg |
diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c index e786e6cdc400..1317fef8dde9 100644 --- a/arch/arm64/kernel/efi-stub.c +++ b/arch/arm64/kernel/efi-stub.c | |||
@@ -10,46 +10,16 @@ | |||
10 | * | 10 | * |
11 | */ | 11 | */ |
12 | #include <linux/efi.h> | 12 | #include <linux/efi.h> |
13 | #include <linux/libfdt.h> | 13 | #include <asm/efi.h> |
14 | #include <asm/sections.h> | 14 | #include <asm/sections.h> |
15 | 15 | ||
16 | /* | 16 | efi_status_t handle_kernel_image(efi_system_table_t *sys_table, |
17 | * AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from | 17 | unsigned long *image_addr, |
18 | * start of kernel and may not cross a 2MiB boundary. We set alignment to | 18 | unsigned long *image_size, |
19 | * 2MiB so we know it won't cross a 2MiB boundary. | 19 | unsigned long *reserve_addr, |
20 | */ | 20 | unsigned long *reserve_size, |
21 | #define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ | 21 | unsigned long dram_base, |
22 | #define MAX_FDT_OFFSET SZ_512M | 22 | efi_loaded_image_t *image) |
23 | |||
24 | #define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) | ||
25 | |||
26 | static void efi_char16_printk(efi_system_table_t *sys_table_arg, | ||
27 | efi_char16_t *str); | ||
28 | |||
29 | static efi_status_t efi_open_volume(efi_system_table_t *sys_table, | ||
30 | void *__image, void **__fh); | ||
31 | static efi_status_t efi_file_close(void *handle); | ||
32 | |||
33 | static efi_status_t | ||
34 | efi_file_read(void *handle, unsigned long *size, void *addr); | ||
35 | |||
36 | static efi_status_t | ||
37 | efi_file_size(efi_system_table_t *sys_table, void *__fh, | ||
38 | efi_char16_t *filename_16, void **handle, u64 *file_sz); | ||
39 | |||
40 | /* Include shared EFI stub code */ | ||
41 | #include "../../../drivers/firmware/efi/efi-stub-helper.c" | ||
42 | #include "../../../drivers/firmware/efi/fdt.c" | ||
43 | #include "../../../drivers/firmware/efi/arm-stub.c" | ||
44 | |||
45 | |||
46 | static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, | ||
47 | unsigned long *image_addr, | ||
48 | unsigned long *image_size, | ||
49 | unsigned long *reserve_addr, | ||
50 | unsigned long *reserve_size, | ||
51 | unsigned long dram_base, | ||
52 | efi_loaded_image_t *image) | ||
53 | { | 23 | { |
54 | efi_status_t status; | 24 | efi_status_t status; |
55 | unsigned long kernel_size, kernel_memsize = 0; | 25 | unsigned long kernel_size, kernel_memsize = 0; |
@@ -69,7 +39,7 @@ static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, | |||
69 | if (*image_addr != (dram_base + TEXT_OFFSET)) { | 39 | if (*image_addr != (dram_base + TEXT_OFFSET)) { |
70 | pr_efi_err(sys_table, "Failed to alloc kernel memory\n"); | 40 | pr_efi_err(sys_table, "Failed to alloc kernel memory\n"); |
71 | efi_free(sys_table, kernel_memsize, *image_addr); | 41 | efi_free(sys_table, kernel_memsize, *image_addr); |
72 | return EFI_ERROR; | 42 | return EFI_LOAD_ERROR; |
73 | } | 43 | } |
74 | *image_size = kernel_memsize; | 44 | *image_size = kernel_memsize; |
75 | } | 45 | } |
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c index 14db1f6e8d7f..e72f3100958f 100644 --- a/arch/arm64/kernel/efi.c +++ b/arch/arm64/kernel/efi.c | |||
@@ -414,13 +414,24 @@ static int __init arm64_enter_virtual_mode(void) | |||
414 | for_each_efi_memory_desc(&memmap, md) { | 414 | for_each_efi_memory_desc(&memmap, md) { |
415 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) | 415 | if (!(md->attribute & EFI_MEMORY_RUNTIME)) |
416 | continue; | 416 | continue; |
417 | if (remap_region(md, &virt_md)) | 417 | if (!remap_region(md, &virt_md)) |
418 | ++count; | 418 | goto err_unmap; |
419 | ++count; | ||
419 | } | 420 | } |
420 | 421 | ||
421 | efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table); | 422 | efi.systab = (__force void *)efi_lookup_mapped_addr(efi_system_table); |
422 | if (efi.systab) | 423 | if (!efi.systab) { |
423 | set_bit(EFI_SYSTEM_TABLES, &efi.flags); | 424 | /* |
425 | * If we have no virtual mapping for the System Table at this | ||
426 | * point, the memory map doesn't cover the physical offset where | ||
427 | * it resides. This means the System Table will be inaccessible | ||
428 | * to Runtime Services themselves once the virtual mapping is | ||
429 | * installed. | ||
430 | */ | ||
431 | pr_err("Failed to remap EFI System Table -- buggy firmware?\n"); | ||
432 | goto err_unmap; | ||
433 | } | ||
434 | set_bit(EFI_SYSTEM_TABLES, &efi.flags); | ||
424 | 435 | ||
425 | local_irq_save(flags); | 436 | local_irq_save(flags); |
426 | cpu_switch_mm(idmap_pg_dir, &init_mm); | 437 | cpu_switch_mm(idmap_pg_dir, &init_mm); |
@@ -449,21 +460,18 @@ static int __init arm64_enter_virtual_mode(void) | |||
449 | 460 | ||
450 | /* Set up runtime services function pointers */ | 461 | /* Set up runtime services function pointers */ |
451 | runtime = efi.systab->runtime; | 462 | runtime = efi.systab->runtime; |
452 | efi.get_time = runtime->get_time; | 463 | efi_native_runtime_setup(); |
453 | efi.set_time = runtime->set_time; | ||
454 | efi.get_wakeup_time = runtime->get_wakeup_time; | ||
455 | efi.set_wakeup_time = runtime->set_wakeup_time; | ||
456 | efi.get_variable = runtime->get_variable; | ||
457 | efi.get_next_variable = runtime->get_next_variable; | ||
458 | efi.set_variable = runtime->set_variable; | ||
459 | efi.query_variable_info = runtime->query_variable_info; | ||
460 | efi.update_capsule = runtime->update_capsule; | ||
461 | efi.query_capsule_caps = runtime->query_capsule_caps; | ||
462 | efi.get_next_high_mono_count = runtime->get_next_high_mono_count; | ||
463 | efi.reset_system = runtime->reset_system; | ||
464 | |||
465 | set_bit(EFI_RUNTIME_SERVICES, &efi.flags); | 464 | set_bit(EFI_RUNTIME_SERVICES, &efi.flags); |
466 | 465 | ||
467 | return 0; | 466 | return 0; |
467 | |||
468 | err_unmap: | ||
469 | /* unmap all mappings that succeeded: there are 'count' of those */ | ||
470 | for (virt_md = virtmap; count--; virt_md += memmap.desc_size) { | ||
471 | md = virt_md; | ||
472 | iounmap((__force void __iomem *)md->virt_addr); | ||
473 | } | ||
474 | kfree(virtmap); | ||
475 | return -1; | ||
468 | } | 476 | } |
469 | early_initcall(arm64_enter_virtual_mode); | 477 | early_initcall(arm64_enter_virtual_mode); |
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index 0d2bcb37ec35..bee0acd52f7e 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h | |||
@@ -426,6 +426,7 @@ extern void iounmap (volatile void __iomem *addr); | |||
426 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); | 426 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); |
427 | #define early_memremap(phys_addr, size) early_ioremap(phys_addr, size) | 427 | #define early_memremap(phys_addr, size) early_ioremap(phys_addr, size) |
428 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); | 428 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); |
429 | #define early_memunmap(addr, size) early_iounmap(addr, size) | ||
429 | static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) | 430 | static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) |
430 | { | 431 | { |
431 | return ioremap(phys_addr, size); | 432 | return ioremap(phys_addr, size); |
diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c index 55d4ba47a907..deed6fa96bb0 100644 --- a/arch/ia64/kernel/process.c +++ b/arch/ia64/kernel/process.c | |||
@@ -662,7 +662,7 @@ void | |||
662 | machine_restart (char *restart_cmd) | 662 | machine_restart (char *restart_cmd) |
663 | { | 663 | { |
664 | (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0); | 664 | (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0); |
665 | (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); | 665 | efi_reboot(REBOOT_WARM, NULL); |
666 | } | 666 | } |
667 | 667 | ||
668 | void | 668 | void |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 2840c27d4479..3fc7d724d0a3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1522,6 +1522,7 @@ config EFI | |||
1522 | bool "EFI runtime service support" | 1522 | bool "EFI runtime service support" |
1523 | depends on ACPI | 1523 | depends on ACPI |
1524 | select UCS2_STRING | 1524 | select UCS2_STRING |
1525 | select EFI_RUNTIME_WRAPPERS | ||
1525 | ---help--- | 1526 | ---help--- |
1526 | This enables the kernel to use EFI runtime services that are | 1527 | This enables the kernel to use EFI runtime services that are |
1527 | available (such as the EFI variable services). | 1528 | available (such as the EFI variable services). |
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 \ | |||
33 | $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone | 33 | $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone |
34 | 34 | ||
35 | ifeq ($(CONFIG_EFI_STUB), y) | 35 | ifeq ($(CONFIG_EFI_STUB), y) |
36 | VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o | 36 | VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \ |
37 | $(objtree)/drivers/firmware/efi/libstub/lib.a | ||
37 | endif | 38 | endif |
38 | 39 | ||
39 | $(obj)/vmlinux: $(VMLINUX_OBJS) FORCE | 40 | $(obj)/vmlinux: $(VMLINUX_OBJS) FORCE |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index 0331d765c2bb..f277184e2ac1 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -19,10 +19,7 @@ | |||
19 | 19 | ||
20 | static efi_system_table_t *sys_table; | 20 | static efi_system_table_t *sys_table; |
21 | 21 | ||
22 | static struct efi_config *efi_early; | 22 | struct efi_config *efi_early; |
23 | |||
24 | #define efi_call_early(f, ...) \ | ||
25 | efi_early->call(efi_early->f, __VA_ARGS__); | ||
26 | 23 | ||
27 | #define BOOT_SERVICES(bits) \ | 24 | #define BOOT_SERVICES(bits) \ |
28 | static void setup_boot_services##bits(struct efi_config *c) \ | 25 | static void setup_boot_services##bits(struct efi_config *c) \ |
@@ -48,8 +45,7 @@ static void setup_boot_services##bits(struct efi_config *c) \ | |||
48 | BOOT_SERVICES(32); | 45 | BOOT_SERVICES(32); |
49 | BOOT_SERVICES(64); | 46 | BOOT_SERVICES(64); |
50 | 47 | ||
51 | static void efi_printk(efi_system_table_t *, char *); | 48 | void efi_char16_printk(efi_system_table_t *, efi_char16_t *); |
52 | static void efi_char16_printk(efi_system_table_t *, efi_char16_t *); | ||
53 | 49 | ||
54 | static efi_status_t | 50 | static efi_status_t |
55 | __file_size32(void *__fh, efi_char16_t *filename_16, | 51 | __file_size32(void *__fh, efi_char16_t *filename_16, |
@@ -156,7 +152,7 @@ grow: | |||
156 | 152 | ||
157 | return status; | 153 | return status; |
158 | } | 154 | } |
159 | static efi_status_t | 155 | efi_status_t |
160 | efi_file_size(efi_system_table_t *sys_table, void *__fh, | 156 | efi_file_size(efi_system_table_t *sys_table, void *__fh, |
161 | efi_char16_t *filename_16, void **handle, u64 *file_sz) | 157 | efi_char16_t *filename_16, void **handle, u64 *file_sz) |
162 | { | 158 | { |
@@ -166,7 +162,7 @@ efi_file_size(efi_system_table_t *sys_table, void *__fh, | |||
166 | return __file_size32(__fh, filename_16, handle, file_sz); | 162 | return __file_size32(__fh, filename_16, handle, file_sz); |
167 | } | 163 | } |
168 | 164 | ||
169 | static inline efi_status_t | 165 | efi_status_t |
170 | efi_file_read(void *handle, unsigned long *size, void *addr) | 166 | efi_file_read(void *handle, unsigned long *size, void *addr) |
171 | { | 167 | { |
172 | unsigned long func; | 168 | unsigned long func; |
@@ -184,7 +180,7 @@ efi_file_read(void *handle, unsigned long *size, void *addr) | |||
184 | } | 180 | } |
185 | } | 181 | } |
186 | 182 | ||
187 | static inline efi_status_t efi_file_close(void *handle) | 183 | efi_status_t efi_file_close(void *handle) |
188 | { | 184 | { |
189 | if (efi_early->is64) { | 185 | if (efi_early->is64) { |
190 | efi_file_handle_64_t *fh = handle; | 186 | efi_file_handle_64_t *fh = handle; |
@@ -249,7 +245,7 @@ static inline efi_status_t __open_volume64(void *__image, void **__fh) | |||
249 | return status; | 245 | return status; |
250 | } | 246 | } |
251 | 247 | ||
252 | static inline efi_status_t | 248 | efi_status_t |
253 | efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) | 249 | efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) |
254 | { | 250 | { |
255 | if (efi_early->is64) | 251 | if (efi_early->is64) |
@@ -258,7 +254,7 @@ efi_open_volume(efi_system_table_t *sys_table, void *__image, void **__fh) | |||
258 | return __open_volume32(__image, __fh); | 254 | return __open_volume32(__image, __fh); |
259 | } | 255 | } |
260 | 256 | ||
261 | static void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) | 257 | void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) |
262 | { | 258 | { |
263 | unsigned long output_string; | 259 | unsigned long output_string; |
264 | size_t offset; | 260 | size_t offset; |
@@ -284,8 +280,6 @@ static void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) | |||
284 | } | 280 | } |
285 | } | 281 | } |
286 | 282 | ||
287 | #include "../../../../drivers/firmware/efi/efi-stub-helper.c" | ||
288 | |||
289 | static void find_bits(unsigned long mask, u8 *pos, u8 *size) | 283 | static void find_bits(unsigned long mask, u8 *pos, u8 *size) |
290 | { | 284 | { |
291 | u8 first, len; | 285 | u8 first, len; |
@@ -1038,6 +1032,7 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
1038 | int i; | 1032 | int i; |
1039 | unsigned long ramdisk_addr; | 1033 | unsigned long ramdisk_addr; |
1040 | unsigned long ramdisk_size; | 1034 | unsigned long ramdisk_size; |
1035 | unsigned long initrd_addr_max; | ||
1041 | 1036 | ||
1042 | efi_early = c; | 1037 | efi_early = c; |
1043 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; | 1038 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; |
@@ -1100,14 +1095,21 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
1100 | 1095 | ||
1101 | memset(sdt, 0, sizeof(*sdt)); | 1096 | memset(sdt, 0, sizeof(*sdt)); |
1102 | 1097 | ||
1098 | if (hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) | ||
1099 | initrd_addr_max = -1UL; | ||
1100 | else | ||
1101 | initrd_addr_max = hdr->initrd_addr_max; | ||
1102 | |||
1103 | status = handle_cmdline_files(sys_table, image, | 1103 | status = handle_cmdline_files(sys_table, image, |
1104 | (char *)(unsigned long)hdr->cmd_line_ptr, | 1104 | (char *)(unsigned long)hdr->cmd_line_ptr, |
1105 | "initrd=", hdr->initrd_addr_max, | 1105 | "initrd=", initrd_addr_max, |
1106 | &ramdisk_addr, &ramdisk_size); | 1106 | &ramdisk_addr, &ramdisk_size); |
1107 | if (status != EFI_SUCCESS) | 1107 | if (status != EFI_SUCCESS) |
1108 | goto fail2; | 1108 | goto fail2; |
1109 | hdr->ramdisk_image = ramdisk_addr; | 1109 | hdr->ramdisk_image = ramdisk_addr & 0xffffffff; |
1110 | hdr->ramdisk_size = ramdisk_size; | 1110 | hdr->ramdisk_size = ramdisk_size & 0xffffffff; |
1111 | boot_params->ext_ramdisk_image = (u64)ramdisk_addr >> 32; | ||
1112 | boot_params->ext_ramdisk_size = (u64)ramdisk_size >> 32; | ||
1111 | 1113 | ||
1112 | return boot_params; | 1114 | return boot_params; |
1113 | fail2: | 1115 | fail2: |
@@ -1374,7 +1376,10 @@ struct boot_params *efi_main(struct efi_config *c, | |||
1374 | 1376 | ||
1375 | setup_graphics(boot_params); | 1377 | setup_graphics(boot_params); |
1376 | 1378 | ||
1377 | setup_efi_pci(boot_params); | 1379 | status = setup_efi_pci(boot_params); |
1380 | if (status != EFI_SUCCESS) { | ||
1381 | efi_printk(sys_table, "setup_efi_pci() failed!\n"); | ||
1382 | } | ||
1378 | 1383 | ||
1379 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, | 1384 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, |
1380 | sizeof(*gdt), (void **)&gdt); | 1385 | sizeof(*gdt), (void **)&gdt); |
@@ -1401,16 +1406,20 @@ struct boot_params *efi_main(struct efi_config *c, | |||
1401 | hdr->init_size, hdr->init_size, | 1406 | hdr->init_size, hdr->init_size, |
1402 | hdr->pref_address, | 1407 | hdr->pref_address, |
1403 | hdr->kernel_alignment); | 1408 | hdr->kernel_alignment); |
1404 | if (status != EFI_SUCCESS) | 1409 | if (status != EFI_SUCCESS) { |
1410 | efi_printk(sys_table, "efi_relocate_kernel() failed!\n"); | ||
1405 | goto fail; | 1411 | goto fail; |
1412 | } | ||
1406 | 1413 | ||
1407 | hdr->pref_address = hdr->code32_start; | 1414 | hdr->pref_address = hdr->code32_start; |
1408 | hdr->code32_start = bzimage_addr; | 1415 | hdr->code32_start = bzimage_addr; |
1409 | } | 1416 | } |
1410 | 1417 | ||
1411 | status = exit_boot(boot_params, handle, is64); | 1418 | status = exit_boot(boot_params, handle, is64); |
1412 | if (status != EFI_SUCCESS) | 1419 | if (status != EFI_SUCCESS) { |
1420 | efi_printk(sys_table, "exit_boot() failed!\n"); | ||
1413 | goto fail; | 1421 | goto fail; |
1422 | } | ||
1414 | 1423 | ||
1415 | memset((char *)gdt->address, 0x0, gdt->size); | 1424 | memset((char *)gdt->address, 0x0, gdt->size); |
1416 | desc = (struct desc_struct *)gdt->address; | 1425 | desc = (struct desc_struct *)gdt->address; |
@@ -1470,5 +1479,6 @@ struct boot_params *efi_main(struct efi_config *c, | |||
1470 | 1479 | ||
1471 | return boot_params; | 1480 | return boot_params; |
1472 | fail: | 1481 | fail: |
1482 | efi_printk(sys_table, "efi_main() failed!\n"); | ||
1473 | return NULL; | 1483 | return NULL; |
1474 | } | 1484 | } |
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 { | |||
103 | void *blt; | 103 | void *blt; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | struct efi_config { | ||
107 | u64 image_handle; | ||
108 | u64 table; | ||
109 | u64 allocate_pool; | ||
110 | u64 allocate_pages; | ||
111 | u64 get_memory_map; | ||
112 | u64 free_pool; | ||
113 | u64 free_pages; | ||
114 | u64 locate_handle; | ||
115 | u64 handle_protocol; | ||
116 | u64 exit_boot_services; | ||
117 | u64 text_output; | ||
118 | efi_status_t (*call)(unsigned long, ...); | ||
119 | bool is64; | ||
120 | } __packed; | ||
121 | |||
122 | #endif /* BOOT_COMPRESSED_EBOOT_H */ | 106 | #endif /* BOOT_COMPRESSED_EBOOT_H */ |
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index 7a6d43a554d7..16ef02596db2 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S | |||
@@ -154,7 +154,7 @@ extra_header_fields: | |||
154 | #else | 154 | #else |
155 | .quad 0 # ImageBase | 155 | .quad 0 # ImageBase |
156 | #endif | 156 | #endif |
157 | .long 0x20 # SectionAlignment | 157 | .long CONFIG_PHYSICAL_ALIGN # SectionAlignment |
158 | .long 0x20 # FileAlignment | 158 | .long 0x20 # FileAlignment |
159 | .word 0 # MajorOperatingSystemVersion | 159 | .word 0 # MajorOperatingSystemVersion |
160 | .word 0 # MinorOperatingSystemVersion | 160 | .word 0 # MinorOperatingSystemVersion |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 1eb5f6433ad8..044a2fd3c5fe 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -104,6 +104,8 @@ extern void __init runtime_code_page_mkexec(void); | |||
104 | extern void __init efi_runtime_mkexec(void); | 104 | extern void __init efi_runtime_mkexec(void); |
105 | extern void __init efi_dump_pagetable(void); | 105 | extern void __init efi_dump_pagetable(void); |
106 | extern void __init efi_apply_memmap_quirks(void); | 106 | extern void __init efi_apply_memmap_quirks(void); |
107 | extern int __init efi_reuse_config(u64 tables, int nr_tables); | ||
108 | extern void efi_delete_dummy_variable(void); | ||
107 | 109 | ||
108 | struct efi_setup_data { | 110 | struct efi_setup_data { |
109 | u64 fw_vendor; | 111 | u64 fw_vendor; |
@@ -156,6 +158,33 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( | |||
156 | return EFI_SUCCESS; | 158 | return EFI_SUCCESS; |
157 | } | 159 | } |
158 | #endif /* CONFIG_EFI_MIXED */ | 160 | #endif /* CONFIG_EFI_MIXED */ |
161 | |||
162 | |||
163 | /* arch specific definitions used by the stub code */ | ||
164 | |||
165 | struct efi_config { | ||
166 | u64 image_handle; | ||
167 | u64 table; | ||
168 | u64 allocate_pool; | ||
169 | u64 allocate_pages; | ||
170 | u64 get_memory_map; | ||
171 | u64 free_pool; | ||
172 | u64 free_pages; | ||
173 | u64 locate_handle; | ||
174 | u64 handle_protocol; | ||
175 | u64 exit_boot_services; | ||
176 | u64 text_output; | ||
177 | efi_status_t (*call)(unsigned long, ...); | ||
178 | bool is64; | ||
179 | } __packed; | ||
180 | |||
181 | extern struct efi_config *efi_early; | ||
182 | |||
183 | #define efi_call_early(f, ...) \ | ||
184 | efi_early->call(efi_early->f, __VA_ARGS__); | ||
185 | |||
186 | extern bool efi_reboot_required(void); | ||
187 | |||
159 | #else | 188 | #else |
160 | /* | 189 | /* |
161 | * IF EFI is not configured, have the EFI calls return -ENOSYS. | 190 | * IF EFI is not configured, have the EFI calls return -ENOSYS. |
@@ -168,6 +197,10 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( | |||
168 | #define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS) | 197 | #define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS) |
169 | #define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS) | 198 | #define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS) |
170 | static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} | 199 | static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} |
200 | static inline bool efi_reboot_required(void) | ||
201 | { | ||
202 | return false; | ||
203 | } | ||
171 | #endif /* CONFIG_EFI */ | 204 | #endif /* CONFIG_EFI */ |
172 | 205 | ||
173 | #endif /* _ASM_X86_EFI_H */ | 206 | #endif /* _ASM_X86_EFI_H */ |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 52b1157c53eb..17962e667a91 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/mc146818rtc.h> | 28 | #include <linux/mc146818rtc.h> |
29 | #include <asm/realmode.h> | 29 | #include <asm/realmode.h> |
30 | #include <asm/x86_init.h> | 30 | #include <asm/x86_init.h> |
31 | #include <asm/efi.h> | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * Power off function, if any | 34 | * Power off function, if any |
@@ -401,12 +402,25 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
401 | 402 | ||
402 | static int __init reboot_init(void) | 403 | static int __init reboot_init(void) |
403 | { | 404 | { |
405 | int rv; | ||
406 | |||
404 | /* | 407 | /* |
405 | * Only do the DMI check if reboot_type hasn't been overridden | 408 | * Only do the DMI check if reboot_type hasn't been overridden |
406 | * on the command line | 409 | * on the command line |
407 | */ | 410 | */ |
408 | if (reboot_default) | 411 | if (!reboot_default) |
409 | dmi_check_system(reboot_dmi_table); | 412 | return 0; |
413 | |||
414 | /* | ||
415 | * The DMI quirks table takes precedence. If no quirks entry | ||
416 | * matches and the ACPI Hardware Reduced bit is set, force EFI | ||
417 | * reboot. | ||
418 | */ | ||
419 | rv = dmi_check_system(reboot_dmi_table); | ||
420 | |||
421 | if (!rv && efi_reboot_required()) | ||
422 | reboot_type = BOOT_EFI; | ||
423 | |||
410 | return 0; | 424 | return 0; |
411 | } | 425 | } |
412 | core_initcall(reboot_init); | 426 | core_initcall(reboot_init); |
@@ -528,11 +542,7 @@ static void native_machine_emergency_restart(void) | |||
528 | break; | 542 | break; |
529 | 543 | ||
530 | case BOOT_EFI: | 544 | case BOOT_EFI: |
531 | if (efi_enabled(EFI_RUNTIME_SERVICES)) | 545 | efi_reboot(reboot_mode, NULL); |
532 | efi.reset_system(reboot_mode == REBOOT_WARM ? | ||
533 | EFI_RESET_WARM : | ||
534 | EFI_RESET_COLD, | ||
535 | EFI_SUCCESS, 0, NULL); | ||
536 | reboot_type = BOOT_BIOS; | 546 | reboot_type = BOOT_BIOS; |
537 | break; | 547 | break; |
538 | 548 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 78a0e6298922..41ead8d3bc0b 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -924,10 +924,10 @@ void __init setup_arch(char **cmdline_p) | |||
924 | #endif | 924 | #endif |
925 | #ifdef CONFIG_EFI | 925 | #ifdef CONFIG_EFI |
926 | if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, | 926 | if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, |
927 | "EL32", 4)) { | 927 | EFI32_LOADER_SIGNATURE, 4)) { |
928 | set_bit(EFI_BOOT, &efi.flags); | 928 | set_bit(EFI_BOOT, &efi.flags); |
929 | } else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, | 929 | } else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature, |
930 | "EL64", 4)) { | 930 | EFI64_LOADER_SIGNATURE, 4)) { |
931 | set_bit(EFI_BOOT, &efi.flags); | 931 | set_bit(EFI_BOOT, &efi.flags); |
932 | set_bit(EFI_64BIT, &efi.flags); | 932 | set_bit(EFI_64BIT, &efi.flags); |
933 | } | 933 | } |
diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile index d51045afcaaf..2846aaab5103 100644 --- a/arch/x86/platform/efi/Makefile +++ b/arch/x86/platform/efi/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o | 1 | obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o |
2 | obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o | 2 | obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o |
3 | obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o | 3 | obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o |
4 | obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o | 4 | obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 87fc96bcc13c..850da94fef30 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -56,13 +56,6 @@ | |||
56 | 56 | ||
57 | #define EFI_DEBUG | 57 | #define EFI_DEBUG |
58 | 58 | ||
59 | #define EFI_MIN_RESERVE 5120 | ||
60 | |||
61 | #define EFI_DUMMY_GUID \ | ||
62 | EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) | ||
63 | |||
64 | static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; | ||
65 | |||
66 | struct efi_memory_map memmap; | 59 | struct efi_memory_map memmap; |
67 | 60 | ||
68 | static struct efi efi_phys __initdata; | 61 | static struct efi efi_phys __initdata; |
@@ -95,139 +88,6 @@ static int __init setup_add_efi_memmap(char *arg) | |||
95 | } | 88 | } |
96 | early_param("add_efi_memmap", setup_add_efi_memmap); | 89 | early_param("add_efi_memmap", setup_add_efi_memmap); |
97 | 90 | ||
98 | static bool efi_no_storage_paranoia; | ||
99 | |||
100 | static int __init setup_storage_paranoia(char *arg) | ||
101 | { | ||
102 | efi_no_storage_paranoia = true; | ||
103 | return 0; | ||
104 | } | ||
105 | early_param("efi_no_storage_paranoia", setup_storage_paranoia); | ||
106 | |||
107 | static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) | ||
108 | { | ||
109 | unsigned long flags; | ||
110 | efi_status_t status; | ||
111 | |||
112 | spin_lock_irqsave(&rtc_lock, flags); | ||
113 | status = efi_call_virt(get_time, tm, tc); | ||
114 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
115 | return status; | ||
116 | } | ||
117 | |||
118 | static efi_status_t virt_efi_set_time(efi_time_t *tm) | ||
119 | { | ||
120 | unsigned long flags; | ||
121 | efi_status_t status; | ||
122 | |||
123 | spin_lock_irqsave(&rtc_lock, flags); | ||
124 | status = efi_call_virt(set_time, tm); | ||
125 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
126 | return status; | ||
127 | } | ||
128 | |||
129 | static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled, | ||
130 | efi_bool_t *pending, | ||
131 | efi_time_t *tm) | ||
132 | { | ||
133 | unsigned long flags; | ||
134 | efi_status_t status; | ||
135 | |||
136 | spin_lock_irqsave(&rtc_lock, flags); | ||
137 | status = efi_call_virt(get_wakeup_time, enabled, pending, tm); | ||
138 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
139 | return status; | ||
140 | } | ||
141 | |||
142 | static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm) | ||
143 | { | ||
144 | unsigned long flags; | ||
145 | efi_status_t status; | ||
146 | |||
147 | spin_lock_irqsave(&rtc_lock, flags); | ||
148 | status = efi_call_virt(set_wakeup_time, enabled, tm); | ||
149 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
150 | return status; | ||
151 | } | ||
152 | |||
153 | static efi_status_t virt_efi_get_variable(efi_char16_t *name, | ||
154 | efi_guid_t *vendor, | ||
155 | u32 *attr, | ||
156 | unsigned long *data_size, | ||
157 | void *data) | ||
158 | { | ||
159 | return efi_call_virt(get_variable, | ||
160 | name, vendor, attr, | ||
161 | data_size, data); | ||
162 | } | ||
163 | |||
164 | static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, | ||
165 | efi_char16_t *name, | ||
166 | efi_guid_t *vendor) | ||
167 | { | ||
168 | return efi_call_virt(get_next_variable, | ||
169 | name_size, name, vendor); | ||
170 | } | ||
171 | |||
172 | static efi_status_t virt_efi_set_variable(efi_char16_t *name, | ||
173 | efi_guid_t *vendor, | ||
174 | u32 attr, | ||
175 | unsigned long data_size, | ||
176 | void *data) | ||
177 | { | ||
178 | return efi_call_virt(set_variable, | ||
179 | name, vendor, attr, | ||
180 | data_size, data); | ||
181 | } | ||
182 | |||
183 | static efi_status_t virt_efi_query_variable_info(u32 attr, | ||
184 | u64 *storage_space, | ||
185 | u64 *remaining_space, | ||
186 | u64 *max_variable_size) | ||
187 | { | ||
188 | if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) | ||
189 | return EFI_UNSUPPORTED; | ||
190 | |||
191 | return efi_call_virt(query_variable_info, attr, storage_space, | ||
192 | remaining_space, max_variable_size); | ||
193 | } | ||
194 | |||
195 | static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) | ||
196 | { | ||
197 | return efi_call_virt(get_next_high_mono_count, count); | ||
198 | } | ||
199 | |||
200 | static void virt_efi_reset_system(int reset_type, | ||
201 | efi_status_t status, | ||
202 | unsigned long data_size, | ||
203 | efi_char16_t *data) | ||
204 | { | ||
205 | __efi_call_virt(reset_system, reset_type, status, | ||
206 | data_size, data); | ||
207 | } | ||
208 | |||
209 | static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules, | ||
210 | unsigned long count, | ||
211 | unsigned long sg_list) | ||
212 | { | ||
213 | if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) | ||
214 | return EFI_UNSUPPORTED; | ||
215 | |||
216 | return efi_call_virt(update_capsule, capsules, count, sg_list); | ||
217 | } | ||
218 | |||
219 | static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, | ||
220 | unsigned long count, | ||
221 | u64 *max_size, | ||
222 | int *reset_type) | ||
223 | { | ||
224 | if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) | ||
225 | return EFI_UNSUPPORTED; | ||
226 | |||
227 | return efi_call_virt(query_capsule_caps, capsules, count, max_size, | ||
228 | reset_type); | ||
229 | } | ||
230 | |||
231 | static efi_status_t __init phys_efi_set_virtual_address_map( | 91 | static efi_status_t __init phys_efi_set_virtual_address_map( |
232 | unsigned long memory_map_size, | 92 | unsigned long memory_map_size, |
233 | unsigned long descriptor_size, | 93 | unsigned long descriptor_size, |
@@ -244,42 +104,6 @@ static efi_status_t __init phys_efi_set_virtual_address_map( | |||
244 | return status; | 104 | return status; |
245 | } | 105 | } |
246 | 106 | ||
247 | int efi_set_rtc_mmss(const struct timespec *now) | ||
248 | { | ||
249 | unsigned long nowtime = now->tv_sec; | ||
250 | efi_status_t status; | ||
251 | efi_time_t eft; | ||
252 | efi_time_cap_t cap; | ||
253 | struct rtc_time tm; | ||
254 | |||
255 | status = efi.get_time(&eft, &cap); | ||
256 | if (status != EFI_SUCCESS) { | ||
257 | pr_err("Oops: efitime: can't read time!\n"); | ||
258 | return -1; | ||
259 | } | ||
260 | |||
261 | rtc_time_to_tm(nowtime, &tm); | ||
262 | if (!rtc_valid_tm(&tm)) { | ||
263 | eft.year = tm.tm_year + 1900; | ||
264 | eft.month = tm.tm_mon + 1; | ||
265 | eft.day = tm.tm_mday; | ||
266 | eft.minute = tm.tm_min; | ||
267 | eft.second = tm.tm_sec; | ||
268 | eft.nanosecond = 0; | ||
269 | } else { | ||
270 | pr_err("%s: Invalid EFI RTC value: write of %lx to EFI RTC failed\n", | ||
271 | __func__, nowtime); | ||
272 | return -1; | ||
273 | } | ||
274 | |||
275 | status = efi.set_time(&eft); | ||
276 | if (status != EFI_SUCCESS) { | ||
277 | pr_err("Oops: efitime: can't write time!\n"); | ||
278 | return -1; | ||
279 | } | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | void efi_get_time(struct timespec *now) | 107 | void efi_get_time(struct timespec *now) |
284 | { | 108 | { |
285 | efi_status_t status; | 109 | efi_status_t status; |
@@ -350,6 +174,9 @@ int __init efi_memblock_x86_reserve_range(void) | |||
350 | struct efi_info *e = &boot_params.efi_info; | 174 | struct efi_info *e = &boot_params.efi_info; |
351 | unsigned long pmap; | 175 | unsigned long pmap; |
352 | 176 | ||
177 | if (efi_enabled(EFI_PARAVIRT)) | ||
178 | return 0; | ||
179 | |||
353 | #ifdef CONFIG_X86_32 | 180 | #ifdef CONFIG_X86_32 |
354 | /* Can't handle data above 4GB at this time */ | 181 | /* Can't handle data above 4GB at this time */ |
355 | if (e->efi_memmap_hi) { | 182 | if (e->efi_memmap_hi) { |
@@ -392,69 +219,15 @@ static void __init print_efi_memmap(void) | |||
392 | #endif /* EFI_DEBUG */ | 219 | #endif /* EFI_DEBUG */ |
393 | } | 220 | } |
394 | 221 | ||
395 | void __init efi_reserve_boot_services(void) | ||
396 | { | ||
397 | void *p; | ||
398 | |||
399 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
400 | efi_memory_desc_t *md = p; | ||
401 | u64 start = md->phys_addr; | ||
402 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
403 | |||
404 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
405 | md->type != EFI_BOOT_SERVICES_DATA) | ||
406 | continue; | ||
407 | /* Only reserve where possible: | ||
408 | * - Not within any already allocated areas | ||
409 | * - Not over any memory area (really needed, if above?) | ||
410 | * - Not within any part of the kernel | ||
411 | * - Not the bios reserved area | ||
412 | */ | ||
413 | if ((start + size > __pa_symbol(_text) | ||
414 | && start <= __pa_symbol(_end)) || | ||
415 | !e820_all_mapped(start, start+size, E820_RAM) || | ||
416 | memblock_is_region_reserved(start, size)) { | ||
417 | /* Could not reserve, skip it */ | ||
418 | md->num_pages = 0; | ||
419 | memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", | ||
420 | start, start+size-1); | ||
421 | } else | ||
422 | memblock_reserve(start, size); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | void __init efi_unmap_memmap(void) | 222 | void __init efi_unmap_memmap(void) |
427 | { | 223 | { |
428 | clear_bit(EFI_MEMMAP, &efi.flags); | 224 | clear_bit(EFI_MEMMAP, &efi.flags); |
429 | if (memmap.map) { | 225 | if (memmap.map) { |
430 | early_iounmap(memmap.map, memmap.nr_map * memmap.desc_size); | 226 | early_memunmap(memmap.map, memmap.nr_map * memmap.desc_size); |
431 | memmap.map = NULL; | 227 | memmap.map = NULL; |
432 | } | 228 | } |
433 | } | 229 | } |
434 | 230 | ||
435 | void __init efi_free_boot_services(void) | ||
436 | { | ||
437 | void *p; | ||
438 | |||
439 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
440 | efi_memory_desc_t *md = p; | ||
441 | unsigned long long start = md->phys_addr; | ||
442 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
443 | |||
444 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
445 | md->type != EFI_BOOT_SERVICES_DATA) | ||
446 | continue; | ||
447 | |||
448 | /* Could not reserve boot area */ | ||
449 | if (!size) | ||
450 | continue; | ||
451 | |||
452 | free_bootmem_late(start, size); | ||
453 | } | ||
454 | |||
455 | efi_unmap_memmap(); | ||
456 | } | ||
457 | |||
458 | static int __init efi_systab_init(void *phys) | 231 | static int __init efi_systab_init(void *phys) |
459 | { | 232 | { |
460 | if (efi_enabled(EFI_64BIT)) { | 233 | if (efi_enabled(EFI_64BIT)) { |
@@ -467,12 +240,12 @@ static int __init efi_systab_init(void *phys) | |||
467 | if (!data) | 240 | if (!data) |
468 | return -ENOMEM; | 241 | return -ENOMEM; |
469 | } | 242 | } |
470 | systab64 = early_ioremap((unsigned long)phys, | 243 | systab64 = early_memremap((unsigned long)phys, |
471 | sizeof(*systab64)); | 244 | sizeof(*systab64)); |
472 | if (systab64 == NULL) { | 245 | if (systab64 == NULL) { |
473 | pr_err("Couldn't map the system table!\n"); | 246 | pr_err("Couldn't map the system table!\n"); |
474 | if (data) | 247 | if (data) |
475 | early_iounmap(data, sizeof(*data)); | 248 | early_memunmap(data, sizeof(*data)); |
476 | return -ENOMEM; | 249 | return -ENOMEM; |
477 | } | 250 | } |
478 | 251 | ||
@@ -504,9 +277,9 @@ static int __init efi_systab_init(void *phys) | |||
504 | systab64->tables; | 277 | systab64->tables; |
505 | tmp |= data ? data->tables : systab64->tables; | 278 | tmp |= data ? data->tables : systab64->tables; |
506 | 279 | ||
507 | early_iounmap(systab64, sizeof(*systab64)); | 280 | early_memunmap(systab64, sizeof(*systab64)); |
508 | if (data) | 281 | if (data) |
509 | early_iounmap(data, sizeof(*data)); | 282 | early_memunmap(data, sizeof(*data)); |
510 | #ifdef CONFIG_X86_32 | 283 | #ifdef CONFIG_X86_32 |
511 | if (tmp >> 32) { | 284 | if (tmp >> 32) { |
512 | pr_err("EFI data located above 4GB, disabling EFI.\n"); | 285 | pr_err("EFI data located above 4GB, disabling EFI.\n"); |
@@ -516,7 +289,7 @@ static int __init efi_systab_init(void *phys) | |||
516 | } else { | 289 | } else { |
517 | efi_system_table_32_t *systab32; | 290 | efi_system_table_32_t *systab32; |
518 | 291 | ||
519 | systab32 = early_ioremap((unsigned long)phys, | 292 | systab32 = early_memremap((unsigned long)phys, |
520 | sizeof(*systab32)); | 293 | sizeof(*systab32)); |
521 | if (systab32 == NULL) { | 294 | if (systab32 == NULL) { |
522 | pr_err("Couldn't map the system table!\n"); | 295 | pr_err("Couldn't map the system table!\n"); |
@@ -537,7 +310,7 @@ static int __init efi_systab_init(void *phys) | |||
537 | efi_systab.nr_tables = systab32->nr_tables; | 310 | efi_systab.nr_tables = systab32->nr_tables; |
538 | efi_systab.tables = systab32->tables; | 311 | efi_systab.tables = systab32->tables; |
539 | 312 | ||
540 | early_iounmap(systab32, sizeof(*systab32)); | 313 | early_memunmap(systab32, sizeof(*systab32)); |
541 | } | 314 | } |
542 | 315 | ||
543 | efi.systab = &efi_systab; | 316 | efi.systab = &efi_systab; |
@@ -563,7 +336,7 @@ static int __init efi_runtime_init32(void) | |||
563 | { | 336 | { |
564 | efi_runtime_services_32_t *runtime; | 337 | efi_runtime_services_32_t *runtime; |
565 | 338 | ||
566 | runtime = early_ioremap((unsigned long)efi.systab->runtime, | 339 | runtime = early_memremap((unsigned long)efi.systab->runtime, |
567 | sizeof(efi_runtime_services_32_t)); | 340 | sizeof(efi_runtime_services_32_t)); |
568 | if (!runtime) { | 341 | if (!runtime) { |
569 | pr_err("Could not map the runtime service table!\n"); | 342 | pr_err("Could not map the runtime service table!\n"); |
@@ -578,7 +351,7 @@ static int __init efi_runtime_init32(void) | |||
578 | efi_phys.set_virtual_address_map = | 351 | efi_phys.set_virtual_address_map = |
579 | (efi_set_virtual_address_map_t *) | 352 | (efi_set_virtual_address_map_t *) |
580 | (unsigned long)runtime->set_virtual_address_map; | 353 | (unsigned long)runtime->set_virtual_address_map; |
581 | early_iounmap(runtime, sizeof(efi_runtime_services_32_t)); | 354 | early_memunmap(runtime, sizeof(efi_runtime_services_32_t)); |
582 | 355 | ||
583 | return 0; | 356 | return 0; |
584 | } | 357 | } |
@@ -587,7 +360,7 @@ static int __init efi_runtime_init64(void) | |||
587 | { | 360 | { |
588 | efi_runtime_services_64_t *runtime; | 361 | efi_runtime_services_64_t *runtime; |
589 | 362 | ||
590 | runtime = early_ioremap((unsigned long)efi.systab->runtime, | 363 | runtime = early_memremap((unsigned long)efi.systab->runtime, |
591 | sizeof(efi_runtime_services_64_t)); | 364 | sizeof(efi_runtime_services_64_t)); |
592 | if (!runtime) { | 365 | if (!runtime) { |
593 | pr_err("Could not map the runtime service table!\n"); | 366 | pr_err("Could not map the runtime service table!\n"); |
@@ -602,7 +375,7 @@ static int __init efi_runtime_init64(void) | |||
602 | efi_phys.set_virtual_address_map = | 375 | efi_phys.set_virtual_address_map = |
603 | (efi_set_virtual_address_map_t *) | 376 | (efi_set_virtual_address_map_t *) |
604 | (unsigned long)runtime->set_virtual_address_map; | 377 | (unsigned long)runtime->set_virtual_address_map; |
605 | early_iounmap(runtime, sizeof(efi_runtime_services_64_t)); | 378 | early_memunmap(runtime, sizeof(efi_runtime_services_64_t)); |
606 | 379 | ||
607 | return 0; | 380 | return 0; |
608 | } | 381 | } |
@@ -616,14 +389,24 @@ static int __init efi_runtime_init(void) | |||
616 | * the runtime services table so that we can grab the physical | 389 | * the runtime services table so that we can grab the physical |
617 | * address of several of the EFI runtime functions, needed to | 390 | * address of several of the EFI runtime functions, needed to |
618 | * set the firmware into virtual mode. | 391 | * set the firmware into virtual mode. |
392 | * | ||
393 | * When EFI_PARAVIRT is in force then we could not map runtime | ||
394 | * service memory region because we do not have direct access to it. | ||
395 | * However, runtime services are available through proxy functions | ||
396 | * (e.g. in case of Xen dom0 EFI implementation they call special | ||
397 | * hypercall which executes relevant EFI functions) and that is why | ||
398 | * they are always enabled. | ||
619 | */ | 399 | */ |
620 | if (efi_enabled(EFI_64BIT)) | ||
621 | rv = efi_runtime_init64(); | ||
622 | else | ||
623 | rv = efi_runtime_init32(); | ||
624 | 400 | ||
625 | if (rv) | 401 | if (!efi_enabled(EFI_PARAVIRT)) { |
626 | return rv; | 402 | if (efi_enabled(EFI_64BIT)) |
403 | rv = efi_runtime_init64(); | ||
404 | else | ||
405 | rv = efi_runtime_init32(); | ||
406 | |||
407 | if (rv) | ||
408 | return rv; | ||
409 | } | ||
627 | 410 | ||
628 | set_bit(EFI_RUNTIME_SERVICES, &efi.flags); | 411 | set_bit(EFI_RUNTIME_SERVICES, &efi.flags); |
629 | 412 | ||
@@ -632,8 +415,11 @@ static int __init efi_runtime_init(void) | |||
632 | 415 | ||
633 | static int __init efi_memmap_init(void) | 416 | static int __init efi_memmap_init(void) |
634 | { | 417 | { |
418 | if (efi_enabled(EFI_PARAVIRT)) | ||
419 | return 0; | ||
420 | |||
635 | /* Map the EFI memory map */ | 421 | /* Map the EFI memory map */ |
636 | memmap.map = early_ioremap((unsigned long)memmap.phys_map, | 422 | memmap.map = early_memremap((unsigned long)memmap.phys_map, |
637 | memmap.nr_map * memmap.desc_size); | 423 | memmap.nr_map * memmap.desc_size); |
638 | if (memmap.map == NULL) { | 424 | if (memmap.map == NULL) { |
639 | pr_err("Could not map the memory map!\n"); | 425 | pr_err("Could not map the memory map!\n"); |
@@ -649,62 +435,6 @@ static int __init efi_memmap_init(void) | |||
649 | return 0; | 435 | return 0; |
650 | } | 436 | } |
651 | 437 | ||
652 | /* | ||
653 | * A number of config table entries get remapped to virtual addresses | ||
654 | * after entering EFI virtual mode. However, the kexec kernel requires | ||
655 | * their physical addresses therefore we pass them via setup_data and | ||
656 | * correct those entries to their respective physical addresses here. | ||
657 | * | ||
658 | * Currently only handles smbios which is necessary for some firmware | ||
659 | * implementation. | ||
660 | */ | ||
661 | static int __init efi_reuse_config(u64 tables, int nr_tables) | ||
662 | { | ||
663 | int i, sz, ret = 0; | ||
664 | void *p, *tablep; | ||
665 | struct efi_setup_data *data; | ||
666 | |||
667 | if (!efi_setup) | ||
668 | return 0; | ||
669 | |||
670 | if (!efi_enabled(EFI_64BIT)) | ||
671 | return 0; | ||
672 | |||
673 | data = early_memremap(efi_setup, sizeof(*data)); | ||
674 | if (!data) { | ||
675 | ret = -ENOMEM; | ||
676 | goto out; | ||
677 | } | ||
678 | |||
679 | if (!data->smbios) | ||
680 | goto out_memremap; | ||
681 | |||
682 | sz = sizeof(efi_config_table_64_t); | ||
683 | |||
684 | p = tablep = early_memremap(tables, nr_tables * sz); | ||
685 | if (!p) { | ||
686 | pr_err("Could not map Configuration table!\n"); | ||
687 | ret = -ENOMEM; | ||
688 | goto out_memremap; | ||
689 | } | ||
690 | |||
691 | for (i = 0; i < efi.systab->nr_tables; i++) { | ||
692 | efi_guid_t guid; | ||
693 | |||
694 | guid = ((efi_config_table_64_t *)p)->guid; | ||
695 | |||
696 | if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) | ||
697 | ((efi_config_table_64_t *)p)->table = data->smbios; | ||
698 | p += sz; | ||
699 | } | ||
700 | early_iounmap(tablep, nr_tables * sz); | ||
701 | |||
702 | out_memremap: | ||
703 | early_iounmap(data, sizeof(*data)); | ||
704 | out: | ||
705 | return ret; | ||
706 | } | ||
707 | |||
708 | void __init efi_init(void) | 438 | void __init efi_init(void) |
709 | { | 439 | { |
710 | efi_char16_t *c16; | 440 | efi_char16_t *c16; |
@@ -728,8 +458,6 @@ void __init efi_init(void) | |||
728 | if (efi_systab_init(efi_phys.systab)) | 458 | if (efi_systab_init(efi_phys.systab)) |
729 | return; | 459 | return; |
730 | 460 | ||
731 | set_bit(EFI_SYSTEM_TABLES, &efi.flags); | ||
732 | |||
733 | efi.config_table = (unsigned long)efi.systab->tables; | 461 | efi.config_table = (unsigned long)efi.systab->tables; |
734 | efi.fw_vendor = (unsigned long)efi.systab->fw_vendor; | 462 | efi.fw_vendor = (unsigned long)efi.systab->fw_vendor; |
735 | efi.runtime = (unsigned long)efi.systab->runtime; | 463 | efi.runtime = (unsigned long)efi.systab->runtime; |
@@ -737,14 +465,14 @@ void __init efi_init(void) | |||
737 | /* | 465 | /* |
738 | * Show what we know for posterity | 466 | * Show what we know for posterity |
739 | */ | 467 | */ |
740 | c16 = tmp = early_ioremap(efi.systab->fw_vendor, 2); | 468 | c16 = tmp = early_memremap(efi.systab->fw_vendor, 2); |
741 | if (c16) { | 469 | if (c16) { |
742 | for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i) | 470 | for (i = 0; i < sizeof(vendor) - 1 && *c16; ++i) |
743 | vendor[i] = *c16++; | 471 | vendor[i] = *c16++; |
744 | vendor[i] = '\0'; | 472 | vendor[i] = '\0'; |
745 | } else | 473 | } else |
746 | pr_err("Could not map the firmware vendor!\n"); | 474 | pr_err("Could not map the firmware vendor!\n"); |
747 | early_iounmap(tmp, 2); | 475 | early_memunmap(tmp, 2); |
748 | 476 | ||
749 | pr_info("EFI v%u.%.02u by %s\n", | 477 | pr_info("EFI v%u.%.02u by %s\n", |
750 | efi.systab->hdr.revision >> 16, | 478 | efi.systab->hdr.revision >> 16, |
@@ -770,8 +498,6 @@ void __init efi_init(void) | |||
770 | if (efi_memmap_init()) | 498 | if (efi_memmap_init()) |
771 | return; | 499 | return; |
772 | 500 | ||
773 | set_bit(EFI_MEMMAP, &efi.flags); | ||
774 | |||
775 | print_efi_memmap(); | 501 | print_efi_memmap(); |
776 | } | 502 | } |
777 | 503 | ||
@@ -847,22 +573,6 @@ void __init old_map_region(efi_memory_desc_t *md) | |||
847 | (unsigned long long)md->phys_addr); | 573 | (unsigned long long)md->phys_addr); |
848 | } | 574 | } |
849 | 575 | ||
850 | static void native_runtime_setup(void) | ||
851 | { | ||
852 | efi.get_time = virt_efi_get_time; | ||
853 | efi.set_time = virt_efi_set_time; | ||
854 | efi.get_wakeup_time = virt_efi_get_wakeup_time; | ||
855 | efi.set_wakeup_time = virt_efi_set_wakeup_time; | ||
856 | efi.get_variable = virt_efi_get_variable; | ||
857 | efi.get_next_variable = virt_efi_get_next_variable; | ||
858 | efi.set_variable = virt_efi_set_variable; | ||
859 | efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; | ||
860 | efi.reset_system = virt_efi_reset_system; | ||
861 | efi.query_variable_info = virt_efi_query_variable_info; | ||
862 | efi.update_capsule = virt_efi_update_capsule; | ||
863 | efi.query_capsule_caps = virt_efi_query_capsule_caps; | ||
864 | } | ||
865 | |||
866 | /* Merge contiguous regions of the same type and attribute */ | 576 | /* Merge contiguous regions of the same type and attribute */ |
867 | static void __init efi_merge_regions(void) | 577 | static void __init efi_merge_regions(void) |
868 | { | 578 | { |
@@ -1049,7 +759,7 @@ static void __init kexec_enter_virtual_mode(void) | |||
1049 | */ | 759 | */ |
1050 | efi.runtime_version = efi_systab.hdr.revision; | 760 | efi.runtime_version = efi_systab.hdr.revision; |
1051 | 761 | ||
1052 | native_runtime_setup(); | 762 | efi_native_runtime_setup(); |
1053 | 763 | ||
1054 | efi.set_virtual_address_map = NULL; | 764 | efi.set_virtual_address_map = NULL; |
1055 | 765 | ||
@@ -1057,11 +767,7 @@ static void __init kexec_enter_virtual_mode(void) | |||
1057 | runtime_code_page_mkexec(); | 767 | runtime_code_page_mkexec(); |
1058 | 768 | ||
1059 | /* clean DUMMY object */ | 769 | /* clean DUMMY object */ |
1060 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | 770 | efi_delete_dummy_variable(); |
1061 | EFI_VARIABLE_NON_VOLATILE | | ||
1062 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1063 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1064 | 0, NULL); | ||
1065 | #endif | 771 | #endif |
1066 | } | 772 | } |
1067 | 773 | ||
@@ -1142,7 +848,7 @@ static void __init __efi_enter_virtual_mode(void) | |||
1142 | efi.runtime_version = efi_systab.hdr.revision; | 848 | efi.runtime_version = efi_systab.hdr.revision; |
1143 | 849 | ||
1144 | if (efi_is_native()) | 850 | if (efi_is_native()) |
1145 | native_runtime_setup(); | 851 | efi_native_runtime_setup(); |
1146 | else | 852 | else |
1147 | efi_thunk_runtime_setup(); | 853 | efi_thunk_runtime_setup(); |
1148 | 854 | ||
@@ -1179,15 +885,14 @@ static void __init __efi_enter_virtual_mode(void) | |||
1179 | free_pages((unsigned long)new_memmap, pg_shift); | 885 | free_pages((unsigned long)new_memmap, pg_shift); |
1180 | 886 | ||
1181 | /* clean DUMMY object */ | 887 | /* clean DUMMY object */ |
1182 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | 888 | efi_delete_dummy_variable(); |
1183 | EFI_VARIABLE_NON_VOLATILE | | ||
1184 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1185 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1186 | 0, NULL); | ||
1187 | } | 889 | } |
1188 | 890 | ||
1189 | void __init efi_enter_virtual_mode(void) | 891 | void __init efi_enter_virtual_mode(void) |
1190 | { | 892 | { |
893 | if (efi_enabled(EFI_PARAVIRT)) | ||
894 | return; | ||
895 | |||
1191 | if (efi_setup) | 896 | if (efi_setup) |
1192 | kexec_enter_virtual_mode(); | 897 | kexec_enter_virtual_mode(); |
1193 | else | 898 | else |
@@ -1220,6 +925,9 @@ u64 efi_mem_attributes(unsigned long phys_addr) | |||
1220 | efi_memory_desc_t *md; | 925 | efi_memory_desc_t *md; |
1221 | void *p; | 926 | void *p; |
1222 | 927 | ||
928 | if (!efi_enabled(EFI_MEMMAP)) | ||
929 | return 0; | ||
930 | |||
1223 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | 931 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { |
1224 | md = p; | 932 | md = p; |
1225 | if ((md->phys_addr <= phys_addr) && | 933 | if ((md->phys_addr <= phys_addr) && |
@@ -1230,86 +938,6 @@ u64 efi_mem_attributes(unsigned long phys_addr) | |||
1230 | return 0; | 938 | return 0; |
1231 | } | 939 | } |
1232 | 940 | ||
1233 | /* | ||
1234 | * Some firmware implementations refuse to boot if there's insufficient space | ||
1235 | * in the variable store. Ensure that we never use more than a safe limit. | ||
1236 | * | ||
1237 | * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable | ||
1238 | * store. | ||
1239 | */ | ||
1240 | efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | ||
1241 | { | ||
1242 | efi_status_t status; | ||
1243 | u64 storage_size, remaining_size, max_size; | ||
1244 | |||
1245 | if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) | ||
1246 | return 0; | ||
1247 | |||
1248 | status = efi.query_variable_info(attributes, &storage_size, | ||
1249 | &remaining_size, &max_size); | ||
1250 | if (status != EFI_SUCCESS) | ||
1251 | return status; | ||
1252 | |||
1253 | /* | ||
1254 | * We account for that by refusing the write if permitting it would | ||
1255 | * reduce the available space to under 5KB. This figure was provided by | ||
1256 | * Samsung, so should be safe. | ||
1257 | */ | ||
1258 | if ((remaining_size - size < EFI_MIN_RESERVE) && | ||
1259 | !efi_no_storage_paranoia) { | ||
1260 | |||
1261 | /* | ||
1262 | * Triggering garbage collection may require that the firmware | ||
1263 | * generate a real EFI_OUT_OF_RESOURCES error. We can force | ||
1264 | * that by attempting to use more space than is available. | ||
1265 | */ | ||
1266 | unsigned long dummy_size = remaining_size + 1024; | ||
1267 | void *dummy = kzalloc(dummy_size, GFP_ATOMIC); | ||
1268 | |||
1269 | if (!dummy) | ||
1270 | return EFI_OUT_OF_RESOURCES; | ||
1271 | |||
1272 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
1273 | EFI_VARIABLE_NON_VOLATILE | | ||
1274 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1275 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1276 | dummy_size, dummy); | ||
1277 | |||
1278 | if (status == EFI_SUCCESS) { | ||
1279 | /* | ||
1280 | * This should have failed, so if it didn't make sure | ||
1281 | * that we delete it... | ||
1282 | */ | ||
1283 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
1284 | EFI_VARIABLE_NON_VOLATILE | | ||
1285 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
1286 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
1287 | 0, dummy); | ||
1288 | } | ||
1289 | |||
1290 | kfree(dummy); | ||
1291 | |||
1292 | /* | ||
1293 | * The runtime code may now have triggered a garbage collection | ||
1294 | * run, so check the variable info again | ||
1295 | */ | ||
1296 | status = efi.query_variable_info(attributes, &storage_size, | ||
1297 | &remaining_size, &max_size); | ||
1298 | |||
1299 | if (status != EFI_SUCCESS) | ||
1300 | return status; | ||
1301 | |||
1302 | /* | ||
1303 | * There still isn't enough room, so return an error | ||
1304 | */ | ||
1305 | if (remaining_size - size < EFI_MIN_RESERVE) | ||
1306 | return EFI_OUT_OF_RESOURCES; | ||
1307 | } | ||
1308 | |||
1309 | return EFI_SUCCESS; | ||
1310 | } | ||
1311 | EXPORT_SYMBOL_GPL(efi_query_variable_store); | ||
1312 | |||
1313 | static int __init parse_efi_cmdline(char *str) | 941 | static int __init parse_efi_cmdline(char *str) |
1314 | { | 942 | { |
1315 | if (*str == '=') | 943 | if (*str == '=') |
@@ -1321,22 +949,3 @@ static int __init parse_efi_cmdline(char *str) | |||
1321 | return 0; | 949 | return 0; |
1322 | } | 950 | } |
1323 | early_param("efi", parse_efi_cmdline); | 951 | early_param("efi", parse_efi_cmdline); |
1324 | |||
1325 | void __init efi_apply_memmap_quirks(void) | ||
1326 | { | ||
1327 | /* | ||
1328 | * Once setup is done earlier, unmap the EFI memory map on mismatched | ||
1329 | * firmware/kernel architectures since there is no support for runtime | ||
1330 | * services. | ||
1331 | */ | ||
1332 | if (!efi_runtime_supported()) { | ||
1333 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | ||
1334 | efi_unmap_memmap(); | ||
1335 | } | ||
1336 | |||
1337 | /* | ||
1338 | * UV doesn't support the new EFI pagetable mapping yet. | ||
1339 | */ | ||
1340 | if (is_uv_system()) | ||
1341 | set_bit(EFI_OLD_MEMMAP, &efi.flags); | ||
1342 | } | ||
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c new file mode 100644 index 000000000000..1c7380da65ff --- /dev/null +++ b/arch/x86/platform/efi/quirks.c | |||
@@ -0,0 +1,290 @@ | |||
1 | #include <linux/init.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/string.h> | ||
4 | #include <linux/time.h> | ||
5 | #include <linux/types.h> | ||
6 | #include <linux/efi.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/memblock.h> | ||
9 | #include <linux/bootmem.h> | ||
10 | #include <linux/acpi.h> | ||
11 | #include <asm/efi.h> | ||
12 | #include <asm/uv/uv.h> | ||
13 | |||
14 | #define EFI_MIN_RESERVE 5120 | ||
15 | |||
16 | #define EFI_DUMMY_GUID \ | ||
17 | EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) | ||
18 | |||
19 | static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; | ||
20 | |||
21 | static bool efi_no_storage_paranoia; | ||
22 | |||
23 | /* | ||
24 | * Some firmware implementations refuse to boot if there's insufficient | ||
25 | * space in the variable store. The implementation of garbage collection | ||
26 | * in some FW versions causes stale (deleted) variables to take up space | ||
27 | * longer than intended and space is only freed once the store becomes | ||
28 | * almost completely full. | ||
29 | * | ||
30 | * Enabling this option disables the space checks in | ||
31 | * efi_query_variable_store() and forces garbage collection. | ||
32 | * | ||
33 | * Only enable this option if deleting EFI variables does not free up | ||
34 | * space in your variable store, e.g. if despite deleting variables | ||
35 | * you're unable to create new ones. | ||
36 | */ | ||
37 | static int __init setup_storage_paranoia(char *arg) | ||
38 | { | ||
39 | efi_no_storage_paranoia = true; | ||
40 | return 0; | ||
41 | } | ||
42 | early_param("efi_no_storage_paranoia", setup_storage_paranoia); | ||
43 | |||
44 | /* | ||
45 | * Deleting the dummy variable which kicks off garbage collection | ||
46 | */ | ||
47 | void efi_delete_dummy_variable(void) | ||
48 | { | ||
49 | efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
50 | EFI_VARIABLE_NON_VOLATILE | | ||
51 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
52 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
53 | 0, NULL); | ||
54 | } | ||
55 | |||
56 | /* | ||
57 | * Some firmware implementations refuse to boot if there's insufficient space | ||
58 | * in the variable store. Ensure that we never use more than a safe limit. | ||
59 | * | ||
60 | * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable | ||
61 | * store. | ||
62 | */ | ||
63 | efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) | ||
64 | { | ||
65 | efi_status_t status; | ||
66 | u64 storage_size, remaining_size, max_size; | ||
67 | |||
68 | if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) | ||
69 | return 0; | ||
70 | |||
71 | status = efi.query_variable_info(attributes, &storage_size, | ||
72 | &remaining_size, &max_size); | ||
73 | if (status != EFI_SUCCESS) | ||
74 | return status; | ||
75 | |||
76 | /* | ||
77 | * We account for that by refusing the write if permitting it would | ||
78 | * reduce the available space to under 5KB. This figure was provided by | ||
79 | * Samsung, so should be safe. | ||
80 | */ | ||
81 | if ((remaining_size - size < EFI_MIN_RESERVE) && | ||
82 | !efi_no_storage_paranoia) { | ||
83 | |||
84 | /* | ||
85 | * Triggering garbage collection may require that the firmware | ||
86 | * generate a real EFI_OUT_OF_RESOURCES error. We can force | ||
87 | * that by attempting to use more space than is available. | ||
88 | */ | ||
89 | unsigned long dummy_size = remaining_size + 1024; | ||
90 | void *dummy = kzalloc(dummy_size, GFP_ATOMIC); | ||
91 | |||
92 | if (!dummy) | ||
93 | return EFI_OUT_OF_RESOURCES; | ||
94 | |||
95 | status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, | ||
96 | EFI_VARIABLE_NON_VOLATILE | | ||
97 | EFI_VARIABLE_BOOTSERVICE_ACCESS | | ||
98 | EFI_VARIABLE_RUNTIME_ACCESS, | ||
99 | dummy_size, dummy); | ||
100 | |||
101 | if (status == EFI_SUCCESS) { | ||
102 | /* | ||
103 | * This should have failed, so if it didn't make sure | ||
104 | * that we delete it... | ||
105 | */ | ||
106 | efi_delete_dummy_variable(); | ||
107 | } | ||
108 | |||
109 | kfree(dummy); | ||
110 | |||
111 | /* | ||
112 | * The runtime code may now have triggered a garbage collection | ||
113 | * run, so check the variable info again | ||
114 | */ | ||
115 | status = efi.query_variable_info(attributes, &storage_size, | ||
116 | &remaining_size, &max_size); | ||
117 | |||
118 | if (status != EFI_SUCCESS) | ||
119 | return status; | ||
120 | |||
121 | /* | ||
122 | * There still isn't enough room, so return an error | ||
123 | */ | ||
124 | if (remaining_size - size < EFI_MIN_RESERVE) | ||
125 | return EFI_OUT_OF_RESOURCES; | ||
126 | } | ||
127 | |||
128 | return EFI_SUCCESS; | ||
129 | } | ||
130 | EXPORT_SYMBOL_GPL(efi_query_variable_store); | ||
131 | |||
132 | /* | ||
133 | * The UEFI specification makes it clear that the operating system is free to do | ||
134 | * whatever it wants with boot services code after ExitBootServices() has been | ||
135 | * called. Ignoring this recommendation a significant bunch of EFI implementations | ||
136 | * continue calling into boot services code (SetVirtualAddressMap). In order to | ||
137 | * work around such buggy implementations we reserve boot services region during | ||
138 | * EFI init and make sure it stays executable. Then, after SetVirtualAddressMap(), it | ||
139 | * is discarded. | ||
140 | */ | ||
141 | void __init efi_reserve_boot_services(void) | ||
142 | { | ||
143 | void *p; | ||
144 | |||
145 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
146 | efi_memory_desc_t *md = p; | ||
147 | u64 start = md->phys_addr; | ||
148 | u64 size = md->num_pages << EFI_PAGE_SHIFT; | ||
149 | |||
150 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
151 | md->type != EFI_BOOT_SERVICES_DATA) | ||
152 | continue; | ||
153 | /* Only reserve where possible: | ||
154 | * - Not within any already allocated areas | ||
155 | * - Not over any memory area (really needed, if above?) | ||
156 | * - Not within any part of the kernel | ||
157 | * - Not the bios reserved area | ||
158 | */ | ||
159 | if ((start + size > __pa_symbol(_text) | ||
160 | && start <= __pa_symbol(_end)) || | ||
161 | !e820_all_mapped(start, start+size, E820_RAM) || | ||
162 | memblock_is_region_reserved(start, size)) { | ||
163 | /* Could not reserve, skip it */ | ||
164 | md->num_pages = 0; | ||
165 | memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", | ||
166 | start, start+size-1); | ||
167 | } else | ||
168 | memblock_reserve(start, size); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | void __init efi_free_boot_services(void) | ||
173 | { | ||
174 | void *p; | ||
175 | |||
176 | for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { | ||
177 | efi_memory_desc_t *md = p; | ||
178 | unsigned long long start = md->phys_addr; | ||
179 | unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; | ||
180 | |||
181 | if (md->type != EFI_BOOT_SERVICES_CODE && | ||
182 | md->type != EFI_BOOT_SERVICES_DATA) | ||
183 | continue; | ||
184 | |||
185 | /* Could not reserve boot area */ | ||
186 | if (!size) | ||
187 | continue; | ||
188 | |||
189 | free_bootmem_late(start, size); | ||
190 | } | ||
191 | |||
192 | efi_unmap_memmap(); | ||
193 | } | ||
194 | |||
195 | /* | ||
196 | * A number of config table entries get remapped to virtual addresses | ||
197 | * after entering EFI virtual mode. However, the kexec kernel requires | ||
198 | * their physical addresses therefore we pass them via setup_data and | ||
199 | * correct those entries to their respective physical addresses here. | ||
200 | * | ||
201 | * Currently only handles smbios which is necessary for some firmware | ||
202 | * implementation. | ||
203 | */ | ||
204 | int __init efi_reuse_config(u64 tables, int nr_tables) | ||
205 | { | ||
206 | int i, sz, ret = 0; | ||
207 | void *p, *tablep; | ||
208 | struct efi_setup_data *data; | ||
209 | |||
210 | if (!efi_setup) | ||
211 | return 0; | ||
212 | |||
213 | if (!efi_enabled(EFI_64BIT)) | ||
214 | return 0; | ||
215 | |||
216 | data = early_memremap(efi_setup, sizeof(*data)); | ||
217 | if (!data) { | ||
218 | ret = -ENOMEM; | ||
219 | goto out; | ||
220 | } | ||
221 | |||
222 | if (!data->smbios) | ||
223 | goto out_memremap; | ||
224 | |||
225 | sz = sizeof(efi_config_table_64_t); | ||
226 | |||
227 | p = tablep = early_memremap(tables, nr_tables * sz); | ||
228 | if (!p) { | ||
229 | pr_err("Could not map Configuration table!\n"); | ||
230 | ret = -ENOMEM; | ||
231 | goto out_memremap; | ||
232 | } | ||
233 | |||
234 | for (i = 0; i < efi.systab->nr_tables; i++) { | ||
235 | efi_guid_t guid; | ||
236 | |||
237 | guid = ((efi_config_table_64_t *)p)->guid; | ||
238 | |||
239 | if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) | ||
240 | ((efi_config_table_64_t *)p)->table = data->smbios; | ||
241 | p += sz; | ||
242 | } | ||
243 | early_memunmap(tablep, nr_tables * sz); | ||
244 | |||
245 | out_memremap: | ||
246 | early_memunmap(data, sizeof(*data)); | ||
247 | out: | ||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | void __init efi_apply_memmap_quirks(void) | ||
252 | { | ||
253 | /* | ||
254 | * Once setup is done earlier, unmap the EFI memory map on mismatched | ||
255 | * firmware/kernel architectures since there is no support for runtime | ||
256 | * services. | ||
257 | */ | ||
258 | if (!efi_runtime_supported()) { | ||
259 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | ||
260 | efi_unmap_memmap(); | ||
261 | } | ||
262 | |||
263 | /* | ||
264 | * UV doesn't support the new EFI pagetable mapping yet. | ||
265 | */ | ||
266 | if (is_uv_system()) | ||
267 | set_bit(EFI_OLD_MEMMAP, &efi.flags); | ||
268 | } | ||
269 | |||
270 | /* | ||
271 | * For most modern platforms the preferred method of powering off is via | ||
272 | * ACPI. However, there are some that are known to require the use of | ||
273 | * EFI runtime services and for which ACPI does not work at all. | ||
274 | * | ||
275 | * Using EFI is a last resort, to be used only if no other option | ||
276 | * exists. | ||
277 | */ | ||
278 | bool efi_reboot_required(void) | ||
279 | { | ||
280 | if (!acpi_gbl_reduced_hardware) | ||
281 | return false; | ||
282 | |||
283 | efi_reboot_quirk_mode = EFI_RESET_WARM; | ||
284 | return true; | ||
285 | } | ||
286 | |||
287 | bool efi_poweroff_required(void) | ||
288 | { | ||
289 | return !!acpi_gbl_reduced_hardware; | ||
290 | } | ||
diff --git a/arch/x86/xen/Makefile b/arch/x86/xen/Makefile index 96ab2c09cb68..7322755f337a 100644 --- a/arch/x86/xen/Makefile +++ b/arch/x86/xen/Makefile | |||
@@ -22,3 +22,4 @@ obj-$(CONFIG_PARAVIRT_SPINLOCKS)+= spinlock.o | |||
22 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o | 22 | obj-$(CONFIG_XEN_DEBUG_FS) += debugfs.o |
23 | obj-$(CONFIG_XEN_DOM0) += apic.o vga.o | 23 | obj-$(CONFIG_XEN_DOM0) += apic.o vga.o |
24 | obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o | 24 | obj-$(CONFIG_SWIOTLB_XEN) += pci-swiotlb-xen.o |
25 | obj-$(CONFIG_XEN_EFI) += efi.o | ||
diff --git a/arch/x86/xen/efi.c b/arch/x86/xen/efi.c new file mode 100644 index 000000000000..a02e09e18f57 --- /dev/null +++ b/arch/x86/xen/efi.c | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Oracle Co., Daniel Kiper | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program. If not, see <http://www.gnu.org/licenses/>. | ||
16 | */ | ||
17 | |||
18 | #include <linux/efi.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/string.h> | ||
21 | |||
22 | #include <xen/xen-ops.h> | ||
23 | |||
24 | #include <asm/setup.h> | ||
25 | |||
26 | void __init xen_efi_init(void) | ||
27 | { | ||
28 | efi_system_table_t *efi_systab_xen; | ||
29 | |||
30 | efi_systab_xen = xen_efi_probe(); | ||
31 | |||
32 | if (efi_systab_xen == NULL) | ||
33 | return; | ||
34 | |||
35 | strncpy((char *)&boot_params.efi_info.efi_loader_signature, "Xen", | ||
36 | sizeof(boot_params.efi_info.efi_loader_signature)); | ||
37 | boot_params.efi_info.efi_systab = (__u32)__pa(efi_systab_xen); | ||
38 | boot_params.efi_info.efi_systab_hi = (__u32)(__pa(efi_systab_xen) >> 32); | ||
39 | |||
40 | set_bit(EFI_BOOT, &efi.flags); | ||
41 | set_bit(EFI_PARAVIRT, &efi.flags); | ||
42 | set_bit(EFI_64BIT, &efi.flags); | ||
43 | } | ||
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index ffb101e45731..94813515fdd6 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1718,6 +1718,8 @@ asmlinkage __visible void __init xen_start_kernel(void) | |||
1718 | 1718 | ||
1719 | xen_setup_runstate_info(0); | 1719 | xen_setup_runstate_info(0); |
1720 | 1720 | ||
1721 | xen_efi_init(); | ||
1722 | |||
1721 | /* Start the world */ | 1723 | /* Start the world */ |
1722 | #ifdef CONFIG_X86_32 | 1724 | #ifdef CONFIG_X86_32 |
1723 | i386_start_kernel(); | 1725 | i386_start_kernel(); |
diff --git a/arch/x86/xen/xen-ops.h b/arch/x86/xen/xen-ops.h index 97d87659f779..28c7e0be56e4 100644 --- a/arch/x86/xen/xen-ops.h +++ b/arch/x86/xen/xen-ops.h | |||
@@ -105,6 +105,14 @@ static inline void __init xen_init_apic(void) | |||
105 | } | 105 | } |
106 | #endif | 106 | #endif |
107 | 107 | ||
108 | #ifdef CONFIG_XEN_EFI | ||
109 | extern void xen_efi_init(void); | ||
110 | #else | ||
111 | static inline void __init xen_efi_init(void) | ||
112 | { | ||
113 | } | ||
114 | #endif | ||
115 | |||
108 | /* Declare an asm function, along with symbols needed to make it | 116 | /* Declare an asm function, along with symbols needed to make it |
109 | inlineable */ | 117 | inlineable */ |
110 | #define DECL_ASM(ret, name, ...) \ | 118 | #define DECL_ASM(ret, name, ...) \ |