[QEMU backport] riscv: fix wfi exception behavior #1995
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The QEMU version currently used by Unicorn treats the
wfi
(wait for interrupt) instruction slightly incorrectly per the ratified wording in the RISC-V ISA specification. I believe this is because the QEMU implementation was originally based on an earlier revision (pre-ratification) and then the specification was subsequently refined.This problem has been fixed in upstream QEMU in
719f0f60
, and so this PR is proposing to backport that change to Unicorn without any modification except for the changed paths now being under theqemu
directory.The upstream commit gives the full details but the broad idea is that in U-Mode and S-Mode
wfi
should be treated as an invalid instruction exception in certain situations, which then allows a higher privilege mode to virtualize that instruction. In the context of Unicorn this means that we can use either an invalid instruction hook or an interrupt hook to detectwfi
and then emulate its effect in the host program.One notable quirk here is that upstream QEMU has also already merged
e39a8320
which added support for the hypervisor extension's new "virtual instruction fault", and changed several of theop_helper.c
functions to use it instead of the main illegal instruction exception when running under hardware virtualization (VS-mode or VU-mode).That is a far more intrusive patch and so I've not attempted to backport it here, but that does mean that the effect of this patch is still not quite conforming to the ratified specification. It is, however, no worse than how this was handled before: it will raise the illegal instruction exception in both VS-mode and S-mode, which is consistent with the existing incomplete handling of the hypervisor extension in current Unicorn. (It seems that the currently-used QEMU version is partially implementing a pre-ratification version of that ISA extension, so current Unicorn2 users should not expect conforming behavior when using VS-mode or VU-mode regardless of this PR.)
I believe the effect of this patch is conforming for non-virtualized S-mode and U-mode, which are the two situations important to my use-case.
I have verified that
wfi
does indeed trigger the relevant Unicorn hooks using my calling application that's written in Rust.I did try to write a Unicorn unit test for this but it's currently quite complicated to transition into a lower privilege mode in RISC-V emulation, as I described (and proposed a solution for) in #1989. Since this change was already presumably well tested upstream in QEMU I imagine a Unicorn-specific test is not crucial, but I'd be willing to add one if maintainers consider it important, particularly if #1989 were merged first so that the new test could straightforwardly select S mode and U mode.
Without that PR a test for this would need to include similar
mret
setup boilerplate to drop privilege before executing thewfi
instruction, which is possible but would result in a test that's harder to read and maintain.