Skip to content

Commit

Permalink
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/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
  • Loading branch information
torvalds committed Jan 31, 2013
2 parents bdb0ae6 + becbd66 commit 04c2eee
Show file tree
Hide file tree
Showing 14 changed files with 216 additions and 76 deletions.
27 changes: 26 additions & 1 deletion Documentation/x86/boot.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
protocol entry point.

Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields
to struct boot_params for for loading bzImage and ramdisk
above 4G in 64bit.

**** MEMORY LAYOUT

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

Field name: xloadflags
Type: read
Offset/size: 0x236/2
Protocol: 2.12+

This field is a bitmask.

Bit 0 (read): XLF_KERNEL_64
- If 1, this kernel has the legacy 64-bit entry point at 0x200.

Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
- If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.

Bit 2 (read): XLF_EFI_HANDOVER_32
- If 1, the kernel supports the 32-bit EFI handoff entry point
given at handover_offset.

Bit 3 (read): XLF_EFI_HANDOVER_64
- If 1, the kernel supports the 64-bit EFI handoff entry point
given at handover_offset + 0x200.

Field name: cmdline_size
Type: read
Offset/size: 0x238/4
Expand Down
4 changes: 4 additions & 0 deletions Documentation/x86/zero-page.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ Offset Proto Name Meaning
090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!!
0A0/010 ALL sys_desc_table System description table (struct sys_desc_table)
0B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends
0C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits
0C4/004 ALL ext_ramdisk_size ramdisk_size high 32bits
0C8/004 ALL ext_cmd_line_ptr cmd_line_ptr high 32bits
140/080 ALL edid_info Video mode setup (struct edid_info)
1C0/020 ALL efi_info EFI 32 information (struct efi_info)
1E0/004 ALL alk_mem_k Alternative mem check, in KB
Expand All @@ -27,6 +30,7 @@ Offset Proto Name Meaning
1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
(below)
1EF/001 ALL sentinel Used to detect broken bootloaders
290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
2D0/A00 ALL e820_map E820 memory map table
(array of struct e820entry)
Expand Down
4 changes: 2 additions & 2 deletions arch/x86/boot/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ GCOV_PROFILE := n
$(obj)/bzImage: asflags-y := $(SVGA_MODE)

quiet_cmd_image = BUILD $@
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin > $@
cmd_image = $(obj)/tools/build $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/zoffset.h > $@

$(obj)/bzImage: $(obj)/setup.bin $(obj)/vmlinux.bin $(obj)/tools/build FORCE
$(call if_changed,image)
Expand All @@ -92,7 +92,7 @@ targets += voffset.h
$(obj)/voffset.h: vmlinux FORCE
$(call if_changed,voffset)

sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p'
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'

quiet_cmd_zoffset = ZOFFSET $@
cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@
Expand Down
21 changes: 11 additions & 10 deletions arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,10 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
int i;
struct setup_data *data;

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

while (data && data->next)
data = (struct setup_data *)data->next;
data = (struct setup_data *)(unsigned long)data->next;

status = efi_call_phys5(sys_table->boottime->locate_handle,
EFI_LOCATE_BY_PROTOCOL, &pci_proto,
Expand Down Expand Up @@ -295,16 +295,18 @@ static efi_status_t setup_efi_pci(struct boot_params *params)
if (!pci)
continue;

#ifdef CONFIG_X86_64
status = efi_call_phys4(pci->attributes, pci,
EfiPciIoAttributeOperationGet, 0,
&attributes);

#else
status = efi_call_phys5(pci->attributes, pci,
EfiPciIoAttributeOperationGet, 0, 0,
&attributes);
#endif
if (status != EFI_SUCCESS)
continue;

if (!(attributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM))
continue;

if (!pci->romimage || !pci->romsize)
continue;

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

if (data)
data->next = (uint64_t)rom;
data->next = (unsigned long)rom;
else
params->hdr.setup_data = (uint64_t)rom;
params->hdr.setup_data = (unsigned long)rom;

data = (struct setup_data *)rom;

Expand Down Expand Up @@ -432,10 +434,9 @@ static efi_status_t setup_gop(struct screen_info *si, efi_guid_t *proto,
* Once we've found a GOP supporting ConOut,
* don't bother looking any further.
*/
first_gop = gop;
if (conout_found)
break;

first_gop = gop;
}
}

Expand Down
8 changes: 5 additions & 3 deletions arch/x86/boot/compressed/head_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ ENTRY(startup_32)
#ifdef CONFIG_EFI_STUB
jmp preferred_addr

.balign 0x10
/*
* We don't need the return address, so set up the stack so
* efi_main() can find its arugments.
* efi_main() can find its arguments.
*/
ENTRY(efi_pe_entry)
add $0x4, %esp

call make_boot_params
Expand All @@ -50,8 +50,10 @@ ENTRY(startup_32)
pushl %eax
pushl %esi
pushl %ecx
sub $0x4, %esp

.org 0x30,0x90
ENTRY(efi_stub_entry)
add $0x4, %esp
call efi_main
cmpl $0, %eax
movl %eax, %esi
Expand Down
8 changes: 4 additions & 4 deletions arch/x86/boot/compressed/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,12 @@ ENTRY(startup_64)
*/
#ifdef CONFIG_EFI_STUB
/*
* The entry point for the PE/COFF executable is 0x210, so only
* legacy boot loaders will execute this jmp.
* The entry point for the PE/COFF executable is efi_pe_entry, so
* only legacy boot loaders will execute this jmp.
*/
jmp preferred_addr

.org 0x210
ENTRY(efi_pe_entry)
mov %rcx, %rdi
mov %rdx, %rsi
pushq %rdi
Expand All @@ -218,7 +218,7 @@ ENTRY(startup_64)
popq %rsi
popq %rdi

.org 0x230,0x90
ENTRY(efi_stub_entry)
call efi_main
movq %rax,%rsi
cmpq $0,%rax
Expand Down
39 changes: 29 additions & 10 deletions arch/x86/boot/header.S
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <asm/e820.h>
#include <asm/page_types.h>
#include <asm/setup.h>
#include <asm/bootparam.h>
#include "boot.h"
#include "voffset.h"
#include "zoffset.h"
Expand Down Expand Up @@ -255,6 +256,9 @@ section_table:
# header, from the old boot sector.

.section ".header", "a"
.globl sentinel
sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */

.globl hdr
hdr:
setup_sects: .byte 0 /* Filled in by build.c */
Expand All @@ -279,7 +283,7 @@ _start:
# Part 2 of the header, from the old setup.S

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

# flags, unused bits must be zero (RFU) bit within loadflags
loadflags:
LOADED_HIGH = 1 # If set, the kernel is loaded high
CAN_USE_HEAP = 0x80 # If set, the loader also has set
# heap_end_ptr to tell how much
# space behind setup.S can be used for
# heap purposes.
# Only the loader knows what is free
.byte LOADED_HIGH
.byte LOADED_HIGH # The kernel is to be loaded high

setup_move_size: .word 0x8000 # size to move, when setup is not
# loaded at 0x90000. We will move setup
Expand Down Expand Up @@ -369,7 +367,23 @@ relocatable_kernel: .byte 1
relocatable_kernel: .byte 0
#endif
min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment
pad3: .word 0

xloadflags:
#ifdef CONFIG_X86_64
# define XLF0 XLF_KERNEL_64 /* 64-bit kernel */
#else
# define XLF0 0
#endif
#ifdef CONFIG_EFI_STUB
# 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
#else
# define XLF23 0
#endif
.word XLF0 | XLF23

cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
#added with boot protocol
Expand Down Expand Up @@ -397,8 +411,13 @@ 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: .long 0x30 # offset to the handover
handover_offset:
#ifdef CONFIG_EFI_STUB
.long 0x30 # offset to the handover
# protocol entry point
#else
.long 0
#endif

# End of setup header #####################################################

Expand Down
2 changes: 1 addition & 1 deletion arch/x86/boot/setup.ld
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SECTIONS
.bstext : { *(.bstext) }
.bsdata : { *(.bsdata) }

. = 497;
. = 495;
.header : { *(.header) }
.entrytext : { *(.entrytext) }
.inittext : { *(.inittext) }
Expand Down
Loading

0 comments on commit 04c2eee

Please sign in to comment.