Skip to content

Commit 3f5dca2

Browse files
committed
skipped unnecessary kvm_immediate_exits
Skipped switches in the presence of run_emulation and VcpuEvent::Resume Signed-off-by: Matias Teragni <mteragni@amazon.com>
1 parent 8a1719f commit 3f5dca2

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

src/vmm/src/vstate/vcpu/mod.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::{fmt, io, thread};
1616
use kvm_bindings::{KVM_SYSTEM_EVENT_RESET, KVM_SYSTEM_EVENT_SHUTDOWN};
1717
use kvm_ioctls::VcpuExit;
1818
use libc::{c_int, c_void, siginfo_t};
19-
use log::{error, info};
19+
use log::{error, info, warn};
2020
use seccompiler::{BpfProgram, BpfProgramRef};
2121
use utils::errno;
2222
use utils::eventfd::EventFd;
@@ -341,6 +341,13 @@ impl Vcpu {
341341
match self.event_receiver.recv() {
342342
// Paused ---- Resume ----> Running
343343
Ok(VcpuEvent::Resume) => {
344+
if self.kvm_vcpu.fd.get_kvm_run().immediate_exit == 1u8 {
345+
warn!(
346+
"Received a VcpuEvent::Resume message with immediate_exit enabled. \
347+
immediate_exit was disabled before proceeding"
348+
);
349+
self.kvm_vcpu.fd.set_kvm_immediate_exit(0);
350+
}
344351
// Nothing special to do.
345352
self.response_sender
346353
.send(VcpuResponse::Resumed)
@@ -445,7 +452,12 @@ impl Vcpu {
445452
/// Runs the vCPU in KVM context and handles the kvm exit reason.
446453
///
447454
/// Returns error or enum specifying whether emulation was handled or interrupted.
448-
pub fn run_emulation(&self) -> Result<VcpuEmulation, VcpuError> {
455+
pub fn run_emulation(&mut self) -> Result<VcpuEmulation, VcpuError> {
456+
if self.kvm_vcpu.fd.get_kvm_run().immediate_exit == 1u8 {
457+
warn!("Requested a vCPU run with immediate_exit enabled. The operation was skipped");
458+
self.kvm_vcpu.fd.set_kvm_immediate_exit(0);
459+
return Ok(VcpuEmulation::Interrupted);
460+
}
449461
match self.emulate() {
450462
Ok(run) => match run {
451463
VcpuExit::MmioRead(addr, data) => {
@@ -1059,6 +1071,32 @@ pub mod tests {
10591071
);
10601072
}
10611073

1074+
#[test]
1075+
fn test_immediate_exit_shortcircuits_execution() {
1076+
let (_vm, mut vcpu, _) = setup_vcpu(0x1000);
1077+
1078+
vcpu.kvm_vcpu.fd.set_kvm_immediate_exit(1);
1079+
// Set a dummy value to be returned by the emulate call
1080+
*(vcpu.test_vcpu_exit_reason.lock().unwrap()) = Some(Ok(VcpuExit::Shutdown));
1081+
let result = vcpu.run_emulation().expect("Failed to run emulation");
1082+
assert_eq!(
1083+
result,
1084+
VcpuEmulation::Interrupted,
1085+
"The Immediate Exit short-circuit should have prevented the execution of emulate"
1086+
);
1087+
1088+
let event_sender = vcpu.event_sender.take().expect("vCPU already started");
1089+
let _ = event_sender.send(VcpuEvent::Resume);
1090+
vcpu.kvm_vcpu.fd.set_kvm_immediate_exit(1);
1091+
// paused is expected to coerce immediate_exit to 0 when receiving a VcpuEvent::Resume
1092+
let _ = vcpu.paused();
1093+
assert_eq!(
1094+
0,
1095+
vcpu.kvm_vcpu.fd.get_kvm_run().immediate_exit,
1096+
"Immediate Exit should have been disabled by sending Resume to a paused VM"
1097+
)
1098+
}
1099+
10621100
#[test]
10631101
fn test_vcpu_pause_resume() {
10641102
let (vcpu_handle, vcpu_exit_evt) = vcpu_configured_for_boot();

0 commit comments

Comments
 (0)