From: Michael Matz Subject: x86/boot: fix clobbered register in vesa_store_edid References: bnc#400487 The only relevant difference that I can detect in the asm (comparing the output of gcc42-4.2.1_20070724-17.1 and gcc43-4.3.3_20081022-1.2) is in vesa_store_edid(), where the constant 0x4f15 is stored in a register which is reused in the second use after an int 0x10 call that could possibly clobber that register. The asm certainly misses a clobber. So, can you try adding one to this asm in vesa_store_edid: /* Note: The VBE DDC spec is different from the main VESA spec; we genuinely have to assume all registers are destroyed here. */ asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" : "+a" (ax), "+b" (bx) : "c" (cx), "D" (di) : "esi"); In particular add "edx" to the clobber list (that's the register used in my case), but the above also misses "ecx", "edi", which have to be added as in/out constraints (i.e. "+c") probably, not as clobbers. Note especially how the comment explicitely warns about assuming that all regs are destroyed, but how the asm makes no try to cater for that. Tested-by: Andreas Schwab Acked-by: Jeff Mahoney --- arch/x86/boot/video-vesa.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) --- a/arch/x86/boot/video-vesa.c +++ b/arch/x86/boot/video-vesa.c @@ -270,9 +270,10 @@ void vesa_store_edid(void) we genuinely have to assume all registers are destroyed here. */ asm("pushw %%es; movw %2,%%es; "INT10"; popw %%es" - : "+a" (ax), "+b" (bx) - : "c" (cx), "D" (di) - : "esi"); + : "+a" (ax), "+b" (bx), + "+c" (cx), "+D" (di) + : + : "esi", "edx"); if (ax != 0x004f) return; /* No EDID */ @@ -286,8 +287,9 @@ void vesa_store_edid(void) dx = 0; /* EDID block number */ di =(size_t) &boot_params.edid_info; /* (ES:)Pointer to block */ asm(INT10 - : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info) - : "c" (cx), "D" (di) + : "+a" (ax), "+b" (bx), "+d" (dx), "=m" (boot_params.edid_info), + "+c" (cx), "+D" (di) + : : "esi"); #endif /* CONFIG_FIRMWARE_EDID */ }