diff options
author | David 'Digit' Turner <digit@google.com> | 2009-10-09 11:37:14 -0700 |
---|---|---|
committer | David 'Digit' Turner <digit@google.com> | 2009-10-09 11:52:33 -0700 |
commit | 3af4f6ae1fa6e06de1284fa1143cb8a485ac6437 (patch) | |
tree | 15710dea9719cc49d7607e8f726c39e940d08900 /block/nbd.c | |
parent | 48ed3267dfffedb65385b0a1f1462fdd46d049bb (diff) | |
download | external_qemu-3af4f6ae1fa6e06de1284fa1143cb8a485ac6437.zip external_qemu-3af4f6ae1fa6e06de1284fa1143cb8a485ac6437.tar.gz external_qemu-3af4f6ae1fa6e06de1284fa1143cb8a485ac6437.tar.bz2 |
Fix upstream ARM emulation bug that broke singlestep mode.
This fixes a really bad bug in the Thumb/Thumb2 ARM emulation related to
conditional instructions execution. The issue was that the previous
implementation did break badly if a page fault occured during the conditional
instruction's emulation. Giving an example if probably the best way to demonstrate
this. Consider the following two instructions:
itt eq
streq r0,[r4, #0]
These two instructions mean, respectively:
- If the Z flag is set, execute the next instruction. Otherwise ignore it
- Store the value of r0 at the address pointed to by r4
In single-step mode (used when debugging the emulator), each instruction is
separately JIT-ed and executed in a different pass. The 'condexec_bits' field
of the CPU state if used to store flags corresponding to the conditional
execution of up to 4 next instructions.
When the first instruction is executed, it simply sets 'condexec_bits' to a
specific value (4).
When the second instruction is executed, things get slightly bit more funky
because what happened was the following:
- the JIT-ed code started by clearing the 'condexec_bits' right at the
start of its sequence (a comment says "to avoid complications trying to
do it at the end of the block", famous last words...)
- a conditional test, based on the current value of the Z flag was added
to skip over the rest of the instruction sequence
- the store itself is implemented through a call to the __stl_mmu helper
function.
The thing is that __stl_mmu may implement a *page fault* (i.e. when the
address in r4 hasn't been commited to memory yet) which requires a switch
to kernel mode (to populate the page), then going back to the instruction's
execution.
This is done in the current implementation by re-running the JIT-er for the
same instruction, however, since 'condexec_bits' was already cleared to 0,
the new JIT-ed code sequence doesn't have the conditional test to skip over
the store. The conditional instruction has been transformed into a
non-conditional one due to the page fault ! This results in either bad behaviour
or, even a crash in the emulator.
The patch fixes the clearing of condexec_bits to happen as it should, i.e.
only when execution has really cleared it.
This is preliminary work to fix the -trace option.
Also, disable the IO Thread when running the standalone emulator. This makes
debugging much easier since everything happens in a single thread.
Diffstat (limited to 'block/nbd.c')
0 files changed, 0 insertions, 0 deletions