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

Support for full interrupts virtualization #257

Merged
merged 6 commits into from
Oct 30, 2024
Merged

Conversation

CharlyCst
Copy link
Owner

This PR implements proper full M-mode interrupts virtualization, as outlined in #186.

Full interrupt virtualization changes the way interrupts are handled: instead of re-injecting physical interrupts into the vCPU (like we use to do until this PR) Miralis maintains the state of the virtual mip bits for the virtualized interrupts itself and checks if an interrupt should be injected before each re-entry.

This is an important change because:

  1. It is needed for correctness.
  2. It will enable out-of-band interrupts, i.e. interrupts managed by Miralis rather than the firmware. This is a requirement for most security policies on multi-core platforms.
  3. It should fix the issues we are facing on the board.

@CharlyCst
Copy link
Owner Author

Current status:

  • Implemented full interrupt virtualization for M-mode timer interrupts.
  • No support for out-of-band interrupts yet.
  • Fixed the SEIE issue on platforms without Sstc extension.

To be done:

  • Virtualization of MEIE
  • Virtualization of MSIE

Both of which requires a virtual CLINT device, which is being developped as part of #199.

The mip.SEIE bit is in fact composed of two different bits, a
hardware-writeable one and another software-writable one. The behavior
of CSR set and clear operations is modified for the particular case of
this bit. To emulate it properly we would need to special case all of
the CSR set and clear functions to ignore the hardware-writeable bit.

Instead of duplicating the whole logic, this commit simply omit the
hardware-writeable bit, making it invisible to the virtualized firmware.
In practice this is not really an issue as we force the external
supervisor interrupts to be delegated, so the firmware should not be in
charge of devices generating such interrupts (because we don't want to
emulate them).

This commit fixes the hangs with the Linux shell payload when the Sstc
exension is not present. This can be tested with the following config
parameters on a sufficiently modern QEMU:

```
[qemu]
machine = "virt"
cpu = "sifive-u54,sstc=false"
```
@CharlyCst CharlyCst force-pushed the push-xrwkmynnvkst branch 3 times, most recently from 05cd128 to 5bad60e Compare October 30, 2024 15:26
CharlyCst and others added 5 commits October 30, 2024 20:29
This PR implements proper MTI virtualization. For that purpose it lays
out the foundations of full interrupt virtualization, i.e. it lets
Miralis manage the `mip` bits and inject interrupts rather than relying
on the hardware physical interrupts.

For now all physical M-mode timer interrupts are still assumed to be
caused by the firmware and update the virtual `mip.MTIP` bit. If we need
out-of-band MTI we should implement a mechanism for distinguishing the
cause of a timer interrupt, most likely simply checking if the virtual
`mtimecmp` deadline passed or not.
This commit implements proper MSI virtualization. For that purpose it
virtualizes the list of pending MSI in the virtual CLINT. When a vCPU
sends an MSI to another core the virtual CLINT triggers a physical MSI
to signal the core that a virtual interrupt should be injected. If a
vCPU triggers an MSI on the current core then a virtual interrupt is
injected directly without causing a physical interrupt.

This is an important first step toward allowing out-of-band (host) MSI,
which are required by some security policies for cross-caches flushes.
This commit adds three integration tests to exercise the new machine
timer (MTI) and software (MSI) interrupts. The tests exercise:

1. (clint_interrupt) the MTI, including proper reset and multiple
   interrupts delivery.
2. (clint_interrupt_multihart) the MSI across cores.
3. (clint_interrupt_priority) the relative priority of interrupts
   delivery between MSI and MTI.


Co-authored-by: Sofia <[email protected]>
Update the documentation to clarify that only M-mode interrupts are
virtualized, and that S-mode interrupts are explicitly out-of-scope.

Also removes some white-spaces in the doc ASCII art of the relevant
section, as those can cause rendering issue on the website.
The new crate can be extended in the future to hold more test helpers,
such as macros to generate proper interrupt handlers. For now it is
limited to clint functionalities and assumes the QEMU virt platform (it
is not meant to be a general-purpose library).
@CharlyCst CharlyCst marked this pull request as ready for review October 30, 2024 19:35
@CharlyCst CharlyCst merged commit c5a0e58 into main Oct 30, 2024
1 check passed
@CharlyCst CharlyCst deleted the push-xrwkmynnvkst branch October 30, 2024 19:45
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.

1 participant