Skip to contentSkip to conversation

EFI changes for v3.15

GIT PULL Ingo Molnar 1 participant 1 message Mar 31, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Linus,

Please pull the latest x86-efi-for-linus git tree from:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-efi-for-linus

# HEAD: 204b0a1a4b92612c957a042df1a3be0e9cc79391 x86, efi: Abstract x86 efi_early calls

The main changes:

* Add debug code to the dump EFI pagetable - Borislav Petkov

* Make 1:1 runtime mapping robust when booting on machines with lots of memory - Borislav Petkov

* Move the EFI facilities bits out of 'x86_efi_facility' and into efi.flags which is the standard architecture independent place to keep EFI state, by Matt Fleming.

* Add 'EFI mixed mode' support: this allows 64-bit kernels to be booted from 32-bit firmware. This needs a bootloader that supports the 'EFI handover protocol'. By Matt Fleming.

out-of-topic modifications in x86-efi-for-linus:
--------------------------------------------------
arch/ia64/kernel/efi.c # 0920638: ia64/efi: Implement efi_enabled()
drivers/firmware/efi/efi-stub-helper.c# 204b0a1: x86, efi: Abstract x86 efi_early
# 54b52d8: x86/efi: Build our own EFI servic
drivers/firmware/efi/efi.c # 69e6084: efi: Use NULL instead of 0 for po
# 0f8093a: efi: Set feature flags inside fea
drivers/firmware/efi/efivars.c # 69e6084: efi: Use NULL instead of 0 for po
fs/efivarfs/file.c # aca32b5: efivarfs: 'efivarfs_file_write' f

Thanks,

Ingo

------------------>
Borislav Petkov (5):
x86, ptdump: Add the functionality to dump an arbitrary pagetable x86/efi: Dump the EFI page table
x86, pageattr: Export page unmapping interface x86/efi: Make efi virtual runtime map passing more robust x86/efi: Split efi_enter_virtual_mode

Daeseok Youn (1):
efi: Use NULL instead of 0 for pointer

Geyslan G. Bem (1):
efivarfs: 'efivarfs_file_write' function reorganization

Joe Perches (1):
x86/efi: Style neatening

Madper Xie (1):
x86/efi: Delete out-of-date comments of efi_query_variable_store

Matt Fleming (22):
efi: Move facility flags to struct efi
efi: Set feature flags inside feature init functions ia64/efi: Implement efi_enabled()
x86/boot: Cleanup header.S by removing some #ifdefs x86, tools: Consolidate #ifdef code x86/mm/pageattr: Always dump the right page table in an oops x86/efi: Delete dead code when checking for non-native
efi: Add separate 32-bit/64-bit definitions x86/efi: Build our own EFI services pointer table x86/efi: Add early thunk code to go from 64-bit to 32-bit x86/efi: Split the boot stub into 32/64 code paths x86/efi: Firmware agnostic handover entry points x86/efi: Add mixed runtime services support x86/efi: Wire up CONFIG_EFI_MIXED
x86/boot: Don't overwrite cr4 when enabling PAE x86/efi: Re-disable interrupts after calling firmware services x86, tools: Fix up compiler warnings
x86/boot: Fix non-EFI build
x86/efi: Preserve segment registers in mixed mode x86/efi: Rip out phys_efi_get_time()
x86/efi: Restore 'attr' argument to query_variable_info() x86, efi: Abstract x86 efi_early calls

 arch/ia64/kernel/efi.c                 |    7 +
 arch/x86/Kconfig                       |   14 +
 arch/x86/Kconfig.debug                 |    9 +
 arch/x86/boot/Makefile                 |    2 +-
 arch/x86/boot/compressed/eboot.c       | 1017 +++++++++++++++++++++++++-------
 arch/x86/boot/compressed/eboot.h       |   60 ++
 arch/x86/boot/compressed/efi_stub_64.S |   29 +
 arch/x86/boot/compressed/head_32.S     |   52 +-
 arch/x86/boot/compressed/head_64.S     |  111 +++-
 arch/x86/boot/header.S                 |   23 +-
 arch/x86/boot/tools/build.c            |   77 ++-
 arch/x86/include/asm/efi.h             |   43 +-
 arch/x86/include/asm/pgtable.h         |    3 +-
 arch/x86/include/asm/pgtable_types.h   |    4 +
 arch/x86/kernel/setup.c                |    6 +-
 arch/x86/mm/dump_pagetables.c          |   84 ++-
 arch/x86/mm/fault.c                    |    7 +-
 arch/x86/mm/pageattr.c                 |   56 +-
 arch/x86/platform/efi/Makefile         |    1 +
 arch/x86/platform/efi/efi.c            |  415 ++++++++-----
 arch/x86/platform/efi/efi_32.c         |    7 +-
 arch/x86/platform/efi/efi_64.c         |  368 +++++++++++-
 arch/x86/platform/efi/efi_stub_64.S    |  166 ++++++
 arch/x86/platform/efi/efi_thunk_64.S   |   65 ++
 drivers/firmware/efi/efi-stub-helper.c |  136 +----
 drivers/firmware/efi/efi.c             |    5 +-
 drivers/firmware/efi/efivars.c         |    2 +-
 fs/efivarfs/file.c                     |   13 +-
 include/linux/efi.h                    |  268 ++++++++-
 29 files changed, 2452 insertions(+), 598 deletions(-)
 create mode 100644 arch/x86/platform/efi/efi_thunk_64.S
arch/ia64/kernel/efi.c +7 -0
index da5b462..741b99c 100644
@@ -477,6 +477,9 @@ efi_init (void)
 	char *cp, vendor[100] = "unknown";
 	int i;
 
+	set_bit(EFI_BOOT, &efi.flags);
+	set_bit(EFI_64BIT, &efi.flags);
+
 	/*
 	 * It's too early to be able to use the standard kernel command line
 	 * support...
@@ -529,6 +532,8 @@ efi_init (void)
 	       efi.systab->hdr.revision >> 16,
 	       efi.systab->hdr.revision & 0xffff, vendor);
 
+	set_bit(EFI_SYSTEM_TABLES, &efi.flags);
+
 	palo_phys      = EFI_INVALID_TABLE_ADDR;
 
 	if (efi_config_init(arch_tables) != 0)
@@ -657,6 +662,8 @@ efi_enter_virtual_mode (void)
 		return;
 	}
 
+	set_bit(EFI_RUNTIME_SERVICES, &efi.flags);
+
 	/*
 	 * Now that EFI is in virtual mode, we call the EFI functions more
 	 * efficiently:
arch/x86/Kconfig +14 -0
index 0af5250..8453fe1 100644
@@ -1585,6 +1585,20 @@ config EFI_STUB
 
 	  See Documentation/efi-stub.txt for more information.
 
+config EFI_MIXED
+	bool "EFI mixed-mode support"
+	depends on EFI_STUB && X86_64
+	---help---
+	   Enabling this feature allows a 64-bit kernel to be booted
+	   on a 32-bit firmware, provided that your CPU supports 64-bit
+	   mode.
+
+	   Note that it is not possible to boot a mixed-mode enabled
+	   kernel via the EFI boot stub - a bootloader that supports
+	   the EFI handover protocol must be used.
+
+	   If unsure, say N.
+
 config SECCOMP
 	def_bool y
 	prompt "Enable seccomp to safely compute untrusted bytecode"
arch/x86/Kconfig.debug +9 -0
index 321a52c..61bd2ad 100644
@@ -81,6 +81,15 @@ config X86_PTDUMP
 	  kernel.
 	  If in doubt, say "N"
 
+config EFI_PGT_DUMP
+	bool "Dump the EFI pagetable"
+	depends on EFI && X86_PTDUMP
+	---help---
+	  Enable this if you want to dump the EFI page table before
+	  enabling virtual mode. This can be used to debug miscellaneous
+	  issues with the mapping of the EFI runtime regions into that
+	  table.
+
 config DEBUG_RODATA
 	bool "Write protect kernel read-only data structures"
 	default y
arch/x86/boot/Makefile +1 -1
index 878df7e..abb9eba 100644
@@ -80,7 +80,7 @@ targets += voffset.h
 $(obj)/voffset.h: vmlinux FORCE
 	$(call if_changed,voffset)
 
-sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi_pe_entry\|efi_stub_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
+sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
 
 quiet_cmd_zoffset = ZOFFSET $@
       cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
arch/x86/boot/compressed/eboot.c +814 -203

1,257 lines not on this page · raw message

arch/x86/boot/compressed/eboot.h +60 -0

82 lines not on this page · raw message

arch/x86/boot/compressed/efi_stub_64.S +29 -0
index cedc60d..7ff3632 100644
@@ -1 +1,30 @@
+#include <asm/segment.h>
+#include <asm/msr.h>
+#include <asm/processor-flags.h>
+
 #include "../../platform/efi/efi_stub_64.S"
+
+#ifdef CONFIG_EFI_MIXED
+	.code64
+	.text
+ENTRY(efi64_thunk)
+	push	%rbp
+	push	%rbx
+
+	subq	$16, %rsp
+	leaq	efi_exit32(%rip), %rax
+	movl	%eax, 8(%rsp)
+	leaq	efi_gdt64(%rip), %rax
+	movl	%eax, 4(%rsp)
+	movl	%eax, 2(%rax)		/* Fixup the gdt base address */
+	leaq	efi32_boot_gdt(%rip), %rax
+	movl	%eax, (%rsp)
+
+	call	__efi64_thunk
+
+	addq	$16, %rsp
+	pop	%rbx
+	pop	%rbp
+	ret
+ENDPROC(efi64_thunk)
+#endif /* CONFIG_EFI_MIXED */
arch/x86/boot/compressed/head_32.S +44 -8

76 lines not on this page · raw message

arch/x86/boot/compressed/head_64.S +99 -12

156 lines not on this page · raw message

arch/x86/boot/header.S +11 -12
index ec3b8ba..2563882 100644
@@ -283,7 +283,7 @@ _start:
 	# Part 2 of the header, from the old setup.S
 
 		.ascii	"HdrS"		# header signature
-		.word	0x020c		# header version number (>= 0x0105)
+		.word	0x020d		# header version number (>= 0x0105)
 					# or else old loadlin-1.5 will fail)
 		.globl realmode_swtch
 realmode_swtch:	.word	0, 0		# default_switch, SETUPSEG
@@ -375,7 +375,8 @@ xloadflags:
 # define XLF0 0
 #endif
 
-#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64)
+#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64) && \
+	!defined(CONFIG_EFI_MIXED)
    /* kernel/boot_param/ramdisk could be loaded above 4g */
 # define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G
 #else
@@ -383,10 +384,14 @@ xloadflags:
 #endif
 
 #ifdef CONFIG_EFI_STUB
-# ifdef CONFIG_X86_64
-#  define XLF23 XLF_EFI_HANDOVER_64		/* 64-bit EFI handover ok */
+# ifdef CONFIG_EFI_MIXED
+#  define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64)
 # else
-#  define XLF23 XLF_EFI_HANDOVER_32		/* 32-bit EFI handover ok */
+#  ifdef CONFIG_X86_64
+#   define XLF23 XLF_EFI_HANDOVER_64		/* 64-bit EFI handover ok */
+#  else
+#   define XLF23 XLF_EFI_HANDOVER_32		/* 32-bit EFI handover ok */
+#  endif
 # endif
 #else
 # define XLF23 0
@@ -426,13 +431,7 @@ pref_address:		.quad LOAD_PHYSICAL_ADDR	# preferred load addr
 #define INIT_SIZE VO_INIT_SIZE
 #endif
 init_size:		.long INIT_SIZE		# kernel initialization size
-handover_offset:
-#ifdef CONFIG_EFI_STUB
-  			.long 0x30		# offset to the handover
-						# protocol entry point
-#else
-			.long 0
-#endif
+handover_offset:	.long 0			# Filled in by build.c
 
 # End of setup header #####################################################
 
arch/x86/boot/tools/build.c +53 -24

122 lines not on this page · raw message

arch/x86/include/asm/efi.h +38 -5

80 lines not on this page · raw message

arch/x86/include/asm/pgtable.h +2 -1
index 5ad38ad..938ef1d 100644
@@ -15,9 +15,10 @@
 	 : (prot))
 
 #ifndef __ASSEMBLY__
-
 #include <asm/x86_init.h>
 
+void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
+
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
arch/x86/include/asm/pgtable_types.h +4 -0
index 1aa9ccd..708f19f 100644
@@ -382,9 +382,13 @@ static inline void update_page_count(int level, unsigned long pages) { }
  * as a pte too.
  */
 extern pte_t *lookup_address(unsigned long address, unsigned int *level);
+extern pte_t *lookup_address_in_pgd(pgd_t *pgd, unsigned long address,
+				    unsigned int *level);
 extern phys_addr_t slow_virt_to_phys(void *__address);
 extern int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,
 				   unsigned numpages, unsigned long page_flags);
+void kernel_unmap_pages_in_pgd(pgd_t *root, unsigned long address,
+			       unsigned numpages);
 #endif	/* !__ASSEMBLY__ */
 
 #endif /* _ASM_X86_PGTABLE_DEFS_H */
arch/x86/kernel/setup.c +3 -3
index ce72964..fa511ac 100644
@@ -926,11 +926,11 @@ void __init setup_arch(char **cmdline_p)
 #ifdef CONFIG_EFI
 	if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
 		     "EL32", 4)) {
-		set_bit(EFI_BOOT, &x86_efi_facility);
+		set_bit(EFI_BOOT, &efi.flags);
 	} else if (!strncmp((char *)&boot_params.efi_info.efi_loader_signature,
 		     "EL64", 4)) {
-		set_bit(EFI_BOOT, &x86_efi_facility);
-		set_bit(EFI_64BIT, &x86_efi_facility);
+		set_bit(EFI_BOOT, &efi.flags);
+		set_bit(EFI_64BIT, &efi.flags);
 	}
 
 	if (efi_enabled(EFI_BOOT))
arch/x86/mm/dump_pagetables.c +54 -30

171 lines not on this page · raw message

arch/x86/mm/fault.c +6 -1
index e7fa28b..a92c4c9 100644
@@ -584,8 +584,13 @@ show_fault_oops(struct pt_regs *regs, unsigned long error_code,
 
 	if (error_code & PF_INSTR) {
 		unsigned int level;
+		pgd_t *pgd;
+		pte_t *pte;
 
-		pte_t *pte = lookup_address(address, &level);
+		pgd = __va(read_cr3() & PHYSICAL_PAGE_MASK);
+		pgd += pgd_index(address);
+
+		pte = lookup_address_in_pgd(pgd, address, &level);
 
 		if (pte && pte_present(*pte) && !pte_exec(*pte))
 			printk(nx_warning, from_kuid(&init_user_ns, current_uid()));
arch/x86/mm/pageattr.c +39 -17

114 lines not on this page · raw message

arch/x86/platform/efi/Makefile +1 -0
index b7b0b35..d51045a 100644
@@ -1,3 +1,4 @@
 obj-$(CONFIG_EFI) 		+= efi.o efi_$(BITS).o efi_stub_$(BITS).o
 obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o
 obj-$(CONFIG_EARLY_PRINTK_EFI)	+= early_printk.o
+obj-$(CONFIG_EFI_MIXED)		+= efi_thunk_$(BITS).o
arch/x86/platform/efi/efi.c +262 -153

634 lines not on this page · raw message

arch/x86/platform/efi/efi_32.c +6 -1
index 0b74cdf..9ee3491 100644
@@ -40,7 +40,12 @@
 static unsigned long efi_rt_eflags;
 
 void efi_sync_low_kernel_mappings(void) {}
-void efi_setup_page_tables(void) {}
+void __init efi_dump_pagetable(void) {}
+int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
+{
+	return 0;
+}
+void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) {}
 
 void __init efi_map_region(efi_memory_desc_t *md)
 {
arch/x86/platform/efi/efi_64.c +364 -4

93 lines not on this page · raw message

arch/x86/platform/efi/efi_stub_64.S +166 -0

166 lines not on this page · raw message

arch/x86/platform/efi/efi_thunk_64.S new file +65 -0

65 lines not on this page · raw message

drivers/firmware/efi/efi-stub-helper.c +32 -104

136 lines not on this page · raw message

drivers/firmware/efi/efi.c +4 -1
index 4753bac..af20f17 100644

Lines of this file are not shown. View the raw message.

drivers/firmware/efi/efivars.c +1 -1
index 3dc2482..50ea412 100644

Lines of this file are not shown. View the raw message.

fs/efivarfs/file.c +4 -9
index 8dd524f..cdb2971 100644

Lines of this file are not shown. View the raw message.

include/linux/efi.h +260 -8

268 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.