Skip to content

Commit

Permalink
modifications for libkrun integration
Browse files Browse the repository at this point in the history
Signed-off-by: Jake Correnti <[email protected]>
  • Loading branch information
jakecorrenti committed Sep 18, 2024
1 parent 487699b commit 6b363ba
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 19 deletions.
46 changes: 31 additions & 15 deletions src/launch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,17 @@ use kvm_bindings::{kvm_enable_cap, KVM_CAP_MAX_VCPUS, KVM_CAP_SPLIT_IRQCHIP};
use linux::{Capabilities, Cmd, CmdId, CpuidConfig, InitVm, TdxError};

use bitflags::bitflags;
use kvm_ioctls::{Kvm, VmFd};
use kvm_ioctls::VmFd;

// Defined in linux/arch/x86/include/uapi/asm/kvm.h
pub const KVM_X86_TDX_VM: u64 = 2;

/// Handle to the TDX VM file descriptor
pub struct TdxVm<'a> {
fd: &'a VmFd,
}
pub struct TdxVm {}

impl<'a> TdxVm<'a> {
impl TdxVm {
/// Create a new TDX VM with KVM
pub fn new(vm_fd: &'a VmFd, max_vcpus: u64) -> Result<Self, TdxError> {
pub fn new(vm_fd: &VmFd, max_vcpus: u64) -> Result<Self, TdxError> {
// TDX requires that MAX_VCPUS and SPLIT_IRQCHIP be set
let mut cap: kvm_enable_cap = kvm_enable_cap {
cap: KVM_CAP_MAX_VCPUS,
Expand All @@ -35,16 +33,16 @@ impl<'a> TdxVm<'a> {
cap.args[0] = (1 << 0) | (1 << 1);
vm_fd.enable_cap(&cap).unwrap();

Ok(Self { fd: vm_fd })
Ok(Self {})
}

/// Retrieve information about the Intel TDX module
pub fn get_capabilities(&self) -> Result<TdxCapabilities, TdxError> {
pub fn get_capabilities(&self, fd: &VmFd) -> Result<TdxCapabilities, TdxError> {
let caps = Capabilities::default();
let mut cmd: Cmd = Cmd::from(&caps);

unsafe {
self.fd.encrypt_op(&mut cmd)?;
fd.encrypt_op(&mut cmd)?;
}

Ok(TdxCapabilities {
Expand All @@ -62,7 +60,7 @@ impl<'a> TdxVm<'a> {
}

/// Do additional VM initialization that is specific to Intel TDX
pub fn init_vm(&self, cpuid: kvm_bindings::CpuId) -> Result<kvm_bindings::CpuId, TdxError> {
pub fn init_vm(&self, fd: &VmFd, cpuid: kvm_bindings::CpuId) -> Result<(), TdxError> {
let mut cpuid_entries: Vec<kvm_bindings::kvm_cpuid_entry2> = cpuid.as_slice().to_vec();

// resize to 256 entries to make sure that InitVm is 8KB
Expand All @@ -88,15 +86,16 @@ impl<'a> TdxVm<'a> {

let mut cmd = Cmd::from(&InitVm::new(&cpuid_entries));
unsafe {
self.fd.encrypt_op(&mut cmd)?;
fd.encrypt_op(&mut cmd)?;
}

Ok(cpuid)
Ok(())
}

/// Encrypt a memory continuous region
pub fn init_mem_region(
&self,
fd: &VmFd,
gpa: u64,
nr_pages: u64,
attributes: u32,
Expand All @@ -119,20 +118,20 @@ impl<'a> TdxVm<'a> {
};

unsafe {
self.fd.encrypt_op(&mut cmd)?;
fd.encrypt_op(&mut cmd)?;
}

Ok(())
}

/// Complete measurement of the initial TD contents and mark it ready to run
pub fn finalize(&self) -> Result<(), TdxError> {
pub fn finalize(&self, fd: &VmFd) -> Result<(), TdxError> {
let mut cmd = Cmd {
id: CmdId::FinalizeVm as u32,
..Default::default()
};
unsafe {
self.fd.encrypt_op(&mut cmd)?;
fd.encrypt_op(&mut cmd)?;
}

Ok(())
Expand Down Expand Up @@ -300,6 +299,23 @@ pub struct TdxVcpu<'a> {
}

impl<'a> TdxVcpu<'a> {
pub fn init_raw(fd: &kvm_ioctls::VcpuFd, hob_address: u64) -> Result<(), TdxError> {
let mut cmd = Cmd {
id: linux::CmdId::InitVcpu as u32,
flags: 0,
data: hob_address as *const u64 as _,
error: 0,
_unused: 0,
};
let ret = unsafe { ioctl::ioctl_with_mut_ptr(fd, KVM_MEMORY_ENCRYPT_OP(), &mut cmd) };
if ret < 0 {
// can't return `ret` because it will just return -1 and not give the error
// code. `cmd.error` will also just be 0.
return Err(TdxError::from(errno::Error::last()));
}
Ok(())
}

pub fn init(&self, hob_address: u64) -> Result<(), TdxError> {
let mut cmd = Cmd {
id: linux::CmdId::InitVcpu as u32,
Expand Down
8 changes: 4 additions & 4 deletions tests/launch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ fn launch() {
let mut kvm_fd = Kvm::new().unwrap();
let vm_fd = kvm_fd.create_vm_with_type(tdx::launch::KVM_X86_TDX_VM).unwrap();
let tdx_vm = TdxVm::new(&vm_fd, 100).unwrap();
let _caps = tdx_vm.get_capabilities().unwrap();
let _caps = tdx_vm.get_capabilities(&vm_fd).unwrap();
let cpuid = kvm_fd
.get_supported_cpuid(kvm_bindings::KVM_MAX_CPUID_ENTRIES)
.unwrap();
let _ = tdx_vm.init_vm(cpuid).unwrap();
let _ = tdx_vm.init_vm(&vm_fd, cpuid).unwrap();

// get tdvf sections
let mut firmware = std::fs::File::open("/usr/share/edk2/ovmf/OVMF.inteltdx.fd").unwrap();
Expand Down Expand Up @@ -104,12 +104,12 @@ fn launch() {
// KVM_TDX_EXTEND_MEMORY ioctls, which is what we would typically use here.
} else {
tdx_vm
.init_mem_region(guest_addr, 1, 1, firmware_userspace)
.init_mem_region(&vm_fd, guest_addr, 1, 1, firmware_userspace)
.unwrap();
}

// finalize measurement
tdx_vm.finalize().unwrap();
tdx_vm.finalize(&vm_fd).unwrap();

// run the vCPU

Expand Down

0 comments on commit 6b363ba

Please sign in to comment.