mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
pci: Allow for registering IO and Memory BAR
This patch adds the support for both IO and Memory BARs by expecting the function allocate_bars() to identify the type of each BAR. Based on the type, register_mapping() insert the address range on the appropriate bus (PIO or MMIO). Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
+21
-6
@@ -2,7 +2,9 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE-BSD-3-Clause file.
|
// found in the LICENSE-BSD-3-Clause file.
|
||||||
|
|
||||||
use crate::configuration::{PciBridgeSubclass, PciClassCode, PciConfiguration, PciHeaderType};
|
use crate::configuration::{
|
||||||
|
PciBarRegionType, PciBridgeSubclass, PciClassCode, PciConfiguration, PciHeaderType,
|
||||||
|
};
|
||||||
use crate::device::{Error as PciDeviceError, PciDevice};
|
use crate::device::{Error as PciDeviceError, PciDevice};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use devices::BusDevice;
|
use devices::BusDevice;
|
||||||
@@ -21,6 +23,8 @@ pub enum PciRootError {
|
|||||||
AllocateDeviceAddrs(PciDeviceError),
|
AllocateDeviceAddrs(PciDeviceError),
|
||||||
/// Could not allocate an IRQ number.
|
/// Could not allocate an IRQ number.
|
||||||
AllocateIrq,
|
AllocateIrq,
|
||||||
|
/// Could not add a device to the port io bus.
|
||||||
|
PioInsert(devices::BusError),
|
||||||
/// Could not add a device to the mmio bus.
|
/// Could not add a device to the mmio bus.
|
||||||
MmioInsert(devices::BusError),
|
MmioInsert(devices::BusError),
|
||||||
}
|
}
|
||||||
@@ -89,12 +93,23 @@ impl PciConfigIo {
|
|||||||
pub fn register_mapping(
|
pub fn register_mapping(
|
||||||
&self,
|
&self,
|
||||||
dev: Arc<Mutex<dyn BusDevice>>,
|
dev: Arc<Mutex<dyn BusDevice>>,
|
||||||
bus: &mut devices::Bus,
|
io_bus: &mut devices::Bus,
|
||||||
bars: Vec<(GuestAddress, GuestUsize)>,
|
mmio_bus: &mut devices::Bus,
|
||||||
|
bars: Vec<(GuestAddress, GuestUsize, PciBarRegionType)>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
for (address, size) in bars {
|
for (address, size, type_) in bars {
|
||||||
bus.insert(dev.clone(), address.raw_value(), size)
|
match type_ {
|
||||||
.map_err(PciRootError::MmioInsert)?;
|
PciBarRegionType::IORegion => {
|
||||||
|
io_bus
|
||||||
|
.insert(dev.clone(), address.raw_value(), size)
|
||||||
|
.map_err(PciRootError::PioInsert)?;
|
||||||
|
}
|
||||||
|
PciBarRegionType::Memory32BitRegion | PciBarRegionType::Memory64BitRegion => {
|
||||||
|
mmio_bus
|
||||||
|
.insert(dev.clone(), address.raw_value(), size)
|
||||||
|
.map_err(PciRootError::MmioInsert)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE-BSD-3-Clause file.
|
// found in the LICENSE-BSD-3-Clause file.
|
||||||
|
|
||||||
use crate::configuration;
|
use crate::configuration::{self, PciBarRegionType};
|
||||||
use crate::msix::MsixTableEntry;
|
use crate::msix::MsixTableEntry;
|
||||||
use crate::PciInterruptPin;
|
use crate::PciInterruptPin;
|
||||||
use devices::BusDevice;
|
use devices::BusDevice;
|
||||||
@@ -66,7 +66,7 @@ pub trait PciDevice: BusDevice {
|
|||||||
fn allocate_bars(
|
fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
_allocator: &mut SystemAllocator,
|
_allocator: &mut SystemAllocator,
|
||||||
) -> Result<Vec<(GuestAddress, GuestUsize)>> {
|
) -> Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>> {
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ use std::sync::Mutex;
|
|||||||
use devices::BusDevice;
|
use devices::BusDevice;
|
||||||
use pci::{
|
use pci::{
|
||||||
InterruptDelivery, InterruptParameters, MsixCap, MsixConfig, PciBarConfiguration,
|
InterruptDelivery, InterruptParameters, MsixCap, MsixConfig, PciBarConfiguration,
|
||||||
PciCapability, PciCapabilityID, PciClassCode, PciConfiguration, PciDevice, PciDeviceError,
|
PciBarRegionType, PciCapability, PciCapabilityID, PciClassCode, PciConfiguration, PciDevice,
|
||||||
PciHeaderType, PciInterruptPin, PciMassStorageSubclass, PciNetworkControllerSubclass,
|
PciDeviceError, PciHeaderType, PciInterruptPin, PciMassStorageSubclass,
|
||||||
PciSubclass,
|
PciNetworkControllerSubclass, PciSubclass,
|
||||||
};
|
};
|
||||||
use vm_allocator::SystemAllocator;
|
use vm_allocator::SystemAllocator;
|
||||||
use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap, GuestUsize, Le32};
|
use vm_memory::{Address, ByteValued, GuestAddress, GuestMemoryMmap, GuestUsize, Le32};
|
||||||
@@ -444,7 +444,8 @@ impl PciDevice for VirtioPciDevice {
|
|||||||
fn allocate_bars(
|
fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &mut SystemAllocator,
|
allocator: &mut SystemAllocator,
|
||||||
) -> std::result::Result<Vec<(GuestAddress, GuestUsize)>, PciDeviceError> {
|
) -> std::result::Result<Vec<(GuestAddress, GuestUsize, PciBarRegionType)>, PciDeviceError>
|
||||||
|
{
|
||||||
let mut ranges = Vec::new();
|
let mut ranges = Vec::new();
|
||||||
|
|
||||||
// Allocate the virtio-pci capability BAR.
|
// Allocate the virtio-pci capability BAR.
|
||||||
@@ -461,7 +462,11 @@ impl PciDevice for VirtioPciDevice {
|
|||||||
PciDeviceError::IoRegistrationFailed(virtio_pci_bar_addr.raw_value(), e)
|
PciDeviceError::IoRegistrationFailed(virtio_pci_bar_addr.raw_value(), e)
|
||||||
})? as u8;
|
})? as u8;
|
||||||
|
|
||||||
ranges.push((virtio_pci_bar_addr, CAPABILITY_BAR_SIZE));
|
ranges.push((
|
||||||
|
virtio_pci_bar_addr,
|
||||||
|
CAPABILITY_BAR_SIZE,
|
||||||
|
PciBarRegionType::Memory64BitRegion,
|
||||||
|
));
|
||||||
|
|
||||||
// Once the BARs are allocated, the capabilities can be added to the PCI configuration.
|
// Once the BARs are allocated, the capabilities can be added to the PCI configuration.
|
||||||
self.add_pci_capabilities(virtio_pci_bar)?;
|
self.add_pci_capabilities(virtio_pci_bar)?;
|
||||||
@@ -475,7 +480,11 @@ impl PciDevice for VirtioPciDevice {
|
|||||||
let _device_bar = self.configuration.add_pci_bar(&config).map_err(|e| {
|
let _device_bar = self.configuration.add_pci_bar(&config).map_err(|e| {
|
||||||
PciDeviceError::IoRegistrationFailed(device_bar_addr.raw_value(), e)
|
PciDeviceError::IoRegistrationFailed(device_bar_addr.raw_value(), e)
|
||||||
})?;
|
})?;
|
||||||
ranges.push((device_bar_addr, config.get_size()));
|
ranges.push((
|
||||||
|
device_bar_addr,
|
||||||
|
config.get_size(),
|
||||||
|
PciBarRegionType::Memory64BitRegion,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(ranges)
|
Ok(ranges)
|
||||||
|
|||||||
+24
-9
@@ -414,6 +414,11 @@ impl Vcpu {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BusInfo<'a> {
|
||||||
|
io: &'a mut devices::Bus,
|
||||||
|
mmio: &'a mut devices::Bus,
|
||||||
|
}
|
||||||
|
|
||||||
struct InterruptInfo<'a> {
|
struct InterruptInfo<'a> {
|
||||||
msi_capable: bool,
|
msi_capable: bool,
|
||||||
ioapic: &'a Option<Arc<Mutex<ioapic::Ioapic>>>,
|
ioapic: &'a Option<Arc<Mutex<ioapic::Ioapic>>>,
|
||||||
@@ -488,9 +493,14 @@ impl DeviceManager {
|
|||||||
msi_capable: bool,
|
msi_capable: bool,
|
||||||
userspace_ioapic: bool,
|
userspace_ioapic: bool,
|
||||||
) -> DeviceManagerResult<Self> {
|
) -> DeviceManagerResult<Self> {
|
||||||
let io_bus = devices::Bus::new();
|
let mut io_bus = devices::Bus::new();
|
||||||
let mut mmio_bus = devices::Bus::new();
|
let mut mmio_bus = devices::Bus::new();
|
||||||
|
|
||||||
|
let mut buses = BusInfo {
|
||||||
|
io: &mut io_bus,
|
||||||
|
mmio: &mut mmio_bus,
|
||||||
|
};
|
||||||
|
|
||||||
let ioapic = if userspace_ioapic {
|
let ioapic = if userspace_ioapic {
|
||||||
// Create IOAPIC
|
// Create IOAPIC
|
||||||
Some(Arc::new(Mutex::new(ioapic::Ioapic::new(vm_fd.clone()))))
|
Some(Arc::new(Mutex::new(ioapic::Ioapic::new(vm_fd.clone()))))
|
||||||
@@ -578,7 +588,7 @@ impl DeviceManager {
|
|||||||
allocator,
|
allocator,
|
||||||
vm_fd,
|
vm_fd,
|
||||||
&mut pci,
|
&mut pci,
|
||||||
&mut mmio_bus,
|
&mut buses,
|
||||||
&interrupt_info,
|
&interrupt_info,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@@ -605,7 +615,7 @@ impl DeviceManager {
|
|||||||
allocator,
|
allocator,
|
||||||
vm_fd,
|
vm_fd,
|
||||||
&mut pci,
|
&mut pci,
|
||||||
&mut mmio_bus,
|
&mut buses,
|
||||||
&interrupt_info,
|
&interrupt_info,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@@ -622,7 +632,7 @@ impl DeviceManager {
|
|||||||
allocator,
|
allocator,
|
||||||
vm_fd,
|
vm_fd,
|
||||||
&mut pci,
|
&mut pci,
|
||||||
&mut mmio_bus,
|
&mut buses,
|
||||||
&interrupt_info,
|
&interrupt_info,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@@ -645,7 +655,7 @@ impl DeviceManager {
|
|||||||
allocator,
|
allocator,
|
||||||
vm_fd,
|
vm_fd,
|
||||||
&mut pci,
|
&mut pci,
|
||||||
&mut mmio_bus,
|
&mut buses,
|
||||||
&interrupt_info,
|
&interrupt_info,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@@ -710,7 +720,7 @@ impl DeviceManager {
|
|||||||
allocator,
|
allocator,
|
||||||
vm_fd,
|
vm_fd,
|
||||||
&mut pci,
|
&mut pci,
|
||||||
&mut mmio_bus,
|
&mut buses,
|
||||||
&interrupt_info,
|
&interrupt_info,
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
@@ -735,7 +745,7 @@ impl DeviceManager {
|
|||||||
allocator: &mut SystemAllocator,
|
allocator: &mut SystemAllocator,
|
||||||
vm_fd: &Arc<VmFd>,
|
vm_fd: &Arc<VmFd>,
|
||||||
pci: &mut PciConfigIo,
|
pci: &mut PciConfigIo,
|
||||||
mmio_bus: &mut devices::Bus,
|
buses: &mut BusInfo,
|
||||||
interrupt_info: &InterruptInfo,
|
interrupt_info: &InterruptInfo,
|
||||||
) -> DeviceManagerResult<()> {
|
) -> DeviceManagerResult<()> {
|
||||||
let msix_num = if interrupt_info.msi_capable {
|
let msix_num = if interrupt_info.msi_capable {
|
||||||
@@ -828,8 +838,13 @@ impl DeviceManager {
|
|||||||
pci.add_device(virtio_pci_device.clone())
|
pci.add_device(virtio_pci_device.clone())
|
||||||
.map_err(DeviceManagerError::AddPciDevice)?;
|
.map_err(DeviceManagerError::AddPciDevice)?;
|
||||||
|
|
||||||
pci.register_mapping(virtio_pci_device.clone(), mmio_bus, bars)
|
pci.register_mapping(
|
||||||
.map_err(DeviceManagerError::AddPciDevice)?;
|
virtio_pci_device.clone(),
|
||||||
|
&mut buses.io,
|
||||||
|
&mut buses.mmio,
|
||||||
|
bars,
|
||||||
|
)
|
||||||
|
.map_err(DeviceManagerError::AddPciDevice)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user