Skip to content

Commit ea54085

Browse files
committed
vstate: support serializing interrupts to snapshots
Vm object is now maintaining information about the interrupts (both traditional IRQs and MSI-X vectors) that are being used by microVM devices. Derive Serialize/Deserialize add logic for recreating objects for relevant types. Signed-off-by: Babis Chalios <[email protected]>
1 parent c7846d3 commit ea54085

File tree

2 files changed

+37
-3
lines changed

2 files changed

+37
-3
lines changed

src/vmm/src/arch/aarch64/vm.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
// Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
// SPDX-License-Identifier: Apache-2.0
33

4+
use std::collections::HashMap;
5+
use std::sync::{Arc, Mutex};
6+
47
use serde::{Deserialize, Serialize};
58

69
use crate::Kvm;
710
use crate::arch::aarch64::gic::GicState;
811
use crate::vstate::memory::{GuestMemoryExtension, GuestMemoryState};
9-
use crate::vstate::vm::{VmCommon, VmError};
12+
use crate::vstate::vm::{RoutingEntry, VmCommon, VmError};
1013

1114
/// Structure representing the current architecture's understand of what a "virtual machine" is.
1215
#[derive(Debug)]
@@ -74,6 +77,7 @@ impl ArchVm {
7477
.get_irqchip()
7578
.save_device(mpidrs)
7679
.map_err(ArchVmError::SaveGic)?,
80+
interrupts: self.common.interrupts.clone(),
7781
})
7882
}
7983

@@ -86,6 +90,7 @@ impl ArchVm {
8690
self.get_irqchip()
8791
.restore_device(mpidrs, &state.gic)
8892
.map_err(ArchVmError::RestoreGic)?;
93+
self.common.interrupts = state.interrupts.clone();
8994

9095
Ok(())
9196
}
@@ -98,4 +103,6 @@ pub struct VmState {
98103
pub memory: GuestMemoryState,
99104
/// GIC state.
100105
pub gic: GicState,
106+
/// Interrupts state
107+
interrupts: Arc<Mutex<HashMap<u32, RoutingEntry>>>,
101108
}

src/vmm/src/vstate/vm.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use kvm_bindings::{
2020
};
2121
use kvm_ioctls::VmFd;
2222
use log::debug;
23+
use serde::{Deserialize, Serialize};
2324
use vm_device::interrupt::{InterruptSourceGroup, MsiIrqSourceConfig};
2425
use vmm_sys_util::errno;
2526
use vmm_sys_util::eventfd::EventFd;
@@ -49,7 +50,7 @@ pub enum InterruptError {
4950
Kvm(#[from] kvm_ioctls::Error),
5051
}
5152

52-
#[derive(Debug)]
53+
#[derive(Debug, Serialize, Deserialize)]
5354
/// A struct representing an interrupt line used by some device of the microVM
5455
pub struct RoutingEntry {
5556
entry: kvm_irq_routing_entry,
@@ -112,6 +113,32 @@ impl MsiVectorGroup {
112113
pub fn num_vectors(&self) -> u16 {
113114
u16::try_from(self.irq_routes.len()).unwrap()
114115
}
116+
117+
/// Save the vectors state
118+
pub fn state(&self) -> Vec<(u32, (u32, bool))> {
119+
let mut state = vec![];
120+
for (idx, irq_route) in &self.irq_routes {
121+
state.push((
122+
*idx,
123+
(irq_route.gsi, irq_route.enabled.load(Ordering::Acquire)),
124+
));
125+
}
126+
state
127+
}
128+
129+
/// Create a new group from state
130+
pub fn from_state(
131+
vm: Arc<Vm>,
132+
state: &[(u32, (u32, bool))],
133+
) -> Result<MsiVectorGroup, InterruptError> {
134+
let mut irq_routes = HashMap::new();
135+
136+
for (idx, (gsi, enabled)) in state {
137+
irq_routes.insert(*idx, MsiVector::new(*gsi, *enabled)?);
138+
}
139+
140+
Ok(MsiVectorGroup { vm, irq_routes })
141+
}
115142
}
116143

117144
impl InterruptSourceGroup for MsiVectorGroup {
@@ -207,7 +234,7 @@ pub struct VmCommon {
207234
/// The guest memory of this Vm.
208235
pub guest_memory: GuestMemoryMmap,
209236
/// Interrupts used by Vm's devices
210-
interrupts: Arc<Mutex<HashMap<u32, RoutingEntry>>>,
237+
pub interrupts: Arc<Mutex<HashMap<u32, RoutingEntry>>>,
211238
}
212239

213240
/// Errors associated with the wrappers over KVM ioctls.

0 commit comments

Comments
 (0)