use crate::{
api::launch::types::*,
error::{Error, Indeterminate},
impl_const_id,
};
use std::{
marker::PhantomData,
os::{raw::c_ulong, unix::io::AsRawFd},
};
use iocuddle::*;
impl_const_id! {
pub Id => u32;
Init = 0,
EsInit = 1,
LaunchStart<'_> = 2,
LaunchUpdateData<'_> = 3,
LaunchUpdateVmsa = 4,
LaunchSecret<'_> = 5,
LaunchMeasure<'_> = 6,
LaunchFinish = 7,
Attestation<'_> = 20,
}
const KVM: Group = Group::new(0xAE);
const ENC_OP: Ioctl<WriteRead, &c_ulong> = unsafe { KVM.write_read(0xBA) };
pub const INIT: Ioctl<WriteRead, &Command<Init>> = unsafe { ENC_OP.lie() };
pub const ES_INIT: Ioctl<WriteRead, &Command<EsInit>> = unsafe { ENC_OP.lie() };
pub const LAUNCH_START: Ioctl<WriteRead, &Command<LaunchStart>> = unsafe { ENC_OP.lie() };
pub const LAUNCH_UPDATE_DATA: Ioctl<WriteRead, &Command<LaunchUpdateData>> =
unsafe { ENC_OP.lie() };
pub const LAUNCH_UPDATE_VMSA: Ioctl<WriteRead, &Command<LaunchUpdateVmsa>> =
unsafe { ENC_OP.lie() };
pub const LAUNCH_SECRET: Ioctl<WriteRead, &Command<LaunchSecret>> = unsafe { ENC_OP.lie() };
pub const LAUNCH_MEASUREMENT: Ioctl<WriteRead, &Command<LaunchMeasure>> = unsafe { ENC_OP.lie() };
pub const LAUNCH_FINISH: Ioctl<WriteRead, &Command<LaunchFinish>> = unsafe { ENC_OP.lie() };
pub const ATTESTATION: Ioctl<WriteRead, &Command<Attestation>> = unsafe { ENC_OP.lie() };
pub const ENC_REG_REGION: Ioctl<Write, &KvmEncRegion> =
unsafe { KVM.read::<KvmEncRegion>(0xBB).lie() };
#[repr(C)]
#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
pub struct KvmEncRegion<'a> {
addr: u64,
size: u64,
phantom: PhantomData<&'a [u8]>,
}
impl<'a> KvmEncRegion<'a> {
pub fn new(data: &'a [u8]) -> Self {
Self {
addr: data.as_ptr() as _,
size: data.len() as _,
phantom: PhantomData,
}
}
pub fn register(&mut self, vm_fd: &mut impl AsRawFd) -> std::io::Result<std::os::raw::c_uint> {
ENC_REG_REGION.ioctl(vm_fd, self)
}
}
#[repr(C)]
pub struct Command<'a, T: Id> {
code: u32,
data: u64,
error: u32,
csv_fd: u32,
_phantom: PhantomData<&'a T>,
}
impl<'a, T: Id> Command<'a, T> {
pub fn from_mut(csv: &'a mut impl AsRawFd, subcmd: &'a mut T) -> Self {
Self {
code: T::ID,
data: subcmd as *mut T as _,
error: 0,
csv_fd: csv.as_raw_fd() as _,
_phantom: PhantomData,
}
}
pub fn from(csv: &'a mut impl AsRawFd, subcmd: &'a T) -> Self {
Self {
code: T::ID,
data: subcmd as *const T as _,
error: 0,
csv_fd: csv.as_raw_fd() as _,
_phantom: PhantomData,
}
}
pub fn encapsulate(&self, err: std::io::Error) -> Indeterminate<Error> {
match self.error {
0 => Indeterminate::<Error>::from(err),
_ => Indeterminate::<Error>::from(self.error),
}
}
}