#[cfg(target_arch = "x86_64")]
use crate::hv::VmExit;
use crate::hv::kvm::vcpu::KvmVcpu;
#[cfg(target_arch = "x86_64")]
use crate::sys::kvm::{KvmExit, KvmRunExitIo};
impl KvmVcpu {
#[cfg(target_endian = "little")]
pub(super) fn entry_mmio(&mut self, data: u64) {
use crate::sys::kvm::KvmExit;
assert_eq!(self.kvm_run.exit_reason, KvmExit::MMIO);
let kvm_mmio = unsafe { &mut self.kvm_run.exit.mmio };
assert_eq!(kvm_mmio.is_write, 0);
kvm_mmio.data = data.to_ne_bytes();
}
pub(super) fn set_immediate_exit(&mut self, enable: bool) {
self.kvm_run.immediate_exit = enable as u8;
}
#[cfg(target_arch = "x86_64")]
fn entry_io_in(&mut self, data: u32, kvm_io: KvmRunExitIo) {
let offset = kvm_io.data_offset as usize;
let count = kvm_io.count as usize;
let index = self.arch.io_index;
match kvm_io.size {
1 => unsafe {
self.kvm_run.data_slice_mut(offset, count)[index] = data as u8;
},
2 => unsafe {
self.kvm_run.data_slice_mut(offset, count)[index] = data as u16;
},
4 => unsafe {
self.kvm_run.data_slice_mut(offset, count)[index] = data;
},
_ => unreachable!("kvm_io.size = {}", kvm_io.size),
}
}
#[cfg(target_arch = "x86_64")]
pub(super) fn entry_io(&mut self, data: Option<u32>) -> Option<VmExit> {
assert_eq!(self.kvm_run.exit_reason, KvmExit::IO);
let kvm_io = unsafe { self.kvm_run.exit.io };
if let Some(data) = data {
self.entry_io_in(data, kvm_io);
}
self.arch.io_index += 1;
if self.arch.io_index == kvm_io.count as usize {
self.arch.io_index = 0;
return None;
}
Some(self.handle_io())
}
}