mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
vmm, docs: make PCI BDF configurable for ivshmem
Add shared PCI config to ivshmem. On-behalf-of: SAP philipp.schuster@sap.com Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de>
This commit is contained in:
committed by
Rob Bradford
parent
5aa0587f2a
commit
212986f013
+1
-1
@@ -19,7 +19,7 @@ This argument takes a file as a `path` value and a file size as a `size` value.
|
|||||||
The `size` value must be 2^n.
|
The `size` value must be 2^n.
|
||||||
|
|
||||||
```
|
```
|
||||||
--ivshmem <ivshmem> device backend file "path=</path/to/a/file>,size=<file_size>"
|
--ivshmem <ivshmem> device backend file "path=</path/to/a/file>,size=<file_size>,id=<device_id>,pci_segment=<segment_id>,pci_device_id=<pci_slot>"
|
||||||
```
|
```
|
||||||
|
|
||||||
## Example
|
## Example
|
||||||
|
|||||||
+32
-3
@@ -2911,12 +2911,14 @@ impl LandlockConfig {
|
|||||||
#[cfg(feature = "ivshmem")]
|
#[cfg(feature = "ivshmem")]
|
||||||
impl IvshmemConfig {
|
impl IvshmemConfig {
|
||||||
pub const SYNTAX: &'static str = "Ivshmem device. Specify the backend file path and size \
|
pub const SYNTAX: &'static str = "Ivshmem device. Specify the backend file path and size \
|
||||||
for the shared memory: \"path=</path/to/a/file>, size=<file_size>\" \
|
for the shared memory: \"path=</path/to/a/file>,size=<file_size>,id=<device_id>,\
|
||||||
|
pci_segment=<segment_id>,pci_device_id=<pci_slot>\" \
|
||||||
\nThe <file_size> must be a power of 2 (e.g., 2M, 4M, etc.), as it represents the size \
|
\nThe <file_size> must be a power of 2 (e.g., 2M, 4M, etc.), as it represents the size \
|
||||||
of the memory region mapped to the guest. Default size is 128M.";
|
of the memory region mapped to the guest. Default size is 128M.";
|
||||||
pub fn parse(ivshmem: &str) -> Result<Self> {
|
pub fn parse(ivshmem: &str) -> Result<Self> {
|
||||||
let mut parser = OptionParser::new();
|
let mut parser = OptionParser::new();
|
||||||
parser.add("path").add("size");
|
parser.add("path").add("size");
|
||||||
|
parser.add_all(PciDeviceCommonConfig::OPTIONS);
|
||||||
parser.parse(ivshmem).map_err(Error::ParseIvshmem)?;
|
parser.parse(ivshmem).map_err(Error::ParseIvshmem)?;
|
||||||
let path = parser
|
let path = parser
|
||||||
.get("path")
|
.get("path")
|
||||||
@@ -2927,13 +2929,20 @@ impl IvshmemConfig {
|
|||||||
.map_err(Error::ParseIvshmem)?
|
.map_err(Error::ParseIvshmem)?
|
||||||
.unwrap_or(ByteSized((DEFAULT_IVSHMEM_SIZE << 20) as u64))
|
.unwrap_or(ByteSized((DEFAULT_IVSHMEM_SIZE << 20) as u64))
|
||||||
.0;
|
.0;
|
||||||
|
let pci_common = PciDeviceCommonConfig::parse(ivshmem)?;
|
||||||
Ok(IvshmemConfig {
|
Ok(IvshmemConfig {
|
||||||
|
pci_common,
|
||||||
path,
|
path,
|
||||||
size: size as usize,
|
size: size as usize,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate(&self) -> ValidationResult<()> {
|
pub fn validate(&self, vm_config: &VmConfig) -> ValidationResult<()> {
|
||||||
|
if self.pci_common.iommu {
|
||||||
|
return Err(ValidationError::IommuNotSupported);
|
||||||
|
}
|
||||||
|
self.pci_common.validate(vm_config)?;
|
||||||
|
|
||||||
let size = self.size as u64;
|
let size = self.size as u64;
|
||||||
let path = &self.path;
|
let path = &self.path;
|
||||||
// size must = 2^n
|
// size must = 2^n
|
||||||
@@ -3376,7 +3385,8 @@ impl VmConfig {
|
|||||||
}
|
}
|
||||||
#[cfg(feature = "ivshmem")]
|
#[cfg(feature = "ivshmem")]
|
||||||
if let Some(ivshmem_config) = &self.ivshmem {
|
if let Some(ivshmem_config) = &self.ivshmem {
|
||||||
ivshmem_config.validate()?;
|
ivshmem_config.validate(self)?;
|
||||||
|
Self::validate_identifier(&mut id_list, &ivshmem_config.pci_common.id)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(id_list)
|
Ok(id_list)
|
||||||
@@ -4420,6 +4430,25 @@ mod unit_tests {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "ivshmem")]
|
||||||
|
fn test_parse_ivshmem() -> Result<()> {
|
||||||
|
assert_eq!(
|
||||||
|
IvshmemConfig::parse("path=/tmp/ivshmem.data,size=2M,pci_segment=1,pci_device_id=7")?,
|
||||||
|
IvshmemConfig {
|
||||||
|
pci_common: PciDeviceCommonConfig {
|
||||||
|
pci_segment: 1,
|
||||||
|
pci_device_id: Some(7),
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
path: PathBuf::from("/tmp/ivshmem.data"),
|
||||||
|
size: 2 << 20,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn fs_fixture() -> FsConfig {
|
fn fs_fixture() -> FsConfig {
|
||||||
FsConfig {
|
FsConfig {
|
||||||
pci_common: PciDeviceCommonConfig::default(),
|
pci_common: PciDeviceCommonConfig::default(),
|
||||||
|
|||||||
@@ -1560,8 +1560,11 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ivshmem")]
|
#[cfg(feature = "ivshmem")]
|
||||||
if let Some(ivshmem) = self.config.clone().lock().unwrap().ivshmem.as_ref() {
|
{
|
||||||
self.ivshmem_device = self.add_ivshmem_device(ivshmem, snapshot)?;
|
let mut ivshmem = self.config.lock().unwrap().ivshmem.clone();
|
||||||
|
if let Some(ivshmem) = &mut ivshmem {
|
||||||
|
self.ivshmem_device = self.add_ivshmem_device(ivshmem, snapshot)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -4481,15 +4484,24 @@ impl DeviceManager {
|
|||||||
#[cfg(feature = "ivshmem")]
|
#[cfg(feature = "ivshmem")]
|
||||||
fn add_ivshmem_device(
|
fn add_ivshmem_device(
|
||||||
&mut self,
|
&mut self,
|
||||||
ivshmem_cfg: &IvshmemConfig,
|
ivshmem_cfg: &mut IvshmemConfig,
|
||||||
snapshot: Option<&Snapshot>,
|
snapshot: Option<&Snapshot>,
|
||||||
) -> DeviceManagerResult<Option<Arc<Mutex<devices::IvshmemDevice>>>> {
|
) -> DeviceManagerResult<Option<Arc<Mutex<devices::IvshmemDevice>>>> {
|
||||||
let id = String::from(IVSHMEM_DEVICE_NAME);
|
let id = match ivshmem_cfg.pci_common.id.as_ref() {
|
||||||
let pci_segment_id = 0x0_u16;
|
Some(id) => id.clone(),
|
||||||
|
None => ivshmem_cfg
|
||||||
|
.pci_common
|
||||||
|
.id
|
||||||
|
.insert(IVSHMEM_DEVICE_NAME.to_string())
|
||||||
|
.clone(),
|
||||||
|
};
|
||||||
info!("Creating ivshmem device {id}");
|
info!("Creating ivshmem device {id}");
|
||||||
|
|
||||||
let (pci_segment_id, pci_device_bdf, resources) =
|
let (pci_segment_id, pci_device_bdf, resources) = self.pci_resources(
|
||||||
self.pci_resources(&id, pci_segment_id, None)?;
|
&id,
|
||||||
|
ivshmem_cfg.pci_common.pci_segment,
|
||||||
|
ivshmem_cfg.pci_common.pci_device_id,
|
||||||
|
)?;
|
||||||
let snapshot = snapshot_from_id(snapshot, id.as_str());
|
let snapshot = snapshot_from_id(snapshot, id.as_str());
|
||||||
|
|
||||||
let ivshmem_ops = Arc::new(Mutex::new(IvshmemHandler {
|
let ivshmem_ops = Arc::new(Mutex::new(IvshmemHandler {
|
||||||
@@ -4558,6 +4570,14 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ivshmem")]
|
||||||
|
if let Some(ivshmem_cfg) = &config.ivshmem
|
||||||
|
&& let Some(device_id) = ivshmem_cfg.pci_common.pci_device_id
|
||||||
|
{
|
||||||
|
self.pci_segments[ivshmem_cfg.pci_common.pci_segment as usize]
|
||||||
|
.reserve_device_id(device_id)?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -837,6 +837,8 @@ pub const DEFAULT_IVSHMEM_SIZE: usize = 128;
|
|||||||
#[cfg(feature = "ivshmem")]
|
#[cfg(feature = "ivshmem")]
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
|
||||||
pub struct IvshmemConfig {
|
pub struct IvshmemConfig {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub pci_common: PciDeviceCommonConfig,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub size: usize,
|
pub size: usize,
|
||||||
}
|
}
|
||||||
@@ -845,6 +847,7 @@ pub struct IvshmemConfig {
|
|||||||
impl Default for IvshmemConfig {
|
impl Default for IvshmemConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
pci_common: PciDeviceCommonConfig::default(),
|
||||||
path: PathBuf::new(),
|
path: PathBuf::new(),
|
||||||
size: DEFAULT_IVSHMEM_SIZE << 20,
|
size: DEFAULT_IVSHMEM_SIZE << 20,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user