Signed-off-by: Jie Yang <yangjieyj.yang@huawei.com> (cherry picked from commit e9cfa81784d4a86efd4392a487c0294d440c03c0)
113 lines
4.2 KiB
Diff
113 lines
4.2 KiB
Diff
From cd3d687aeaee2d94a1b09895b14f87a3f232cb22 Mon Sep 17 00:00:00 2001
|
|
From: zhouli57 <zhouli57@huawei.com>
|
|
Date: Mon, 7 Mar 2022 20:51:56 +0800
|
|
Subject: [PATCH 2/8] pci: no need to delete the unmapped region
|
|
|
|
When we hot-plug a pci device but fail for some reason, for example,
|
|
hot-plug to an unsupported bus, at this point, the device has finished
|
|
registering the region, and we need to clean up the registered region.
|
|
Because the device has not been actually used, the address in the BAR
|
|
may not have been updated, so there may be an error in unregister_bars.
|
|
in fact, there is no need to delete the unmapped region.
|
|
|
|
Signed-off-by: zhouli57 <zhouli57@huawei.com>
|
|
---
|
|
pci/src/config.rs | 75 ++++++++++++++++++++++++++++++++++++++++++++---
|
|
1 file changed, 71 insertions(+), 4 deletions(-)
|
|
|
|
diff --git a/pci/src/config.rs b/pci/src/config.rs
|
|
index 88d7f03..c2b4c88 100644
|
|
--- a/pci/src/config.rs
|
|
+++ b/pci/src/config.rs
|
|
@@ -569,11 +569,12 @@ impl PciConfig {
|
|
pub fn unregister_bars(&mut self, bus: &Arc<Mutex<PciBus>>) -> Result<()> {
|
|
let locked_bus = bus.lock().unwrap();
|
|
for bar in self.bars.iter_mut() {
|
|
+ if bar.address == BAR_SPACE_UNMAPPED || bar.size == 0 {
|
|
+ continue;
|
|
+ }
|
|
match bar.region_type {
|
|
- RegionType::Io => {
|
|
- if bar.address == BAR_SPACE_UNMAPPED || bar.size == 0 {
|
|
- continue;
|
|
- }
|
|
+ RegionType::Io =>
|
|
+ {
|
|
#[cfg(target_arch = "x86_64")]
|
|
if let Some(region) = bar.region.as_ref() {
|
|
locked_bus
|
|
@@ -1102,4 +1103,70 @@ mod tests {
|
|
assert_eq!(size1, 0x10);
|
|
assert_eq!(size2, 0x40);
|
|
}
|
|
+
|
|
+ #[test]
|
|
+ fn test_unregister_bars() {
|
|
+ let read_ops = move |_data: &mut [u8], _addr: GuestAddress, _offset: u64| -> bool { true };
|
|
+ let write_ops = move |_data: &[u8], _addr: GuestAddress, _offset: u64| -> bool { true };
|
|
+ let region_ops = RegionOps {
|
|
+ read: Arc::new(read_ops),
|
|
+ write: Arc::new(write_ops),
|
|
+ };
|
|
+ let region = Region::init_io_region(2048, region_ops);
|
|
+ let mut pci_config = PciConfig::new(PCI_CONFIG_SPACE_SIZE, 3);
|
|
+
|
|
+ // bar is unmapped
|
|
+ #[cfg(target_arch = "x86_64")]
|
|
+ pci_config.register_bar(0, region.clone(), RegionType::Io, false, 2048);
|
|
+ pci_config.register_bar(1, region.clone(), RegionType::Mem32Bit, false, 2048);
|
|
+ pci_config.register_bar(2, region.clone(), RegionType::Mem64Bit, true, 2048);
|
|
+
|
|
+ #[cfg(target_arch = "x86_64")]
|
|
+ let io_region = Region::init_container_region(1 << 16);
|
|
+ let mem_region = Region::init_container_region(u64::max_value());
|
|
+ let bus = Arc::new(Mutex::new(PciBus::new(
|
|
+ String::from("bus"),
|
|
+ #[cfg(target_arch = "x86_64")]
|
|
+ io_region.clone(),
|
|
+ mem_region.clone(),
|
|
+ )));
|
|
+
|
|
+ assert!(pci_config.unregister_bars(&bus).is_ok());
|
|
+
|
|
+ // bar is mapped
|
|
+ #[cfg(target_arch = "x86_64")]
|
|
+ pci_config.register_bar(0, region.clone(), RegionType::Io, false, 2048);
|
|
+ pci_config.register_bar(1, region.clone(), RegionType::Mem32Bit, false, 2048);
|
|
+ pci_config.register_bar(2, region.clone(), RegionType::Mem64Bit, true, 2048);
|
|
+
|
|
+ #[cfg(target_arch = "x86_64")]
|
|
+ le_write_u32(
|
|
+ &mut pci_config.config,
|
|
+ BAR_0 as usize,
|
|
+ 2048 | BAR_IO_SPACE as u32,
|
|
+ )
|
|
+ .unwrap();
|
|
+ le_write_u32(&mut pci_config.config, BAR_0 as usize + REG_SIZE, 2048).unwrap();
|
|
+ le_write_u32(
|
|
+ &mut pci_config.config,
|
|
+ BAR_0 as usize + 2 * REG_SIZE,
|
|
+ 2048 | BAR_MEM_64BIT as u32 | BAR_PREFETCH as u32,
|
|
+ )
|
|
+ .unwrap();
|
|
+ le_write_u16(
|
|
+ &mut pci_config.config,
|
|
+ COMMAND as usize,
|
|
+ COMMAND_IO_SPACE | COMMAND_MEMORY_SPACE,
|
|
+ )
|
|
+ .unwrap();
|
|
+ pci_config
|
|
+ .update_bar_mapping(
|
|
+ #[cfg(target_arch = "x86_64")]
|
|
+ &io_region,
|
|
+ &mem_region,
|
|
+ )
|
|
+ .unwrap();
|
|
+
|
|
+ assert!(pci_config.unregister_bars(&bus).is_ok());
|
|
+ }
|
|
}
|
|
--
|
|
2.20.1
|
|
|