Skip to content

Commit

Permalink
bzimage: Fixup for kernel changes to EFI handover protocol
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Matt Fleming committed Mar 20, 2013
1 parent 5d6e34f commit ba392ad
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 11 deletions.
3 changes: 2 additions & 1 deletion loaders/bzimage/bzimage.c
Expand Up @@ -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;
}

Expand Down
27 changes: 18 additions & 9 deletions loaders/bzimage/i386.h
Expand Up @@ -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__ */
3 changes: 2 additions & 1 deletion loaders/bzimage/x86_64.h
Expand Up @@ -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;
Expand Down

0 comments on commit ba392ad

Please sign in to comment.