mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
pci: Save deferred BAR reprogramming state
OVMF can reprogram PCI BARs while memory space decoding is disabled. Cloud Hypervisor defers the corresponding BAR move in `pending_bar_reprogram` until the PCI command register enables Memory Space again. That deferred state was not part of `PciConfigurationState`. A snapshot taken in that window restored the new BAR values in PCI config space, but lost the pending BAR relocation needed to update the VMM-side BAR mapping. The restore logs show guest MMIO accesses to the reprogrammed BAR addresses `0xc0000000`, `0x100000000`, and `0x100080000` hitting unregistered addresses. The firmware serial output shows OVMF assigning those same BAR addresses during PCI resource allocation, then reaching BDS, finding the mass-storage device, and failing to boot from it. Serialize and restore `pending_bar_reprogram` so deferred BAR moves survive snapshot and restore. Co-authored-by: Thomas Prescher <thomas.prescher@cyberus-technology.de> Co-authored-by: Julian Schindel <julian.schindel@cyberus-technology.de> On-behalf-of: SAP leander.kohler@sap.com Signed-off-by: Leander Kohler <leander.kohler@cyberus-technology.de>
This commit is contained in:
committed by
Rob Bradford
parent
0686045290
commit
db93c6fdc7
@@ -422,6 +422,9 @@ pub struct PciConfigurationState {
|
||||
rom_bar_used: bool,
|
||||
last_capability: Option<(usize, usize)>,
|
||||
msix_cap_reg_idx: Option<usize>,
|
||||
// Preserve deferred BAR moves across snapshot and restore.
|
||||
#[serde(default)]
|
||||
pending_bar_reprogram: Vec<BarReprogrammingParams>,
|
||||
}
|
||||
|
||||
/// Contains the configuration space of a PCI node.
|
||||
@@ -557,6 +560,7 @@ impl PciConfiguration {
|
||||
rom_bar_used,
|
||||
last_capability,
|
||||
msix_cap_reg_idx,
|
||||
pending_bar_reprogram,
|
||||
) = if let Some(state) = state {
|
||||
(
|
||||
state.registers.try_into().unwrap(),
|
||||
@@ -567,6 +571,7 @@ impl PciConfiguration {
|
||||
state.rom_bar_used,
|
||||
state.last_capability,
|
||||
state.msix_cap_reg_idx,
|
||||
state.pending_bar_reprogram,
|
||||
)
|
||||
} else {
|
||||
let mut registers = [0u32; NUM_CONFIGURATION_REGISTERS];
|
||||
@@ -606,6 +611,7 @@ impl PciConfiguration {
|
||||
false,
|
||||
None,
|
||||
None,
|
||||
Vec::new(),
|
||||
)
|
||||
};
|
||||
|
||||
@@ -619,7 +625,7 @@ impl PciConfiguration {
|
||||
last_capability,
|
||||
msix_cap_reg_idx,
|
||||
msix_config,
|
||||
pending_bar_reprogram: Vec::new(),
|
||||
pending_bar_reprogram,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -633,6 +639,7 @@ impl PciConfiguration {
|
||||
rom_bar_used: self.rom_bar_used,
|
||||
last_capability: self.last_capability,
|
||||
msix_cap_reg_idx: self.msix_cap_reg_idx,
|
||||
pending_bar_reprogram: self.pending_bar_reprogram.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ use std::any::Any;
|
||||
use std::sync::{Arc, Barrier, Mutex};
|
||||
use std::{io, result};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use thiserror::Error;
|
||||
use vm_allocator::{AddressAllocator, SystemAllocator};
|
||||
use vm_device::Resource;
|
||||
@@ -35,7 +36,7 @@ pub enum Error {
|
||||
}
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
|
||||
pub struct BarReprogrammingParams {
|
||||
pub old_base: u64,
|
||||
pub new_base: u64,
|
||||
|
||||
Reference in New Issue
Block a user