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

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

 



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


[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