Skip to content

Commit 776ccda

Browse files
author
Serban Iorga
committed
forward the vCPU exit code to the VMM
Signed-off-by: Serban Iorga <[email protected]>
1 parent 646b83b commit 776ccda

File tree

3 files changed

+40
-8
lines changed

3 files changed

+40
-8
lines changed

src/vmm/src/lib.rs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1271,7 +1271,21 @@ impl Vmm {
12711271
match self.epoll_context.dispatch_table[event.data as usize] {
12721272
Some(EpollDispatch::Exit) => {
12731273
self.exit_evt.read().map_err(Error::EventFd)?;
1274-
self.stop(i32::from(FC_EXIT_CODE_OK));
1274+
1275+
// Query each vcpu for the exit_code.
1276+
// If the exit_code can't be found on any vcpu, it means that the exit signal
1277+
// has been issued by the i8042 controller in which case we exit with
1278+
// FC_EXIT_CODE_OK.
1279+
let exit_code = self
1280+
.vcpus_handles
1281+
.iter()
1282+
.find_map(|handle| match handle.response_receiver().try_recv() {
1283+
Ok(VcpuResponse::Exited(exit_code)) => Some(exit_code),
1284+
_ => None,
1285+
})
1286+
.unwrap_or(FC_EXIT_CODE_OK);
1287+
1288+
self.stop(i32::from(exit_code));
12751289
}
12761290
Some(EpollDispatch::Stdin) => {
12771291
let mut out = [0u8; 64];

src/vmm/src/vstate.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use std::sync::mpsc::{channel, Receiver, Sender, TryRecvError};
1414
use std::thread;
1515

1616
use super::TimestampUs;
17-
use arch;
17+
use super::FC_EXIT_CODE_GENERIC_ERROR;
1818
#[cfg(target_arch = "aarch64")]
1919
use arch::aarch64::gic::GICDevice;
2020
#[cfg(target_arch = "x86_64")]
@@ -30,6 +30,7 @@ use kvm_bindings::{kvm_userspace_memory_region, KVM_API_VERSION};
3030
use kvm_ioctls::*;
3131
use logger::{Metric, METRICS};
3232
use seccomp::{BpfProgram, SeccompFilter};
33+
use std::sync::Barrier;
3334
use utils::eventfd::EventFd;
3435
use utils::signal::{register_signal_handler, sigrtmin, Killable};
3536
use utils::sm::StateMachine;
@@ -1002,7 +1003,7 @@ impl Vcpu {
10021003
// Emulation was interrupted, check external events.
10031004
Ok(VcpuEmulation::Interrupted) => break,
10041005
// Emulation errors lead to vCPU exit.
1005-
Err(_) => return StateMachine::next(Self::exited),
1006+
Err(_) => return self.exit(FC_EXIT_CODE_GENERIC_ERROR),
10061007
}
10071008
}
10081009

@@ -1032,7 +1033,7 @@ impl Vcpu {
10321033
// Unhandled exit of the other end.
10331034
Err(TryRecvError::Disconnected) => {
10341035
// Move to 'exited' state.
1035-
state = StateMachine::next(Self::exited);
1036+
state = self.exit(FC_EXIT_CODE_GENERIC_ERROR);
10361037
}
10371038
// All other events or lack thereof have no effect on current 'running' state.
10381039
Err(TryRecvError::Empty) => (),
@@ -1058,18 +1059,33 @@ impl Vcpu {
10581059
// Unhandled exit of the other end.
10591060
Err(_) => {
10601061
// Move to 'exited' state.
1061-
StateMachine::next(Self::exited)
1062+
self.exit(FC_EXIT_CODE_GENERIC_ERROR)
10621063
}
10631064
}
10641065
}
10651066

1066-
// This is the main loop of the `Exited` state.
1067-
fn exited(&mut self) -> StateMachine<Self> {
1067+
// Transition to the exited state
1068+
fn exit(&mut self, exit_code: u8) -> StateMachine<Self> {
1069+
self.response_sender
1070+
.send(VcpuResponse::Exited(exit_code))
1071+
.expect("failed to send Exited status");
1072+
10681073
if let Err(e) = self.exit_evt.write(1) {
10691074
METRICS.vcpu.failures.inc();
10701075
error!("Failed signaling vcpu exit event: {}", e);
10711076
}
1077+
10721078
// State machine reached its end.
1079+
StateMachine::next(Self::exited)
1080+
}
1081+
1082+
// This is the main loop of the `Exited` state.
1083+
fn exited(&mut self) -> StateMachine<Self> {
1084+
// Wait indefinitely.
1085+
// The VMM thread will kill the entire process.
1086+
let barrier = Barrier::new(2);
1087+
barrier.wait();
1088+
10731089
StateMachine::finish(Self::exited)
10741090
}
10751091
}
@@ -1114,6 +1130,8 @@ pub enum VcpuResponse {
11141130
Paused,
11151131
/// Vcpu is resumed.
11161132
Resumed,
1133+
/// Vcpu is stopped.
1134+
Exited(u8),
11171135
}
11181136

11191137
/// Wrapper over Vcpu that hides the underlying interactions with the Vcpu thread.

tests/integration_tests/build/test_coverage.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
import host_tools.cargo_build as host # pylint: disable=import-error
2121

22-
COVERAGE_TARGET_PCT = 85.05
22+
COVERAGE_TARGET_PCT = 84.90
2323
COVERAGE_MAX_DELTA = 0.05
2424

2525
CARGO_KCOV_REL_PATH = os.path.join(host.CARGO_BUILD_REL_PATH, 'kcov')

0 commit comments

Comments
 (0)