diff --git a/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs b/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs index 7511f350c1..864494f2e4 100644 --- a/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs +++ b/src/runtime-rs/crates/hypervisor/src/device/device_manager.rs @@ -4,7 +4,11 @@ // SPDX-License-Identifier: Apache-2.0 // -use std::{collections::HashMap, sync::Arc}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, + sync::Arc, +}; use anyhow::{anyhow, Context, Result}; use kata_sys_util::rand::RandomBytes; @@ -12,7 +16,8 @@ use kata_types::config::hypervisor::{BlockDeviceInfo, TopologyConfigInfo, VIRTIO use tokio::sync::{Mutex, RwLock}; use crate::{ - vhost_user_blk::VhostUserBlkDevice, BlockConfig, BlockDevice, HybridVsockDevice, Hypervisor, + vfio_device::VfioDeviceModernHandle, vhost_user_blk::VhostUserBlkDevice, BlockConfig, + BlockConfigModern, BlockDevice, BlockDeviceModernHandle, HybridVsockDevice, Hypervisor, NetworkDevice, PCIePortDevice, ProtectionDevice, ShareFsDevice, VfioDevice, VhostUserConfig, VhostUserNetDevice, VsockDevice, KATA_BLK_DEV_TYPE, KATA_CCW_DEV_TYPE, KATA_MMIO_BLK_DEV_TYPE, KATA_NVDIMM_DEV_TYPE, KATA_SCSI_DEV_TYPE, VIRTIO_BLOCK_CCW, VIRTIO_BLOCK_MMIO, @@ -251,12 +256,20 @@ impl DeviceManager { return Some(device_id.to_string()); } } + DeviceType::VfioModern(device) => { + if device.lock().await.config.iommu_group_devnode == Path::new(&host_path) { + return Some(device_id.to_string()); + } + } + DeviceType::BlockModern(device) => { + if device.lock().await.config.path_on_host == host_path { + return Some(device_id.to_string()); + } + } DeviceType::HybridVsock(_) | DeviceType::Vsock(_) | DeviceType::Protection(_) - | DeviceType::PortDevice(_) - | DeviceType::VfioModern(_) - | DeviceType::BlockModern(_) => { + | DeviceType::PortDevice(_) => { continue; } } @@ -303,6 +316,16 @@ impl DeviceManager { .await .context("failed to create device")? } + DeviceConfig::BlockCfgModern(config) => { + if let Some(device_matched_id) = self.find_device(config.path_on_host.clone()).await + { + return Ok(device_matched_id); + } + + self.create_block_device_modern(config, device_id.clone()) + .await + .context("failed to create block device modern")? + } DeviceConfig::VfioCfg(config) => { let mut vfio_dev_config = config.clone(); let dev_host_path = vfio_dev_config.host_path.clone(); @@ -317,6 +340,22 @@ impl DeviceManager { &vfio_dev_config, )?)) } + DeviceConfig::VfioModernCfg(config) => { + let dev_host_path = config.host_path.clone(); + if let Some(device_matched_id) = self.find_device(dev_host_path.clone()).await { + return Ok(device_matched_id); + } + + let virt_path = self.get_dev_virt_path(&config.dev_type, false)?; + let mut vfio_base = config.clone(); + vfio_base.iommu_group_devnode = PathBuf::from(dev_host_path); + vfio_base.virt_path = virt_path; + + Arc::new(Mutex::new(VfioDeviceModernHandle::new( + device_id.clone(), + &vfio_base, + )?)) + } DeviceConfig::VhostUserBlkCfg(config) => { // try to find the device, found and just return id. if let Some(dev_id_matched) = self.find_device(config.socket_path.clone()).await { @@ -447,6 +486,56 @@ impl DeviceManager { )))) } + async fn create_block_device_modern( + &mut self, + config: &BlockConfigModern, + device_id: String, + ) -> Result { + let mut block_config = config.clone(); + let mut is_pmem = false; + + match block_config.driver_option.as_str() { + VIRTIO_BLOCK_MMIO => { + block_config.driver_option = KATA_MMIO_BLK_DEV_TYPE.to_string(); + } + VIRTIO_BLOCK_PCI => { + block_config.driver_option = KATA_BLK_DEV_TYPE.to_string(); + } + VIRTIO_BLOCK_CCW => { + block_config.driver_option = KATA_CCW_DEV_TYPE.to_string(); + } + VIRTIO_PMEM => { + block_config.driver_option = KATA_NVDIMM_DEV_TYPE.to_string(); + is_pmem = true; + } + VIRTIO_SCSI => { + block_config.driver_option = KATA_SCSI_DEV_TYPE.to_string(); + } + _ => { + return Err(anyhow!( + "unsupported driver type {}", + block_config.driver_option + )); + } + }; + + if let Some(virt_path) = self.get_dev_virt_path(DEVICE_TYPE_BLOCK, is_pmem)? { + block_config.index = virt_path.0; + block_config.virt_path = virt_path.1; + } + + if block_config.path_on_host.is_empty() { + block_config.path_on_host = + get_host_path(DEVICE_TYPE_BLOCK, config.major, config.minor) + .context("failed to get host path")?; + } + + Ok(Arc::new(Mutex::new(BlockDeviceModernHandle::new( + device_id, + block_config, + )))) + } + async fn create_block_device( &mut self, config: &BlockConfig, diff --git a/src/runtime-rs/crates/hypervisor/src/device/mod.rs b/src/runtime-rs/crates/hypervisor/src/device/mod.rs index b3067fffeb..87d378918f 100644 --- a/src/runtime-rs/crates/hypervisor/src/device/mod.rs +++ b/src/runtime-rs/crates/hypervisor/src/device/mod.rs @@ -12,11 +12,12 @@ use tokio::sync::Mutex; use crate::device::driver::vhost_user_blk::VhostUserBlkDevice; use crate::device::driver::vfio_device::VfioDeviceModern; use crate::device::driver::virtio_blk_modern::BlockDeviceModern; +use crate::vfio_device::VfioDeviceBase; use crate::{ - BlockConfig, BlockDevice, HybridVsockConfig, HybridVsockDevice, Hypervisor as hypervisor, - NetworkConfig, NetworkDevice, PCIePortDevice, PortDeviceConfig, ProtectionDevice, - ProtectionDeviceConfig, ShareFsConfig, ShareFsDevice, VfioConfig, VfioDevice, VhostUserConfig, - VhostUserNetDevice, VsockConfig, VsockDevice, + BlockConfig, BlockConfigModern, BlockDevice, HybridVsockConfig, HybridVsockDevice, + Hypervisor as hypervisor, NetworkConfig, NetworkDevice, PCIePortDevice, PortDeviceConfig, + ProtectionDevice, ProtectionDeviceConfig, ShareFsConfig, ShareFsDevice, VfioConfig, + VfioDevice, VhostUserConfig, VhostUserNetDevice, VsockConfig, VsockDevice, }; use anyhow::Result; use async_trait::async_trait; @@ -34,11 +35,13 @@ pub mod util; #[derive(Debug)] pub enum DeviceConfig { BlockCfg(BlockConfig), + BlockCfgModern(BlockConfigModern), VhostUserBlkCfg(VhostUserConfig), NetworkCfg(NetworkConfig), VhostUserNetworkCfg(VhostUserConfig), ShareFsCfg(ShareFsConfig), VfioCfg(VfioConfig), + VfioModernCfg(VfioDeviceBase), VsockCfg(VsockConfig), HybridVsockCfg(HybridVsockConfig), ProtectionDevCfg(ProtectionDeviceConfig),