Skip to content

Commit 5bc223f

Browse files
committed
refactor(pci): separate functions for new and restored types
The code we inherited from Cloud Hypervisor was using a single `new` method for creating objects both for booted and snapshot resumed VMs. The `new` method had an optional `state` argument. When this argument was `Some(state)` the construction of the object happened through copying values from `state`. Split this functionality, for various types, in two distinct methods `new` & `from_state` which are only called for booted and snapshotted microVMs respectively. This is similar to the pattern we're using throughout Firecracker, reduces if/else branches, as well as the arguments of distinct methods. Signed-off-by: Babis Chalios <[email protected]>
1 parent 1a7abe9 commit 5bc223f

File tree

4 files changed

+104
-123
lines changed

4 files changed

+104
-123
lines changed

src/vmm/src/devices/virtio/transport/pci/device.rs

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,6 @@ impl VirtioPciDevice {
312312
fn pci_configuration(
313313
virtio_device_type: u32,
314314
msix_config: &Arc<Mutex<MsixConfig>>,
315-
pci_config_state: Option<PciConfigurationState>,
316315
) -> PciConfiguration {
317316
let pci_device_id = VIRTIO_PCI_DEVICE_ID_BASE + u16::try_from(virtio_device_type).unwrap();
318317
let (class, subclass) = match virtio_device_type {
@@ -339,25 +338,9 @@ impl VirtioPciDevice {
339338
VIRTIO_PCI_VENDOR_ID,
340339
pci_device_id,
341340
Some(msix_config.clone()),
342-
pci_config_state,
343341
)
344342
}
345343

346-
fn msix_config(
347-
pci_device_bdf: u32,
348-
msix_vectors: Arc<MsiVectorGroup>,
349-
msix_config_state: Option<MsixConfigState>,
350-
) -> Result<Arc<Mutex<MsixConfig>>> {
351-
let msix_config = Arc::new(Mutex::new(MsixConfig::new(
352-
msix_vectors.num_vectors(),
353-
msix_vectors,
354-
pci_device_bdf,
355-
msix_config_state,
356-
)?));
357-
358-
Ok(msix_config)
359-
}
360-
361344
/// Allocate the PCI BAR for the VirtIO device and its associated capabilities.
362345
///
363346
/// This must happen only during the creation of a brand new VM. When a VM is restored from a
@@ -399,11 +382,14 @@ impl VirtioPciDevice {
399382
) -> Result<Self> {
400383
let num_queues = device.lock().expect("Poisoned lock").queues().len();
401384

402-
let msix_config = Self::msix_config(pci_device_bdf, msi_vectors.clone(), None)?;
385+
let msix_config = Arc::new(Mutex::new(MsixConfig::new(
386+
msi_vectors.num_vectors(),
387+
msi_vectors.clone(),
388+
pci_device_bdf,
389+
)?));
403390
let pci_config = Self::pci_configuration(
404391
device.lock().expect("Poisoned lock").device_type(),
405392
&msix_config,
406-
None,
407393
);
408394

409395
let virtio_common_config = VirtioPciCommonConfig::new(VirtioPciCommonConfigState {
@@ -448,16 +434,15 @@ impl VirtioPciDevice {
448434
msi_vectors: Arc<MsiVectorGroup>,
449435
state: VirtioPciDeviceState,
450436
) -> Result<Self> {
451-
let msix_config = Self::msix_config(
437+
let msix_config = Arc::new(Mutex::new(MsixConfig::from_state(
438+
state.msix_state,
452439
state.pci_device_bdf.into(),
453440
msi_vectors.clone(),
454-
Some(state.msix_state),
455-
)?;
441+
)?));
456442

457-
let pci_config = Self::pci_configuration(
458-
device.lock().expect("Poisoned lock").device_type(),
459-
&msix_config,
460-
Some(state.pci_configuration_state),
443+
let pci_config = PciConfiguration::type0_from_state(
444+
state.pci_configuration_state,
445+
Some(msix_config.clone()),
461446
);
462447
let virtio_common_config = VirtioPciCommonConfig::new(state.pci_dev_state);
463448
let cap_pci_cfg_info = VirtioPciCfgCapInfo {

src/vmm/src/pci/bus.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ impl PciRoot {
5353
0,
5454
0,
5555
None,
56-
None,
5756
),
5857
}
5958
}
@@ -500,7 +499,6 @@ mod tests {
500499
0x13,
501500
0x12,
502501
None,
503-
None,
504502
);
505503

506504
config.add_pci_bar(0, 0x1000, 0x1000);

src/vmm/src/pci/configuration.rs

Lines changed: 30 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -102,46 +102,41 @@ impl PciConfiguration {
102102
subsystem_vendor_id: u16,
103103
subsystem_id: u16,
104104
msix_config: Option<Arc<Mutex<MsixConfig>>>,
105-
state: Option<PciConfigurationState>,
106105
) -> Self {
107-
let (registers, writable_bits, bars, last_capability, msix_cap_reg_idx) =
108-
if let Some(state) = state {
109-
(
110-
state.registers.try_into().unwrap(),
111-
state.writable_bits.try_into().unwrap(),
112-
state.bars.try_into().unwrap(),
113-
state.last_capability,
114-
state.msix_cap_reg_idx,
115-
)
116-
} else {
117-
let mut registers = [0u32; NUM_CONFIGURATION_REGISTERS];
118-
let mut writable_bits = [0u32; NUM_CONFIGURATION_REGISTERS];
119-
registers[0] = (u32::from(device_id) << 16) | u32::from(vendor_id);
120-
// TODO(dverkamp): Status should be write-1-to-clear
121-
writable_bits[1] = 0x0000_ffff; // Status (r/o), command (r/w)
122-
registers[2] = (u32::from(class_code.get_register_value()) << 24)
123-
| (u32::from(subclass.get_register_value()) << 16)
124-
| u32::from(revision_id);
125-
writable_bits[3] = 0x0000_00ff; // Cacheline size (r/w)
126-
registers[3] = 0x0000_0000; // Header type 0 (device)
127-
writable_bits[15] = 0x0000_00ff; // IRQ line (r/w)
128-
registers[11] = (u32::from(subsystem_id) << 16) | u32::from(subsystem_vendor_id);
129-
130-
(
131-
registers,
132-
writable_bits,
133-
[PciBar::default(); NUM_BAR_REGS],
134-
None,
135-
None,
136-
)
137-
};
106+
let mut registers = [0u32; NUM_CONFIGURATION_REGISTERS];
107+
let mut writable_bits = [0u32; NUM_CONFIGURATION_REGISTERS];
108+
registers[0] = (u32::from(device_id) << 16) | u32::from(vendor_id);
109+
// TODO(dverkamp): Status should be write-1-to-clear
110+
writable_bits[1] = 0x0000_ffff; // Status (r/o), command (r/w)
111+
registers[2] = (u32::from(class_code.get_register_value()) << 24)
112+
| (u32::from(subclass.get_register_value()) << 16)
113+
| u32::from(revision_id);
114+
writable_bits[3] = 0x0000_00ff; // Cacheline size (r/w)
115+
registers[3] = 0x0000_0000; // Header type 0 (device)
116+
writable_bits[15] = 0x0000_00ff; // IRQ line (r/w)
117+
registers[11] = (u32::from(subsystem_id) << 16) | u32::from(subsystem_vendor_id);
138118

139119
PciConfiguration {
140120
registers,
141121
writable_bits,
142-
bars,
143-
last_capability,
144-
msix_cap_reg_idx,
122+
bars: [PciBar::default(); NUM_BAR_REGS],
123+
last_capability: None,
124+
msix_cap_reg_idx: None,
125+
msix_config,
126+
}
127+
}
128+
129+
/// Create a type 0 PCI configuration from snapshot state
130+
pub fn type0_from_state(
131+
state: PciConfigurationState,
132+
msix_config: Option<Arc<Mutex<MsixConfig>>>,
133+
) -> Self {
134+
PciConfiguration {
135+
registers: state.registers.try_into().unwrap(),
136+
writable_bits: state.writable_bits.try_into().unwrap(),
137+
bars: state.bars.try_into().unwrap(),
138+
last_capability: state.last_capability,
139+
msix_cap_reg_idx: state.msix_cap_reg_idx,
145140
msix_config,
146141
}
147142
}
@@ -654,7 +649,6 @@ mod tests {
654649
0xABCD,
655650
0x2468,
656651
None,
657-
None,
658652
)
659653
}
660654

0 commit comments

Comments
 (0)