Skip to content

Commit 04c2eee

Browse files
committed
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
2 parents bdb0ae6 + becbd66 commit 04c2eee

File tree

14 files changed

+216
-76
lines changed

14 files changed

+216
-76
lines changed

Documentation/x86/boot.txt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
5757
Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
5858
protocol entry point.
5959

60+
Protocol 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+
6064
**** MEMORY LAYOUT
6165

6266
The traditional memory map for the kernel loader, used for Image or
@@ -182,7 +186,7 @@ Offset Proto Name Meaning
182186
0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
183187
0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
184188
0235/1 2.10+ min_alignment Minimum alignment, as a power of two
185-
0236/2 N/A pad3 Unused
189+
0236/2 2.12+ xloadflags Boot protocol option flags
186190
0238/4 2.06+ cmdline_size Maximum size of the kernel command line
187191
023C/4 2.07+ hardware_subarch Hardware subarchitecture
188192
0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data
@@ -582,6 +586,27 @@ Protocol: 2.10+
582586
misaligned kernel. Therefore, a loader should typically try each
583587
power-of-two alignment from kernel_alignment down to this alignment.
584588

589+
Field name: xloadflags
590+
Type: read
591+
Offset/size: 0x236/2
592+
Protocol: 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+
585610
Field name: cmdline_size
586611
Type: read
587612
Offset/size: 0x238/4

Documentation/x86/zero-page.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ Offset Proto Name Meaning
1919
090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!!
2020
0A0/010 ALL sys_desc_table System description table (struct sys_desc_table)
2121
0B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends
22+
0C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits
23+
0C4/004 ALL ext_ramdisk_size ramdisk_size high 32bits
24+
0C8/004 ALL ext_cmd_line_ptr cmd_line_ptr high 32bits
2225
140/080 ALL edid_info Video mode setup (struct edid_info)
2326
1C0/020 ALL efi_info EFI 32 information (struct efi_info)
2427
1E0/004 ALL alk_mem_k Alternative mem check, in KB
@@ -27,6 +30,7 @@ Offset Proto Name Meaning
2730
1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
2831
1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
2932
(below)
33+
1EF/001 ALL sentinel Used to detect broken bootloaders
3034
290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
3135
2D0/A00 ALL e820_map E820 memory map table
3236
(array of struct e820entry)

arch/x86/boot/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ GCOV_PROFILE := n
7171
$(obj)/bzImage: asflags-y := $(SVGA_MODE)
7272

7373
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 > $@
7575

7676
$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
7777
$(call if_changed,image)
@@ -92,7 +92,7 @@ targets += voffset.h
9292
$(obj)/voffset.h: vmlinux FORCE
9393
$(call if_changed,voffset)
9494

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'
9696

9797
quiet_cmd_zoffset = ZOFFSET $@
9898
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@

arch/x86/boot/compressed/eboot.c

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,10 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
256256
int i;
257257
struct setup_data *data;
258258

259-
data = (struct setup_data *)params->hdr.setup_data;
259+
data = (struct setup_data *)(unsigned long)params->hdr.setup_data;
260260

261261
while (data && data->next)
262-
data = (struct setup_data *)data->next;
262+
data = (struct setup_data *)(unsigned long)data->next;
263263

264264
status = efi_call_phys5(sys_table->boottime->locate_handle,
265265
EFI_LOCATE_BY_PROTOCOL, &pci_proto,
@@ -295,16 +295,18 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
295295
if (!pci)
296296
continue;
297297

298+
#ifdef CONFIG_X86_64
298299
status = efi_call_phys4(pci->attributes, pci,
299300
EfiPciIoAttributeOperationGet, 0,
300301
&attributes);
301-
302+
#else
303+
status = efi_call_phys5(pci->attributes, pci,
304+
EfiPciIoAttributeOperationGet, 0, 0,
305+
&attributes);
306+
#endif
302307
if (status != EFI_SUCCESS)
303308
continue;
304309

305-
if (!(attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM))
306-
continue;
307-
308310
if (!pci->romimage || !pci->romsize)
309311
continue;
310312

@@ -345,9 +347,9 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
345347
memcpy(rom->romdata, pci->romimage, pci->romsize);
346348

347349
if (data)
348-
data->next = (uint64_t)rom;
350+
data->next = (unsigned long)rom;
349351
else
350-
params->hdr.setup_data = (uint64_t)rom;
352+
params->hdr.setup_data = (unsigned long)rom;
351353

352354
data = (struct setup_data *)rom;
353355

@@ -432,10 +434,9 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
432434
* Once we've found a GOP supporting ConOut,
433435
* don't bother looking any further.
434436
*/
437+
first_gop = gop;
435438
if (conout_found)
436439
break;
437-
438-
first_gop = gop;
439440
}
440441
}
441442

arch/x86/boot/compressed/head_32.S

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,11 @@ ENTRY(startup_32)
3535
#ifdef CONFIG_EFI_STUB
3636
jmp preferred_addr
3737

38-
.balign 0x10
3938
/*
4039
* 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.
4241
*/
42+
ENTRY(efi_pe_entry)
4343
add $0x4, %esp
4444

4545
call make_boot_params
@@ -50,8 +50,10 @@ ENTRY(startup_32)
5050
pushl %eax
5151
pushl %esi
5252
pushl %ecx
53+
sub $0x4, %esp
5354

54-
.org 0x30,0x90
55+
ENTRY(efi_stub_entry)
56+
add $0x4, %esp
5557
call efi_main
5658
cmpl $0, %eax
5759
movl %eax, %esi

arch/x86/boot/compressed/head_64.S

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,12 @@ ENTRY(startup_64)
201201
*/
202202
#ifdef CONFIG_EFI_STUB
203203
/*
204-
* The entry point for the PE/COFF executable is 0x210, so only
205-
* legacy boot loaders will execute this jmp.
204+
* The entry point for the PE/COFF executable is efi_pe_entry, so
205+
* only legacy boot loaders will execute this jmp.
206206
*/
207207
jmp preferred_addr
208208

209-
.org 0x210
209+
ENTRY(efi_pe_entry)
210210
mov %rcx, %rdi
211211
mov %rdx, %rsi
212212
pushq %rdi
@@ -218,7 +218,7 @@ ENTRY(startup_64)
218218
popq %rsi
219219
popq %rdi
220220

221-
.org 0x230,0x90
221+
ENTRY(efi_stub_entry)
222222
call efi_main
223223
movq %rax,%rsi
224224
cmpq $0,%rax

arch/x86/boot/header.S

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <asm/e820.h>
2222
#include <asm/page_types.h>
2323
#include <asm/setup.h>
24+
#include <asm/bootparam.h>
2425
#include "boot.h"
2526
#include "voffset.h"
2627
#include "zoffset.h"
@@ -255,6 +256,9 @@ section_table:
255256
# header, from the old boot sector.
256257

257258
.section ".header", "a"
259+
.globl sentinel
260+
sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */
261+
258262
.globl hdr
259263
hdr:
260264
setup_sects: .byte 0 /* Filled in by build.c */
@@ -279,7 +283,7 @@ _start:
279283
# Part 2 of the header, from the old setup.S
280284

281285
.ascii "HdrS" # header signature
282-
.word 0x020b # header version number (>= 0x0105)
286+
.word 0x020c # header version number (>= 0x0105)
283287
# or else old loadlin-1.5 will fail)
284288
.globl realmode_swtch
285289
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
@@ -297,13 +301,7 @@ type_of_loader: .byte 0 # 0 means ancient bootloader, newer
297301

298302
# flags, unused bits must be zero (RFU) bit within loadflags
299303
loadflags:
300-
LOADED_HIGH = 1 # If set, the kernel is 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
304+
.byte LOADED_HIGH # The kernel is to be loaded high
307305

308306
setup_move_size: .word 0x8000 # size to move, when setup is not
309307
# loaded at 0x90000. We will move setup
@@ -369,7 +367,23 @@ relocatable_kernel: .byte 1
369367
relocatable_kernel: .byte 0
370368
#endif
371369
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
373387

374388
cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
375389
#added with boot protocol
@@ -397,8 +411,13 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
397411
#define INIT_SIZE VO_INIT_SIZE
398412
#endif
399413
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
401417
# protocol entry point
418+
#else
419+
.long 0
420+
#endif
402421

403422
# End of setup header #####################################################
404423

arch/x86/boot/setup.ld

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ SECTIONS
1313
.bstext : { *(.bstext) }
1414
.bsdata : { *(.bsdata) }
1515

16-
. = 497;
16+
. = 495;
1717
.header : { *(.header) }
1818
.entrytext : { *(.entrytext) }
1919
.inittext : { *(.inittext) }

0 commit comments

Comments
 (0)