Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add macro c_enum for C enum bindings #41

Merged
merged 5 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 50 additions & 28 deletions alioth/src/hv/kvm/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,21 @@ 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;

pub const KVM_X86_DEFAULT_VM: u64 = 0;
// pub const KVM_X86_SW_PROTECTED_VM: u64 = 1;
// pub const KVM_X86_SEV_VM: u64 = 2;
// pub const KVM_X86_SEV_ES_VM: u64 = 3;
pub const KVM_X86_SNP_VM: u64 = 4;
c_enum! {
pub struct KvmVmType(u64);
{
DEFAULT = 0;
SW_PROTECTED = 1;
SEV = 2;
SEV_ES = 3;
SNP = 4;
}
}

pub const KVM_MAX_CPUID_ENTRIES: usize = 256;

Expand Down Expand Up @@ -208,45 +215,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,
Expand All @@ -268,14 +293,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 {
Expand Down Expand Up @@ -395,12 +412,17 @@ pub struct KvmMsi {
pub pad: [u8; 12usize],
}

pub const KVM_CAP_NR_MEMSLOTS: u32 = 10;
pub const KVM_CAP_IRQFD: u32 = 32;
pub const KVM_CAP_SIGNAL_MSI: u32 = 77;
pub const KVM_CAP_EXIT_HYPERCALL: u32 = 201;
// pub const KVM_CAP_GUEST_MEMFD: u32 = 234;
// pub const KVM_CAP_VM_TYPES: u32 = 235;
c_enum! {
pub struct KvmCap(u32);
{
NR_MEMSLOTS = 10;
IRQFD = 32;
SIGNAL_MSI = 77;
EXIT_HYPERCALL = 201;
// GUEST_MEMFD = 234;
// VM_TYPES = 235;
}
}

pub const KVM_HC_MAP_GPA_RANGE: u64 = 12;

Expand Down Expand Up @@ -443,7 +465,7 @@ pub struct KvmEncRegion {
#[repr(C)]
#[derive(Debug, Clone)]
pub struct KvmEnableCap {
pub cap: u32,
pub cap: KvmCap,
pub flags: u32,
pub args: [u64; 4],
pub pad: [u8; 64],
Expand Down
10 changes: 5 additions & 5 deletions alioth/src/hv/kvm/ioctls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
// limitations under the License.

use crate::hv::kvm::bindings::{
KvmCpuid2, KvmCreateGuestMemfd, KvmEnableCap, KvmEncRegion, KvmIoEventFd, KvmIrqRouting,
KvmIrqfd, KvmMemoryAttributes, KvmMsi, KvmRegs, KvmSregs, KvmSregs2, KvmUserspaceMemoryRegion,
KvmUserspaceMemoryRegion2, KVMIO,
KvmCap, KvmCpuid2, KvmCreateGuestMemfd, KvmEnableCap, KvmEncRegion, KvmIoEventFd,
KvmIrqRouting, KvmIrqfd, KvmMemoryAttributes, KvmMsi, KvmRegs, KvmSregs, KvmSregs2,
KvmUserspaceMemoryRegion, KvmUserspaceMemoryRegion2, KvmVmType, KVMIO,
};
use crate::utils::ioctls::{ioctl_io, ioctl_ior, ioctl_iowr};
use crate::{
Expand All @@ -24,8 +24,8 @@ use crate::{
};

ioctl_none!(kvm_get_api_version, KVMIO, 0x00, 0);
ioctl_write_val!(kvm_create_vm, ioctl_io(KVMIO, 0x01));
ioctl_write_val!(kvm_check_extension, ioctl_io(KVMIO, 0x03), u32);
ioctl_write_val!(kvm_create_vm, ioctl_io(KVMIO, 0x01), KvmVmType);
ioctl_write_val!(kvm_check_extension, ioctl_io(KVMIO, 0x03), KvmCap);
ioctl_none!(kvm_get_vcpu_mmap_size, KVMIO, 0x04, 0);
#[cfg(target_arch = "x86_64")]
ioctl_writeread_buf!(kvm_get_supported_cpuid, KVMIO, 0x05, KvmCpuid2);
Expand Down
12 changes: 6 additions & 6 deletions alioth/src/hv/kvm/kvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ use crate::hv::Cpuid;
use crate::hv::{error, Coco, Hypervisor, MemMapOption, Result, VmConfig};

use bindings::{
KvmCpuid2, KvmCpuid2Flag, KvmCpuidEntry2, KvmCreateGuestMemfd, KvmEnableCap, KVM_API_VERSION,
KVM_CAP_EXIT_HYPERCALL, KVM_MAX_CPUID_ENTRIES, KVM_X86_DEFAULT_VM, KVM_X86_SNP_VM,
KvmCap, KvmCpuid2, KvmCpuid2Flag, KvmCpuidEntry2, KvmCreateGuestMemfd, KvmEnableCap, KvmVmType,
KVM_API_VERSION, KVM_MAX_CPUID_ENTRIES,
};
use ioctls::{
kvm_check_extension, kvm_create_guest_memfd, kvm_create_irqchip, kvm_create_vm, kvm_enable_cap,
Expand Down Expand Up @@ -144,9 +144,9 @@ impl Hypervisor for Kvm {
let vcpu_mmap_size =
unsafe { kvm_get_vcpu_mmap_size(&self.fd) }.context(error::CreateVm)? as usize;
let kvm_vm_type = if let Some(Coco::AmdSnp { .. }) = &config.coco {
KVM_X86_SNP_VM
KvmVmType::SNP
} else {
KVM_X86_DEFAULT_VM
KvmVmType::DEFAULT
};
let vm_fd = unsafe { kvm_create_vm(&self.fd, kvm_vm_type) }.context(error::CreateVm)?;
let fd = unsafe { OwnedFd::from_raw_fd(vm_fd) };
Expand Down Expand Up @@ -194,13 +194,13 @@ impl Hypervisor for Kvm {
}
}
Coco::AmdSnp { .. } => {
let bitmap = unsafe { kvm_check_extension(&kvm_vm.vm, KVM_CAP_EXIT_HYPERCALL) }
let bitmap = unsafe { kvm_check_extension(&kvm_vm.vm, KvmCap::EXIT_HYPERCALL) }
.context(kvm_error::CheckExtension {
ext: "KVM_CAP_EXIT_HYPERCALL",
})?;
if bitmap != 0 {
let request = KvmEnableCap {
cap: KVM_CAP_EXIT_HYPERCALL,
cap: KvmCap::EXIT_HYPERCALL,
args: [bitmap as _, 0, 0, 0],
flags: 0,
pad: [0; 64],
Expand Down
14 changes: 6 additions & 8 deletions alioth/src/hv/kvm/vcpu/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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))),
},
}
}
Expand Down
13 changes: 6 additions & 7 deletions alioth/src/hv/kvm/vm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,10 @@ use snafu::ResultExt;
use crate::arch::sev::{SnpPageType, SnpPolicy};
use crate::ffi;
use crate::hv::kvm::bindings::{
KvmEncRegion, KvmIoEventFd, KvmIoEventFdFlag, KvmIrqRouting, KvmIrqRoutingEntry,
KvmCap, KvmEncRegion, KvmIoEventFd, KvmIoEventFdFlag, KvmIrqRouting, KvmIrqRoutingEntry,
KvmIrqRoutingIrqchip, KvmIrqRoutingMsi, KvmIrqfd, KvmIrqfdFlag, KvmMemFlag, KvmMemoryAttribute,
KvmMemoryAttributes, KvmMsi, KvmUserspaceMemoryRegion, KvmUserspaceMemoryRegion2,
KVM_CAP_IRQFD, KVM_CAP_NR_MEMSLOTS, KVM_CAP_SIGNAL_MSI, KVM_IRQCHIP_IOAPIC,
KVM_IRQ_ROUTING_IRQCHIP, KVM_IRQ_ROUTING_MSI,
KVM_IRQCHIP_IOAPIC, KVM_IRQ_ROUTING_IRQCHIP, KVM_IRQ_ROUTING_MSI,
};
use crate::hv::kvm::ioctls::{
kvm_check_extension, kvm_create_vcpu, kvm_ioeventfd, kvm_irqfd, kvm_memory_encrypt_op,
Expand Down Expand Up @@ -109,7 +108,7 @@ impl VmInner {
Ok(())
}

fn check_extension(&self, id: u32) -> Result<i32, Error> {
fn check_extension(&self, id: KvmCap) -> Result<i32, Error> {
let ret = unsafe { kvm_check_extension(self, id) };
match ret {
Ok(num) => Ok(num),
Expand Down Expand Up @@ -206,7 +205,7 @@ impl VmMemory for KvmMemory {

fn max_mem_slots(&self) -> Result<u32, Error> {
self.vm
.check_extension(KVM_CAP_NR_MEMSLOTS)
.check_extension(KvmCap::NR_MEMSLOTS)
.map(|r| r as u32)
}

Expand Down Expand Up @@ -599,7 +598,7 @@ impl Vm for KvmVm {
return Err(std::io::ErrorKind::AlreadyExists.into())
.context(error::CreateIntx { pin });
}
if self.vm.check_extension(KVM_CAP_IRQFD)? == 0 {
if self.vm.check_extension(KvmCap::IRQFD)? == 0 {
return error::Capability {
cap: "KVM_CAP_IRQFD",
}
Expand All @@ -622,7 +621,7 @@ impl Vm for KvmVm {
}

fn create_msi_sender(&self) -> Result<Self::MsiSender> {
if self.vm.check_extension(KVM_CAP_SIGNAL_MSI)? == 0 {
if self.vm.check_extension(KvmCap::SIGNAL_MSI)? == 0 {
return error::Capability {
cap: "KVM_CAP_SIGNAL_MSI",
}
Expand Down
10 changes: 6 additions & 4 deletions alioth/src/hv/kvm/vmentry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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 {
Expand Down
14 changes: 6 additions & 8 deletions alioth/src/hv/kvm/vmexit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
),
};
Expand Down
Loading