feat(hvf): create and destroy VCPUs

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
This commit is contained in:
Changyuan Lyu 2024-06-23 15:08:05 -07:00 committed by Lencerf
parent 8165673b00
commit f0719ff1c4
6 changed files with 92 additions and 10 deletions

View file

@ -13,6 +13,7 @@
// limitations under the License.
use crate::c_enum;
use bitfield::bitfield;
use bitflags::bitflags;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@ -58,8 +59,12 @@ pub const fn encode(op0: u16, op1: u16, crn: u16, crm: u16, op2: u16) -> u16 {
}
c_enum! {
/// https://developer.arm.com/documentation/ddi0601/2020-12/Index-by-Encoding
pub struct SReg(u16);
{
/// Exception Syndrome Register (EL2)
ESR_EL2 = encode(3, 4, 5, 2, 0);
/// Multiprocessor Affinity Register
MPIDR_EL1 = encode(3, 0, 0, 0, 5);
}
}
@ -95,3 +100,17 @@ bitflags! {
const EL_H = 1 << 0;
}
}
bitfield! {
/// Exception Syndrome Register (EL2)
///
/// https://developer.arm.com/documentation/ddi0595/2020-12/AArch64-Registers/ESR-EL2--Exception-Syndrome-Register--EL2-
#[derive(Copy, Clone, Default, PartialEq, Eq, Hash)]
#[repr(transparent)]
pub struct EsrEl2(u64);
impl Debug;
pub iss2, _: 36, 32;
pub ec, _: 31, 26;
pub il, _: 25;
pub iss, _: 24, 0;
}

View file

@ -12,8 +12,41 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::os::raw::c_void;
use crate::arch::reg::EsrEl2;
use crate::c_enum;
c_enum! {
#[derive(Default)]
pub struct HvExitReason(u32);
{
CANCEL = 0;
EXCEPTION = 1;
VTIMER_ACTIVATED = 2;
UNKNOWN = 3;
}
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct HvVcpuExitException {
pub syndrome: EsrEl2,
pub virtual_address: u64,
pub physical_address: u64,
}
#[repr(C)]
#[derive(Debug, Clone, Default)]
pub struct HvVcpuExit {
pub reason: HvExitReason,
pub exception: HvVcpuExitException,
}
#[link(name = "Hypervisor", kind = "framework")]
extern "C" {
pub fn hv_vm_create(config: *mut i32) -> i32;
pub fn hv_vm_destroy() -> i32;
pub fn hv_vcpu_create(vcpu: &mut u64, exit: &mut *mut HvVcpuExit, config: *mut c_void) -> i32;
pub fn hv_vcpu_destroy(vcpu: u64) -> i32;
}

View file

@ -17,10 +17,12 @@ mod bindings;
mod vcpu;
mod vm;
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
use std::ptr::null_mut;
use bindings::hv_vm_create;
use parking_lot::Mutex;
use snafu::ResultExt;
use crate::hv::{error, Hypervisor, Result, VmConfig};
@ -61,6 +63,8 @@ impl Hypervisor for Hvf {
fn create_vm(&self, _config: &VmConfig) -> Result<Self::Vm> {
let ret = unsafe { hv_vm_create(null_mut()) };
check_ret(ret).context(error::CreateVm)?;
Ok(HvfVm {})
Ok(HvfVm {
vcpus: Mutex::new(HashMap::new()),
})
}
}

View file

@ -13,10 +13,24 @@
// limitations under the License.
use crate::arch::reg::{Reg, SReg};
use crate::hv::hvf::bindings::{hv_vcpu_destroy, HvVcpuExit};
use crate::hv::hvf::check_ret;
use crate::hv::{Result, Vcpu, VmEntry, VmExit};
#[derive(Debug)]
pub struct HvfVcpu {}
pub struct HvfVcpu {
pub exit: *mut HvVcpuExit,
pub vcpu_id: u64,
}
impl Drop for HvfVcpu {
fn drop(&mut self) {
let ret = unsafe { hv_vcpu_destroy(self.vcpu_id) };
if let Err(e) = check_ret(ret) {
log::error!("hv_vcpu_destroy: {e:?}");
}
}
}
impl Vcpu for HvfVcpu {
fn reset(&self, _is_bsp: bool) -> Result<()> {

View file

@ -12,15 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
use std::collections::HashMap;
use std::os::fd::{AsFd, BorrowedFd};
use std::ptr::null_mut;
use std::thread::JoinHandle;
use crate::hv::hvf::bindings::hv_vm_destroy;
use parking_lot::Mutex;
use snafu::ResultExt;
use crate::hv::hvf::bindings::{hv_vcpu_create, hv_vm_destroy};
use crate::hv::hvf::check_ret;
use crate::hv::hvf::vcpu::HvfVcpu;
use crate::hv::{
GicV2, IoeventFd, IoeventFdRegistry, IrqFd, IrqSender, MemMapOption, MsiSender, Result, Vm,
VmMemory,
error, GicV2, IoeventFd, IoeventFdRegistry, IrqFd, IrqSender, MemMapOption, MsiSender, Result,
Vm, VmMemory,
};
#[derive(Debug)]
@ -173,7 +178,9 @@ impl GicV2 for HvfGicV2 {
}
#[derive(Debug)]
pub struct HvfVm {}
pub struct HvfVm {
pub(super) vcpus: Mutex<HashMap<u32, u64>>,
}
impl Drop for HvfVm {
fn drop(&mut self) {
@ -195,8 +202,13 @@ impl Vm for HvfVm {
fn create_msi_sender(&self) -> Result<Self::MsiSender> {
unimplemented!()
}
fn create_vcpu(&self, _id: u32) -> Result<Self::Vcpu> {
unimplemented!()
fn create_vcpu(&self, id: u32) -> Result<Self::Vcpu> {
let mut exit = null_mut();
let mut vcpu_id = 0;
let ret = unsafe { hv_vcpu_create(&mut vcpu_id, &mut exit, null_mut()) };
check_ret(ret).context(error::CreateVcpu)?;
self.vcpus.lock().insert(id, vcpu_id);
Ok(HvfVcpu { exit, vcpu_id })
}
fn create_vm_memory(&mut self) -> Result<Self::Memory> {
unimplemented!()

View file

@ -105,7 +105,7 @@ macro_rules! c_enum {
$(#[$attr:meta])*
$vs:vis struct $EnumName:ident($TyName:ty);
{
$($VARIANT:ident = $value:expr;)*
$( $(#[$vattr:meta])* $VARIANT:ident = $value:expr;)*
}
) => {
#[repr(transparent)]
@ -114,7 +114,7 @@ macro_rules! c_enum {
$vs struct $EnumName($TyName);
impl $EnumName {
$(pub const $VARIANT: $EnumName = $EnumName($value);)*
$($(#[$vattr])* pub const $VARIANT: $EnumName = $EnumName($value);)*
pub const fn raw(self) -> $TyName {
self.0