MCPcopy Create free account
hub / github.com/cloud-hypervisor/cloud-hypervisor / eject_device

Method eject_device

vmm/src/device_manager.rs:4779–5010  ·  view source on GitHub ↗
(&mut self, pci_segment_id: u16, device_id: u8)

Source from the content-addressed store, hash-verified

4777 }
4778
4779 pub fn eject_device(&mut self, pci_segment_id: u16, device_id: u8) -> DeviceManagerResult<()> {
4780 info!("Ejecting device_id = {device_id} on segment_id={pci_segment_id}");
4781
4782 // Convert the device ID into the corresponding b/d/f.
4783 let pci_device_bdf = PciBdf::new(pci_segment_id, 0, device_id, 0);
4784
4785 // Give the PCI device ID back to the PCI bus.
4786 self.pci_segments[pci_segment_id as usize]
4787 .pci_bus
4788 .lock()
4789 .unwrap()
4790 .free_device_id(device_id)
4791 .map_err(DeviceManagerError::FreePciDeviceId)?;
4792
4793 let (pci_device_handle, id) = {
4794 // Remove the device from the device tree along with its children.
4795 let mut device_tree = self.device_tree.lock().unwrap();
4796 let pci_device_node = device_tree
4797 .remove_node_by_pci_bdf(pci_device_bdf)
4798 .ok_or(DeviceManagerError::MissingPciDevice)?;
4799
4800 // For VFIO and vfio-user the PCI device id is the id.
4801 // For virtio we overwrite it later as we want the id of the
4802 // underlying device.
4803 let mut id = pci_device_node.id;
4804 let pci_device_handle = pci_device_node
4805 .pci_device_handle
4806 .ok_or(DeviceManagerError::MissingPciDevice)?;
4807 if matches!(pci_device_handle, PciDeviceHandle::Virtio(_)) {
4808 // The virtio-pci device has a single child
4809 if !pci_device_node.children.is_empty() {
4810 assert_eq!(pci_device_node.children.len(), 1);
4811 let child_id = &pci_device_node.children[0];
4812 id.clone_from(child_id);
4813 }
4814 }
4815 for child in pci_device_node.children.iter() {
4816 device_tree.remove(child);
4817 }
4818
4819 (pci_device_handle, id)
4820 };
4821
4822 let mut iommu_attached = false;
4823 if let Some((_, iommu_attached_devices)) = &self.iommu_attached_devices
4824 && iommu_attached_devices.contains(&pci_device_bdf)
4825 {
4826 iommu_attached = true;
4827 }
4828
4829 let (pci_device, bus_device, virtio_device, remove_dma_handler) = match pci_device_handle {
4830 // VirtioMemMappingSource::Container cleanup is handled by
4831 // cleanup_vfio_ops when the last VFIO device is removed.
4832 PciDeviceHandle::Vfio(vfio_pci_device) => {
4833 // Remove this device's MMIO regions from the DeviceManager's
4834 // mmio_regions list. We match on UserMemoryRegion slot numbers
4835 // rather than MmioRegion start addresses because move_bar()
4836 // updates the device's region addresses but not the

Callers 1

writeMethod · 0.80

Calls 15

newFunction · 0.85
free_device_idMethod · 0.80
iterMethod · 0.80
containsMethod · 0.80
mmio_regionsMethod · 0.80
has_matching_slotsMethod · 0.80
ioeventfdsMethod · 0.80
dma_handlerMethod · 0.80
memory_zonesMethod · 0.80
start_addrMethod · 0.80
virtio_deviceMethod · 0.80

Tested by

no test coverage detected