mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-04 04:25:45 +00:00
vmm: Provide a common method to build a virtio PCI device
Since more virtio devices will be added and this code can be reused for any type of virtio device. Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com>
This commit is contained in:
parent
c0be6642ad
commit
97865b605f
109
vmm/src/vm.rs
109
vmm/src/vm.rs
@ -328,34 +328,15 @@ impl DeviceManager {
|
|||||||
// Add virtio-blk
|
// Add virtio-blk
|
||||||
let virtio_block_device =
|
let virtio_block_device =
|
||||||
vm_virtio::Block::new(raw_img, false).map_err(Error::CreateVirtioBlock)?;
|
vm_virtio::Block::new(raw_img, false).map_err(Error::CreateVirtioBlock)?;
|
||||||
let virtio_block_device = Box::new(virtio_block_device);
|
|
||||||
let mut virtio_pci_device = VirtioPciDevice::new(memory.clone(), virtio_block_device)
|
|
||||||
.map_err(|_| Error::VirtioDevice)?;
|
|
||||||
let bars = virtio_pci_device
|
|
||||||
.allocate_bars(allocator)
|
|
||||||
.map_err(Error::AllocateBars)?;
|
|
||||||
|
|
||||||
for (event, addr, _) in virtio_pci_device.ioeventfds() {
|
DeviceManager::add_virtio_pci_device(
|
||||||
let io_addr = IoEventAddress::Mmio(addr);
|
Box::new(virtio_block_device),
|
||||||
vm_fd
|
memory.clone(),
|
||||||
.register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)
|
allocator,
|
||||||
.map_err(Error::RegisterIoevent)?;
|
vm_fd,
|
||||||
}
|
&mut pci_root,
|
||||||
|
&mut mmio_bus,
|
||||||
// Assign IRQ to the virtio-blk device
|
)?;
|
||||||
let irqfd = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFd)?;
|
|
||||||
let irq_num = allocator.allocate_irq().ok_or(Error::AllocateIrq)?;
|
|
||||||
vm_fd
|
|
||||||
.register_irqfd(irqfd.as_raw_fd(), irq_num)
|
|
||||||
.map_err(Error::Irq)?;
|
|
||||||
// Let's use irq line INTA for now.
|
|
||||||
virtio_pci_device.assign_irq(irqfd, irq_num as u32, PciInterruptPin::IntA);
|
|
||||||
|
|
||||||
let virtio_pci_device = Arc::new(Mutex::new(virtio_pci_device));
|
|
||||||
|
|
||||||
pci_root
|
|
||||||
.add_device(virtio_pci_device.clone(), &mut mmio_bus, bars)
|
|
||||||
.map_err(Error::AddPciDevice)?;
|
|
||||||
|
|
||||||
// Add virtio-net if required
|
// Add virtio-net if required
|
||||||
if let Some(net_params) = &vm_cfg.net_params {
|
if let Some(net_params) = &vm_cfg.net_params {
|
||||||
@ -364,34 +345,15 @@ impl DeviceManager {
|
|||||||
let tap = Tap::open_named(tap_if_name).unwrap();
|
let tap = Tap::open_named(tap_if_name).unwrap();
|
||||||
let virtio_net_device = vm_virtio::Net::new_with_tap(tap, Some(&mac))
|
let virtio_net_device = vm_virtio::Net::new_with_tap(tap, Some(&mac))
|
||||||
.map_err(Error::CreateVirtioNet)?;
|
.map_err(Error::CreateVirtioNet)?;
|
||||||
let virtio_net_device = Box::new(virtio_net_device);
|
|
||||||
let mut virtio_pci_device = VirtioPciDevice::new(memory.clone(), virtio_net_device)
|
|
||||||
.map_err(|_| Error::VirtioDevice)?;
|
|
||||||
let bars = virtio_pci_device
|
|
||||||
.allocate_bars(allocator)
|
|
||||||
.map_err(Error::AllocateBars)?;
|
|
||||||
|
|
||||||
for (event, addr, _) in virtio_pci_device.ioeventfds() {
|
DeviceManager::add_virtio_pci_device(
|
||||||
let io_addr = IoEventAddress::Mmio(addr);
|
Box::new(virtio_net_device),
|
||||||
vm_fd
|
memory.clone(),
|
||||||
.register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)
|
allocator,
|
||||||
.map_err(Error::RegisterIoevent)?;
|
vm_fd,
|
||||||
}
|
&mut pci_root,
|
||||||
|
&mut mmio_bus,
|
||||||
// Assign IRQ to the virtio-blk device
|
)?;
|
||||||
let irqfd = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFd)?;
|
|
||||||
let irq_num = allocator.allocate_irq().ok_or(Error::AllocateIrq)?;
|
|
||||||
vm_fd
|
|
||||||
.register_irqfd(irqfd.as_raw_fd(), irq_num)
|
|
||||||
.map_err(Error::Irq)?;
|
|
||||||
// Let's use irq line INTA for now.
|
|
||||||
virtio_pci_device.assign_irq(irqfd, irq_num as u32, PciInterruptPin::IntA);
|
|
||||||
|
|
||||||
let virtio_pci_device = Arc::new(Mutex::new(virtio_pci_device));
|
|
||||||
|
|
||||||
pci_root
|
|
||||||
.add_device(virtio_pci_device.clone(), &mut mmio_bus, bars)
|
|
||||||
.map_err(Error::AddPciDevice)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -408,6 +370,45 @@ impl DeviceManager {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn add_virtio_pci_device(
|
||||||
|
virtio_device: Box<vm_virtio::VirtioDevice>,
|
||||||
|
memory: GuestMemoryMmap,
|
||||||
|
allocator: &mut SystemAllocator,
|
||||||
|
vm_fd: &VmFd,
|
||||||
|
pci_root: &mut PciRoot,
|
||||||
|
mmio_bus: &mut devices::Bus,
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut virtio_pci_device =
|
||||||
|
VirtioPciDevice::new(memory, virtio_device).map_err(|_| Error::VirtioDevice)?;
|
||||||
|
let bars = virtio_pci_device
|
||||||
|
.allocate_bars(allocator)
|
||||||
|
.map_err(Error::AllocateBars)?;
|
||||||
|
|
||||||
|
for (event, addr, _) in virtio_pci_device.ioeventfds() {
|
||||||
|
let io_addr = IoEventAddress::Mmio(addr);
|
||||||
|
vm_fd
|
||||||
|
.register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)
|
||||||
|
.map_err(Error::RegisterIoevent)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Assign IRQ to the virtio-pci device
|
||||||
|
let irqfd = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFd)?;
|
||||||
|
let irq_num = allocator.allocate_irq().ok_or(Error::AllocateIrq)?;
|
||||||
|
vm_fd
|
||||||
|
.register_irqfd(irqfd.as_raw_fd(), irq_num)
|
||||||
|
.map_err(Error::Irq)?;
|
||||||
|
// Let's use irq line INTA for now.
|
||||||
|
virtio_pci_device.assign_irq(irqfd, irq_num as u32, PciInterruptPin::IntA);
|
||||||
|
|
||||||
|
let virtio_pci_device = Arc::new(Mutex::new(virtio_pci_device));
|
||||||
|
|
||||||
|
pci_root
|
||||||
|
.add_device(virtio_pci_device.clone(), mmio_bus, bars)
|
||||||
|
.map_err(Error::AddPciDevice)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn register_devices(&mut self) -> Result<()> {
|
pub fn register_devices(&mut self) -> Result<()> {
|
||||||
// Insert serial device
|
// Insert serial device
|
||||||
self.io_bus
|
self.io_bus
|
||||||
|
Loading…
Reference in New Issue
Block a user