vmm: cpu: Warn if the guest is trying to access unregistered IO ranges

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2020-09-04 08:42:33 +02:00 committed by Sebastien Boeuf
parent 7f2ee1f984
commit e5ce6dc43c
2 changed files with 42 additions and 26 deletions

View File

@ -214,30 +214,30 @@ impl Bus {
/// Reads data from the device that owns the range containing `addr` and puts it into `data`.
///
/// Returns true on success, otherwise `data` is untouched.
pub fn read(&self, addr: u64, data: &mut [u8]) -> bool {
pub fn read(&self, addr: u64, data: &mut [u8]) -> Result<()> {
if let Some((base, offset, dev)) = self.resolve(addr) {
// OK to unwrap as lock() failing is a serious error condition and should panic.
dev.lock()
.expect("Failed to acquire device lock")
.read(base, offset, data);
true
Ok(())
} else {
false
Err(Error::MissingAddressRange)
}
}
/// Writes `data` to the device that owns the range containing `addr`.
///
/// Returns true on success, otherwise `data` is untouched.
pub fn write(&self, addr: u64, data: &[u8]) -> bool {
pub fn write(&self, addr: u64, data: &[u8]) -> Result<()> {
if let Some((base, offset, dev)) = self.resolve(addr) {
// OK to unwrap as lock() failing is a serious error condition and should panic.
dev.lock()
.expect("Failed to acquire device lock")
.write(base, offset, data);
true
Ok(())
} else {
false
Err(Error::MissingAddressRange)
}
}
}
@ -290,16 +290,16 @@ mod tests {
let bus = Bus::new();
let dummy = Arc::new(Mutex::new(DummyDevice));
assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
assert!(bus.write(0x10, &[0, 0, 0, 0]));
assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
assert!(bus.write(0x11, &[0, 0, 0, 0]));
assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
assert!(bus.write(0x16, &[0, 0, 0, 0]));
assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
assert!(!bus.write(0x20, &mut [0, 0, 0, 0]));
assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
assert!(!bus.write(0x06, &mut [0, 0, 0, 0]));
assert!(bus.read(0x10, &mut [0, 0, 0, 0]).is_ok());
assert!(bus.write(0x10, &[0, 0, 0, 0]).is_ok());
assert!(bus.read(0x11, &mut [0, 0, 0, 0]).is_ok());
assert!(bus.write(0x11, &[0, 0, 0, 0]).is_ok());
assert!(bus.read(0x16, &mut [0, 0, 0, 0]).is_ok());
assert!(bus.write(0x16, &[0, 0, 0, 0]).is_ok());
assert!(bus.read(0x20, &mut [0, 0, 0, 0]).is_err());
assert!(bus.write(0x20, &mut [0, 0, 0, 0]).is_err());
assert!(bus.read(0x06, &mut [0, 0, 0, 0]).is_err());
assert!(bus.write(0x06, &mut [0, 0, 0, 0]).is_err());
}
#[test]
@ -309,12 +309,12 @@ mod tests {
assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
let mut values = [0, 1, 2, 3];
assert!(bus.read(0x10, &mut values));
assert!(bus.read(0x10, &mut values).is_ok());
assert_eq!(values, [0, 1, 2, 3]);
assert!(bus.write(0x10, &values));
assert!(bus.read(0x15, &mut values));
assert!(bus.write(0x10, &values).is_ok());
assert!(bus.read(0x15, &mut values).is_ok());
assert_eq!(values, [5, 6, 7, 8]);
assert!(bus.write(0x15, &values));
assert!(bus.write(0x15, &values).is_ok());
}
#[test]
@ -332,8 +332,8 @@ mod tests {
let mut data = [1, 2, 3, 4];
let device = Arc::new(Mutex::new(DummyDevice));
assert!(bus.insert(device.clone(), 0x10, 0x10).is_ok());
assert!(bus.write(0x10, &mut data));
assert!(bus.read(0x10, &mut data));
assert!(bus.write(0x10, &mut data).is_ok());
assert!(bus.read(0x10, &mut data).is_ok());
assert_eq!(data, [1, 2, 3, 4]);
}

View File

@ -321,7 +321,11 @@ impl Vcpu {
Ok(run) => match run {
#[cfg(target_arch = "x86_64")]
VmExit::IoIn(addr, data) => {
self.io_bus.read(u64::from(addr), data);
if let Err(e) = self.io_bus.read(u64::from(addr), data) {
if let devices::BusError::MissingAddressRange = e {
warn!("Guest PIO read to unregistered address 0x{:x}", addr);
}
}
Ok(true)
}
#[cfg(target_arch = "x86_64")]
@ -329,15 +333,27 @@ impl Vcpu {
if addr == DEBUG_IOPORT && data.len() == 1 {
self.log_debug_ioport(data[0]);
}
self.io_bus.write(u64::from(addr), data);
if let Err(e) = self.io_bus.write(u64::from(addr), data) {
if let devices::BusError::MissingAddressRange = e {
warn!("Guest PIO write to unregistered address 0x{:x}", addr);
}
}
Ok(true)
}
VmExit::MmioRead(addr, data) => {
self.mmio_bus.read(addr as u64, data);
if let Err(e) = self.mmio_bus.read(addr as u64, data) {
if let devices::BusError::MissingAddressRange = e {
warn!("Guest MMIO read to unregistered address 0x{:x}", addr);
}
}
Ok(true)
}
VmExit::MmioWrite(addr, data) => {
self.mmio_bus.write(addr as u64, data);
if let Err(e) = self.mmio_bus.write(addr as u64, data) {
if let devices::BusError::MissingAddressRange = e {
warn!("Guest MMIO write to unregistered address 0x{:x}", addr);
}
}
Ok(true)
}
#[cfg(target_arch = "x86_64")]