Some more debug information (if it helps someone analyze my problem and suggest a solution). I changed the wrapper code to hang just before making the call. And here is the modified wrapper: FUNCTION(efi_wrap_4_with_hang) subq $40, %rsp mov %r8, %r9 mov %rcx, %r8 mov %rsi, %rcx efi_wrap_4_hang: jmp efi_wrap_4_hang call *%rdi addq $40, %rsp ret I am not making the call as: efi_call_4 (b->allocate_pages, type, GRUB_EFI_LOADER_DATA, pages, &address); #define efi_call_4(func, a, b, c, d) \ efi_wrap_4(func, (grub_uint64_t) a, (grub_uint64_t) b, (grub_uint64_t) c, \ (grub_uint64_t) d) The target of the call is (and the calling convention is as per EFI requirements): And the target 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 register dump at the hang-ed point for both kvm-enabled and kvm-disabled is as below. Note that the code seems to work for kvm-disabled case but issues an exception for kvm-enabled case. That is the issue I am facing. (With KVM enabled, code issues exception, register layout at hang is): (qemu) info registers RAX=000000001ff34f18 RBX=0000000000000006 RCX=0000000000000000 RDX=0000000000000002 RSI=0000000000000000 RDI=000000001ff9a504 RBP=000000001d9a4285 RSP=000000001ff97708 R8 =0000000000000006 R9 =000000001ff97740 R10=0000000000000010 R11=0000000000000009 R12=000000001ffb5960 R13=000000001ff97740 R14=0000000000000000 R15=000000001d99d750 RIP=000000001d99d75d RFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =0008 0000000000000000 ffffffff 00c09300 DPL=0 DS [-WA] CS =0028 0000000000000000 ffffffff 00a09b00 DPL=0 CS64 [-RA] SS =0008 0000000000000000 ffffffff 00c09300 DPL=0 DS [-WA] DS =0008 0000000000000000 ffffffff 00c09300 DPL=0 DS [-WA] FS =0008 0000000000000000 ffffffff 00c09300 DPL=0 DS [-WA] GS =0008 0000000000000000 ffffffff 00c09300 DPL=0 DS [-WA] LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy GDT= 000000001ff1ce98 0000003f IDT= 000000001fe88bc0 00000fff CR0=80000023 CR2=0000000000000000 CR3=000000001ff36000 CR4=00000668 DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 DR6=00000000ffff0ff0 DR7=0000000000000400 EFER=0000000000000500 FCW=027f FSW=0000 [ST=0] FTW=00 MXCSR=00000000 FPR0=0000000000000000 0000 FPR1=0000000000000000 0000 FPR2=0000000000000000 0000 FPR3=0000000000000000 0000 FPR4=0000000000000000 0000 FPR5=0000000000000000 0000 FPR6=0000000000000000 0000 FPR7=0000000000000000 0000 XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000 XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000 XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000 XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000 XMM08=00000000000000000000000000000000 XMM09=00000000000000000000000000000000 XMM10=00000000000000000000000000000000 XMM11=00000000000000000000000000000000 XMM12=00000000000000000000000000000000 XMM13=00000000000000000000000000000000 XMM14=00000000000000000000000000000000 XMM15=00000000000000000000000000000000 The working case (with kvm disabled), register layout at hang: (qemu) info registers RAX=000000001ff34f18 RBX=0000000000000006 RCX=0000000000000000 RDX=0000000000000002 RSI=0000000000000000 RDI=000000001ff9a504 RBP=000000001d9a4285 RSP=000000001ff97708 R8 =0000000000000006 R9 =000000001ff97740 R10=0000000000000010 R11=0000000000000009 R12=000000001ffb5960 R13=000000001ff97740 R14=0000000000000000 R15=000000001d99d750 RIP=000000001d99d75d RFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0 ES =0008 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] CS =0028 0000000000000000 ffffffff 00af9b00 DPL=0 CS64 [-RA] SS =0008 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] DS =0008 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] FS =0008 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] GS =0008 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] LDT=0000 0000000000000000 0000ffff 00008200 DPL=0 LDT TR =0000 0000000000000000 0000ffff 00008b00 DPL=0 TSS64-busy GDT= 000000001ff1ce98 0000003f IDT= 000000001fe88bc0 00000fff CR0=80000033 CR2=0000000000000000 CR3=000000001ff36000 CR4=00000668 DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 DR6=00000000ffff0ff0 DR7=0000000000000400 EFER=0000000000000500 FCW=027f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80 FPR0=0000000000000000 0000 FPR1=0000000000000000 0000 FPR2=0000000000000000 0000 FPR3=0000000000000000 0000 FPR4=0000000000000000 0000 FPR5=0000000000000000 0000 FPR6=0000000000000000 0000 FPR7=0000000000000000 0000 XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000 XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000 XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000 XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000 XMM08=00000000000000000000000000000000 XMM09=00000000000000000000000000000000 XMM10=00000000000000000000000000000000 XMM11=00000000000000000000000000000000 XMM12=00000000000000000000000000000000 XMM13=00000000000000000000000000000000 XMM14=00000000000000000000000000000000 XMM15=00000000000000000000000000000000 Does that give someone an idea as to what may be going wrong? I will try to debug it further to root cause the issue. Thanks, Adhyas On Sat, Nov 13, 2010 at 10:22 PM, Adhyas Avasthi <adhyas@xxxxxxxxx> wrote: > 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. > ******************************************************************** > -- 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