瀏覽代碼

[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 <rath@mglug.de>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 10 年之前
父節點
當前提交
54c5d08df1
共有 1 個文件被更改,包括 1 次插入1 次删除
  1. 1
    1
      src/arch/i386/interface/pcbios/vesafb.c

+ 1
- 1
src/arch/i386/interface/pcbios/vesafb.c 查看文件

@@ -171,7 +171,7 @@ static int vesafb_mode_list ( uint16_t **mode_numbers ) {
171 171
 			       : "=a" ( status )
172 172
 			       : "a" ( VBE_CONTROLLER_INFO ),
173 173
 				 "D" ( __from_data16 ( controller ) )
174
-			       : "memory" );
174
+			       : "memory", "ebx", "edx" );
175 175
 	if ( ( rc = vesafb_rc ( status ) ) != 0 ) {
176 176
 		DBGC ( &vbe_buf, "VESAFB could not get controller information: "
177 177
 		       "[%04x] %s\n", status, strerror ( rc ) );

Loading…
取消
儲存