Issue with 64-bit code execution with kvm enabled

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I am trying to boot a 64-bit GRUB2 based EFI Boot Loader on top of
OVMF based EFI BIOS (also 64 bit) for x86_64. My host is Ubuntu 10.04
x86_64 and I am running qemu-kvm-0.13.0 with self-built
kvm-kmod-2.6.32.17 for my kernel version which is 2.6.32-24 (I used
the default Ubuntu KVM and qemu versions with same issue earlier). My
host PC is Lenovo T410 with Intel Core i5

GRUB2 is built with gcc and apparently, EFI has a different calling
convention so GRUB2 has an assembly wrapper file that changes the
parameter as per desired calling convention. The problem is that if I
start the loader with kvm disabled, everything goes fine and their
wrapper instructions do the right thing as well. If I enable kvm,
however, I get an x64 exception (as below):

!!!! X64 Exception Type - 000000000000000D !!!!
ExceptionData - 0000000000000000
RIP - 000000001FFA95FA, RFL - 0000000000010202
RAX - 000000001FF35900, RCX - 0000000000000000, RDX - 000000001FFBB510
RBX - 000000001FF35640, RSP - 000000001FF975C0, RBP - 000000001FFBB510
RSI - 000000001FFBB550, RDI - 000000001FF35940
R8  - 0000000000000000, R9  - 000000001FFBB54F, R10 - 000000001D996FFF
R11 - 000000001FF96EB8, R12 - 000000001FFB6A90, R13 - 0000000000000070
R14 - 000000001D99CFFF, R15 - 0000000000000060
CS  - 0028, DS  - 0008, ES  - 0008, FS  - 0008, GS  - 0008, SS  - 0008
GDT - 000000001FF1CE98; 003F,                   IDT - 000000001FE88BC0; 0FFF
LDT - 0000000000000000, TR  - 0000000000000000
CR0 - 0000000080000023, CR2 - 0000000000000000, CR3 - 000000001FF36000
CR4 - 0000000000000668, CR8 - 0000000000000000
DR0 - 0000000000000000, DR1 - 0000000000000000, DR2 - 0000000000000000
DR3 - 0000000000000000, DR6 - 00000000FFFF0FF0, DR7 - 0000000000000400

Here is the call that I am making (and also the target function I am
invoking in EFI):
status = efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA,
pages, &address);
(the target function is:)
EFI_STATUS
EFIAPI
CoreAllocatePages (
  IN EFI_ALLOCATE_TYPE      Type,
  IN EFI_MEMORY_TYPE        MemoryType,
  IN UINTN                  NumberOfPages,
  IN OUT EFI_PHYSICAL_ADDRESS  *Memory
  )

The assembly wrapper that changes as per calling convention in GRUB2 is:

/*
 * x86_64 uses registry to pass parameters. Unfortunately, gcc and efi use
 * different call conversion, so we need to do some conversion.
 *
 * gcc:
 *   %rdi,  %esi,  %rdx,  %rcx, %r8, %r9, 8(%rsp), 16(%rsp), ...
 *
 * efi:
 *   %rcx,  %rdx,  %r8,  %r9,  32(%rsp), 40(%rsp), 48(%rsp), ...
 *
 */
FUNCTION(efi_wrap_4)
        subq $40, %rsp
        mov %r8, %r9
        mov %rcx, %r8
        mov %rsi, %rcx
        call *%rdi
        addq $40, %rsp
        ret


Is this a bug? How can the same piece of code work fine on pure qemu
emulation and not on kvm mode?
I will appreciate if someone can throw more light on this issue I am facing.

Thanks,
Adhyas
********************************************************************
Two types have compatible type if their types are the same.
    — ANSI C Standard, 3.1.2.6.
********************************************************************
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux