Signed-off-by: Jie Yang <yangjieyj.yang@huawei.com> (cherry picked from commit 6158eab66897bf7fb11ce7ae8c3b568f8de0e2dd)
131 lines
5.4 KiB
Diff
131 lines
5.4 KiB
Diff
From 7d40dbe810cf21added24d7cf2425a62bae4b25b Mon Sep 17 00:00:00 2001
|
|
From: "Xinle.Guo" <guoxinle1@huawei.com>
|
|
Date: Tue, 24 Aug 2021 15:29:08 +0800
|
|
Subject: [PATCH 06/10] vfio: adding ram device region to vfio bar region
|
|
|
|
The ram device region was added to memory region of parent bus.
|
|
But vfio bar region could not manage ram device region when
|
|
adding or deleting sub region. To fix this problem, it should be
|
|
added as sub region of vfio bar region. The VM exits when
|
|
guest tries to read/write device bar region. Using ram device
|
|
region which remaps mmio region can improve I/O performance. So,
|
|
the memory region should look like as follows:
|
|
|
|
|----- IO region ----------|
|
|
|-----|---- IO region ----|-----|------|-ram device region-|(memory region)
|
|
virtio bar region vfio bar region
|
|
|
|
So, guest can read/write host device bar region directly.
|
|
|
|
Signed-off-by: Xinle.Guo <guoxinle1@huawei.com>
|
|
---
|
|
vfio/src/lib.rs | 4 ++--
|
|
vfio/src/vfio_pci.rs | 35 ++++++++++++++++++++---------------
|
|
2 files changed, 22 insertions(+), 17 deletions(-)
|
|
|
|
diff --git a/vfio/src/lib.rs b/vfio/src/lib.rs
|
|
index be70f45..801b7d0 100644
|
|
--- a/vfio/src/lib.rs
|
|
+++ b/vfio/src/lib.rs
|
|
@@ -23,8 +23,8 @@ pub mod errors {
|
|
PciErr(pci::errors::Error, pci::errors::ErrorKind);
|
|
}
|
|
errors {
|
|
- UnregMemBar(id: usize) {
|
|
- display("Failed to unmap BAR {} in memory space.", id)
|
|
+ AddRegBar(id: usize) {
|
|
+ display("Failed to add sub region at the BAR {} in memory space.", id)
|
|
}
|
|
VfioIoctl(ioctl: String, result: i32) {
|
|
display("Vfio ioctl failed: {}, result is: {}", ioctl, result)
|
|
diff --git a/vfio/src/vfio_pci.rs b/vfio/src/vfio_pci.rs
|
|
index b42e321..e366e47 100644
|
|
--- a/vfio/src/vfio_pci.rs
|
|
+++ b/vfio/src/vfio_pci.rs
|
|
@@ -345,19 +345,19 @@ impl VfioPciDevice {
|
|
.chain_err(|| "Failed to get vfio bar info")?;
|
|
let size = vfio_bar.size;
|
|
|
|
+ let region = Region::init_container_region(size);
|
|
let bar_region = if i == table_bar {
|
|
- let region = Region::init_container_region(size);
|
|
region
|
|
.add_subregion(
|
|
Region::init_io_region(table_size as u64, table_ops.clone()),
|
|
table_offset,
|
|
)
|
|
- .chain_err(|| ErrorKind::UnregMemBar(i as usize))?;
|
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
|
|
|
if table_offset > 0 {
|
|
region
|
|
.add_subregion(Region::init_io_region(table_offset, bar_ops.clone()), 0)
|
|
- .chain_err(|| ErrorKind::UnregMemBar(i as usize))?;
|
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
|
}
|
|
|
|
if table_offset + table_size < size {
|
|
@@ -369,11 +369,14 @@ impl VfioPciDevice {
|
|
),
|
|
table_offset + table_size,
|
|
)
|
|
- .chain_err(|| ErrorKind::UnregMemBar(i as usize))?;
|
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
|
}
|
|
region
|
|
} else {
|
|
- Region::init_io_region(size, bar_ops.clone())
|
|
+ region
|
|
+ .add_subregion(Region::init_io_region(size, bar_ops.clone()), 0)
|
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
|
+ region
|
|
};
|
|
|
|
self.pci_config
|
|
@@ -634,14 +637,16 @@ impl VfioPciDevice {
|
|
.chain_err(|| "Failed to create HostMemMapping")?;
|
|
|
|
let ram_device = Region::init_ram_device_region(Arc::new(host_mmap));
|
|
- // Avoid being covered by user memory region.
|
|
- ram_device.set_priority(1);
|
|
- let parent_bus = self.parent_bus.upgrade().unwrap();
|
|
- let locked_parent_bus = parent_bus.lock().unwrap();
|
|
- locked_parent_bus
|
|
- .mem_region
|
|
- .add_subregion(ram_device, gpa + mmap.offset)
|
|
- .chain_err(|| "Failed add to mem region")?;
|
|
+ let bar = self
|
|
+ .pci_config
|
|
+ .bars
|
|
+ .get_mut(i as usize)
|
|
+ .chain_err(|| "Failed to get pci bar info")?;
|
|
+ bar.region
|
|
+ .as_ref()
|
|
+ .unwrap()
|
|
+ .add_subregion(ram_device, mmap.offset)
|
|
+ .chain_err(|| ErrorKind::AddRegBar(i as usize))?;
|
|
}
|
|
}
|
|
Ok(())
|
|
@@ -757,7 +762,7 @@ impl PciDevOps for VfioPciDevice {
|
|
return;
|
|
}
|
|
|
|
- if offset >= (BAR_0 as usize) && offset < (BAR_5 as usize) + REG_SIZE {
|
|
+ if ranges_overlap(offset, end, BAR_0 as usize, BAR_5 as usize + REG_SIZE) {
|
|
self.pci_config.read(offset, data);
|
|
return;
|
|
}
|
|
@@ -806,7 +811,7 @@ impl PciDevOps for VfioPciDevice {
|
|
cap_offset = msix.lock().unwrap().msix_cap_offset as usize;
|
|
}
|
|
|
|
- if ranges_overlap(offset, end, COMMAND as usize, COMMAND as usize + 4) {
|
|
+ if ranges_overlap(offset, end, COMMAND as usize, COMMAND as usize + REG_SIZE) {
|
|
self.pci_config
|
|
.write(offset, data, self.dev_id.load(Ordering::Acquire));
|
|
|
|
--
|
|
2.25.1
|
|
|