hypervisor: kvm: check interrupt readiness before injecting

The caller of VcpuX86_64 should normally check ready_for_interrupt()
before calling interrupt(), but it is relatively cheap to add the check
to interrupt() itself and return an error in the case of incorrect use.

For KVM on x86, this is only called in the split irqchip mode, so it
should not affect performance in the normal in-kernel irqchip crosvm
configuration. In any case, the data accessed by ready_for_interrupt()
should be cheap to access since it will already be in the cache on the
second call.

Fixes hypervisor::test_interrupt_injection_when_not_ready on Linux/AMD.

BUG=None
TEST=tools/dev_container tools/presubmit

Change-Id: Id830771b3fc920d1e9705275f1da3efdd3de3367
Reviewed-on: https://chromium-review.googlesource.com/c/crosvm/crosvm/+/5651809
Reviewed-by: Kaiyi Li <kaiyili@google.com>
Reviewed-by: Frederick Mayle <fmayle@google.com>
Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
Daniel Verkamp 2024-06-24 18:09:52 -07:00 committed by crosvm LUCI
parent 383ae1a6bf
commit 318319ce54

View file

@ -22,6 +22,7 @@ use data_model::vec_with_array_field;
use data_model::FlexibleArrayWrapper;
use kvm_sys::*;
use libc::E2BIG;
use libc::EAGAIN;
use libc::EIO;
use libc::ENXIO;
use serde::Deserialize;
@ -565,6 +566,10 @@ impl VcpuX86_64 for KvmVcpu {
/// While this ioctl exists on PPC and MIPS as well as x86, the semantics are different and
/// ChromeOS doesn't support PPC or MIPS.
fn interrupt(&self, irq: u8) -> Result<()> {
if !self.ready_for_interrupt() {
return Err(Error::new(EAGAIN));
}
let interrupt = kvm_interrupt { irq: irq.into() };
// SAFETY:
// safe becuase we allocated the struct and we know the kernel will read