Skip to content
This repository has been archived by the owner on Jan 28, 2023. It is now read-only.

handle_string_io: Use GVA recorded in VMCS #36

Merged
merged 1 commit into from Mar 26, 2018
Merged

handle_string_io: Use GVA recorded in VMCS #36

merged 1 commit into from Mar 26, 2018

Conversation

raphaelning
Copy link
Contributor

For some variants of the OUTS instruction, handle_string_io() fails
to determine the correct guest virtual address (GVA) from which to
copy data. For example, the long-standing issue where ISOLINUX
boots to a hang under HAXM is in fact due to misemulation of the
following real-mode instruction (part of rom16.o of SeaBIOS):

26 67 f3 6f rep outsl %es:(%si),(%dx)

(Cf. outsw_fl() in src/farptr.h of SeaBIOS source tree. For the
record, it is called by ata_atapi_process_op() and eventually by
ISOLINUX via the INT 13h AH=42h BIOS interface.)

The disassembler treats it as a 32-bit instruction, thus the wrong
operand size. But one thing is clear: the instruction overrides the
default segment (DS) with ES, so the GVA should be ES:SI. However,
the current handle_string_io() logic does not parse the instruction
and assumes that the GVA is always DS:SI for OUTS. As a result, it
reads the wrong data into the I/O buffer.

Fix this bug by utilizing the Guest-Linear Address field of VMCS,
which is convenient and is guaranteed to give the correct GVA.

  • Remove the old hack for INS emulation. It is unclear why it was
    needed, but it doesn't seem necessary now.

Fixes #15.

For some variants of the OUTS instruction, handle_string_io() fails
to determine the correct guest virtual address (GVA) from which to
copy data. For example, the long-standing issue where ISOLINUX
boots to a hang under HAXM is in fact due to misemulation of the
following real-mode instruction (part of rom16.o of SeaBIOS):

 26 67 f3 6f  rep outsl %es:(%si),(%dx)

(Cf. outsw_fl() in src/farptr.h of SeaBIOS source tree. For the
record, it is called by ata_atapi_process_op() and eventually by
ISOLINUX via the INT 13h AH=42h BIOS interface.)

The disassembler treats it as a 32-bit instruction, thus the wrong
operand size. But one thing is clear: the instruction overrides the
default segment (DS) with ES, so the GVA should be ES:SI. However,
the current handle_string_io() logic does not parse the instruction
and assumes that the GVA is always DS:SI for OUTS. As a result, it
reads the wrong data into the I/O buffer.

Fix this bug by utilizing the Guest-Linear Address field of VMCS,
which is convenient and is guaranteed to give the correct GVA.

+ Remove the old hack for INS emulation. It is unclear why it was
  needed, but it doesn't seem necessary now.

Fixes #15.
@wcwang wcwang merged commit 42f8006 into master Mar 26, 2018
@raphaelning raphaelning deleted the string-pio branch March 26, 2018 10:08
@raphaelning raphaelning mentioned this pull request Mar 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants