refactor(kvm): use c_enum for VM exit constants

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
This commit is contained in:
Changyuan Lyu 2024-06-16 13:12:46 -07:00 committed by Lencerf
parent 4cb8d9c799
commit 6c00567356
4 changed files with 46 additions and 36 deletions

View file

@ -16,6 +16,8 @@ use std::fmt::{Debug, Formatter, Result};
use bitflags::bitflags;
use crate::c_enum;
pub const KVMIO: u8 = 0xAE;
pub const KVM_API_VERSION: i32 = 12;
@ -208,45 +210,63 @@ pub struct KvmSregs2 {
pub pdptrs: [u64; 4],
}
c_enum! {
pub struct KvmExit(u32);
{
IO = 2;
HYPERCALL = 3;
MMIO = 6;
SHUTDOWN = 8;
}
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct KvmRun {
pub request_interrupt_window: u8,
pub immediate_exit: u8,
pub padding1: [u8; 6],
pub exit_reason: u32,
pub exit_reason: KvmExit,
pub ready_for_interrupt_injection: u8,
pub if_flag: u8,
pub flags: u16,
pub cr8: u64,
pub apic_base: u64,
pub exit: KvmExit,
pub exit: KvmRunExit,
pub kvm_valid_regs: u64,
pub kvm_dirty_regs: u64,
pub s: KvmSyncRegsBlock,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union KvmExit {
pub mmio: KvmExitMmio,
pub io: KvmExitIo,
pub union KvmRunExit {
pub mmio: KvmRunExitMmio,
pub io: KvmRunExitIo,
pub hypercall: KvmRunExitHypercall,
pub padding: [u8; 256],
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct KvmExitMmio {
pub struct KvmRunExitMmio {
pub phys_addr: u64,
pub data: [u8; 8],
pub len: u32,
pub is_write: u8,
}
c_enum! {
pub struct KvmExitIo(u8);
{
IN = 0;
OUT = 1;
}
}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct KvmExitIo {
pub direction: u8,
pub struct KvmRunExitIo {
pub direction: KvmExitIo,
pub size: u8,
pub port: u16,
pub count: u32,
@ -268,14 +288,6 @@ pub union KvmSyncRegsBlock {
pub padding: [u8; 2048],
}
pub const KVM_EXIT_IO: u32 = 2;
pub const KVM_EXIT_HYPERCALL: u32 = 3;
pub const KVM_EXIT_MMIO: u32 = 6;
pub const KVM_EXIT_SHUTDOWN: u32 = 8;
pub const KVM_EXIT_IO_IN: u8 = 0;
pub const KVM_EXIT_IO_OUT: u8 = 1;
bitflags! {
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct KvmIrqfdFlag: u32 {

View file

@ -25,15 +25,13 @@ use snafu::ResultExt;
use crate::ffi;
use crate::hv::arch::Reg;
use crate::hv::kvm::bindings::{KvmRun, KVM_EXIT_IO, KVM_EXIT_MMIO};
use crate::hv::kvm::bindings::{KvmExit, KvmRun};
use crate::hv::kvm::ioctls::kvm_run;
use crate::hv::kvm::{kvm_error, KvmError};
use crate::hv::{error, Error, Vcpu, VmEntry, VmExit};
#[cfg(target_arch = "x86_64")]
use crate::hv::{Cpuid, DtReg, DtRegVal, SReg, SegReg, SegRegVal};
use super::bindings::{KVM_EXIT_HYPERCALL, KVM_EXIT_SHUTDOWN};
pub(super) struct KvmRunBlock {
addr: usize,
size: usize,
@ -146,11 +144,11 @@ impl Vcpu for KvmVcpu {
_ => Err(e).context(error::RunVcpu),
},
Ok(_) => match self.kvm_run.exit_reason {
KVM_EXIT_IO => self.handle_io(),
KVM_EXIT_HYPERCALL => self.handle_hypercall(),
KVM_EXIT_MMIO => self.handle_mmio(),
KVM_EXIT_SHUTDOWN => Ok(VmExit::Shutdown),
reason => Ok(VmExit::Unknown(format!("unkown kvm exit: {:#x}", reason))),
KvmExit::IO => self.handle_io(),
KvmExit::HYPERCALL => self.handle_hypercall(),
KvmExit::MMIO => self.handle_mmio(),
KvmExit::SHUTDOWN => Ok(VmExit::Shutdown),
reason => Ok(VmExit::Unknown(format!("unkown kvm exit: {:#x?}", reason))),
},
}
}

View file

@ -12,14 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::hv::kvm::bindings::{KVM_EXIT_IO, KVM_EXIT_IO_IN, KVM_EXIT_MMIO};
use crate::hv::kvm::bindings::{KvmExit, KvmExitIo};
use super::vcpu::KvmVcpu;
impl KvmVcpu {
#[cfg(target_endian = "little")]
pub(super) fn entry_mmio(&mut self, data: u64) {
assert_eq!(self.kvm_run.exit_reason, KVM_EXIT_MMIO);
use crate::hv::kvm::bindings::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();
@ -30,9 +32,9 @@ impl KvmVcpu {
}
pub(super) fn entry_io(&mut self, data: u32) {
assert_eq!(self.kvm_run.exit_reason, KVM_EXIT_IO);
assert_eq!(self.kvm_run.exit_reason, KvmExit::IO);
let kvm_io = unsafe { &self.kvm_run.exit.io };
assert_eq!(kvm_io.direction, KVM_EXIT_IO_IN);
assert_eq!(kvm_io.direction, KvmExitIo::IN);
let offset = kvm_io.data_offset as usize;
let count = kvm_io.count as usize;
match kvm_io.size {

View file

@ -12,9 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use crate::hv::kvm::bindings::{
KvmMapGpaRangeFlag, KVM_EXIT_IO_IN, KVM_EXIT_IO_OUT, KVM_HC_MAP_GPA_RANGE,
};
use crate::hv::kvm::bindings::{KvmExitIo, KvmMapGpaRangeFlag, KVM_HC_MAP_GPA_RANGE};
use crate::hv::{Error, VmExit};
use super::vcpu::KvmVcpu;
@ -41,18 +39,18 @@ impl KvmVcpu {
let count = kvm_io.count as usize;
assert_eq!(count, 1);
let write = match (kvm_io.direction, kvm_io.size) {
(KVM_EXIT_IO_IN, _) => None,
(KVM_EXIT_IO_OUT, 1) => {
(KvmExitIo::IN, _) => None,
(KvmExitIo::OUT, 1) => {
Some(unsafe { self.kvm_run.data_slice::<u8>(offset, count) }[0] as u32)
}
(KVM_EXIT_IO_OUT, 2) => {
(KvmExitIo::OUT, 2) => {
Some(unsafe { self.kvm_run.data_slice::<u16>(offset, count) }[0] as u32)
}
(KVM_EXIT_IO_OUT, 4) => {
(KvmExitIo::OUT, 4) => {
Some(unsafe { self.kvm_run.data_slice::<u32>(offset, count) }[0])
}
_ => unreachable!(
"kvm_io.direction = {}, kvm_io.size = {}",
"kvm_io.direction = {:?}, kvm_io.size = {}",
kvm_io.direction, kvm_io.size
),
};