提交 3151b942 编写于 作者: I Ingo Molnar

Merge tag 'efi-urgent' of...

Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/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: NIngo Molnar <mingo@kernel.org>
...@@ -112,7 +112,7 @@ __file_size64(void *__fh, efi_char16_t *filename_16, ...@@ -112,7 +112,7 @@ __file_size64(void *__fh, efi_char16_t *filename_16,
efi_file_info_t *info; efi_file_info_t *info;
efi_status_t status; efi_status_t status;
efi_guid_t info_guid = EFI_FILE_INFO_ID; 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, status = efi_early->call((unsigned long)fh->open, fh, &h, filename_16,
EFI_FILE_MODE_READ, (u64)0); EFI_FILE_MODE_READ, (u64)0);
...@@ -167,31 +167,31 @@ efi_file_size(efi_system_table_t *sys_table, void *__fh, ...@@ -167,31 +167,31 @@ efi_file_size(efi_system_table_t *sys_table, void *__fh,
} }
static inline efi_status_t 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; unsigned long func;
if (efi_early->is64) { if (efi_early->is64) {
efi_file_handle_64_t *fh = __fh; efi_file_handle_64_t *fh = handle;
func = (unsigned long)fh->read; func = (unsigned long)fh->read;
return efi_early->call(func, handle, size, addr); return efi_early->call(func, handle, size, addr);
} else { } else {
efi_file_handle_32_t *fh = __fh; efi_file_handle_32_t *fh = handle;
func = (unsigned long)fh->read; func = (unsigned long)fh->read;
return efi_early->call(func, handle, size, addr); 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) { 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); return efi_early->call((unsigned long)fh->close, handle);
} else { } else {
efi_file_handle_32_t *fh = __fh; efi_file_handle_32_t *fh = handle;
return efi_early->call((unsigned long)fh->close, handle); return efi_early->call((unsigned long)fh->close, handle);
} }
...@@ -1016,6 +1016,9 @@ void setup_graphics(struct boot_params *boot_params) ...@@ -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 * Because the x86 boot code expects to be passed a boot_params we
* need to create one ourselves (usually the bootloader would create * need to create one ourselves (usually the bootloader would create
* one for us). * 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) struct boot_params *make_boot_params(struct efi_config *c)
{ {
...@@ -1081,8 +1084,6 @@ struct boot_params *make_boot_params(struct efi_config *c) ...@@ -1081,8 +1084,6 @@ struct boot_params *make_boot_params(struct efi_config *c)
hdr->vid_mode = 0xffff; hdr->vid_mode = 0xffff;
hdr->boot_flag = 0xAA55; hdr->boot_flag = 0xAA55;
hdr->code32_start = (__u64)(unsigned long)image->image_base;
hdr->type_of_loader = 0x21; hdr->type_of_loader = 0x21;
/* Convert unicode cmdline to ascii */ /* Convert unicode cmdline to ascii */
......
...@@ -59,6 +59,7 @@ ENTRY(efi_pe_entry) ...@@ -59,6 +59,7 @@ ENTRY(efi_pe_entry)
call make_boot_params call make_boot_params
cmpl $0, %eax cmpl $0, %eax
je fail je fail
movl %esi, BP_code32_start(%eax)
popl %ecx popl %ecx
pushl %eax pushl %eax
pushl %ecx pushl %ecx
...@@ -90,12 +91,7 @@ fail: ...@@ -90,12 +91,7 @@ fail:
hlt hlt
jmp fail jmp fail
2: 2:
call 3f movl BP_code32_start(%esi), %eax
3:
popl %eax
subl $3b, %eax
subl BP_pref_address(%esi), %eax
add BP_code32_start(%esi), %eax
leal preferred_addr(%eax), %eax leal preferred_addr(%eax), %eax
jmp *%eax jmp *%eax
......
...@@ -261,6 +261,8 @@ ENTRY(efi_pe_entry) ...@@ -261,6 +261,8 @@ ENTRY(efi_pe_entry)
cmpq $0,%rax cmpq $0,%rax
je fail je fail
mov %rax, %rsi mov %rax, %rsi
leaq startup_32(%rip), %rax
movl %eax, BP_code32_start(%rsi)
jmp 2f /* Skip the relocation */ jmp 2f /* Skip the relocation */
handover_entry: handover_entry:
...@@ -284,12 +286,7 @@ fail: ...@@ -284,12 +286,7 @@ fail:
hlt hlt
jmp fail jmp fail
2: 2:
call 3f movl BP_code32_start(%esi), %eax
3:
popq %rax
subq $3b, %rax
subq BP_pref_address(%rsi), %rax
add BP_code32_start(%esi), %eax
leaq preferred_addr(%rax), %rax leaq preferred_addr(%rax), %rax
jmp *%rax jmp *%rax
......
...@@ -397,7 +397,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, ...@@ -397,7 +397,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
else else
chunksize = size; chunksize = size;
status = efi_file_read(fh, files[j].handle, status = efi_file_read(files[j].handle,
&chunksize, &chunksize,
(void *)addr); (void *)addr);
if (status != EFI_SUCCESS) { if (status != EFI_SUCCESS) {
...@@ -408,7 +408,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, ...@@ -408,7 +408,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
size -= chunksize; size -= chunksize;
} }
efi_file_close(fh, files[j].handle); efi_file_close(files[j].handle);
} }
} }
...@@ -425,7 +425,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg, ...@@ -425,7 +425,7 @@ static efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
close_handles: close_handles:
for (k = j; k < i; k++) for (k = j; k < i; k++)
efi_file_close(fh, files[k].handle); efi_file_close(files[k].handle);
free_files: free_files:
efi_call_early(free_pool, files); efi_call_early(free_pool, files);
fail: fail:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册