vm-device, vmm: Wait for barrier if one is returned

Wait for the barrier if one is provided by the result of the MMIO and
PIO write.

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-12-04 10:17:51 +00:00
parent 1fc6d50f3e
commit a8643dc523
2 changed files with 28 additions and 12 deletions

View File

@ -231,13 +231,13 @@ impl Bus {
/// Writes `data` to the device that owns the range containing `addr`. /// Writes `data` to the device that owns the range containing `addr`.
/// ///
/// Returns true on success, otherwise `data` is untouched. /// Returns true on success, otherwise `data` is untouched.
pub fn write(&self, addr: u64, data: &[u8]) -> Result<()> { pub fn write(&self, addr: u64, data: &[u8]) -> Result<Option<Arc<Barrier>>> {
if let Some((base, offset, dev)) = self.resolve(addr) { if let Some((base, offset, dev)) = self.resolve(addr) {
// OK to unwrap as lock() failing is a serious error condition and should panic. // OK to unwrap as lock() failing is a serious error condition and should panic.
dev.lock() Ok(dev
.lock()
.expect("Failed to acquire device lock") .expect("Failed to acquire device lock")
.write(base, offset, data); .write(base, offset, data))
Ok(())
} else { } else {
Err(Error::MissingAddressRange) Err(Error::MissingAddressRange)
} }

View File

@ -400,11 +400,19 @@ impl VmmOps for VmOps {
} }
fn mmio_write(&self, addr: u64, data: &[u8]) -> hypervisor::vm::Result<()> { fn mmio_write(&self, addr: u64, data: &[u8]) -> hypervisor::vm::Result<()> {
if let Err(e) = self.mmio_bus.write(addr, data) { match self.mmio_bus.write(addr, data) {
if let vm_device::BusError::MissingAddressRange = e { Err(e) => {
warn!("Guest MMIO write to unregistered address 0x{:x}", addr); if let vm_device::BusError::MissingAddressRange = e {
warn!("Guest MMIO write to unregistered address 0x{:x}", addr);
}
} }
} Ok(Some(barrier)) => {
info!("Waiting for barrier");
barrier.wait();
info!("Barrier released");
}
_ => {}
};
Ok(()) Ok(())
} }
@ -425,11 +433,19 @@ impl VmmOps for VmOps {
return Ok(()); return Ok(());
} }
if let Err(e) = self.io_bus.write(addr, data) { match self.io_bus.write(addr, data) {
if let vm_device::BusError::MissingAddressRange = e { Err(e) => {
warn!("Guest PIO write to unregistered address 0x{:x}", addr); if let vm_device::BusError::MissingAddressRange = e {
warn!("Guest PIO write to unregistered address 0x{:x}", addr);
}
} }
} Ok(Some(barrier)) => {
info!("Waiting for barrier");
barrier.wait();
info!("Barrier released");
}
_ => {}
};
Ok(()) Ok(())
} }
} }