mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-12-22 13:45:20 +00:00
vmm: assign each pci segment 32-bit mmio allocator
Signed-off-by: Thomas Barrett <tbarrett@crusoeenergy.com>
This commit is contained in:
parent
ef16ee37d9
commit
45b01d592a
@ -181,8 +181,9 @@ impl PciDevice for PvPanicDevice {
|
|||||||
|
|
||||||
fn allocate_bars(
|
fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &Arc<Mutex<SystemAllocator>>,
|
_allocator: &Arc<Mutex<SystemAllocator>>,
|
||||||
_mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
_mmio64_allocator: &mut AddressAllocator,
|
||||||
resources: Option<Vec<Resource>>,
|
resources: Option<Vec<Resource>>,
|
||||||
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
||||||
let mut bars = Vec::new();
|
let mut bars = Vec::new();
|
||||||
@ -190,10 +191,8 @@ impl PciDevice for PvPanicDevice {
|
|||||||
let bar_id = 0;
|
let bar_id = 0;
|
||||||
let region_size = PVPANIC_DEVICE_MMIO_SIZE;
|
let region_size = PVPANIC_DEVICE_MMIO_SIZE;
|
||||||
let restoring = resources.is_some();
|
let restoring = resources.is_some();
|
||||||
let bar_addr = allocator
|
let bar_addr = mmio32_allocator
|
||||||
.lock()
|
.allocate(None, region_size, Some(PVPANIC_DEVICE_MMIO_ALIGNMENT))
|
||||||
.unwrap()
|
|
||||||
.allocate_mmio_hole_addresses(None, region_size, Some(PVPANIC_DEVICE_MMIO_ALIGNMENT))
|
|
||||||
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
|
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?;
|
||||||
|
|
||||||
let bar = PciBarConfiguration::default()
|
let bar = PciBarConfiguration::default()
|
||||||
@ -218,11 +217,12 @@ impl PciDevice for PvPanicDevice {
|
|||||||
|
|
||||||
fn free_bars(
|
fn free_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &mut SystemAllocator,
|
_allocator: &mut SystemAllocator,
|
||||||
_mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
_mmio64_allocator: &mut AddressAllocator,
|
||||||
) -> std::result::Result<(), PciDeviceError> {
|
) -> std::result::Result<(), PciDeviceError> {
|
||||||
for bar in self.bar_regions.drain(..) {
|
for bar in self.bar_regions.drain(..) {
|
||||||
allocator.free_mmio_hole_addresses(GuestAddress(bar.addr()), bar.size());
|
mmio32_allocator.free(GuestAddress(bar.addr()), bar.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -58,7 +58,8 @@ pub trait PciDevice: BusDevice {
|
|||||||
fn allocate_bars(
|
fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
_allocator: &Arc<Mutex<SystemAllocator>>,
|
_allocator: &Arc<Mutex<SystemAllocator>>,
|
||||||
_mmio_allocator: &mut AddressAllocator,
|
_mmio32_allocator: &mut AddressAllocator,
|
||||||
|
_mmio64_allocator: &mut AddressAllocator,
|
||||||
_resources: Option<Vec<Resource>>,
|
_resources: Option<Vec<Resource>>,
|
||||||
) -> Result<Vec<PciBarConfiguration>> {
|
) -> Result<Vec<PciBarConfiguration>> {
|
||||||
Ok(Vec::new())
|
Ok(Vec::new())
|
||||||
@ -68,7 +69,8 @@ pub trait PciDevice: BusDevice {
|
|||||||
fn free_bars(
|
fn free_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
_allocator: &mut SystemAllocator,
|
_allocator: &mut SystemAllocator,
|
||||||
_mmio_allocator: &mut AddressAllocator,
|
_mmio32_allocator: &mut AddressAllocator,
|
||||||
|
_mmio64_allocator: &mut AddressAllocator,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -529,10 +529,13 @@ impl VfioCommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The `allocator` argument is unused on `aarch64`
|
||||||
|
#[allow(unused_variables)]
|
||||||
pub(crate) fn allocate_bars(
|
pub(crate) fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &Arc<Mutex<SystemAllocator>>,
|
allocator: &Arc<Mutex<SystemAllocator>>,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
resources: Option<Vec<Resource>>,
|
resources: Option<Vec<Resource>>,
|
||||||
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
||||||
let mut bars = Vec::new();
|
let mut bars = Vec::new();
|
||||||
@ -681,21 +684,15 @@ impl VfioCommon {
|
|||||||
}
|
}
|
||||||
PciBarRegionType::Memory32BitRegion => {
|
PciBarRegionType::Memory32BitRegion => {
|
||||||
// BAR allocation must be naturally aligned
|
// BAR allocation must be naturally aligned
|
||||||
allocator
|
mmio32_allocator
|
||||||
.lock()
|
.allocate(restored_bar_addr, region_size, Some(region_size))
|
||||||
.unwrap()
|
|
||||||
.allocate_mmio_hole_addresses(
|
|
||||||
restored_bar_addr,
|
|
||||||
region_size,
|
|
||||||
Some(region_size),
|
|
||||||
)
|
|
||||||
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?
|
.ok_or(PciDeviceError::IoAllocationFailed(region_size))?
|
||||||
}
|
}
|
||||||
PciBarRegionType::Memory64BitRegion => {
|
PciBarRegionType::Memory64BitRegion => {
|
||||||
// We need do some fixup to keep MMIO RW region and msix cap region page size
|
// We need do some fixup to keep MMIO RW region and msix cap region page size
|
||||||
// aligned.
|
// aligned.
|
||||||
region_size = self.fixup_msix_region(bar_id, region_size);
|
region_size = self.fixup_msix_region(bar_id, region_size);
|
||||||
mmio_allocator
|
mmio64_allocator
|
||||||
.allocate(
|
.allocate(
|
||||||
restored_bar_addr,
|
restored_bar_addr,
|
||||||
region_size,
|
region_size,
|
||||||
@ -742,10 +739,13 @@ impl VfioCommon {
|
|||||||
Ok(bars)
|
Ok(bars)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The `allocator` argument is unused on `aarch64`
|
||||||
|
#[allow(unused_variables)]
|
||||||
pub(crate) fn free_bars(
|
pub(crate) fn free_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &mut SystemAllocator,
|
allocator: &mut SystemAllocator,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
) -> Result<(), PciDeviceError> {
|
) -> Result<(), PciDeviceError> {
|
||||||
for region in self.mmio_regions.iter() {
|
for region in self.mmio_regions.iter() {
|
||||||
match region.type_ {
|
match region.type_ {
|
||||||
@ -756,10 +756,10 @@ impl VfioCommon {
|
|||||||
error!("I/O region is not supported");
|
error!("I/O region is not supported");
|
||||||
}
|
}
|
||||||
PciBarRegionType::Memory32BitRegion => {
|
PciBarRegionType::Memory32BitRegion => {
|
||||||
allocator.free_mmio_hole_addresses(region.start, region.length);
|
mmio32_allocator.free(region.start, region.length);
|
||||||
}
|
}
|
||||||
PciBarRegionType::Memory64BitRegion => {
|
PciBarRegionType::Memory64BitRegion => {
|
||||||
mmio_allocator.free(region.start, region.length);
|
mmio64_allocator.free(region.start, region.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1694,19 +1694,22 @@ impl PciDevice for VfioPciDevice {
|
|||||||
fn allocate_bars(
|
fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &Arc<Mutex<SystemAllocator>>,
|
allocator: &Arc<Mutex<SystemAllocator>>,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
resources: Option<Vec<Resource>>,
|
resources: Option<Vec<Resource>>,
|
||||||
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
||||||
self.common
|
self.common
|
||||||
.allocate_bars(allocator, mmio_allocator, resources)
|
.allocate_bars(allocator, mmio32_allocator, mmio64_allocator, resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn free_bars(
|
fn free_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &mut SystemAllocator,
|
allocator: &mut SystemAllocator,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
) -> Result<(), PciDeviceError> {
|
) -> Result<(), PciDeviceError> {
|
||||||
self.common.free_bars(allocator, mmio_allocator)
|
self.common
|
||||||
|
.free_bars(allocator, mmio32_allocator, mmio64_allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_config_register(
|
fn write_config_register(
|
||||||
|
@ -397,19 +397,22 @@ impl PciDevice for VfioUserPciDevice {
|
|||||||
fn allocate_bars(
|
fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &Arc<Mutex<SystemAllocator>>,
|
allocator: &Arc<Mutex<SystemAllocator>>,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
resources: Option<Vec<Resource>>,
|
resources: Option<Vec<Resource>>,
|
||||||
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
) -> Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
||||||
self.common
|
self.common
|
||||||
.allocate_bars(allocator, mmio_allocator, resources)
|
.allocate_bars(allocator, mmio32_allocator, mmio64_allocator, resources)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn free_bars(
|
fn free_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &mut SystemAllocator,
|
allocator: &mut SystemAllocator,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
) -> Result<(), PciDeviceError> {
|
) -> Result<(), PciDeviceError> {
|
||||||
self.common.free_bars(allocator, mmio_allocator)
|
self.common
|
||||||
|
.free_bars(allocator, mmio32_allocator, mmio64_allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn as_any(&mut self) -> &mut dyn Any {
|
fn as_any(&mut self) -> &mut dyn Any {
|
||||||
|
@ -955,8 +955,9 @@ impl PciDevice for VirtioPciDevice {
|
|||||||
|
|
||||||
fn allocate_bars(
|
fn allocate_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &Arc<Mutex<SystemAllocator>>,
|
_allocator: &Arc<Mutex<SystemAllocator>>,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
resources: Option<Vec<Resource>>,
|
resources: Option<Vec<Resource>>,
|
||||||
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
|
||||||
let mut bars = Vec::new();
|
let mut bars = Vec::new();
|
||||||
@ -995,7 +996,7 @@ impl PciDevice for VirtioPciDevice {
|
|||||||
// See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004
|
// See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004
|
||||||
let (virtio_pci_bar_addr, region_type) = if use_64bit_bar {
|
let (virtio_pci_bar_addr, region_type) = if use_64bit_bar {
|
||||||
let region_type = PciBarRegionType::Memory64BitRegion;
|
let region_type = PciBarRegionType::Memory64BitRegion;
|
||||||
let addr = mmio_allocator
|
let addr = mmio64_allocator
|
||||||
.allocate(
|
.allocate(
|
||||||
settings_bar_addr,
|
settings_bar_addr,
|
||||||
CAPABILITY_BAR_SIZE,
|
CAPABILITY_BAR_SIZE,
|
||||||
@ -1005,10 +1006,8 @@ impl PciDevice for VirtioPciDevice {
|
|||||||
(addr, region_type)
|
(addr, region_type)
|
||||||
} else {
|
} else {
|
||||||
let region_type = PciBarRegionType::Memory32BitRegion;
|
let region_type = PciBarRegionType::Memory32BitRegion;
|
||||||
let addr = allocator
|
let addr = mmio32_allocator
|
||||||
.lock()
|
.allocate(
|
||||||
.unwrap()
|
|
||||||
.allocate_mmio_hole_addresses(
|
|
||||||
settings_bar_addr,
|
settings_bar_addr,
|
||||||
CAPABILITY_BAR_SIZE,
|
CAPABILITY_BAR_SIZE,
|
||||||
Some(CAPABILITY_BAR_SIZE),
|
Some(CAPABILITY_BAR_SIZE),
|
||||||
@ -1078,16 +1077,17 @@ impl PciDevice for VirtioPciDevice {
|
|||||||
|
|
||||||
fn free_bars(
|
fn free_bars(
|
||||||
&mut self,
|
&mut self,
|
||||||
allocator: &mut SystemAllocator,
|
_allocator: &mut SystemAllocator,
|
||||||
mmio_allocator: &mut AddressAllocator,
|
mmio32_allocator: &mut AddressAllocator,
|
||||||
|
mmio64_allocator: &mut AddressAllocator,
|
||||||
) -> std::result::Result<(), PciDeviceError> {
|
) -> std::result::Result<(), PciDeviceError> {
|
||||||
for bar in self.bar_regions.drain(..) {
|
for bar in self.bar_regions.drain(..) {
|
||||||
match bar.region_type() {
|
match bar.region_type() {
|
||||||
PciBarRegionType::Memory32BitRegion => {
|
PciBarRegionType::Memory32BitRegion => {
|
||||||
allocator.free_mmio_hole_addresses(GuestAddress(bar.addr()), bar.size());
|
mmio32_allocator.free(GuestAddress(bar.addr()), bar.size());
|
||||||
}
|
}
|
||||||
PciBarRegionType::Memory64BitRegion => {
|
PciBarRegionType::Memory64BitRegion => {
|
||||||
mmio_allocator.free(GuestAddress(bar.addr()), bar.size());
|
mmio64_allocator.free(GuestAddress(bar.addr()), bar.size());
|
||||||
}
|
}
|
||||||
_ => error!("Unexpected PCI bar type"),
|
_ => error!("Unexpected PCI bar type"),
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ use crate::page_size::get_page_size;
|
|||||||
/// #[cfg(target_arch = "x86_64")] GuestAddress(0x1000),
|
/// #[cfg(target_arch = "x86_64")] GuestAddress(0x1000),
|
||||||
/// #[cfg(target_arch = "x86_64")] 0x10000,
|
/// #[cfg(target_arch = "x86_64")] 0x10000,
|
||||||
/// GuestAddress(0x10000000), 0x10000000,
|
/// GuestAddress(0x10000000), 0x10000000,
|
||||||
/// GuestAddress(0x20000000), 0x100000,
|
|
||||||
/// #[cfg(target_arch = "x86_64")] vec![GsiApic::new(5, 19)]).unwrap();
|
/// #[cfg(target_arch = "x86_64")] vec![GsiApic::new(5, 19)]).unwrap();
|
||||||
/// #[cfg(target_arch = "x86_64")]
|
/// #[cfg(target_arch = "x86_64")]
|
||||||
/// assert_eq!(allocator.allocate_irq(), Some(5));
|
/// assert_eq!(allocator.allocate_irq(), Some(5));
|
||||||
@ -47,7 +46,6 @@ pub struct SystemAllocator {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
io_address_space: AddressAllocator,
|
io_address_space: AddressAllocator,
|
||||||
platform_mmio_address_space: AddressAllocator,
|
platform_mmio_address_space: AddressAllocator,
|
||||||
mmio_hole_address_space: AddressAllocator,
|
|
||||||
gsi_allocator: GsiAllocator,
|
gsi_allocator: GsiAllocator,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +57,6 @@ impl SystemAllocator {
|
|||||||
/// * `io_size` - (X86) The size of IO memory.
|
/// * `io_size` - (X86) The size of IO memory.
|
||||||
/// * `platform_mmio_base` - The starting address of platform MMIO memory.
|
/// * `platform_mmio_base` - The starting address of platform MMIO memory.
|
||||||
/// * `platform_mmio_size` - The size of platform MMIO memory.
|
/// * `platform_mmio_size` - The size of platform MMIO memory.
|
||||||
/// * `mmio_hole_base` - The starting address of MMIO memory in 32-bit address space.
|
|
||||||
/// * `mmio_hole_size` - The size of MMIO memory in 32-bit address space.
|
|
||||||
/// * `apics` - (X86) Vector of APIC's.
|
/// * `apics` - (X86) Vector of APIC's.
|
||||||
///
|
///
|
||||||
pub fn new(
|
pub fn new(
|
||||||
@ -68,8 +64,6 @@ impl SystemAllocator {
|
|||||||
#[cfg(target_arch = "x86_64")] io_size: GuestUsize,
|
#[cfg(target_arch = "x86_64")] io_size: GuestUsize,
|
||||||
platform_mmio_base: GuestAddress,
|
platform_mmio_base: GuestAddress,
|
||||||
platform_mmio_size: GuestUsize,
|
platform_mmio_size: GuestUsize,
|
||||||
mmio_hole_base: GuestAddress,
|
|
||||||
mmio_hole_size: GuestUsize,
|
|
||||||
#[cfg(target_arch = "x86_64")] apics: Vec<GsiApic>,
|
#[cfg(target_arch = "x86_64")] apics: Vec<GsiApic>,
|
||||||
) -> Option<Self> {
|
) -> Option<Self> {
|
||||||
Some(SystemAllocator {
|
Some(SystemAllocator {
|
||||||
@ -79,7 +73,6 @@ impl SystemAllocator {
|
|||||||
platform_mmio_base,
|
platform_mmio_base,
|
||||||
platform_mmio_size,
|
platform_mmio_size,
|
||||||
)?,
|
)?,
|
||||||
mmio_hole_address_space: AddressAllocator::new(mmio_hole_base, mmio_hole_size)?,
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
gsi_allocator: GsiAllocator::new(apics),
|
gsi_allocator: GsiAllocator::new(apics),
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
@ -123,20 +116,6 @@ impl SystemAllocator {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reserves a section of `size` bytes of MMIO address space.
|
|
||||||
pub fn allocate_mmio_hole_addresses(
|
|
||||||
&mut self,
|
|
||||||
address: Option<GuestAddress>,
|
|
||||||
size: GuestUsize,
|
|
||||||
align_size: Option<GuestUsize>,
|
|
||||||
) -> Option<GuestAddress> {
|
|
||||||
self.mmio_hole_address_space.allocate(
|
|
||||||
address,
|
|
||||||
size,
|
|
||||||
Some(align_size.unwrap_or_else(get_page_size)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
/// Free an IO address range.
|
/// Free an IO address range.
|
||||||
/// We can only free a range if it matches exactly an already allocated range.
|
/// We can only free a range if it matches exactly an already allocated range.
|
||||||
@ -149,10 +128,4 @@ impl SystemAllocator {
|
|||||||
pub fn free_platform_mmio_addresses(&mut self, address: GuestAddress, size: GuestUsize) {
|
pub fn free_platform_mmio_addresses(&mut self, address: GuestAddress, size: GuestUsize) {
|
||||||
self.platform_mmio_address_space.free(address, size)
|
self.platform_mmio_address_space.free(address, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Free an MMIO address range from the 32 bits hole.
|
|
||||||
/// We can only free a range if it matches exactly an already allocated range.
|
|
||||||
pub fn free_mmio_hole_addresses(&mut self, address: GuestAddress, size: GuestUsize) {
|
|
||||||
self.mmio_hole_address_space.free(address, size)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -561,7 +561,8 @@ pub(crate) struct AddressManager {
|
|||||||
pub(crate) mmio_bus: Arc<Bus>,
|
pub(crate) mmio_bus: Arc<Bus>,
|
||||||
pub(crate) vm: Arc<dyn hypervisor::Vm>,
|
pub(crate) vm: Arc<dyn hypervisor::Vm>,
|
||||||
device_tree: Arc<Mutex<DeviceTree>>,
|
device_tree: Arc<Mutex<DeviceTree>>,
|
||||||
pci_mmio_allocators: Vec<Arc<Mutex<AddressAllocator>>>,
|
pci_mmio32_allocators: Vec<Arc<Mutex<AddressAllocator>>>,
|
||||||
|
pci_mmio64_allocators: Vec<Arc<Mutex<AddressAllocator>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DeviceRelocation for AddressManager {
|
impl DeviceRelocation for AddressManager {
|
||||||
@ -604,30 +605,14 @@ impl DeviceRelocation for AddressManager {
|
|||||||
error!("I/O region is not supported");
|
error!("I/O region is not supported");
|
||||||
}
|
}
|
||||||
PciBarRegionType::Memory32BitRegion | PciBarRegionType::Memory64BitRegion => {
|
PciBarRegionType::Memory32BitRegion | PciBarRegionType::Memory64BitRegion => {
|
||||||
// Update system allocator
|
let allocators = if region_type == PciBarRegionType::Memory32BitRegion {
|
||||||
if region_type == PciBarRegionType::Memory32BitRegion {
|
&self.pci_mmio32_allocators
|
||||||
self.allocator
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.free_mmio_hole_addresses(GuestAddress(old_base), len as GuestUsize);
|
|
||||||
|
|
||||||
self.allocator
|
|
||||||
.lock()
|
|
||||||
.unwrap()
|
|
||||||
.allocate_mmio_hole_addresses(
|
|
||||||
Some(GuestAddress(new_base)),
|
|
||||||
len as GuestUsize,
|
|
||||||
Some(len),
|
|
||||||
)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
io::Error::new(
|
|
||||||
io::ErrorKind::Other,
|
|
||||||
"failed allocating new 32 bits MMIO range",
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
} else {
|
} else {
|
||||||
|
&self.pci_mmio64_allocators
|
||||||
|
};
|
||||||
|
|
||||||
// Find the specific allocator that this BAR was allocated from and use it for new one
|
// Find the specific allocator that this BAR was allocated from and use it for new one
|
||||||
for allocator in &self.pci_mmio_allocators {
|
for allocator in allocators {
|
||||||
let allocator_base = allocator.lock().unwrap().base();
|
let allocator_base = allocator.lock().unwrap().base();
|
||||||
let allocator_end = allocator.lock().unwrap().end();
|
let allocator_end = allocator.lock().unwrap().end();
|
||||||
|
|
||||||
@ -640,22 +625,17 @@ impl DeviceRelocation for AddressManager {
|
|||||||
allocator
|
allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate(
|
.allocate(Some(GuestAddress(new_base)), len as GuestUsize, Some(len))
|
||||||
Some(GuestAddress(new_base)),
|
|
||||||
len as GuestUsize,
|
|
||||||
Some(len),
|
|
||||||
)
|
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
io::Error::new(
|
io::Error::new(
|
||||||
io::ErrorKind::Other,
|
io::ErrorKind::Other,
|
||||||
"failed allocating new 64 bits MMIO range",
|
"failed allocating new MMIO range",
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Update MMIO bus
|
// Update MMIO bus
|
||||||
self.mmio_bus
|
self.mmio_bus
|
||||||
@ -1007,23 +987,41 @@ impl DeviceManager {
|
|||||||
1
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
let start_of_device_area = memory_manager.lock().unwrap().start_of_device_area().0;
|
let create_mmio_allocators = |start, end, num_pci_segments, alignment| {
|
||||||
let end_of_device_area = memory_manager.lock().unwrap().end_of_device_area().0;
|
// Start each PCI segment mmio range on an aligned boundary
|
||||||
|
let pci_segment_mmio_size =
|
||||||
|
(end - start + 1) / (alignment * num_pci_segments as u64) * alignment;
|
||||||
|
|
||||||
// Start each PCI segment range on a 4GiB boundary
|
let mut mmio_allocators = vec![];
|
||||||
let pci_segment_size = (end_of_device_area - start_of_device_area + 1)
|
|
||||||
/ ((4 << 30) * num_pci_segments as u64)
|
|
||||||
* (4 << 30);
|
|
||||||
|
|
||||||
let mut pci_mmio_allocators = vec![];
|
|
||||||
for i in 0..num_pci_segments as u64 {
|
for i in 0..num_pci_segments as u64 {
|
||||||
let mmio_start = start_of_device_area + i * pci_segment_size;
|
let mmio_start = start + i * pci_segment_mmio_size;
|
||||||
let allocator = Arc::new(Mutex::new(
|
let allocator = Arc::new(Mutex::new(
|
||||||
AddressAllocator::new(GuestAddress(mmio_start), pci_segment_size).unwrap(),
|
AddressAllocator::new(GuestAddress(mmio_start), pci_segment_mmio_size).unwrap(),
|
||||||
));
|
));
|
||||||
pci_mmio_allocators.push(allocator)
|
mmio_allocators.push(allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mmio_allocators
|
||||||
|
};
|
||||||
|
|
||||||
|
let start_of_mmio32_area = layout::MEM_32BIT_DEVICES_START.0;
|
||||||
|
let end_of_mmio32_area = layout::MEM_32BIT_DEVICES_START.0 + layout::MEM_32BIT_DEVICES_SIZE;
|
||||||
|
let pci_mmio32_allocators = create_mmio_allocators(
|
||||||
|
start_of_mmio32_area,
|
||||||
|
end_of_mmio32_area,
|
||||||
|
num_pci_segments,
|
||||||
|
4 << 10,
|
||||||
|
);
|
||||||
|
|
||||||
|
let start_of_mmio64_area = memory_manager.lock().unwrap().start_of_device_area().0;
|
||||||
|
let end_of_mmio64_area = memory_manager.lock().unwrap().end_of_device_area().0;
|
||||||
|
let pci_mmio64_allocators = create_mmio_allocators(
|
||||||
|
start_of_mmio64_area,
|
||||||
|
end_of_mmio64_area,
|
||||||
|
num_pci_segments,
|
||||||
|
4 << 30,
|
||||||
|
);
|
||||||
|
|
||||||
let address_manager = Arc::new(AddressManager {
|
let address_manager = Arc::new(AddressManager {
|
||||||
allocator: memory_manager.lock().unwrap().allocator(),
|
allocator: memory_manager.lock().unwrap().allocator(),
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -1031,7 +1029,8 @@ impl DeviceManager {
|
|||||||
mmio_bus,
|
mmio_bus,
|
||||||
vm: vm.clone(),
|
vm: vm.clone(),
|
||||||
device_tree: Arc::clone(&device_tree),
|
device_tree: Arc::clone(&device_tree),
|
||||||
pci_mmio_allocators,
|
pci_mmio32_allocators,
|
||||||
|
pci_mmio64_allocators,
|
||||||
});
|
});
|
||||||
|
|
||||||
// First we create the MSI interrupt manager, the legacy one is created
|
// First we create the MSI interrupt manager, the legacy one is created
|
||||||
@ -1061,7 +1060,8 @@ impl DeviceManager {
|
|||||||
|
|
||||||
let mut pci_segments = vec![PciSegment::new_default_segment(
|
let mut pci_segments = vec![PciSegment::new_default_segment(
|
||||||
&address_manager,
|
&address_manager,
|
||||||
Arc::clone(&address_manager.pci_mmio_allocators[0]),
|
Arc::clone(&address_manager.pci_mmio32_allocators[0]),
|
||||||
|
Arc::clone(&address_manager.pci_mmio64_allocators[0]),
|
||||||
&pci_irq_slots,
|
&pci_irq_slots,
|
||||||
)?];
|
)?];
|
||||||
|
|
||||||
@ -1070,7 +1070,8 @@ impl DeviceManager {
|
|||||||
i as u16,
|
i as u16,
|
||||||
numa_node_id_from_pci_segment_id(&numa_nodes, i as u16),
|
numa_node_id_from_pci_segment_id(&numa_nodes, i as u16),
|
||||||
&address_manager,
|
&address_manager,
|
||||||
Arc::clone(&address_manager.pci_mmio_allocators[i]),
|
Arc::clone(&address_manager.pci_mmio32_allocators[i]),
|
||||||
|
Arc::clone(&address_manager.pci_mmio64_allocators[i]),
|
||||||
&pci_irq_slots,
|
&pci_irq_slots,
|
||||||
)?);
|
)?);
|
||||||
}
|
}
|
||||||
@ -2765,7 +2766,7 @@ impl DeviceManager {
|
|||||||
// The memory needs to be 2MiB aligned in order to support
|
// The memory needs to be 2MiB aligned in order to support
|
||||||
// hugepages.
|
// hugepages.
|
||||||
self.pci_segments[pmem_cfg.pci_segment as usize]
|
self.pci_segments[pmem_cfg.pci_segment as usize]
|
||||||
.allocator
|
.mem64_allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate(
|
.allocate(
|
||||||
@ -2780,7 +2781,7 @@ impl DeviceManager {
|
|||||||
// The memory needs to be 2MiB aligned in order to support
|
// The memory needs to be 2MiB aligned in order to support
|
||||||
// hugepages.
|
// hugepages.
|
||||||
let base = self.pci_segments[pmem_cfg.pci_segment as usize]
|
let base = self.pci_segments[pmem_cfg.pci_segment as usize]
|
||||||
.allocator
|
.mem64_allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.allocate(None, size as GuestUsize, Some(0x0020_0000))
|
.allocate(None, size as GuestUsize, Some(0x0020_0000))
|
||||||
@ -3367,7 +3368,11 @@ impl DeviceManager {
|
|||||||
.allocate_bars(
|
.allocate_bars(
|
||||||
&self.address_manager.allocator,
|
&self.address_manager.allocator,
|
||||||
&mut self.pci_segments[segment_id as usize]
|
&mut self.pci_segments[segment_id as usize]
|
||||||
.allocator
|
.mem32_allocator
|
||||||
|
.lock()
|
||||||
|
.unwrap(),
|
||||||
|
&mut self.pci_segments[segment_id as usize]
|
||||||
|
.mem64_allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
resources,
|
resources,
|
||||||
@ -4080,7 +4085,11 @@ impl DeviceManager {
|
|||||||
.free_bars(
|
.free_bars(
|
||||||
&mut self.address_manager.allocator.lock().unwrap(),
|
&mut self.address_manager.allocator.lock().unwrap(),
|
||||||
&mut self.pci_segments[pci_segment_id as usize]
|
&mut self.pci_segments[pci_segment_id as usize]
|
||||||
.allocator
|
.mem32_allocator
|
||||||
|
.lock()
|
||||||
|
.unwrap(),
|
||||||
|
&mut self.pci_segments[pci_segment_id as usize]
|
||||||
|
.mem64_allocator
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
|
@ -16,7 +16,7 @@ use acpi_tables::{aml, Aml};
|
|||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use arch::x86_64::{SgxEpcRegion, SgxEpcSection};
|
use arch::x86_64::{SgxEpcRegion, SgxEpcSection};
|
||||||
use arch::{layout, RegionType};
|
use arch::RegionType;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use devices::ioapic;
|
use devices::ioapic;
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
@ -1160,8 +1160,6 @@ impl MemoryManager {
|
|||||||
},
|
},
|
||||||
start_of_platform_device_area,
|
start_of_platform_device_area,
|
||||||
PLATFORM_DEVICE_AREA_SIZE,
|
PLATFORM_DEVICE_AREA_SIZE,
|
||||||
layout::MEM_32BIT_DEVICES_START,
|
|
||||||
layout::MEM_32BIT_DEVICES_SIZE,
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
vec![GsiApic::new(
|
vec![GsiApic::new(
|
||||||
X86_64_IRQ_BASE,
|
X86_64_IRQ_BASE,
|
||||||
|
@ -38,10 +38,14 @@ pub(crate) struct PciSegment {
|
|||||||
pub(crate) pci_irq_slots: [u8; 32],
|
pub(crate) pci_irq_slots: [u8; 32],
|
||||||
|
|
||||||
// Device memory covered by this segment
|
// Device memory covered by this segment
|
||||||
pub(crate) start_of_device_area: u64,
|
pub(crate) start_of_mem32_area: u64,
|
||||||
pub(crate) end_of_device_area: u64,
|
pub(crate) end_of_mem32_area: u64,
|
||||||
|
|
||||||
pub(crate) allocator: Arc<Mutex<AddressAllocator>>,
|
pub(crate) start_of_mem64_area: u64,
|
||||||
|
pub(crate) end_of_mem64_area: u64,
|
||||||
|
|
||||||
|
pub(crate) mem32_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
|
pub(crate) mem64_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PciSegment {
|
impl PciSegment {
|
||||||
@ -49,7 +53,8 @@ impl PciSegment {
|
|||||||
id: u16,
|
id: u16,
|
||||||
numa_node: u32,
|
numa_node: u32,
|
||||||
address_manager: &Arc<AddressManager>,
|
address_manager: &Arc<AddressManager>,
|
||||||
allocator: Arc<Mutex<AddressAllocator>>,
|
mem32_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
|
mem64_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
pci_irq_slots: &[u8; 32],
|
pci_irq_slots: &[u8; 32],
|
||||||
) -> DeviceManagerResult<PciSegment> {
|
) -> DeviceManagerResult<PciSegment> {
|
||||||
let pci_root = PciRoot::new(None);
|
let pci_root = PciRoot::new(None);
|
||||||
@ -71,8 +76,11 @@ impl PciSegment {
|
|||||||
)
|
)
|
||||||
.map_err(DeviceManagerError::BusError)?;
|
.map_err(DeviceManagerError::BusError)?;
|
||||||
|
|
||||||
let start_of_device_area = allocator.lock().unwrap().base().0;
|
let start_of_mem32_area = mem32_allocator.lock().unwrap().base().0;
|
||||||
let end_of_device_area = allocator.lock().unwrap().end().0;
|
let end_of_mem32_area = mem32_allocator.lock().unwrap().end().0;
|
||||||
|
|
||||||
|
let start_of_mem64_area = mem64_allocator.lock().unwrap().base().0;
|
||||||
|
let end_of_mem64_area = mem64_allocator.lock().unwrap().end().0;
|
||||||
|
|
||||||
let segment = PciSegment {
|
let segment = PciSegment {
|
||||||
id,
|
id,
|
||||||
@ -84,15 +92,18 @@ impl PciSegment {
|
|||||||
pci_devices_down: 0,
|
pci_devices_down: 0,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pci_config_io: None,
|
pci_config_io: None,
|
||||||
allocator,
|
mem32_allocator,
|
||||||
start_of_device_area,
|
mem64_allocator,
|
||||||
end_of_device_area,
|
start_of_mem32_area,
|
||||||
|
end_of_mem32_area,
|
||||||
|
start_of_mem64_area,
|
||||||
|
end_of_mem64_area,
|
||||||
pci_irq_slots: *pci_irq_slots,
|
pci_irq_slots: *pci_irq_slots,
|
||||||
};
|
};
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Adding PCI segment: id={}, PCI MMIO config address: 0x{:x}, device area [0x{:x}-0x{:x}",
|
"Adding PCI segment: id={}, PCI MMIO config address: 0x{:x}, mem32 area [0x{:x}-0x{:x}, mem64 area [0x{:x}-0x{:x}",
|
||||||
segment.id, segment.mmio_config_address, segment.start_of_device_area, segment.end_of_device_area
|
segment.id, segment.mmio_config_address, segment.start_of_mem32_area, segment.end_of_mem32_area, segment.start_of_mem64_area, segment.end_of_mem64_area
|
||||||
);
|
);
|
||||||
Ok(segment)
|
Ok(segment)
|
||||||
}
|
}
|
||||||
@ -100,10 +111,18 @@ impl PciSegment {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub(crate) fn new_default_segment(
|
pub(crate) fn new_default_segment(
|
||||||
address_manager: &Arc<AddressManager>,
|
address_manager: &Arc<AddressManager>,
|
||||||
allocator: Arc<Mutex<AddressAllocator>>,
|
mem32_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
|
mem64_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
pci_irq_slots: &[u8; 32],
|
pci_irq_slots: &[u8; 32],
|
||||||
) -> DeviceManagerResult<PciSegment> {
|
) -> DeviceManagerResult<PciSegment> {
|
||||||
let mut segment = Self::new(0, 0, address_manager, allocator, pci_irq_slots)?;
|
let mut segment = Self::new(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
address_manager,
|
||||||
|
mem32_allocator,
|
||||||
|
mem64_allocator,
|
||||||
|
pci_irq_slots,
|
||||||
|
)?;
|
||||||
let pci_config_io = Arc::new(Mutex::new(PciConfigIo::new(Arc::clone(&segment.pci_bus))));
|
let pci_config_io = Arc::new(Mutex::new(PciConfigIo::new(Arc::clone(&segment.pci_bus))));
|
||||||
|
|
||||||
address_manager
|
address_manager
|
||||||
@ -123,10 +142,18 @@ impl PciSegment {
|
|||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub(crate) fn new_default_segment(
|
pub(crate) fn new_default_segment(
|
||||||
address_manager: &Arc<AddressManager>,
|
address_manager: &Arc<AddressManager>,
|
||||||
allocator: Arc<Mutex<AddressAllocator>>,
|
mem32_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
|
mem64_allocator: Arc<Mutex<AddressAllocator>>,
|
||||||
pci_irq_slots: &[u8; 32],
|
pci_irq_slots: &[u8; 32],
|
||||||
) -> DeviceManagerResult<PciSegment> {
|
) -> DeviceManagerResult<PciSegment> {
|
||||||
Self::new(0, 0, address_manager, allocator, pci_irq_slots)
|
Self::new(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
address_manager,
|
||||||
|
mem32_allocator,
|
||||||
|
mem64_allocator,
|
||||||
|
pci_irq_slots,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn next_device_bdf(&self) -> DeviceManagerResult<PciBdf> {
|
pub(crate) fn next_device_bdf(&self) -> DeviceManagerResult<PciBdf> {
|
||||||
@ -340,6 +367,7 @@ impl Aml for PciSegment {
|
|||||||
let pci_dsm = PciDsmMethod {};
|
let pci_dsm = PciDsmMethod {};
|
||||||
pci_dsdt_inner_data.push(&pci_dsm);
|
pci_dsdt_inner_data.push(&pci_dsm);
|
||||||
|
|
||||||
|
#[allow(clippy::if_same_then_else)]
|
||||||
let crs = if self.id == 0 {
|
let crs = if self.id == 0 {
|
||||||
aml::Name::new(
|
aml::Name::new(
|
||||||
"_CRS".into(),
|
"_CRS".into(),
|
||||||
@ -347,19 +375,23 @@ impl Aml for PciSegment {
|
|||||||
&aml::AddressSpace::new_bus_number(0x0u16, 0x0u16),
|
&aml::AddressSpace::new_bus_number(0x0u16, 0x0u16),
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
&aml::IO::new(0xcf8, 0xcf8, 1, 0x8),
|
&aml::IO::new(0xcf8, 0xcf8, 1, 0x8),
|
||||||
|
&aml::Memory32Fixed::new(
|
||||||
|
true,
|
||||||
|
self.mmio_config_address as u32,
|
||||||
|
layout::PCI_MMIO_CONFIG_SIZE_PER_SEGMENT as u32,
|
||||||
|
),
|
||||||
&aml::AddressSpace::new_memory(
|
&aml::AddressSpace::new_memory(
|
||||||
aml::AddressSpaceCacheable::NotCacheable,
|
aml::AddressSpaceCacheable::NotCacheable,
|
||||||
true,
|
true,
|
||||||
layout::MEM_32BIT_DEVICES_START.0 as u32,
|
self.start_of_mem32_area,
|
||||||
(layout::MEM_32BIT_DEVICES_START.0 + layout::MEM_32BIT_DEVICES_SIZE - 1)
|
self.end_of_mem32_area,
|
||||||
as u32,
|
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
&aml::AddressSpace::new_memory(
|
&aml::AddressSpace::new_memory(
|
||||||
aml::AddressSpaceCacheable::NotCacheable,
|
aml::AddressSpaceCacheable::NotCacheable,
|
||||||
true,
|
true,
|
||||||
self.start_of_device_area,
|
self.start_of_mem64_area,
|
||||||
self.end_of_device_area,
|
self.end_of_mem64_area,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -381,8 +413,15 @@ impl Aml for PciSegment {
|
|||||||
&aml::AddressSpace::new_memory(
|
&aml::AddressSpace::new_memory(
|
||||||
aml::AddressSpaceCacheable::NotCacheable,
|
aml::AddressSpaceCacheable::NotCacheable,
|
||||||
true,
|
true,
|
||||||
self.start_of_device_area,
|
self.start_of_mem32_area,
|
||||||
self.end_of_device_area,
|
self.end_of_mem32_area,
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
&aml::AddressSpace::new_memory(
|
||||||
|
aml::AddressSpaceCacheable::NotCacheable,
|
||||||
|
true,
|
||||||
|
self.start_of_mem64_area,
|
||||||
|
self.end_of_mem64_area,
|
||||||
None,
|
None,
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
@ -1162,9 +1162,9 @@ impl Vm {
|
|||||||
let pci_space = PciSpaceInfo {
|
let pci_space = PciSpaceInfo {
|
||||||
pci_segment_id: pci_segment.id,
|
pci_segment_id: pci_segment.id,
|
||||||
mmio_config_address: pci_segment.mmio_config_address,
|
mmio_config_address: pci_segment.mmio_config_address,
|
||||||
pci_device_space_start: pci_segment.start_of_device_area,
|
pci_device_space_start: pci_segment.start_of_mem64_area,
|
||||||
pci_device_space_size: pci_segment.end_of_device_area
|
pci_device_space_size: pci_segment.end_of_mem64_area
|
||||||
- pci_segment.start_of_device_area
|
- pci_segment.start_of_mem64_area
|
||||||
+ 1,
|
+ 1,
|
||||||
};
|
};
|
||||||
pci_space_info.push(pci_space);
|
pci_space_info.push(pci_space);
|
||||||
|
Loading…
Reference in New Issue
Block a user