Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QEMU backport] riscv: fix wfi exception behavior #1995

Merged

Conversation

apparentlymart
Copy link
Contributor

@apparentlymart apparentlymart commented Sep 3, 2024

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 the qemu 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 detect wfi 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 the op_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 the wfi instruction, which is possible but would result in a test that's harder to read and maintain.

The wfi exception trigger behavior should take into account user mode,
hstatus.vtw, and the fact the an wfi might raise different types of
exceptions depending on various factors:

If supervisor mode is not present:

- an illegal instruction exception should be generated if user mode
executes and wfi instruction and mstatus.tw = 1.

If supervisor mode is present:

- when a wfi instruction is executed, an illegal exception should be triggered
if either the current mode is user or the mode is supervisor and mstatus.tw is
set.

Plus, if the hypervisor extensions are enabled:

- a virtual instruction exception should be raised when a wfi is executed from
virtual-user or virtual-supervisor and hstatus.vtw is set.

Signed-off-by: Jose Martins <[email protected]>
Reviewed-by: Alistair Francis <[email protected]>
Message-id: [email protected]
Signed-off-by: Alistair Francis <[email protected]>
@wtdcode
Copy link
Member

wtdcode commented Sep 4, 2024

LGTM

@wtdcode wtdcode merged commit 379791a into unicorn-engine:dev Sep 4, 2024
29 of 31 checks passed
@wtdcode
Copy link
Member

wtdcode commented Sep 4, 2024

Thanks! I'm on a conference submission deadline, and I expect to be back after that. =)

@apparentlymart apparentlymart deleted the f-qemu-backport-wfi-umode branch September 17, 2024 18:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants