Skip to content

Commit dfa69db

Browse files
committed
pci: always assume we are using a single 64bit MMIO BAR
Despite the fact we are using a single 64bit MMIO BARs for VirtIO devices, we had code that allowed for multiple BARs including BARs of other types (IO and 32bit MMIO). Remove this code and always assume we are only using 64bit BAR at index 0. Signed-off-by: Babis Chalios <[email protected]>
1 parent cf12e8e commit dfa69db

File tree

2 files changed

+51
-104
lines changed

2 files changed

+51
-104
lines changed

src/vmm/src/device_manager/pci_mngr.rs

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -88,24 +88,14 @@ impl PciDevices {
8888
vm: &Vm,
8989
virtio_device: &Arc<Mutex<VirtioPciDevice>>,
9090
) -> Result<(), PciManagerError> {
91-
for bar in &virtio_device.lock().expect("Poisoned lock").bar_regions {
92-
match bar.region_type {
93-
PciBarRegionType::IoRegion => {
94-
debug!("Inserting I/O BAR region: {:#x}:{:#x}", bar.addr, bar.size);
95-
#[cfg(target_arch = "x86_64")]
96-
vm.pio_bus
97-
.insert(virtio_device.clone(), bar.addr, bar.size)?;
98-
#[cfg(target_arch = "aarch64")]
99-
log::error!("pci: We do not support I/O region allocation")
100-
}
101-
PciBarRegionType::Memory32BitRegion | PciBarRegionType::Memory64BitRegion => {
102-
debug!("Inserting MMIO BAR region: {:#x}:{:#x}", bar.addr, bar.size);
103-
vm.common
104-
.mmio_bus
105-
.insert(virtio_device.clone(), bar.addr, bar.size)?;
106-
}
107-
}
108-
}
91+
let virtio_device_locked = virtio_device.lock().expect("Poisoned lock");
92+
let bar = &virtio_device_locked.bar_region;
93+
assert_eq!(bar.region_type, PciBarRegionType::Memory64BitRegion);
94+
95+
debug!("Inserting MMIO BAR region: {:#x}:{:#x}", bar.addr, bar.size);
96+
vm.common
97+
.mmio_bus
98+
.insert(virtio_device.clone(), bar.addr, bar.size)?;
10999

110100
Ok(())
111101
}

src/vmm/src/devices/virtio/transport/pci/device.rs

Lines changed: 43 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ const VIRTIO_F_NOTIFICATION_DATA: u32 = 38;
6767
/// Vector value used to disable MSI for a queue.
6868
const VIRTQ_MSI_NO_VECTOR: u16 = 0xffff;
6969

70+
/// BAR index we are using for VirtIO configuration
71+
const VIRTIO_BAR_INDEX: u8 = 0;
72+
7073
enum PciCapabilityType {
7174
Common = 1,
7275
Notify = 2,
@@ -110,12 +113,12 @@ impl PciCapability for VirtioPciCap {
110113
const VIRTIO_PCI_CAP_LEN_OFFSET: u8 = 2;
111114

112115
impl VirtioPciCap {
113-
pub fn new(cfg_type: PciCapabilityType, pci_bar: u8, offset: u32, length: u32) -> Self {
116+
pub fn new(cfg_type: PciCapabilityType, offset: u32, length: u32) -> Self {
114117
VirtioPciCap {
115118
cap_len: u8::try_from(std::mem::size_of::<VirtioPciCap>()).unwrap()
116119
+ VIRTIO_PCI_CAP_LEN_OFFSET,
117120
cfg_type: cfg_type as u8,
118-
pci_bar,
121+
pci_bar: VIRTIO_BAR_INDEX,
119122
id: 0,
120123
padding: [0; 2],
121124
offset: Le32::from(offset),
@@ -145,19 +148,13 @@ impl PciCapability for VirtioPciNotifyCap {
145148
}
146149

147150
impl VirtioPciNotifyCap {
148-
pub fn new(
149-
cfg_type: PciCapabilityType,
150-
pci_bar: u8,
151-
offset: u32,
152-
length: u32,
153-
multiplier: Le32,
154-
) -> Self {
151+
pub fn new(cfg_type: PciCapabilityType, offset: u32, length: u32, multiplier: Le32) -> Self {
155152
VirtioPciNotifyCap {
156153
cap: VirtioPciCap {
157154
cap_len: u8::try_from(std::mem::size_of::<VirtioPciNotifyCap>()).unwrap()
158155
+ VIRTIO_PCI_CAP_LEN_OFFSET,
159156
cfg_type: cfg_type as u8,
160-
pci_bar,
157+
pci_bar: VIRTIO_BAR_INDEX,
161158
id: 0,
162159
padding: [0; 2],
163160
offset: Le32::from(offset),
@@ -231,7 +228,7 @@ impl PciCapability for VirtioPciCfgCap {
231228
impl VirtioPciCfgCap {
232229
fn new() -> Self {
233230
VirtioPciCfgCap {
234-
cap: VirtioPciCap::new(PciCapabilityType::Pci, 0, 0, 0),
231+
cap: VirtioPciCap::new(PciCapabilityType::Pci, 0, 0),
235232
..Default::default()
236233
}
237234
}
@@ -306,7 +303,7 @@ pub struct VirtioPciDeviceState {
306303
pub pci_dev_state: VirtioPciCommonConfigState,
307304
pub msix_state: MsixConfigState,
308305
pub msi_vector_group: Vec<u32>,
309-
pub bar_configuration: Vec<PciBarConfiguration>,
306+
pub bar_configuration: PciBarConfiguration,
310307
}
311308

312309
#[derive(Debug, thiserror::Error, displaydoc::Display)]
@@ -348,12 +345,6 @@ pub struct VirtioPciDevice {
348345
// Guest memory
349346
memory: GuestMemoryMmap,
350347

351-
// Settings PCI BAR
352-
settings_bar: u8,
353-
354-
// Whether to use 64-bit bar location or 32-bit
355-
use_64bit_bar: bool,
356-
357348
// Add a dedicated structure to hold information about the very specific
358349
// virtio-pci capability VIRTIO_PCI_CAP_PCI_CFG. This is needed to support
359350
// the legacy/backward compatible mechanism of letting the guest access the
@@ -362,8 +353,8 @@ pub struct VirtioPciDevice {
362353
// a device.
363354
cap_pci_cfg_info: VirtioPciCfgCapInfo,
364355

365-
// Details of bar regions to free
366-
pub bar_regions: Vec<PciBarConfiguration>,
356+
// Details of BAR region
357+
pub bar_region: PciBarConfiguration,
367358
}
368359

369360
impl Debug for VirtioPciDevice {
@@ -471,11 +462,9 @@ impl VirtioPciDevice {
471462
interrupt_status: Arc::new(AtomicUsize::new(0)),
472463
virtio_interrupt: Some(interrupt),
473464
memory,
474-
settings_bar: 0,
475-
use_64bit_bar: true,
476465
interrupt_source_group: msi_vectors,
477466
cap_pci_cfg_info: VirtioPciCfgCapInfo::default(),
478-
bar_regions: vec![],
467+
bar_region: PciBarConfiguration::default(),
479468
};
480469

481470
Ok(virtio_pci_device)
@@ -524,11 +513,9 @@ impl VirtioPciDevice {
524513
interrupt_status: Arc::new(AtomicUsize::new(state.interrupt_status)),
525514
virtio_interrupt: Some(interrupt),
526515
memory: memory.clone(),
527-
settings_bar: 0,
528-
use_64bit_bar: true,
529516
interrupt_source_group: msi_vectors,
530517
cap_pci_cfg_info,
531-
bar_regions: state.bar_configuration,
518+
bar_region: state.bar_configuration,
532519
};
533520

534521
if state.device_activated {
@@ -558,17 +545,13 @@ impl VirtioPciDevice {
558545
}
559546

560547
pub fn config_bar_addr(&self) -> u64 {
561-
self.configuration.get_bar_addr(self.settings_bar as usize)
548+
self.configuration.get_bar_addr(VIRTIO_BAR_INDEX as usize)
562549
}
563550

564-
fn add_pci_capabilities(
565-
&mut self,
566-
settings_bar: u8,
567-
) -> std::result::Result<(), PciDeviceError> {
551+
fn add_pci_capabilities(&mut self) -> std::result::Result<(), PciDeviceError> {
568552
// Add pointers to the different configuration structures from the PCI capabilities.
569553
let common_cap = VirtioPciCap::new(
570554
PciCapabilityType::Common,
571-
settings_bar,
572555
COMMON_CONFIG_BAR_OFFSET.try_into().unwrap(),
573556
COMMON_CONFIG_SIZE.try_into().unwrap(),
574557
);
@@ -578,7 +561,6 @@ impl VirtioPciDevice {
578561

579562
let isr_cap = VirtioPciCap::new(
580563
PciCapabilityType::Isr,
581-
settings_bar,
582564
ISR_CONFIG_BAR_OFFSET.try_into().unwrap(),
583565
ISR_CONFIG_SIZE.try_into().unwrap(),
584566
);
@@ -589,7 +571,6 @@ impl VirtioPciDevice {
589571
// TODO(dgreid) - set based on device's configuration size?
590572
let device_cap = VirtioPciCap::new(
591573
PciCapabilityType::Device,
592-
settings_bar,
593574
DEVICE_CONFIG_BAR_OFFSET.try_into().unwrap(),
594575
DEVICE_CONFIG_SIZE.try_into().unwrap(),
595576
);
@@ -599,7 +580,6 @@ impl VirtioPciDevice {
599580

600581
let notify_cap = VirtioPciNotifyCap::new(
601582
PciCapabilityType::Notify,
602-
settings_bar,
603583
NOTIFICATION_BAR_OFFSET.try_into().unwrap(),
604584
NOTIFICATION_SIZE.try_into().unwrap(),
605585
Le32::from(NOTIFY_OFF_MULTIPLIER),
@@ -618,18 +598,17 @@ impl VirtioPciDevice {
618598

619599
if self.msix_config.is_some() {
620600
let msix_cap = MsixCap::new(
621-
settings_bar,
601+
VIRTIO_BAR_INDEX,
622602
self.msix_num,
623603
MSIX_TABLE_BAR_OFFSET.try_into().unwrap(),
624-
settings_bar,
604+
VIRTIO_BAR_INDEX,
625605
MSIX_PBA_BAR_OFFSET.try_into().unwrap(),
626606
);
627607
self.configuration
628608
.add_capability(&msix_cap)
629609
.map_err(PciDeviceError::CapabilitiesSetup)?;
630610
}
631611

632-
self.settings_bar = settings_bar;
633612
Ok(())
634613
}
635614

@@ -744,7 +723,7 @@ impl VirtioPciDevice {
744723
.expect("Poisoned lock")
745724
.state(),
746725
msi_vector_group: self.interrupt_source_group.save(),
747-
bar_configuration: self.bar_regions.clone(),
726+
bar_configuration: self.bar_region,
748727
}
749728
}
750729
}
@@ -887,41 +866,25 @@ impl PciDevice for VirtioPciDevice {
887866
mmio32_allocator: &mut AddressAllocator,
888867
mmio64_allocator: &mut AddressAllocator,
889868
) -> std::result::Result<Vec<PciBarConfiguration>, PciDeviceError> {
890-
let mut bars = Vec::new();
891869
let device_clone = self.device.clone();
892870
let device = device_clone.lock().unwrap();
893871

894872
// Allocate the virtio-pci capability BAR.
895873
// See http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html#x1-740004
896-
let (virtio_pci_bar_addr, region_type) = if self.use_64bit_bar {
897-
let region_type = PciBarRegionType::Memory64BitRegion;
898-
let addr = mmio64_allocator
899-
.allocate(
900-
CAPABILITY_BAR_SIZE,
901-
CAPABILITY_BAR_SIZE,
902-
AllocPolicy::FirstMatch,
903-
)
904-
.unwrap()
905-
.start();
906-
(addr, region_type)
907-
} else {
908-
let region_type = PciBarRegionType::Memory32BitRegion;
909-
let addr = mmio32_allocator
910-
.allocate(
911-
CAPABILITY_BAR_SIZE,
912-
CAPABILITY_BAR_SIZE,
913-
AllocPolicy::FirstMatch,
914-
)
915-
.unwrap()
916-
.start();
917-
(addr, region_type)
918-
};
874+
let virtio_pci_bar_addr = mmio64_allocator
875+
.allocate(
876+
CAPABILITY_BAR_SIZE,
877+
CAPABILITY_BAR_SIZE,
878+
AllocPolicy::FirstMatch,
879+
)
880+
.unwrap()
881+
.start();
919882

920883
let bar = PciBarConfiguration {
921884
addr: virtio_pci_bar_addr,
922885
size: CAPABILITY_BAR_SIZE,
923886
idx: VIRTIO_COMMON_BAR_INDEX,
924-
region_type,
887+
region_type: PciBarRegionType::Memory64BitRegion,
925888
prefetchable: pci::PciBarPrefetchable::NotPrefetchable,
926889
};
927890

@@ -934,32 +897,28 @@ impl PciDevice for VirtioPciDevice {
934897
.map_err(|e| PciDeviceError::IoRegistrationFailed(virtio_pci_bar_addr, e))?;
935898

936899
// Once the BARs are allocated, the capabilities can be added to the PCI configuration.
937-
self.add_pci_capabilities(VIRTIO_COMMON_BAR_INDEX.try_into().unwrap())?;
938-
939-
bars.push(bar);
940-
941-
self.bar_regions.clone_from(&bars);
900+
self.add_pci_capabilities()?;
901+
self.bar_region = bar;
942902

943-
Ok(bars)
903+
Ok(vec![bar])
944904
}
945905

946906
fn free_bars(
947907
&mut self,
948908
mmio32_allocator: &mut AddressAllocator,
949909
mmio64_allocator: &mut AddressAllocator,
950910
) -> std::result::Result<(), PciDeviceError> {
951-
for bar in self.bar_regions.drain(..) {
952-
let range = RangeInclusive::new(bar.addr, bar.addr + bar.size).unwrap();
953-
match bar.region_type {
954-
PciBarRegionType::Memory32BitRegion => {
955-
mmio32_allocator.free(&range);
956-
}
957-
PciBarRegionType::Memory64BitRegion => {
958-
mmio64_allocator.free(&range);
959-
}
960-
_ => error!("Unexpected PCI bar type"),
961-
}
962-
}
911+
assert_eq!(
912+
self.bar_region.region_type,
913+
PciBarRegionType::Memory64BitRegion
914+
);
915+
916+
let range = RangeInclusive::new(
917+
self.bar_region.addr,
918+
self.bar_region.addr + self.bar_region.size,
919+
)
920+
.unwrap();
921+
mmio64_allocator.free(&range);
963922
Ok(())
964923
}
965924

@@ -970,10 +929,8 @@ impl PciDevice for VirtioPciDevice {
970929
) -> std::result::Result<(), std::io::Error> {
971930
// We only update our idea of the bar in order to support free_bars() above.
972931
// The majority of the reallocation is done inside DeviceManager.
973-
for bar in self.bar_regions.iter_mut() {
974-
if bar.addr == old_base {
975-
bar.addr = new_base;
976-
}
932+
if self.bar_region.addr == old_base {
933+
self.bar_region.addr = new_base;
977934
}
978935

979936
Ok(())

0 commit comments

Comments
 (0)