Skip to content

Commit

Permalink
Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/g…
Browse files Browse the repository at this point in the history
…it/mfleming/efi into x86/urgent

Pull EFI fixes from Matt Fleming:

"* Fix EFI boot regression introduced during the merge window where the
   firmware was reading random values from the stack because we were
   passing a pointer to the wrong object type.

 * Kernel corruption has been reported when booting with the EFI boot
   stub which was tracked down to setting a bogus value for
   bp->hdr.code32_start, resulting in corruption during relocation.

 * Olivier Martin reported that the wrong file handles were being passed
   to efi_file_(read|close), which works for x86 by luck due to the way
   that the FAT driver is implemented, but doesn't work on ARM."

Signed-off-by: Ingo Molnar <mingo@kernel.org>
  • Loading branch information
Ingo Molnar committed Apr 11, 2014
2 parents f704a7d + 47514c9 commit 3151b94
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 24 deletions.
19 changes: 10 additions & 9 deletions arch/x86/boot/compressed/eboot.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ __file_size64(void *__fh, efi_char16_t *filename_16,
efi_file_info_t *info;
efi_status_t status;
efi_guid_t info_guid = EFI_FILE_INFO_ID;
u32 info_sz;
u64 info_sz;

status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
EFI_FILE_MODE_READ, (u64)0);
Expand Down Expand Up @@ -167,31 +167,31 @@ efi_file_size(efi_system_table_t *sys_table, void *__fh,
}

static inline efi_status_t
efi_file_read(void *__fh, void *handle, unsigned long *size, void *addr)
efi_file_read(void *handle, unsigned long *size, void *addr)
{
unsigned long func;

if (efi_early->is64) {
efi_file_handle_64_t *fh = __fh;
efi_file_handle_64_t *fh = handle;

func = (unsigned long)fh->read;
return efi_early->call(func, handle, size, addr);
} else {
efi_file_handle_32_t *fh = __fh;
efi_file_handle_32_t *fh = handle;

func = (unsigned long)fh->read;
return efi_early->call(func, handle, size, addr);
}
}

static inline efi_status_t efi_file_close(void *__fh, void *handle)
static inline efi_status_t efi_file_close(void *handle)
{
if (efi_early->is64) {
efi_file_handle_64_t *fh = __fh;
efi_file_handle_64_t *fh = handle;

return efi_early->call((unsigned long)fh->close, handle);
} else {
efi_file_handle_32_t *fh = __fh;
efi_file_handle_32_t *fh = handle;

return efi_early->call((unsigned long)fh->close, handle);
}
Expand Down Expand Up @@ -1016,6 +1016,9 @@ void setup_graphics(struct boot_params *boot_params)
* Because the x86 boot code expects to be passed a boot_params we
* need to create one ourselves (usually the bootloader would create
* one for us).
*
* The caller is responsible for filling out ->code32_start in the
* returned boot_params.
*/
struct boot_params *make_boot_params(struct efi_config *c)
{
Expand Down Expand Up @@ -1081,8 +1084,6 @@ struct boot_params *make_boot_params(struct efi_config *c)
hdr->vid_mode = 0xffff;
hdr->boot_flag = 0xAA55;

hdr->code32_start = (__u64)(unsigned long)image->image_base;

hdr->type_of_loader = 0x21;

/* Convert unicode cmdline to ascii */
Expand Down
8 changes: 2 additions & 6 deletions arch/x86/boot/compressed/head_32.S
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ ENTRY(efi_pe_entry)
call make_boot_params
cmpl $0, %eax
je fail
movl %esi, BP_code32_start(%eax)
popl %ecx
pushl %eax
pushl %ecx
Expand Down Expand Up @@ -90,12 +91,7 @@ fail:
hlt
jmp fail
2:
call 3f
3:
popl %eax
subl $3b, %eax
subl BP_pref_address(%esi), %eax
add BP_code32_start(%esi), %eax
movl BP_code32_start(%esi), %eax
leal preferred_addr(%eax), %eax
jmp *%eax

Expand Down
9 changes: 3 additions & 6 deletions arch/x86/boot/compressed/head_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,8 @@ ENTRY(efi_pe_entry)
cmpq $0,%rax
je fail
mov %rax, %rsi
leaq startup_32(%rip), %rax
movl %eax, BP_code32_start(%rsi)
jmp 2f /* Skip the relocation */

handover_entry:
Expand All @@ -284,12 +286,7 @@ fail:
hlt
jmp fail
2:
call 3f
3:
popq %rax
subq $3b, %rax
subq BP_pref_address(%rsi), %rax
add BP_code32_start(%esi), %eax
movl BP_code32_start(%esi), %eax
leaq preferred_addr(%rax), %rax
jmp *%rax

Expand Down
6 changes: 3 additions & 3 deletions drivers/firmware/efi/efi-stub-helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
else
chunksize = size;

status = efi_file_read(fh, files[j].handle,
status = efi_file_read(files[j].handle,
&chunksize,
(void *)addr);
if (status != EFI_SUCCESS) {
Expand All @@ -408,7 +408,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
size -= chunksize;
}

efi_file_close(fh, files[j].handle);
efi_file_close(files[j].handle);
}

}
Expand All @@ -425,7 +425,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,

close_handles:
for (k = j; k < i; k++)
efi_file_close(fh, files[k].handle);
efi_file_close(files[k].handle);
free_files:
efi_call_early(free_pool, files);
fail:
Expand Down

0 comments on commit 3151b94

Please sign in to comment.