3.1.
Precise Interrupt / Exception Delivery
Dynamic translation has some major implications on
interrupt/exception delivery to the guest.
Specifically, a
complication arises because of pseudo-instruction-boundaries being
present in the
translated
instruction sequences, that were not present in the original (guest)
instruction
sequences. When
a gBB instruction is translated into a sequence of multiple xBB instructions,
new instruction
boundaries have been introduced as far as the underlying hardware is concerned.
When delivering
an interrupt or an exception to the guest, it is imperative that we preserve
the
atomicity
corresponding to guest instruction boundaries, and subsequently report the
correct
instruction
boundary at which the interrupt or exception was delivered. Towards this, we
have
designed a
framework that lays out the format of a translated instruction sequence
corresponding
to a given guest
instruction, as follows:
1. Each
individual instruction translation consists of a preamble, an “active”
instruction, and a
postamble.
2. Preamble and
postamble are typically empty. If needed, a typical preamble contains register
spill
instructions to provide available temporary registers for use in instruction
execution, or
a push
instruction (in the case of translating call), or a pop instruction (in the case
of
translating
return), etc. The postamble restores the expected register values into the
hardware
registers for
use by the following instruction. The important point to note about the
requirements of
a preamble and postamble is that a preamble can result in side-effects as
long
as its effects
can be rolled back (i.e., can be safely undone); and, a postamble must not
result
in any
side-effects as visible to the guest, but may result in effects visible to the
emulator.
3. Most
importantly, side-effects that are visible to the guest and are non-undoable, if
any, can
occur as a
result of the execution of only one instruction (as seen by the
underlying
hardware), which
we call the "active" instruction. Then, an interrupt or exception can
occur
only before or
after that instruction, but not in between that instruction.
We now describe
the exception delivery mechanism that uses the above framework: When an
interrupt or
exception occurs while the preamble part of a translation sequence (including
the
point just
before the "active" instruction) is being executed, we roll back the execution
up to the
most recent
instruction boundary. If it occurs after the execution of the "active"
instruction, i.e.,
while the
postamble is being executed, we report the next guest instruction boundary to
the
guest. Note that
postamble operations invariably restore register values that will be restored
anyway on return
from supervisor mode, so postamble instructions do not need to be honored
when a trap
occurs.
In order to
facilitate the rollback of the preamble's execution, the instruction generator
generates
two
instruction streams in parallel. The first is a sequence of instructions
that simulate the input
basic block
instructions. The second is a sequence of bytecodes that describe how to undo
the
effects of the
preambles.
When an
exception occurs in the preamble phase, these bytecodes are interpreted to
determine
which registers
have been spilled and what modifications have been performed to the stack
pointer during
the preamble. These changes are undone, and execution will resume at the
beginning of the
preamble.