mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-01 17:35:19 +00:00
vm-virtio: Allocate BARs for virtio-block devices in 32-bit hole
Currently all devices and guest memory share the same 64GiB allocation. With guest memory working upwards and devices working downwards. This creates issues if you want to either have a VM with a large amount of memory or want to have devices with a large allocation (e.g. virtio-pmem.) As it is possible for the hypervisor to place devices anywhere in its address range it is required for simplistic users like the firmware to set up an identity page table mapping across the full range. Currently the hypervisor sets up an identify mapping of 1GiB which the firmware extends to 64GiB to match the current address space size of the hypervisor. A simpler solution is to place the device needed for booting with the firmware (virtio-block) inside the 32-bit memory hole. This allows the firmware to easily access the block device and paves the way for increasing the address space beyond the current 64GiB limit. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
f0360c92d9
commit
180e6d1e78
@ -239,6 +239,9 @@ pub struct VirtioPciDevice {
|
||||
|
||||
// Setting PCI BAR
|
||||
settings_bar: u8,
|
||||
|
||||
// Whether to use 64-bit bar location or 32-bit
|
||||
use_64bit_bar: bool,
|
||||
}
|
||||
|
||||
impl VirtioPciDevice {
|
||||
@ -268,15 +271,22 @@ impl VirtioPciDevice {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
// All device types *except* virtio block devices should be allocated a 64-bit bar
|
||||
// The block devices should be given a 32-bit BAR so that they are easily accessible
|
||||
// to firmware without requiring excessive identity mapping.
|
||||
let mut use_64bit_bar = true;
|
||||
let (class, subclass) = match VirtioDeviceType::from(device.device_type()) {
|
||||
VirtioDeviceType::TYPE_NET => (
|
||||
PciClassCode::NetworkController,
|
||||
&PciNetworkControllerSubclass::EthernetController as &dyn PciSubclass,
|
||||
),
|
||||
VirtioDeviceType::TYPE_BLOCK => (
|
||||
PciClassCode::MassStorage,
|
||||
&PciMassStorageSubclass::MassStorage as &dyn PciSubclass,
|
||||
),
|
||||
VirtioDeviceType::TYPE_BLOCK => {
|
||||
use_64bit_bar = false;
|
||||
(
|
||||
PciClassCode::MassStorage,
|
||||
&PciMassStorageSubclass::MassStorage as &dyn PciSubclass,
|
||||
)
|
||||
}
|
||||
_ => (
|
||||
PciClassCode::Other,
|
||||
&PciVirtioSubclass::NonTransitionalBase as &dyn PciSubclass,
|
||||
@ -315,6 +325,7 @@ impl VirtioPciDevice {
|
||||
queue_evts,
|
||||
memory: Some(memory),
|
||||
settings_bar: 0,
|
||||
use_64bit_bar,
|
||||
})
|
||||
}
|
||||
|
||||
@ -531,9 +542,28 @@ impl PciDevice for VirtioPciDevice {
|
||||
|
||||
// Allocate the virtio-pci capability BAR.
|
||||
// See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004
|
||||
let virtio_pci_bar_addr = allocator
|
||||
.allocate_mmio_addresses(None, CAPABILITY_BAR_SIZE, None)
|
||||
.ok_or(PciDeviceError::IoAllocationFailed(CAPABILITY_BAR_SIZE))?;
|
||||
let virtio_pci_bar_addr = if self.use_64bit_bar {
|
||||
let addr = allocator
|
||||
.allocate_mmio_addresses(None, CAPABILITY_BAR_SIZE, None)
|
||||
.ok_or(PciDeviceError::IoAllocationFailed(CAPABILITY_BAR_SIZE))?;
|
||||
ranges.push((
|
||||
addr,
|
||||
CAPABILITY_BAR_SIZE,
|
||||
PciBarRegionType::Memory64BitRegion,
|
||||
));
|
||||
addr
|
||||
} else {
|
||||
let addr = allocator
|
||||
.allocate_mmio_hole_addresses(None, CAPABILITY_BAR_SIZE, None)
|
||||
.ok_or(PciDeviceError::IoAllocationFailed(CAPABILITY_BAR_SIZE))?;
|
||||
ranges.push((
|
||||
addr,
|
||||
CAPABILITY_BAR_SIZE,
|
||||
PciBarRegionType::Memory32BitRegion,
|
||||
));
|
||||
addr
|
||||
};
|
||||
|
||||
let config = PciBarConfiguration::default()
|
||||
.set_register_index(0)
|
||||
.set_address(virtio_pci_bar_addr.raw_value())
|
||||
@ -543,12 +573,6 @@ impl PciDevice for VirtioPciDevice {
|
||||
PciDeviceError::IoRegistrationFailed(virtio_pci_bar_addr.raw_value(), e)
|
||||
})? as u8;
|
||||
|
||||
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.
|
||||
self.add_pci_capabilities(virtio_pci_bar)?;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user