diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-31 01:10:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-01-31 01:10:36 -0500 |
commit | 04c2eee5b9dfcb13f3cd07a5537fb8c785f2751a (patch) | |
tree | a70cf1df64b3715c502211233dc307abacaed7da /arch | |
parent | bdb0ae6a767ef2622eb282e06fc225e855341653 (diff) | |
parent | becbd6608026c15afd88fd3d0c893dfb7b8c7845 (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
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/boot/Makefile | 4 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 21 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 8 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 8 | ||||
-rw-r--r-- | arch/x86/boot/header.S | 39 | ||||
-rw-r--r-- | arch/x86/boot/setup.ld | 2 | ||||
-rw-r--r-- | arch/x86/boot/tools/build.c | 81 | ||||
-rw-r--r-- | arch/x86/include/uapi/asm/bootparam.h | 63 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 2 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi_64.c | 22 | ||||
-rw-r--r-- | arch/x86/tools/relocs.c | 6 |
11 files changed, 183 insertions, 73 deletions
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 | ||
73 | quiet_cmd_image = BUILD $@ | 73 | quiet_cmd_image = BUILD $@ |
74 | cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin > $@ | 74 | cmd_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 | ||
95 | sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' | 95 | 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' |
96 | 96 | ||
97 | quiet_cmd_zoffset = ZOFFSET $@ | 97 | quiet_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 | */ |
42 | ENTRY(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 | 55 | ENTRY(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 | 209 | ENTRY(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 | 221 | ENTRY(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 | ||
260 | sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */ | ||
261 | |||
258 | .globl hdr | 262 | .globl hdr |
259 | hdr: | 263 | hdr: |
260 | setup_sects: .byte 0 /* Filled in by build.c */ | 264 | setup_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 |
285 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG | 289 | realmode_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 |
299 | loadflags: | 303 | loadflags: |
300 | LOADED_HIGH = 1 # If set, the kernel is loaded high | 304 | .byte LOADED_HIGH # The kernel is to be loaded high |
301 | CAN_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 | ||
308 | setup_move_size: .word 0x8000 # size to move, when setup is not | 306 | setup_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 | |||
369 | relocatable_kernel: .byte 0 | 367 | relocatable_kernel: .byte 0 |
370 | #endif | 368 | #endif |
371 | min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment | 369 | min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment |
372 | pad3: .word 0 | 370 | |
371 | xloadflags: | ||
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 | ||
374 | cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, | 388 | cmdline_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 |
399 | init_size: .long INIT_SIZE # kernel initialization size | 413 | init_size: .long INIT_SIZE # kernel initialization size |
400 | handover_offset: .long 0x30 # offset to the handover | 414 | handover_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 | ||
55 | unsigned long efi_stub_entry; | ||
56 | unsigned long efi_pe_entry; | ||
57 | unsigned long startup_64; | ||
58 | |||
55 | /*----------------------------------------------------------------------*/ | 59 | /*----------------------------------------------------------------------*/ |
56 | 60 | ||
57 | static const u32 crctab32[] = { | 61 | static const u32 crctab32[] = { |
@@ -132,7 +136,7 @@ static void die(const char * str, ...) | |||
132 | 136 | ||
133 | static void usage(void) | 137 | static 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 | |||
234 | static 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 | |||
233 | int main(int argc, char ** argv) | 261 | int 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 */ |
19 | struct setup_data { | 38 | struct 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 | ||
41 | static pgd_t save_pgd __initdata; | 41 | static pgd_t *save_pgd __initdata; |
42 | static unsigned long efi_flags __initdata; | 42 | static unsigned long efi_flags __initdata; |
43 | 43 | ||
44 | static void __init early_code_mapping_set_exec(int executable) | 44 | static void __init early_code_mapping_set_exec(int executable) |
@@ -61,12 +61,20 @@ static void __init early_code_mapping_set_exec(int executable) | |||
61 | void __init efi_call_phys_prelog(void) | 61 | void __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); |
824 | out: | ||
825 | fclose(fp); | ||
824 | return 0; | 826 | return 0; |
825 | } | 827 | } |