mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-02-22 03:12:27 +00:00
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:
parent
7f2ee1f984
commit
e5ce6dc43c
@ -214,30 +214,30 @@ impl Bus {
|
|||||||
/// Reads data from the device that owns the range containing `addr` and puts it into `data`.
|
/// Reads data from the device that owns the range containing `addr` and puts it into `data`.
|
||||||
///
|
///
|
||||||
/// Returns true on success, otherwise `data` is untouched.
|
/// 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) {
|
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()
|
dev.lock()
|
||||||
.expect("Failed to acquire device lock")
|
.expect("Failed to acquire device lock")
|
||||||
.read(base, offset, data);
|
.read(base, offset, data);
|
||||||
true
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
false
|
Err(Error::MissingAddressRange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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]) -> bool {
|
pub fn write(&self, addr: u64, data: &[u8]) -> Result<()> {
|
||||||
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()
|
dev.lock()
|
||||||
.expect("Failed to acquire device lock")
|
.expect("Failed to acquire device lock")
|
||||||
.write(base, offset, data);
|
.write(base, offset, data);
|
||||||
true
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
false
|
Err(Error::MissingAddressRange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -290,16 +290,16 @@ mod tests {
|
|||||||
let bus = Bus::new();
|
let bus = Bus::new();
|
||||||
let dummy = Arc::new(Mutex::new(DummyDevice));
|
let dummy = Arc::new(Mutex::new(DummyDevice));
|
||||||
assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
|
assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
|
||||||
assert!(bus.read(0x10, &mut [0, 0, 0, 0]));
|
assert!(bus.read(0x10, &mut [0, 0, 0, 0]).is_ok());
|
||||||
assert!(bus.write(0x10, &[0, 0, 0, 0]));
|
assert!(bus.write(0x10, &[0, 0, 0, 0]).is_ok());
|
||||||
assert!(bus.read(0x11, &mut [0, 0, 0, 0]));
|
assert!(bus.read(0x11, &mut [0, 0, 0, 0]).is_ok());
|
||||||
assert!(bus.write(0x11, &[0, 0, 0, 0]));
|
assert!(bus.write(0x11, &[0, 0, 0, 0]).is_ok());
|
||||||
assert!(bus.read(0x16, &mut [0, 0, 0, 0]));
|
assert!(bus.read(0x16, &mut [0, 0, 0, 0]).is_ok());
|
||||||
assert!(bus.write(0x16, &[0, 0, 0, 0]));
|
assert!(bus.write(0x16, &[0, 0, 0, 0]).is_ok());
|
||||||
assert!(!bus.read(0x20, &mut [0, 0, 0, 0]));
|
assert!(bus.read(0x20, &mut [0, 0, 0, 0]).is_err());
|
||||||
assert!(!bus.write(0x20, &mut [0, 0, 0, 0]));
|
assert!(bus.write(0x20, &mut [0, 0, 0, 0]).is_err());
|
||||||
assert!(!bus.read(0x06, &mut [0, 0, 0, 0]));
|
assert!(bus.read(0x06, &mut [0, 0, 0, 0]).is_err());
|
||||||
assert!(!bus.write(0x06, &mut [0, 0, 0, 0]));
|
assert!(bus.write(0x06, &mut [0, 0, 0, 0]).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -309,12 +309,12 @@ mod tests {
|
|||||||
assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
|
assert!(bus.insert(dummy.clone(), 0x10, 0x10).is_ok());
|
||||||
|
|
||||||
let mut values = [0, 1, 2, 3];
|
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_eq!(values, [0, 1, 2, 3]);
|
||||||
assert!(bus.write(0x10, &values));
|
assert!(bus.write(0x10, &values).is_ok());
|
||||||
assert!(bus.read(0x15, &mut values));
|
assert!(bus.read(0x15, &mut values).is_ok());
|
||||||
assert_eq!(values, [5, 6, 7, 8]);
|
assert_eq!(values, [5, 6, 7, 8]);
|
||||||
assert!(bus.write(0x15, &values));
|
assert!(bus.write(0x15, &values).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -332,8 +332,8 @@ mod tests {
|
|||||||
let mut data = [1, 2, 3, 4];
|
let mut data = [1, 2, 3, 4];
|
||||||
let device = Arc::new(Mutex::new(DummyDevice));
|
let device = Arc::new(Mutex::new(DummyDevice));
|
||||||
assert!(bus.insert(device.clone(), 0x10, 0x10).is_ok());
|
assert!(bus.insert(device.clone(), 0x10, 0x10).is_ok());
|
||||||
assert!(bus.write(0x10, &mut data));
|
assert!(bus.write(0x10, &mut data).is_ok());
|
||||||
assert!(bus.read(0x10, &mut data));
|
assert!(bus.read(0x10, &mut data).is_ok());
|
||||||
assert_eq!(data, [1, 2, 3, 4]);
|
assert_eq!(data, [1, 2, 3, 4]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +321,11 @@ impl Vcpu {
|
|||||||
Ok(run) => match run {
|
Ok(run) => match run {
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
VmExit::IoIn(addr, data) => {
|
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)
|
Ok(true)
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -329,15 +333,27 @@ impl Vcpu {
|
|||||||
if addr == DEBUG_IOPORT && data.len() == 1 {
|
if addr == DEBUG_IOPORT && data.len() == 1 {
|
||||||
self.log_debug_ioport(data[0]);
|
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)
|
Ok(true)
|
||||||
}
|
}
|
||||||
VmExit::MmioRead(addr, data) => {
|
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)
|
Ok(true)
|
||||||
}
|
}
|
||||||
VmExit::MmioWrite(addr, data) => {
|
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)
|
Ok(true)
|
||||||
}
|
}
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user