aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-01-31 01:10:36 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-01-31 01:10:36 -0500
commit04c2eee5b9dfcb13f3cd07a5537fb8c785f2751a (patch)
treea70cf1df64b3715c502211233dc307abacaed7da
parentbdb0ae6a767ef2622eb282e06fc225e855341653 (diff)
parentbecbd6608026c15afd88fd3d0c893dfb7b8c7845 (diff)
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI fixes from Peter Anvin: "This is a collection of fixes for the EFI support. The controversial bit here is a set of patches which bumps the boot protocol version as part of fixing some serious problems with the EFI handover protocol, used when booting under EFI using a bootloader as opposed to directly from EFI. These changes should also make it a lot saner to support cross-mode 32/64-bit EFI booting in the future. Getting these changes into 3.8 means we avoid presenting an inconsistent ABI to bootloaders. Other changes are display detection and fixing efivarfs." * 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, efi: remove attribute check from setup_efi_pci x86, build: Dynamically find entry points in compressed startup code x86, efi: Fix PCI ROM handing in EFI boot stub, in 32-bit mode x86, efi: Fix 32-bit EFI handover protocol entry point x86, efi: Fix display detection in EFI boot stub x86, boot: Define the 2.12 bzImage boot protocol x86/boot: Fix minor fd leakage in tools/relocs.c x86, efi: Set runtime_version to the EFI spec revision x86, efi: fix 32-bit warnings in setup_efi_pci() efivarfs: Delete dentry from dcache in efivarfs_file_write() efivarfs: Never return ENOENT from firmware efi, x86: Pass a proper identity mapping in efi_call_phys_prelog efivarfs: Drop link count of the right inode
-rw-r--r--Documentation/x86/boot.txt27
-rw-r--r--Documentation/x86/zero-page.txt4
-rw-r--r--arch/x86/boot/Makefile4
-rw-r--r--arch/x86/boot/compressed/eboot.c21
-rw-r--r--arch/x86/boot/compressed/head_32.S8
-rw-r--r--arch/x86/boot/compressed/head_64.S8
-rw-r--r--arch/x86/boot/header.S39
-rw-r--r--arch/x86/boot/setup.ld2
-rw-r--r--arch/x86/boot/tools/build.c81
-rw-r--r--arch/x86/include/uapi/asm/bootparam.h63
-rw-r--r--arch/x86/platform/efi/efi.c2
-rw-r--r--arch/x86/platform/efi/efi_64.c22
-rw-r--r--arch/x86/tools/relocs.c6
-rw-r--r--drivers/firmware/efivars.c5
14 files changed, 216 insertions, 76 deletions
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt
index 406d82d5d2bb..3edb4c2887a1 100644
--- a/Documentation/x86/boot.txt
+++ b/Documentation/x86/boot.txt
@@ -57,6 +57,10 @@ Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
57Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover 57Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
58 protocol entry point. 58 protocol entry point.
59 59
60Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields
61 to struct boot_params for for loading bzImage and ramdisk
62 above 4G in 64bit.
63
60**** MEMORY LAYOUT 64**** MEMORY LAYOUT
61 65
62The traditional memory map for the kernel loader, used for Image or 66The traditional memory map for the kernel loader, used for Image or
@@ -182,7 +186,7 @@ Offset Proto Name Meaning
1820230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 1860230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
1830234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not 1870234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
1840235/1 2.10+ min_alignment Minimum alignment, as a power of two 1880235/1 2.10+ min_alignment Minimum alignment, as a power of two
1850236/2 N/A pad3 Unused 1890236/2 2.12+ xloadflags Boot protocol option flags
1860238/4 2.06+ cmdline_size Maximum size of the kernel command line 1900238/4 2.06+ cmdline_size Maximum size of the kernel command line
187023C/4 2.07+ hardware_subarch Hardware subarchitecture 191023C/4 2.07+ hardware_subarch Hardware subarchitecture
1880240/8 2.07+ hardware_subarch_data Subarchitecture-specific data 1920240/8 2.07+ hardware_subarch_data Subarchitecture-specific data
@@ -582,6 +586,27 @@ Protocol: 2.10+
582 misaligned kernel. Therefore, a loader should typically try each 586 misaligned kernel. Therefore, a loader should typically try each
583 power-of-two alignment from kernel_alignment down to this alignment. 587 power-of-two alignment from kernel_alignment down to this alignment.
584 588
589Field name: xloadflags
590Type: read
591Offset/size: 0x236/2
592Protocol: 2.12+
593
594 This field is a bitmask.
595
596 Bit 0 (read): XLF_KERNEL_64
597 - If 1, this kernel has the legacy 64-bit entry point at 0x200.
598
599 Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
600 - If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.
601
602 Bit 2 (read): XLF_EFI_HANDOVER_32
603 - If 1, the kernel supports the 32-bit EFI handoff entry point
604 given at handover_offset.
605
606 Bit 3 (read): XLF_EFI_HANDOVER_64
607 - If 1, the kernel supports the 64-bit EFI handoff entry point
608 given at handover_offset + 0x200.
609
585Field name: cmdline_size 610Field name: cmdline_size
586Type: read 611Type: read
587Offset/size: 0x238/4 612Offset/size: 0x238/4
diff --git a/Documentation/x86/zero-page.txt b/Documentation/x86/zero-page.txt
index cf5437deda81..199f453cb4de 100644
--- a/Documentation/x86/zero-page.txt
+++ b/Documentation/x86/zero-page.txt
@@ -19,6 +19,9 @@ Offset Proto Name Meaning
19090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!! 19090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!!
200A0/010 ALL sys_desc_table System description table (struct sys_desc_table) 200A0/010 ALL sys_desc_table System description table (struct sys_desc_table)
210B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends 210B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends
220C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits
230C4/004 ALL ext_ramdisk_size ramdisk_size high 32bits
240C8/004 ALL ext_cmd_line_ptr cmd_line_ptr high 32bits
22140/080 ALL edid_info Video mode setup (struct edid_info) 25140/080 ALL edid_info Video mode setup (struct edid_info)
231C0/020 ALL efi_info EFI 32 information (struct efi_info) 261C0/020 ALL efi_info EFI 32 information (struct efi_info)
241E0/004 ALL alk_mem_k Alternative mem check, in KB 271E0/004 ALL alk_mem_k Alternative mem check, in KB
@@ -27,6 +30,7 @@ Offset Proto Name Meaning
271E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) 301E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
281EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer 311EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
29 (below) 32 (below)
331EF/001 ALL sentinel Used to detect broken bootloaders
30290/040 ALL edd_mbr_sig_buffer EDD MBR signatures 34290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
312D0/A00 ALL e820_map E820 memory map table 352D0/A00 ALL e820_map E820 memory map table
32 (array of struct e820entry) 36 (array of struct e820entry)
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
index ccce0ed67dde..379814bc41e3 100644
--- a/arch/x86/boot/Makefile
+++ b/arch/x86/boot/Makefile
@@ -71,7 +71,7 @@ GCOV_PROFILE := n
71$(obj)/bzImage: asflags-y := $(SVGA_MODE) 71$(obj)/bzImage: asflags-y := $(SVGA_MODE)
72 72
73quiet_cmd_image = BUILD $@ 73quiet_cmd_image = BUILD $@
74cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin > $@ 74cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/zoffset.h > $@
75 75
76$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE 76$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
77 $(call if_changed,image) 77 $(call if_changed,image)
@@ -92,7 +92,7 @@ targets += voffset.h
92$(obj)/voffset.h: vmlinux FORCE 92$(obj)/voffset.h: vmlinux FORCE
93 $(call if_changed,voffset) 93 $(call if_changed,voffset)
94 94
95sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' 95sed-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'
96 96
97quiet_cmd_zoffset = ZOFFSET $@ 97quiet_cmd_zoffset = ZOFFSET $@
98 cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ 98 cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 18e329ca108e..f8fa41190c35 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -256,10 +256,10 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
256 int i; 256 int i;
257 struct setup_data *data; 257 struct setup_data *data;
258 258
259 data = (struct setup_data *)params->hdr.setup_data; 259 data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
260 260
261 while (data && data->next) 261 while (data && data->next)
262 data = (struct setup_data *)data->next; 262 data = (struct setup_data *)(unsigned long)data->next;
263 263
264 status = efi_call_phys5(sys_table->boottime->locate_handle, 264 status = efi_call_phys5(sys_table->boottime->locate_handle,
265 EFI_LOCATE_BY_PROTOCOL, &pci_proto, 265 EFI_LOCATE_BY_PROTOCOL, &pci_proto,
@@ -295,16 +295,18 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
295 if (!pci) 295 if (!pci)
296 continue; 296 continue;
297 297
298#ifdef CONFIG_X86_64
298 status = efi_call_phys4(pci->attributes, pci, 299 status = efi_call_phys4(pci->attributes, pci,
299 EfiPciIoAttributeOperationGet, 0, 300 EfiPciIoAttributeOperationGet, 0,
300 &attributes); 301 &attributes);
301 302#else
303 status = efi_call_phys5(pci->attributes, pci,
304 EfiPciIoAttributeOperationGet, 0, 0,
305 &attributes);
306#endif
302 if (status != EFI_SUCCESS) 307 if (status != EFI_SUCCESS)
303 continue; 308 continue;
304 309
305 if (!(attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM))
306 continue;
307
308 if (!pci->romimage || !pci->romsize) 310 if (!pci->romimage || !pci->romsize)
309 continue; 311 continue;
310 312
@@ -345,9 +347,9 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
345 memcpy(rom->romdata, pci->romimage, pci->romsize); 347 memcpy(rom->romdata, pci->romimage, pci->romsize);
346 348
347 if (data) 349 if (data)
348 data->next = (uint64_t)rom; 350 data->next = (unsigned long)rom;
349 else 351 else
350 params->hdr.setup_data = (uint64_t)rom; 352 params->hdr.setup_data = (unsigned long)rom;
351 353
352 data = (struct setup_data *)rom; 354 data = (struct setup_data *)rom;
353 355
@@ -432,10 +434,9 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
432 * Once we've found a GOP supporting ConOut, 434 * Once we've found a GOP supporting ConOut,
433 * don't bother looking any further. 435 * don't bother looking any further.
434 */ 436 */
437 first_gop = gop;
435 if (conout_found) 438 if (conout_found)
436 break; 439 break;
437
438 first_gop = gop;
439 } 440 }
440 } 441 }
441 442
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index aa4aaf1b2380..1e3184f6072f 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -35,11 +35,11 @@ ENTRY(startup_32)
35#ifdef CONFIG_EFI_STUB 35#ifdef CONFIG_EFI_STUB
36 jmp preferred_addr 36 jmp preferred_addr
37 37
38 .balign 0x10
39 /* 38 /*
40 * We don't need the return address, so set up the stack so 39 * We don't need the return address, so set up the stack so
41 * efi_main() can find its arugments. 40 * efi_main() can find its arguments.
42 */ 41 */
42ENTRY(efi_pe_entry)
43 add $0x4, %esp 43 add $0x4, %esp
44 44
45 call make_boot_params 45 call make_boot_params
@@ -50,8 +50,10 @@ ENTRY(startup_32)
50 pushl %eax 50 pushl %eax
51 pushl %esi 51 pushl %esi
52 pushl %ecx 52 pushl %ecx
53 sub $0x4, %esp
53 54
54 .org 0x30,0x90 55ENTRY(efi_stub_entry)
56 add $0x4, %esp
55 call efi_main 57 call efi_main
56 cmpl $0, %eax 58 cmpl $0, %eax
57 movl %eax, %esi 59 movl %eax, %esi
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 2c4b171eec33..f5d1aaa0dec8 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -201,12 +201,12 @@ ENTRY(startup_64)
201 */ 201 */
202#ifdef CONFIG_EFI_STUB 202#ifdef CONFIG_EFI_STUB
203 /* 203 /*
204 * The entry point for the PE/COFF executable is 0x210, so only 204 * The entry point for the PE/COFF executable is efi_pe_entry, so
205 * legacy boot loaders will execute this jmp. 205 * only legacy boot loaders will execute this jmp.
206 */ 206 */
207 jmp preferred_addr 207 jmp preferred_addr
208 208
209 .org 0x210 209ENTRY(efi_pe_entry)
210 mov %rcx, %rdi 210 mov %rcx, %rdi
211 mov %rdx, %rsi 211 mov %rdx, %rsi
212 pushq %rdi 212 pushq %rdi
@@ -218,7 +218,7 @@ ENTRY(startup_64)
218 popq %rsi 218 popq %rsi
219 popq %rdi 219 popq %rdi
220 220
221 .org 0x230,0x90 221ENTRY(efi_stub_entry)
222 call efi_main 222 call efi_main
223 movq %rax,%rsi 223 movq %rax,%rsi
224 cmpq $0,%rax 224 cmpq $0,%rax
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S
index 8c132a625b94..944ce595f767 100644
--- a/arch/x86/boot/header.S
+++ b/arch/x86/boot/header.S
@@ -21,6 +21,7 @@
21#include <asm/e820.h> 21#include <asm/e820.h>
22#include <asm/page_types.h> 22#include <asm/page_types.h>
23#include <asm/setup.h> 23#include <asm/setup.h>
24#include <asm/bootparam.h>
24#include "boot.h" 25#include "boot.h"
25#include "voffset.h" 26#include "voffset.h"
26#include "zoffset.h" 27#include "zoffset.h"
@@ -255,6 +256,9 @@ section_table:
255 # header, from the old boot sector. 256 # header, from the old boot sector.
256 257
257 .section ".header", "a" 258 .section ".header", "a"
259 .globl sentinel
260sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */
261
258 .globl hdr 262 .globl hdr
259hdr: 263hdr:
260setup_sects: .byte 0 /* Filled in by build.c */ 264setup_sects: .byte 0 /* Filled in by build.c */
@@ -279,7 +283,7 @@ _start:
279 # Part 2 of the header, from the old setup.S 283 # Part 2 of the header, from the old setup.S
280 284
281 .ascii "HdrS" # header signature 285 .ascii "HdrS" # header signature
282 .word 0x020b # header version number (>= 0x0105) 286 .word 0x020c # header version number (>= 0x0105)
283 # or else old loadlin-1.5 will fail) 287 # or else old loadlin-1.5 will fail)
284 .globl realmode_swtch 288 .globl realmode_swtch
285realmode_swtch: .word 0, 0 # default_switch, SETUPSEG 289realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
@@ -297,13 +301,7 @@ type_of_loader: .byte 0 # 0 means ancient bootloader, newer
297 301
298# flags, unused bits must be zero (RFU) bit within loadflags 302# flags, unused bits must be zero (RFU) bit within loadflags
299loadflags: 303loadflags:
300LOADED_HIGH = 1 # If set, the kernel is loaded high 304 .byte LOADED_HIGH # The kernel is to be loaded high
301CAN_USE_HEAP = 0x80 # If set, the loader also has set
302 # heap_end_ptr to tell how much
303 # space behind setup.S can be used for
304 # heap purposes.
305 # Only the loader knows what is free
306 .byte LOADED_HIGH
307 305
308setup_move_size: .word 0x8000 # size to move, when setup is not 306setup_move_size: .word 0x8000 # size to move, when setup is not
309 # loaded at 0x90000. We will move setup 307 # loaded at 0x90000. We will move setup
@@ -369,7 +367,23 @@ relocatable_kernel: .byte 1
369relocatable_kernel: .byte 0 367relocatable_kernel: .byte 0
370#endif 368#endif
371min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment 369min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment
372pad3: .word 0 370
371xloadflags:
372#ifdef CONFIG_X86_64
373# define XLF0 XLF_KERNEL_64 /* 64-bit kernel */
374#else
375# define XLF0 0
376#endif
377#ifdef CONFIG_EFI_STUB
378# ifdef CONFIG_X86_64
379# define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */
380# else
381# define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */
382# endif
383#else
384# define XLF23 0
385#endif
386 .word XLF0 | XLF23
373 387
374cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, 388cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
375 #added with boot protocol 389 #added with boot protocol
@@ -397,8 +411,13 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
397#define INIT_SIZE VO_INIT_SIZE 411#define INIT_SIZE VO_INIT_SIZE
398#endif 412#endif
399init_size: .long INIT_SIZE # kernel initialization size 413init_size: .long INIT_SIZE # kernel initialization size
400handover_offset: .long 0x30 # offset to the handover 414handover_offset:
415#ifdef CONFIG_EFI_STUB
416 .long 0x30 # offset to the handover
401 # protocol entry point 417 # protocol entry point
418#else
419 .long 0
420#endif
402 421
403# End of setup header ##################################################### 422# End of setup header #####################################################
404 423
diff --git a/arch/x86/boot/setup.ld b/arch/x86/boot/setup.ld
index 03c0683636b6..96a6c7563538 100644
--- a/arch/x86/boot/setup.ld
+++ b/arch/x86/boot/setup.ld
@@ -13,7 +13,7 @@ SECTIONS
13 .bstext : { *(.bstext) } 13 .bstext : { *(.bstext) }
14 .bsdata : { *(.bsdata) } 14 .bsdata : { *(.bsdata) }
15 15
16 . = 497; 16 . = 495;
17 .header : { *(.header) } 17 .header : { *(.header) }
18 .entrytext : { *(.entrytext) } 18 .entrytext : { *(.entrytext) }
19 .inittext : { *(.inittext) } 19 .inittext : { *(.inittext) }
diff --git a/arch/x86/boot/tools/build.c b/arch/x86/boot/tools/build.c
index 4b8e165ee572..94c544650020 100644
--- a/arch/x86/boot/tools/build.c
+++ b/arch/x86/boot/tools/build.c
@@ -52,6 +52,10 @@ int is_big_kernel;
52 52
53#define PECOFF_RELOC_RESERVE 0x20 53#define PECOFF_RELOC_RESERVE 0x20
54 54
55unsigned long efi_stub_entry;
56unsigned long efi_pe_entry;
57unsigned long startup_64;
58
55/*----------------------------------------------------------------------*/ 59/*----------------------------------------------------------------------*/
56 60
57static const u32 crctab32[] = { 61static const u32 crctab32[] = {
@@ -132,7 +136,7 @@ static void die(const char * str, ...)
132 136
133static void usage(void) 137static void usage(void)
134{ 138{
135 die("Usage: build setup system [> image]"); 139 die("Usage: build setup system [zoffset.h] [> image]");
136} 140}
137 141
138#ifdef CONFIG_EFI_STUB 142#ifdef CONFIG_EFI_STUB
@@ -206,30 +210,54 @@ static void update_pecoff_text(unsigned int text_start, unsigned int file_sz)
206 */ 210 */
207 put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]); 211 put_unaligned_le32(file_sz - 512, &buf[pe_header + 0x1c]);
208 212
209#ifdef CONFIG_X86_32
210 /* 213 /*
211 * Address of entry point. 214 * Address of entry point for PE/COFF executable
212 *
213 * The EFI stub entry point is +16 bytes from the start of
214 * the .text section.
215 */ 215 */
216 put_unaligned_le32(text_start + 16, &buf[pe_header + 0x28]); 216 put_unaligned_le32(text_start + efi_pe_entry, &buf[pe_header + 0x28]);
217#else
218 /*
219 * Address of entry point. startup_32 is at the beginning and
220 * the 64-bit entry point (startup_64) is always 512 bytes
221 * after. The EFI stub entry point is 16 bytes after that, as
222 * the first instruction allows legacy loaders to jump over
223 * the EFI stub initialisation
224 */
225 put_unaligned_le32(text_start + 528, &buf[pe_header + 0x28]);
226#endif /* CONFIG_X86_32 */
227 217
228 update_pecoff_section_header(".text", text_start, text_sz); 218 update_pecoff_section_header(".text", text_start, text_sz);
229} 219}
230 220
231#endif /* CONFIG_EFI_STUB */ 221#endif /* CONFIG_EFI_STUB */
232 222
223
224/*
225 * Parse zoffset.h and find the entry points. We could just #include zoffset.h
226 * but that would mean tools/build would have to be rebuilt every time. It's
227 * not as if parsing it is hard...
228 */
229#define PARSE_ZOFS(p, sym) do { \
230 if (!strncmp(p, "#define ZO_" #sym " ", 11+sizeof(#sym))) \
231 sym = strtoul(p + 11 + sizeof(#sym), NULL, 16); \
232} while (0)
233
234static void parse_zoffset(char *fname)
235{
236 FILE *file;
237 char *p;
238 int c;
239
240 file = fopen(fname, "r");
241 if (!file)
242 die("Unable to open `%s': %m", fname);
243 c = fread(buf, 1, sizeof(buf) - 1, file);
244 if (ferror(file))
245 die("read-error on `zoffset.h'");
246 buf[c] = 0;
247
248 p = (char *)buf;
249
250 while (p && *p) {
251 PARSE_ZOFS(p, efi_stub_entry);
252 PARSE_ZOFS(p, efi_pe_entry);
253 PARSE_ZOFS(p, startup_64);
254
255 p = strchr(p, '\n');
256 while (p && (*p == '\r' || *p == '\n'))
257 p++;
258 }
259}
260
233int main(int argc, char ** argv) 261int main(int argc, char ** argv)
234{ 262{
235 unsigned int i, sz, setup_sectors; 263 unsigned int i, sz, setup_sectors;
@@ -241,7 +269,19 @@ int main(int argc, char ** argv)
241 void *kernel; 269 void *kernel;
242 u32 crc = 0xffffffffUL; 270 u32 crc = 0xffffffffUL;
243 271
244 if (argc != 3) 272 /* Defaults for old kernel */
273#ifdef CONFIG_X86_32
274 efi_pe_entry = 0x10;
275 efi_stub_entry = 0x30;
276#else
277 efi_pe_entry = 0x210;
278 efi_stub_entry = 0x230;
279 startup_64 = 0x200;
280#endif
281
282 if (argc == 4)
283 parse_zoffset(argv[3]);
284 else if (argc != 3)
245 usage(); 285 usage();
246 286
247 /* Copy the setup code */ 287 /* Copy the setup code */
@@ -299,6 +339,11 @@ int main(int argc, char ** argv)
299 339
300#ifdef CONFIG_EFI_STUB 340#ifdef CONFIG_EFI_STUB
301 update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz)); 341 update_pecoff_text(setup_sectors * 512, sz + i + ((sys_size * 16) - sz));
342
343#ifdef CONFIG_X86_64 /* Yes, this is really how we defined it :( */
344 efi_stub_entry -= 0x200;
345#endif
346 put_unaligned_le32(efi_stub_entry, &buf[0x264]);
302#endif 347#endif
303 348
304 crc = partial_crc32(buf, i, crc); 349 crc = partial_crc32(buf, i, crc);
diff --git a/arch/x86/include/uapi/asm/bootparam.h b/arch/x86/include/uapi/asm/bootparam.h
index 92862cd90201..c15ddaf90710 100644
--- a/arch/x86/include/uapi/asm/bootparam.h
+++ b/arch/x86/include/uapi/asm/bootparam.h
@@ -1,6 +1,31 @@
1#ifndef _ASM_X86_BOOTPARAM_H 1#ifndef _ASM_X86_BOOTPARAM_H
2#define _ASM_X86_BOOTPARAM_H 2#define _ASM_X86_BOOTPARAM_H
3 3
4/* setup_data types */
5#define SETUP_NONE 0
6#define SETUP_E820_EXT 1
7#define SETUP_DTB 2
8#define SETUP_PCI 3
9
10/* ram_size flags */
11#define RAMDISK_IMAGE_START_MASK 0x07FF
12#define RAMDISK_PROMPT_FLAG 0x8000
13#define RAMDISK_LOAD_FLAG 0x4000
14
15/* loadflags */
16#define LOADED_HIGH (1<<0)
17#define QUIET_FLAG (1<<5)
18#define KEEP_SEGMENTS (1<<6)
19#define CAN_USE_HEAP (1<<7)
20
21/* xloadflags */
22#define XLF_KERNEL_64 (1<<0)
23#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
24#define XLF_EFI_HANDOVER_32 (1<<2)
25#define XLF_EFI_HANDOVER_64 (1<<3)
26
27#ifndef __ASSEMBLY__
28
4#include <linux/types.h> 29#include <linux/types.h>
5#include <linux/screen_info.h> 30#include <linux/screen_info.h>
6#include <linux/apm_bios.h> 31#include <linux/apm_bios.h>
@@ -9,12 +34,6 @@
9#include <asm/ist.h> 34#include <asm/ist.h>
10#include <video/edid.h> 35#include <video/edid.h>
11 36
12/* setup data types */
13#define SETUP_NONE 0
14#define SETUP_E820_EXT 1
15#define SETUP_DTB 2
16#define SETUP_PCI 3
17
18/* extensible setup data list node */ 37/* extensible setup data list node */
19struct setup_data { 38struct setup_data {
20 __u64 next; 39 __u64 next;
@@ -28,9 +47,6 @@ struct setup_header {
28 __u16 root_flags; 47 __u16 root_flags;
29 __u32 syssize; 48 __u32 syssize;
30 __u16 ram_size; 49 __u16 ram_size;
31#define RAMDISK_IMAGE_START_MASK 0x07FF
32#define RAMDISK_PROMPT_FLAG 0x8000
33#define RAMDISK_LOAD_FLAG 0x4000
34 __u16 vid_mode; 50 __u16 vid_mode;
35 __u16 root_dev; 51 __u16 root_dev;
36 __u16 boot_flag; 52 __u16 boot_flag;
@@ -42,10 +58,6 @@ struct setup_header {
42 __u16 kernel_version; 58 __u16 kernel_version;
43 __u8 type_of_loader; 59 __u8 type_of_loader;
44 __u8 loadflags; 60 __u8 loadflags;
45#define LOADED_HIGH (1<<0)
46#define QUIET_FLAG (1<<5)
47#define KEEP_SEGMENTS (1<<6)
48#define CAN_USE_HEAP (1<<7)
49 __u16 setup_move_size; 61 __u16 setup_move_size;
50 __u32 code32_start; 62 __u32 code32_start;
51 __u32 ramdisk_image; 63 __u32 ramdisk_image;
@@ -58,7 +70,8 @@ struct setup_header {
58 __u32 initrd_addr_max; 70 __u32 initrd_addr_max;
59 __u32 kernel_alignment; 71 __u32 kernel_alignment;
60 __u8 relocatable_kernel; 72 __u8 relocatable_kernel;
61 __u8 _pad2[3]; 73 __u8 min_alignment;
74 __u16 xloadflags;
62 __u32 cmdline_size; 75 __u32 cmdline_size;
63 __u32 hardware_subarch; 76 __u32 hardware_subarch;
64 __u64 hardware_subarch_data; 77 __u64 hardware_subarch_data;
@@ -106,7 +119,10 @@ struct boot_params {
106 __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */ 119 __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */
107 struct sys_desc_table sys_desc_table; /* 0x0a0 */ 120 struct sys_desc_table sys_desc_table; /* 0x0a0 */
108 struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */ 121 struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */
109 __u8 _pad4[128]; /* 0x0c0 */ 122 __u32 ext_ramdisk_image; /* 0x0c0 */
123 __u32 ext_ramdisk_size; /* 0x0c4 */
124 __u32 ext_cmd_line_ptr; /* 0x0c8 */
125 __u8 _pad4[116]; /* 0x0cc */
110 struct edid_info edid_info; /* 0x140 */ 126 struct edid_info edid_info; /* 0x140 */
111 struct efi_info efi_info; /* 0x1c0 */ 127 struct efi_info efi_info; /* 0x1c0 */
112 __u32 alt_mem_k; /* 0x1e0 */ 128 __u32 alt_mem_k; /* 0x1e0 */
@@ -115,7 +131,20 @@ struct boot_params {
115 __u8 eddbuf_entries; /* 0x1e9 */ 131 __u8 eddbuf_entries; /* 0x1e9 */
116 __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ 132 __u8 edd_mbr_sig_buf_entries; /* 0x1ea */
117 __u8 kbd_status; /* 0x1eb */ 133 __u8 kbd_status; /* 0x1eb */
118 __u8 _pad6[5]; /* 0x1ec */ 134 __u8 _pad5[3]; /* 0x1ec */
135 /*
136 * The sentinel is set to a nonzero value (0xff) in header.S.
137 *
138 * A bootloader is supposed to only take setup_header and put
139 * it into a clean boot_params buffer. If it turns out that
140 * it is clumsy or too generous with the buffer, it most
141 * probably will pick up the sentinel variable too. The fact
142 * that this variable then is still 0xff will let kernel
143 * know that some variables in boot_params are invalid and
144 * kernel should zero out certain portions of boot_params.
145 */
146 __u8 sentinel; /* 0x1ef */
147 __u8 _pad6[1]; /* 0x1f0 */
119 struct setup_header hdr; /* setup header */ /* 0x1f1 */ 148 struct setup_header hdr; /* setup header */ /* 0x1f1 */
120 __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; 149 __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
121 __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ 150 __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
@@ -134,6 +163,6 @@ enum {
134 X86_NR_SUBARCHS, 163 X86_NR_SUBARCHS,
135}; 164};
136 165
137 166#endif /* __ASSEMBLY__ */
138 167
139#endif /* _ASM_X86_BOOTPARAM_H */ 168#endif /* _ASM_X86_BOOTPARAM_H */
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 5426e482db6e..77cf0090c0a3 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -949,7 +949,7 @@ void __init efi_enter_virtual_mode(void)
949 * 949 *
950 * Call EFI services through wrapper functions. 950 * Call EFI services through wrapper functions.
951 */ 951 */
952 efi.runtime_version = efi_systab.fw_revision; 952 efi.runtime_version = efi_systab.hdr.revision;
953 efi.get_time = virt_efi_get_time; 953 efi.get_time = virt_efi_get_time;
954 efi.set_time = virt_efi_set_time; 954 efi.set_time = virt_efi_set_time;
955 efi.get_wakeup_time = virt_efi_get_wakeup_time; 955 efi.get_wakeup_time = virt_efi_get_wakeup_time;
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 95fd505dfeb6..2b2003860615 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -38,7 +38,7 @@
38#include <asm/cacheflush.h> 38#include <asm/cacheflush.h>
39#include <asm/fixmap.h> 39#include <asm/fixmap.h>
40 40
41static pgd_t save_pgd __initdata; 41static pgd_t *save_pgd __initdata;
42static unsigned long efi_flags __initdata; 42static unsigned long efi_flags __initdata;
43 43
44static void __init early_code_mapping_set_exec(int executable) 44static void __init early_code_mapping_set_exec(int executable)
@@ -61,12 +61,20 @@ static void __init early_code_mapping_set_exec(int executable)
61void __init efi_call_phys_prelog(void) 61void __init efi_call_phys_prelog(void)
62{ 62{
63 unsigned long vaddress; 63 unsigned long vaddress;
64 int pgd;
65 int n_pgds;
64 66
65 early_code_mapping_set_exec(1); 67 early_code_mapping_set_exec(1);
66 local_irq_save(efi_flags); 68 local_irq_save(efi_flags);
67 vaddress = (unsigned long)__va(0x0UL); 69
68 save_pgd = *pgd_offset_k(0x0UL); 70 n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT), PGDIR_SIZE);
69 set_pgd(pgd_offset_k(0x0UL), *pgd_offset_k(vaddress)); 71 save_pgd = kmalloc(n_pgds * sizeof(pgd_t), GFP_KERNEL);
72
73 for (pgd = 0; pgd < n_pgds; pgd++) {
74 save_pgd[pgd] = *pgd_offset_k(pgd * PGDIR_SIZE);
75 vaddress = (unsigned long)__va(pgd * PGDIR_SIZE);
76 set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), *pgd_offset_k(vaddress));
77 }
70 __flush_tlb_all(); 78 __flush_tlb_all();
71} 79}
72 80
@@ -75,7 +83,11 @@ void __init efi_call_phys_epilog(void)
75 /* 83 /*
76 * After the lock is released, the original page table is restored. 84 * After the lock is released, the original page table is restored.
77 */ 85 */
78 set_pgd(pgd_offset_k(0x0UL), save_pgd); 86 int pgd;
87 int n_pgds = DIV_ROUND_UP((max_pfn << PAGE_SHIFT) , PGDIR_SIZE);
88 for (pgd = 0; pgd < n_pgds; pgd++)
89 set_pgd(pgd_offset_k(pgd * PGDIR_SIZE), save_pgd[pgd]);
90 kfree(save_pgd);
79 __flush_tlb_all(); 91 __flush_tlb_all();
80 local_irq_restore(efi_flags); 92 local_irq_restore(efi_flags);
81 early_code_mapping_set_exec(0); 93 early_code_mapping_set_exec(0);
diff --git a/arch/x86/tools/relocs.c b/arch/x86/tools/relocs.c
index 5a1847d61930..79d67bd507fa 100644
--- a/arch/x86/tools/relocs.c
+++ b/arch/x86/tools/relocs.c
@@ -814,12 +814,14 @@ int main(int argc, char **argv)
814 read_relocs(fp); 814 read_relocs(fp);
815 if (show_absolute_syms) { 815 if (show_absolute_syms) {
816 print_absolute_symbols(); 816 print_absolute_symbols();
817 return 0; 817 goto out;
818 } 818 }
819 if (show_absolute_relocs) { 819 if (show_absolute_relocs) {
820 print_absolute_relocs(); 820 print_absolute_relocs();
821 return 0; 821 goto out;
822 } 822 }
823 emit_relocs(as_text, use_real_mode); 823 emit_relocs(as_text, use_real_mode);
824out:
825 fclose(fp);
824 return 0; 826 return 0;
825} 827}
diff --git a/drivers/firmware/efivars.c b/drivers/firmware/efivars.c
index 1065119dff92..f5596db0cf58 100644
--- a/drivers/firmware/efivars.c
+++ b/drivers/firmware/efivars.c
@@ -674,7 +674,7 @@ static int efi_status_to_err(efi_status_t status)
674 err = -EACCES; 674 err = -EACCES;
675 break; 675 break;
676 case EFI_NOT_FOUND: 676 case EFI_NOT_FOUND:
677 err = -ENOENT; 677 err = -EIO;
678 break; 678 break;
679 default: 679 default:
680 err = -EINVAL; 680 err = -EINVAL;
@@ -793,6 +793,7 @@ static ssize_t efivarfs_file_write(struct file *file,
793 spin_unlock(&efivars->lock); 793 spin_unlock(&efivars->lock);
794 efivar_unregister(var); 794 efivar_unregister(var);
795 drop_nlink(inode); 795 drop_nlink(inode);
796 d_delete(file->f_dentry);
796 dput(file->f_dentry); 797 dput(file->f_dentry);
797 798
798 } else { 799 } else {
@@ -994,7 +995,7 @@ static int efivarfs_unlink(struct inode *dir, struct dentry *dentry)
994 list_del(&var->list); 995 list_del(&var->list);
995 spin_unlock(&efivars->lock); 996 spin_unlock(&efivars->lock);
996 efivar_unregister(var); 997 efivar_unregister(var);
997 drop_nlink(dir); 998 drop_nlink(dentry->d_inode);
998 dput(dentry); 999 dput(dentry);
999 return 0; 1000 return 0;
1000 } 1001 }