mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm, main: make PCI BDF configurable for ConsoleConfig
Add common PCI device configuration to the virtio-console device configuration. This allows setting the device ID (the name), ID, the PCI segment, and the PCI device ID (BDF), which were previously not configurable for the virtio-console device. This gives management software, such as libvirt, more control over PCI resource assignment and aligns virtio-console with other devices that already support this functionality [0]. [0] https://github.com/cloud-hypervisor/cloud-hypervisor/issues/8175 On-behalf-of: Philipp Schuster <philipp.schuster@sap.com> Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
This commit is contained in:
committed by
Rob Bradford
parent
36a3369802
commit
e793353bfb
@@ -1025,7 +1025,7 @@ mod unit_tests {
|
||||
mode: ConsoleOutputMode::Tty,
|
||||
socket: None,
|
||||
},
|
||||
iommu: false,
|
||||
pci_common: PciDeviceCommonConfig::default(),
|
||||
},
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
debug_console: DebugConsoleConfig::default(),
|
||||
@@ -1693,10 +1693,12 @@ mod unit_tests {
|
||||
"--serial",
|
||||
"null",
|
||||
"--console",
|
||||
"tty",
|
||||
"tty,pci_segment=1,pci_device_id=7",
|
||||
],
|
||||
r#"{
|
||||
"payload": {"kernel": "/path/to/kernel"}
|
||||
"payload": {"kernel": "/path/to/kernel"},
|
||||
"serial": {"mode": "Null"},
|
||||
"console": {"mode": "Tty", "iommu": false, "pci_segment": 1, "pci_device_id": 7}
|
||||
}"#,
|
||||
true,
|
||||
),
|
||||
|
||||
@@ -184,7 +184,7 @@ impl RequestHandler for StubApiRequestHandler {
|
||||
mode: ConsoleOutputMode::Tty,
|
||||
socket: None,
|
||||
},
|
||||
iommu: false,
|
||||
pci_common: PciDeviceCommonConfig::default(),
|
||||
},
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
debug_console: DebugConsoleConfig::default(),
|
||||
|
||||
@@ -2187,18 +2187,17 @@ impl ConsoleConfig {
|
||||
parser
|
||||
.add_all_valueless(CommonConsoleConfig::VALUELESS_OPTIONS)
|
||||
.add_all(CommonConsoleConfig::VALUE_OPTIONS)
|
||||
.add("iommu");
|
||||
.add_all(PciDeviceCommonConfig::OPTIONS_IOMMU);
|
||||
parser.parse(console).map_err(Error::ParseConsole)?;
|
||||
|
||||
let iommu = parser
|
||||
.convert::<Toggle>("iommu")
|
||||
.map_err(Error::ParsePciDeviceCommonConfig)?
|
||||
.unwrap_or(Toggle(false))
|
||||
.0;
|
||||
|
||||
let common = CommonConsoleConfig::parse(console, Error::ParseConsole)?;
|
||||
let pci_common = PciDeviceCommonConfig::parse(console)?;
|
||||
|
||||
Ok(Self { common, iommu })
|
||||
Ok(Self { common, pci_common })
|
||||
}
|
||||
|
||||
pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> {
|
||||
self.pci_common.validate(vm_config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3054,7 +3053,10 @@ impl VmConfig {
|
||||
}
|
||||
|
||||
self.iommu |= self.rng.pci_common.iommu;
|
||||
self.iommu |= self.console.iommu;
|
||||
|
||||
self.console.validate(self)?;
|
||||
Self::validate_identifier(&mut id_list, &self.console.pci_common.id)?;
|
||||
self.iommu |= self.console.pci_common.iommu;
|
||||
|
||||
if let Some(t) = &self.cpus.topology {
|
||||
if t.threads_per_core == 0
|
||||
@@ -4411,7 +4413,10 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
fn test_console_parsing() -> Result<()> {
|
||||
let console_config = |mode, file, socket, iommu| ConsoleConfig {
|
||||
common: CommonConsoleConfig { file, mode, socket },
|
||||
iommu,
|
||||
pci_common: PciDeviceCommonConfig {
|
||||
iommu,
|
||||
..Default::default()
|
||||
},
|
||||
};
|
||||
|
||||
ConsoleConfig::parse("").unwrap_err();
|
||||
@@ -5054,7 +5059,7 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
mode: ConsoleOutputMode::Tty,
|
||||
socket: None,
|
||||
},
|
||||
iommu: false,
|
||||
pci_common: PciDeviceCommonConfig::default(),
|
||||
},
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
debug_console: DebugConsoleConfig::default(),
|
||||
@@ -5981,6 +5986,37 @@ id=\"{id}\",pci_segment={pci_segment},queue_sizes={queue_sizes}"
|
||||
invalid_config.validate(),
|
||||
Err(ValidationError::InvalidPciDeviceId(pci::NUM_DEVICE_IDS + 1))
|
||||
);
|
||||
|
||||
// Invalid console BDF - Same ID as Root device
|
||||
let mut invalid_config = valid_config.clone();
|
||||
invalid_config.console.pci_common.pci_device_id = Some(pci::PCI_ROOT_DEVICE_ID);
|
||||
assert_eq!(
|
||||
invalid_config.validate(),
|
||||
Err(ValidationError::ReservedPciDeviceId(
|
||||
pci::PCI_ROOT_DEVICE_ID
|
||||
))
|
||||
);
|
||||
// Invalid console BDF - Out of range
|
||||
let mut invalid_config = valid_config.clone();
|
||||
invalid_config.console.pci_common.pci_device_id = Some(pci::NUM_DEVICE_IDS + 1);
|
||||
assert_eq!(
|
||||
invalid_config.validate(),
|
||||
Err(ValidationError::InvalidPciDeviceId(pci::NUM_DEVICE_IDS + 1))
|
||||
);
|
||||
// Invalid console ID - Duplicate identifier
|
||||
let mut invalid_config = valid_config.clone();
|
||||
invalid_config.console.pci_common.id = Some("test0".to_string());
|
||||
invalid_config.disks = Some(vec![DiskConfig {
|
||||
pci_common: PciDeviceCommonConfig {
|
||||
id: Some("test0".to_string()),
|
||||
..Default::default()
|
||||
},
|
||||
..disk_fixture()
|
||||
}]);
|
||||
assert_eq!(
|
||||
invalid_config.validate(),
|
||||
Err(ValidationError::IdentifierNotUnique("test0".to_string()))
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_landlock_parsing() -> Result<()> {
|
||||
|
||||
@@ -2368,7 +2368,7 @@ impl DeviceManager {
|
||||
transport: ConsoleTransport,
|
||||
resize_pipe: Option<Arc<File>>,
|
||||
) -> DeviceManagerResult<Option<Arc<virtio_devices::ConsoleResizer>>> {
|
||||
let console_config = self.config.lock().unwrap().console.clone();
|
||||
let mut console_config = self.config.lock().unwrap().console.clone();
|
||||
let endpoint = match transport {
|
||||
ConsoleTransport::File(file) => Endpoint::File(file),
|
||||
ConsoleTransport::Pty(file) => {
|
||||
@@ -2402,7 +2402,15 @@ impl DeviceManager {
|
||||
ConsoleTransport::Null => Endpoint::Null,
|
||||
ConsoleTransport::Off => return Ok(None),
|
||||
};
|
||||
let id = String::from(CONSOLE_DEVICE_NAME);
|
||||
|
||||
let id = match console_config.pci_common.id.as_ref() {
|
||||
Some(id) => id.clone(),
|
||||
None => console_config
|
||||
.pci_common
|
||||
.id
|
||||
.insert(CONSOLE_DEVICE_NAME.to_string())
|
||||
.clone(),
|
||||
};
|
||||
|
||||
let (virtio_console_device, console_resizer) = virtio_devices::Console::new(
|
||||
id.clone(),
|
||||
@@ -2410,7 +2418,7 @@ impl DeviceManager {
|
||||
self.console_resize_pipe
|
||||
.as_ref()
|
||||
.map(|p| p.try_clone().unwrap()),
|
||||
self.force_access_platform | console_config.iommu,
|
||||
self.force_access_platform | console_config.pci_common.iommu,
|
||||
self.seccomp_action.clone(),
|
||||
self.exit_evt
|
||||
.try_clone()
|
||||
@@ -2423,11 +2431,7 @@ impl DeviceManager {
|
||||
self.virtio_devices.push(MetaVirtioDevice {
|
||||
virtio_device: Arc::clone(&virtio_console_device)
|
||||
as Arc<Mutex<dyn virtio_devices::VirtioDevice>>,
|
||||
pci_common: PciDeviceCommonConfig {
|
||||
id: Some(id.clone()),
|
||||
iommu: console_config.iommu,
|
||||
..Default::default()
|
||||
},
|
||||
pci_common: console_config.pci_common.clone(),
|
||||
dma_handler: None,
|
||||
});
|
||||
|
||||
|
||||
@@ -2737,7 +2737,7 @@ mod unit_tests {
|
||||
mode: ConsoleOutputMode::Off,
|
||||
socket: None,
|
||||
},
|
||||
iommu: false,
|
||||
pci_common: PciDeviceCommonConfig::default(),
|
||||
},
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
debug_console: DebugConsoleConfig::default(),
|
||||
|
||||
@@ -574,10 +574,6 @@ impl ApplyLandlock for CommonConsoleConfig {
|
||||
}
|
||||
|
||||
/// Configuration for a legacy serial console device.
|
||||
///
|
||||
/// - On x86_64, this is a port I/O-mapped UART16550-compatible device
|
||||
/// - On aarch64, this is a MMIO-mapped PL011 device
|
||||
/// - On RISCV, this is a MMIO-mapped UART16550-compatible device
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
||||
pub struct SerialConfig {
|
||||
#[serde(flatten)]
|
||||
@@ -611,13 +607,12 @@ impl ApplyLandlock for SerialConfig {
|
||||
pub struct ConsoleConfig {
|
||||
#[serde(flatten)]
|
||||
pub common: CommonConsoleConfig,
|
||||
#[serde(default, skip_serializing_if = "<&bool as std::ops::Not>::not")]
|
||||
pub iommu: bool,
|
||||
#[serde(default, flatten)]
|
||||
pub pci_common: PciDeviceCommonConfig,
|
||||
}
|
||||
|
||||
impl ConsoleConfig {
|
||||
pub const SYNTAX: &str =
|
||||
"Control (virtio) console: \"off|null|pty|tty|file=<path>,iommu=on|off\"";
|
||||
pub const SYNTAX: &str = "Control (virtio) console: \"off|null|pty|tty|file=<path>,iommu=on|off,id=<device_id>,pci_segment=<segment_id>,pci_device_id=<pci_slot>\"";
|
||||
}
|
||||
|
||||
impl Default for ConsoleConfig {
|
||||
@@ -628,7 +623,7 @@ impl Default for ConsoleConfig {
|
||||
mode: ConsoleOutputMode::Tty,
|
||||
socket: None,
|
||||
},
|
||||
iommu: false,
|
||||
pci_common: PciDeviceCommonConfig::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user