Re: Issue with 64-bit code execution with kvm enabled

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

 



An alternate implementation of the efi_wrap_4 function has the same
issue. Here is the alternate function I found from another Unix to EFI
calling wrapper, which is part of the EFI BIOS code base.

 movq    %rdi, %rax    // Swizzle args
 movq    %rsi, %r9
//  movq    %rdx, %rdx
 movq    %rcx, %r8
 movq    %r9,  %rcx

       subq  $40, %rsp              // 32-byte shadow space plus alignment pad
       call    *%rax
 addq  $40, %rsp

       ret

This works in pure emulation without kvm, but gives me an exception
with kvm enabled.
I don't quite understand what may have caused this. Perhaps this is a
naive question, but how good is kvm for recent 64 bit Intel CPUs ? I
have also attached my host's cpuinfo output if that helps.

Thanks,
Adhyas

On Sat, Nov 13, 2010 at 3:37 PM, Adhyas Avasthi <adhyas@xxxxxxxxx> wrote:
> 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.
> ********************************************************************
>



-- 
Adhyas
********************************************************************
Two types have compatible type if their types are the same.
    — ANSI C Standard, 3.1.2.6.
********************************************************************

Attachment: cpuinfo
Description: Binary data


[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