On Mon, Sep 04, 2017 at 04:02:08PM +0200, Gerd Hoffmann wrote:
I was thinking a few instructions to test if calll worked would be sufficient to catch the x86emu case - something like:
pushl $0xffffffff calll 1f 1:popl %eax cmpl %eax, $1b jne running_on_broken_x86emu
Ok, finally picked this up again.
Rebased the branch, added a patch for x86emu detection. https://www.kraxel.org/cgit/seabios/log/?h=serial
--- a/src/romlayout.S +++ b/src/romlayout.S @@ -531,12 +531,31 @@ entry_10_hooked: pushfw pushl %cs:sercon_int10_hook_resume + // Detect broken x86emu versions + pushl %eax + pushl %ebx + pushl $0xffffffff + calll 1f +1: popl %eax + movl $1b, %ebx + cmpl %eax, %ebx + jne running_on_broken_x86emu + popl %ebx // $0xffffffff + popl %ebx + popl %eax
pushl $sercon_10_splitmode #if CONFIG_ENTRY_EXTRASTACK jmp irqentry_arg_extrastack #else jmp irqentry_arg #endif +running_on_broken_x86emu: + popw %bx + popl %ebx + popl %eax + // skip sercon code, jump straight to vgabios + iretw // int 18/19 are special - they reset stack and call into 32bit mode. DECLFUNC entry_19
How is x86emu broken? I'm assuming it ignores the prefix for call, so it'll push a 16bit return address instead of a 32bit return address to the stack?
I think so. Might be safer to save/restore %esp though. This sequence might be simpler:
pushl %eax movl %esp, %eax pushl $1f retl 1: cmpl %esp, %eax jne broken_x86emu popl %eax
...
broken_x86emu: movl %eax, %esp popl %eax iretw
Note, though, in addition to checking for broken x86emu, the assembler entry code would also have to check that the last mode was not set via a vesa call (to avoid the "skifree" bug).
-Kevin