Hi Jordan
Here is the info you asked for. I just produced it (am analyzing it as
well as we speak). Sending upfront:
The non-working case (with kvm enabled), 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 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
I am making the call as follows:
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)
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
)
Thanks,
Adhyas
On Sat, Nov 13, 2010 at 4:20 PM, Jordan Justen <***@gmail.com> wrote:
> Adhyas,
>
> How easy would it be to isolate the instance where the exception
> happens at the outer level?
>
> For instance, could you add this:
>
> 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
>
> Then change the outer level code to use efi_wrap_4_with_hang instead,
> and compare the environment in the working and failing cases after the
> hang is encountered?
>
> What UEFI function is being called? We might be able to add some
> serial messages to the OVMF side of the call, if it gets to the
> firmware code.
>
> -Jordan
>
> On Sat, Nov 13, 2010 at 15:20, Adhyas Avasthi <***@gmail.com> wrote:
>> Alright, I think I have been able to root cause the issue in the case
>> of Grub Boot Loader with kvm enabled. This is a case of calling
>> convention issues between efi and gcc. While Grub has a call wrapper
>> assembly file that seems to do the right thing for the calling
>> convention required by efi, it does not work when kvm is enabled. The
>> assembly file does the right thing with kvm disabled (pure qemu
>> emulation).
>>
>> With kvm enabled, the instructions (I assume) get executed on the real
>> host's cpu. I have no idea why that would mess up with the calling
>> convention. Does anyone have a pointer on what I can put in as a quick
>> hack to solve things. Here is the sample wrapper function from grub's
>> source code that gets invoked before making the call to efi.
>>
>> /*
>> * 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
>>
>> Thanks,
>> Adhyas
>>
>> On Fri, Nov 12, 2010 at 3:51 PM, Adhyas Avasthi <***@gmail.com> wrote:
>>> Looking at kernel sources, I guess the kernel just reboots to where we
>>> are jumping into it from the boot loader. Did someone really test the
>>> openSUSE efi boot ever?
>>>
>>>