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