From 54c5d08df14aa72e3494d4708041aee5f1a8861b Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Fri, 6 Dec 2013 02:37:36 +0000 Subject: [PATCH] [vesafb] Work around data corruption bug in bochs/qemu VBE implementation The vgabios used by bochs and qemu (and other virtualisation products) has a bug in its implementation of INT 10,4f00 which causes the high 16 bits of %ebx and %edx to become corrupted. The vgabios code uses a "pushaw"/"popaw" pair to preserve the low 16 bits of all non-segment registers. The vgabios code is compiled using bcc, which generates 8086-compatible code and so never touches the high 16 bits of the 32-bit registers. However, the function vbe_biosfn_return_controller_information() includes the line: size_64k = (Bit16u)((Bit32u)cur_info->info.XResolution * cur_info->info.XResolution * cur_info->info.BitsPerPixel) >> 19; which generates an implicit call to the "lmulul" function. This function is implemented in vbe.c as: ; helper function for memory size calculation lmulul: and eax, #0x0000FFFF shl ebx, #16 or eax, ebx SEG SS mul eax, dword ptr [di] mov ebx, eax shr ebx, #16 ret which modifies %eax, %ebx, and %edx (as a result of the "mul" instruction, which places its result into %edx:%eax). Work around this problem by marking %ebx and %edx as being clobbered by the call to INT 10,4f00. (%eax is already used as an output register, so does not need to be on the clobber list.) Reported-by: Oliver Rath Signed-off-by: Michael Brown --- src/arch/i386/interface/pcbios/vesafb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/arch/i386/interface/pcbios/vesafb.c b/src/arch/i386/interface/pcbios/vesafb.c index 8543b379..8fc6f3d4 100644 --- a/src/arch/i386/interface/pcbios/vesafb.c +++ b/src/arch/i386/interface/pcbios/vesafb.c @@ -171,7 +171,7 @@ static int vesafb_mode_list ( uint16_t **mode_numbers ) { : "=a" ( status ) : "a" ( VBE_CONTROLLER_INFO ), "D" ( __from_data16 ( controller ) ) - : "memory" ); + : "memory", "ebx", "edx" ); if ( ( rc = vesafb_rc ( status ) ) != 0 ) { DBGC ( &vbe_buf, "VESAFB could not get controller information: " "[%04x] %s\n", status, strerror ( rc ) );