The PL031 RTC provides two features: a real-time counter and an alarm
interrupt. To use the alarm, the driver normally writes a time value
into the match register RTCMR, and when the counter reaches that value
the device triggers the interrupt.
At the moment the implementation ignores programming of the alarm, as
the feature seems rarely used in VMs. However the interrupt is still
triggered arbitrarily when the guest writes to registers, and the line
is never cleared. This really confuses the Linux driver, which loops in
the interrupt handler until Linux realizes that no one is dealing with
the interrupt (200000 unanswered calls) and disables the handler.
One way to fix this would be implementing the alarm function properly,
which isn't too difficult but requires adding some async timer logic
which probably won't ever get used. In addition the device's interrupt
is level-triggered and we don't support level interrupts at the moment,
though we could probably get away with changing this interrupt to edge.
The simplest fix, though, is to just disable the interrupt logic
entirely, so that the alarm function still doesn't work but the guest
doesn't see spurious interrupts.
Add a default() implementation to satisfy clippy's new_without_default
check, since Rtc::new() doesn't take a parameter after this change.
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
This streamlines the Error implementation in the Cloud Hypervisor code
base to match the remaining parts so that everything follows the agreed
conventions. These are leftovers missed in the previous commits.
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
This streamlines the code base to follow best practices for
error handling in Rust: Each error struct implements
std::error::Error (most due via thiserror::Error derive macro)
and sets its source accordingly.
This allows future work that nicely prints the error chains,
for example.
So far, the convention is that each error prints its
sub error as part of its Display::fmt() impl.
Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
On-behalf-of: SAP philipp.schuster@sap.com
The Memory Space Enable (MSE) bit from the COMMAND register in the
PCI configuration space controls whether a PCI device responds to memory
space accesses, e.g. read and write cycles to the device MMIO regions
defined by its BARs. The MSE bit is used by the device drivers to ensure
the correctness of BAR reprogramming. A common workflow is, the driver
first clears the MSE bit, then writes new values to the BAR registers,
and finally set the MSE bit to finish the BAR reprogramming.
This patch changes how we handle BAR reprogramming for all PCI
devices (e.g. virtio-pci, vfio, vfio-user, etc.), so that we follow the
same convention, e.g. moving PCI BARs when its MSE bit is set.
Note that some device drivers (such as edk2) only clear and set MSE once
while reprogramming multiple BARs of a single device. To support such
behavior, this patch adds support for multiple pending BAR reprogramming.
See: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/7027#issuecomment-2853642959
Signed-off-by: Bo Chen <bchen@crusoe.ai>
A BAR reprogramming of a PCI device will only happen when the (guest)
kernel write to its PCI config space, e.g. the detection of bar
reprogramming (`detect_bar_repgraomming()`) can be embedded to the PCI
config space write (`write_config_register()`). It simplifies APIs
exposed by the `struct PciConfiguration` and `trait PciDevice`. It also
prepares for easier handling of pending bar reprogramming when the MSE
bit of the COMMAND register is not enabled at the time of changing BAR
registers.
See: https://github.com/cloud-hypervisor/cloud-hypervisor/issues/7027#issuecomment-2853642959
Signed-off-by: Bo Chen <bchen@crusoe.ai>
Fixing the following clippy issue using `cargo clippy --fix`:
error: variables can be used directly in the `format!` string
--> build.rs:25:27
|
25 | version.push_str(&format!("-{}", extra_version));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
Signed-off-by: Bo Chen <bchen@crusoe.ai>
KVM supports GICv3-ITS emulation and the current GicState is modelled
around the KVM implementation. We should refactor this to accomodate
other hypervisor requirements. For example, MSHV only support GICv2M
emulation for guests for delivering MSI interrupts instead of GICv3-ITS.
Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
TPM support on RISC-V is not scheduled in this stage, we will come back
when it's ready and we have workloads to verify it on RISC-V.
Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
Currently `devices` module cannot be solely built, by specifying
`arch/kvm` to turn on the features required for its dependency - `arch`
crate to build. Thus enabling `devices` crate to be built and tested
with command:
```sh
cargo build -p devices --features kvm
```
Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
`arch` module are required for devices module to build. Enabling `arch`
module in target specific dependencies section.
Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
Asserting on .is_ok()/.is_err() leads to hard to debug failures (as if
the test fails, it will only say "assertion failed: false". We replace
these with `.unwrap()`, which also prints the exact error variant that
was unexpectedly encountered (we can to this these days thanks to
efforts to implement Display and Debug for our error types). If the
assert!((...).is_ok()) was followed by an .unwrap() anyway, we just drop
the assert.
Inspired by and quoted from @roypat.
Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
By introducing `imports_granularity="Module"` format strategy,
effectively groups imports from the same module into one line or block,
improving maintainability and readability.
Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
Historically the Cloud Hypervisor coding style has been to ensure that
all imports are ordered and placed in a single group. Unfortunately
cargo fmt has no support for ensuring that all imports are in a single
group so if whitespace lines were added as part of the import statements
then they would only be odered correctly in the group.
By adopting "group_imports="StdExternalCrate" we can enforce a style
where imports are placed in at most three groups for std, external
crates and the crate itself. Choosing a style enforceable by the tooling
reduces the reviewer burden.
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
Modify `Cargo.toml` in each member crate to follow the dependencies
specified in root `Cargo.toml` file.
Signed-off-by: Ruoqing He <heruoqing@iscas.ac.cn>
Pvmemcontrol provides a way for the guest to control its physical memory
properties, and enables optimizations and security features. For
example, the guest can provide information to the host where parts of a
hugepage may be unbacked, or sensitive data may not be swapped out, etc.
Pvmemcontrol allows guests to manipulate its gPTE entries in the SLAT,
and also some other properties of the memory map the back's host memory.
This is achieved by using the KVM_CAP_SYNC_MMU capability. When this
capability is available, the changes in the backing of the memory region
on the host are automatically reflected into the guest. For example, an
mmap() or madvise() that affects the region will be made visible
immediately.
There are two components of the implementation: the guest Linux driver
and Virtual Machine Monitor (VMM) device. A guest-allocated shared
buffer is negotiated per-cpu through a few PCI MMIO registers, the VMM
device assigns a unique command for each per-cpu buffer. The guest
writes its pvmemcontrol request in the per-cpu buffer, then writes the
corresponding command into the command register, calling into the VMM
device to perform the pvmemcontrol request.
The synchronous per-cpu shared buffer approach avoids the kick and busy
waiting that the guest would have to do with virtio virtqueue transport.
The Cloud Hypervisor component can be enabled with --pvmemcontrol.
Co-developed-by: Stanko Novakovic <stanko@google.com>
Co-developed-by: Pasha Tatashin <tatashin@google.com>
Signed-off-by: Yuanchu Xie <yuanchu@google.com>
In accordance with reuse requirements:
- Place each license file in the LICENSES/ directory
- Add missing SPDX-License-Identifier to files.
- Add .reuse/dep5 to bulk-license files
Fixes: #5887
Signed-off-by: Ruslan Mstoi <ruslan.mstoi@intel.com>
error: the item `io` is imported redundantly
Error: --> devices/src/legacy/uart_pl011.rs:468:9
|
467 | use super::*;
| -------- the item `io` is already imported here
468 | use std::io;
| ^^^^^^^
error: the item `Arc` is imported redundantly
Error: --> devices/src/legacy/uart_pl011.rs:469:21
|
467 | use super::*;
| -------- the item `Arc` is already imported here
468 | use std::io;
469 | use std::sync::{Arc, Mutex};
| ^^^
error: could not compile `devices` (lib test) due to 8 previous errors
Error: warning: build failed, waiting for other jobs to finish...
Error: The process 'cross' failed with exit code 101
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>
error: the item `read_le_u32` is imported redundantly
Error: --> devices/src/legacy/gpio_pl061.rs:342:17
|
341 | use super::*;
| -------- the item `read_le_u32` is already imported here
342 | use crate::{read_le_u32, write_le_u32};
| ^^^^^^^^^^^
|
= note: `-D unused-imports` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(unused_imports)]`
error: the item `write_le_u32` is imported redundantly
Error: --> devices/src/legacy/gpio_pl061.rs:342:30
|
341 | use super::*;
| -------- the item `write_le_u32` is already imported here
342 | use crate::{read_le_u32, write_le_u32};
| ^^^^^^^^^^^^
error: the item `Arc` is imported redundantly
Error: --> devices/src/legacy/gpio_pl061.rs:343:9
|
341 | use super::*;
| -------- the item `Arc` is already imported here
342 | use crate::{read_le_u32, write_le_u32};
343 | use std::sync::Arc;
| ^^^^^^^^^^^^^^
Signed-off-by: Rob Bradford <rbradford@rivosinc.com>