diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-03-20 12:23:33 +0000 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-03-20 12:39:13 +0000 |
commit | ba392ad83d37890d4ec6f0f703076e2b31d350c2 (patch) | |
tree | 5cbefa97b850451a71e535d5bd463788308d041d | |
parent | 5d6e34ffc660136e5f5a0e54be65ee55c1adf00c (diff) | |
download | efilinux-ba392ad83d37890d4ec6f0f703076e2b31d350c2.tar.gz |
bzimage: Fixup for kernel changes to EFI handover protocol
The ABI of the EFI handover protocol was changed in v3.8 with the
following upstream kernel commit,
: commit f791620fa7517e1045742c475a7f005db9a634b8
: Author: David Woodhouse <David.Woodhouse@intel.com>
: Date: Mon Jan 7 22:01:50 2013 +0000
:
: x86, efi: Fix 32-bit EFI handover protocol entry point
from a 'jmp' to a 'call'. This affects the layout of arguments on the
stack since 'call' expects the return address to be the data item at the
top of the stack.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r-- | loaders/bzimage/bzimage.c | 3 | ||||
-rw-r--r-- | loaders/bzimage/i386.h | 27 | ||||
-rw-r--r-- | loaders/bzimage/x86_64.h | 3 |
3 files changed, 22 insertions, 11 deletions
diff --git a/loaders/bzimage/bzimage.c b/loaders/bzimage/bzimage.c index d683eae..6c992b3 100644 --- a/loaders/bzimage/bzimage.c +++ b/loaders/bzimage/bzimage.c @@ -334,7 +334,8 @@ load_kernel(EFI_HANDLE image, CHAR16 *name, char *_cmdline) * protocol. */ if (buf->hdr.version >= 0x20b) { - handover_jump(image, boot_params, kernel_start); + handover_jump(buf->hdr.version, image, + boot_params, kernel_start); goto out; } diff --git a/loaders/bzimage/i386.h b/loaders/bzimage/i386.h index 593e2af..0b74c80 100644 --- a/loaders/bzimage/i386.h +++ b/loaders/bzimage/i386.h @@ -42,19 +42,28 @@ static inline void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start, :: "m" (boot_params), "m" (kernel_start)); } -static inline void handover_jump(EFI_HANDLE image, struct boot_params *bp, +typedef void(*handover_func)(void *, EFI_SYSTEM_TABLE *, + struct boot_params *) __attribute__((regparm(0))); + +static inline void handover_jump(UINT16 kernel_version, EFI_HANDLE image, + struct boot_params *bp, EFI_PHYSICAL_ADDRESS kernel_start) { kernel_start += bp->hdr.handover_offset; - asm volatile ("cli \n" - "pushl %0 \n" - "pushl %1 \n" - "pushl %2 \n" - "movl %3, %%ecx \n" - "jmp *%%ecx \n" - :: "m" (bp), "m" (ST), - "m" (image), "m" (kernel_start)); + if (kernel_version == 0x20b) { + asm volatile ("cli \n" + "pushl %0 \n" + "pushl %1 \n" + "pushl %2 \n" + "movl %3, %%ecx \n" + "jmp *%%ecx \n" + :: "m" (bp), "m" (ST), + "m" (image), "m" (kernel_start)); + } else { + handover_func hf = (handover_func)(UINTN)kernel_start; + hf(image, ST, bp); + } } #endif /* __I386_H__ */ diff --git a/loaders/bzimage/x86_64.h b/loaders/bzimage/x86_64.h index b63710e..e44f7f9 100644 --- a/loaders/bzimage/x86_64.h +++ b/loaders/bzimage/x86_64.h @@ -52,7 +52,8 @@ static inline void kernel_jump(EFI_PHYSICAL_ADDRESS kernel_start, kf(NULL, boot_params); } -static inline void handover_jump(EFI_HANDLE image, struct boot_params *bp, +static inline void handover_jump(UINT16 kernel_version, EFI_HANDLE image, + struct boot_params *bp, EFI_PHYSICAL_ADDRESS kernel_start) { UINT32 offset = bp->hdr.handover_offset; |