ARM Thumb IT block incorrect execution after interrupt
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Fix Released
|
Undecided
|
Unassigned |
Bug Description
Currently if interrupt occurs inside of IT block (after Thumb "it*" instructions which make several next instructions conditional) all remaining instructions of the block are executed unconditionally after returning from the interrupt handling routine. This happens because when translation block (TB) is generated 'it' instruction is processed only by filling 'condexec_bits' field of the variable 'env' containing current processor state. After interrupt occurs inside of the IT block and its handling is done execution returns to the IT block. Obviously no TB is found starting at the new PC address so a new one is generated starting from the instruction which was about to be executed when interrupt occured. IT instruction is left behind and 'condexec_bits' is not filled so all remaining instructions of the IT block are executed unconditionally.
Here is a small application which should show incorrect behavior. It contains a store inside of the IT block which raises a data abort to load a new page and assignment. Store and assignment are mutually exclusive. But if interrupt is generated whle executing store instruction assignment is executed too. This may be seen by examining the program's return value. When fault occurs it is 1. When it doesn't 0 is returned (real hardware tested).
Changed in qemu: | |
status: | New → Fix Committed |
Changed in qemu: | |
status: | Fix Committed → Fix Released |
I created a fix for this bug but it is more of a workaround kind. The idea is to save actual processor conditional execution state inside of the IT block. When interrupt occurs inside of this block the state is stored. After return from ISR this state is restored before generation of a new TB. This fix doesn't work if second similar bug occurs before returning from ISR, e.g. task switch from one program with data abort inside of IT block to another program with other instructions causing interrupt inside of IT block too (though this should be almost impossible event).