mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-21 20:15:21 +00:00
vmm: Conditionally update ioeventfds for virtio PCI device
The specific part of PCI BAR reprogramming that happens for a virtio PCI device is the update of the ioeventfds addresses KVM should listen to. This should not be triggered for every BAR reprogramming associated with the virtio device since a virtio PCI device might have multiple BARs. The update of the ioeventfds addresses should only happen when the BAR related to those addresses is being moved. Signed-off-by: Sebastien Boeuf <sebastien.boeuf@intel.com>
This commit is contained in:
parent
de21c9ba4f
commit
c7cabc88b4
@ -194,14 +194,9 @@ impl PciConfigIo {
|
||||
if let Some(d) = pci_bus.devices.get(device) {
|
||||
let mut device = d.lock().unwrap();
|
||||
|
||||
// Find out if one of the device's BAR is being reprogrammed
|
||||
let bar_reprog_params = device.detect_bar_reprogramming(register, data);
|
||||
|
||||
// Update the register value
|
||||
device.write_config_register(register, offset, data);
|
||||
|
||||
// Reprogram the BAR if needed
|
||||
if let Some(params) = bar_reprog_params {
|
||||
// Find out if one of the device's BAR is being reprogrammed, and
|
||||
// reprogram it if needed.
|
||||
if let Some(params) = device.detect_bar_reprogramming(register, data) {
|
||||
if let Err(e) = pci_bus.device_reloc.upgrade().unwrap().move_bar(
|
||||
params.old_base,
|
||||
params.new_base,
|
||||
@ -212,6 +207,9 @@ impl PciConfigIo {
|
||||
error!("Failed moving device BAR: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the register value
|
||||
device.write_config_register(register, offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
@ -312,14 +310,9 @@ impl PciConfigMmio {
|
||||
if let Some(d) = pci_bus.devices.get(device) {
|
||||
let mut device = d.lock().unwrap();
|
||||
|
||||
// Find out if one of the device's BAR is being reprogrammed
|
||||
let bar_reprog_params = device.detect_bar_reprogramming(register, data);
|
||||
|
||||
// Update the register value
|
||||
device.write_config_register(register, offset, data);
|
||||
|
||||
// Reprogram the BAR if needed
|
||||
if let Some(params) = bar_reprog_params {
|
||||
// Find out if one of the device's BAR is being reprogrammed, and
|
||||
// reprogram it if needed.
|
||||
if let Some(params) = device.detect_bar_reprogramming(register, data) {
|
||||
if let Err(e) = pci_bus.device_reloc.upgrade().unwrap().move_bar(
|
||||
params.old_base,
|
||||
params.new_base,
|
||||
@ -330,6 +323,9 @@ impl PciConfigMmio {
|
||||
error!("Failed moving device BAR: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the register value
|
||||
device.write_config_register(register, offset, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -563,11 +563,11 @@ impl PciConfiguration {
|
||||
pub fn get_bar_addr(&self, bar_num: usize) -> u64 {
|
||||
let bar_idx = BAR0_REG + bar_num;
|
||||
|
||||
let mut addr = u64::from(self.registers[bar_idx] & self.writable_bits[bar_idx]);
|
||||
let mut addr = u64::from(self.bar_addr[bar_num] & self.writable_bits[bar_idx]);
|
||||
|
||||
if let Some(bar_type) = self.bar_type[bar_num] {
|
||||
if bar_type == PciBarRegionType::Memory64BitRegion {
|
||||
addr |= u64::from(self.registers[bar_idx + 1]) << 32;
|
||||
addr |= u64::from(self.bar_addr[bar_num + 1]) << 32;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -362,9 +362,12 @@ impl VirtioPciDevice {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ioeventfds(&self) -> Vec<(&EventFd, u64, u64)> {
|
||||
let bar0 = self.configuration.get_bar_addr(self.settings_bar as usize);
|
||||
let notify_base = bar0 + NOTIFICATION_BAR_OFFSET;
|
||||
pub fn config_bar_addr(&self) -> u64 {
|
||||
self.configuration.get_bar_addr(self.settings_bar as usize)
|
||||
}
|
||||
|
||||
pub fn ioeventfds(&self, bar_addr: u64) -> Vec<(&EventFd, u64, u64)> {
|
||||
let notify_base = bar_addr + NOTIFICATION_BAR_OFFSET;
|
||||
self.queue_evts()
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
@ -358,10 +358,13 @@ impl DeviceRelocation for AddressManager {
|
||||
|
||||
let any_dev = pci_dev.as_any();
|
||||
if let Some(virtio_pci_dev) = any_dev.downcast_ref::<VirtioPciDevice>() {
|
||||
for (event, addr, _) in virtio_pci_dev.ioeventfds() {
|
||||
let io_addr = IoEventAddress::Mmio(addr);
|
||||
self.vm_fd
|
||||
.register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)?;
|
||||
let bar_addr = virtio_pci_dev.config_bar_addr();
|
||||
if bar_addr == new_base {
|
||||
for (event, addr, _) in virtio_pci_dev.ioeventfds(new_base) {
|
||||
let io_addr = IoEventAddress::Mmio(addr);
|
||||
self.vm_fd
|
||||
.register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1200,7 +1203,8 @@ impl DeviceManager {
|
||||
.allocate_bars(&mut allocator)
|
||||
.map_err(DeviceManagerError::AllocateBars)?;
|
||||
|
||||
for (event, addr, _) in virtio_pci_device.ioeventfds() {
|
||||
let bar_addr = virtio_pci_device.config_bar_addr();
|
||||
for (event, addr, _) in virtio_pci_device.ioeventfds(bar_addr) {
|
||||
let io_addr = IoEventAddress::Mmio(addr);
|
||||
vm_fd
|
||||
.register_ioevent(event.as_raw_fd(), &io_addr, NoDatamatch)
|
||||
|
Loading…
x
Reference in New Issue
Block a user