public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* ovmf miscompiles with gcc-12
@ 2022-05-19  5:43 Jiri Slaby
  2022-05-27  3:41 ` [edk2-devel] " joeyli
  2022-06-07 10:31 ` Gerd Hoffmann
  0 siblings, 2 replies; 7+ messages in thread
From: Jiri Slaby @ 2022-05-19  5:43 UTC (permalink / raw)
  To: devel

Hi,

we discovered that qemu-ovmf-x86_64 doesn't start when compiled using 
gcc-12. Originally reported as:
https://bugzilla.suse.com/show_bug.cgi?id=1199597

I run qemu as:
qemu-kvm -drive file=/dev/null,format=raw -drive 
if=pflash,format=raw,unit=0,readonly=on,file=OVMF.fd -m 3000

The platform repeatedly resets after TemporaryRamMigration as can be 
seen in the debuglog:
https://bugzilla.suse.com/attachment.cgi?id=858969

The reason is TemporaryRamMigration() overwrites rbp unconditionally -- 
it adds an offset to rbp even if rbp is NOT used as a frame pointer 
(-fomit-frame-pointer was always used for compilation here). So 
commenting out:
> //JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;

makes it all work again. Also marking TemporaryRamMigration() as:
__attribute__((optimize("-fno-omit-frame-pointer")))
works around the problem too. (But that doesn't guarantee anything.)

The code is:
>   if (SetJump (&JumpBuffer) == 0) {
>  #if defined (MDE_CPU_IA32)
>     JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
>     JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;
>  #endif
>  #if defined (MDE_CPU_X64)
>     JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
>     JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;
>  #endif
>     LongJump (&JumpBuffer, (UINTN)-1);
>   }

It was only coincidence this ever worked -- gcc-11 omits the frame 
pointer too, but apparently the caller (PeiCheckAndSwitchStack) does not 
use rbp.

PeiCheckAndSwitchStack() (gcc-12):

>     79a6:       4c 29 fd                sub    %r15,%rbp <------ used rbp
>     79a9:       4d 29 fe                sub    %r15,%r14
>     79ac:       48 83 ec 20             sub    $0x20,%rsp
>     79b0:       4d 89 e0                mov    %r12,%r8
>     79b3:       48 8d 4b 08             lea    0x8(%rbx),%rcx
>     79b7:       48 8b 44 24 50          mov    0x50(%rsp),%rax
>     79bc:       48 8b 54 24 20          mov    0x20(%rsp),%rdx
>     79c1:       4d 29 e8                sub    %r13,%r8
>     79c4:       4c 8b 4c 24 30          mov    0x30(%rsp),%r9
>     79c9:       ff 10                   call   *(%rax)  <----------- call to TemporaryRamMigration
>     79cb:       48 83 c4 20             add    $0x20,%rsp
>     79cf:       be 01 00 00 00          mov    $0x1,%esi
>     79d4:       4c 89 f7                mov    %r14,%rdi
>     79d7:       e8 f4 a8 ff ff          call   22d0 <MigrateMemoryPages>
>     79dc:       48 83 ec 20             sub    $0x20,%rsp
>     79e0:       4d 89 f0                mov    %r14,%r8
>     79e3:       31 d2                   xor    %edx,%edx
>     79e5:       48 89 e9                mov    %rbp,%rcx   <------ rbp used

gcc-11 seems to copy rbp to r8 first and operates on r8 there instead.

Now, what is the right way to fix this? Do the SetJump/LongJump in 
assembly and wrap it into push rbp/pop rbp?

thanks,
-- 
js
suse labs

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2022-06-08 22:00 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-19  5:43 ovmf miscompiles with gcc-12 Jiri Slaby
2022-05-27  3:41 ` [edk2-devel] " joeyli
2022-06-07 10:31 ` Gerd Hoffmann
2022-06-07 10:38   ` Jiri Slaby
2022-06-07 11:07     ` Gerd Hoffmann
2022-06-07 11:14       ` Jiri Slaby
2022-06-08 22:00         ` Andrew Fish

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox