use core::marker::PhantomData;
use super::super::xstate::XstateSwitch;
use crate::{
PhysAddr,
registers::GeneralRegisters,
virtualization::{ControlMemory, GuestXstate},
};
#[repr(C)]
pub struct SvmEntryContext {
pub guest_regs: GeneralRegisters,
pub(crate) host_stack_top: u64,
pub(crate) host_rflags: u64,
pub(crate) host_vmcb_pa: u64,
pub(crate) xstate: *mut XstateSwitch,
local: PhantomData<*mut ()>,
}
impl SvmEntryContext {
pub fn new(host_save_area: PhysAddr) -> Self {
Self {
guest_regs: GeneralRegisters::default(),
host_stack_top: 0,
host_rflags: 0,
host_vmcb_pa: host_save_area.as_usize() as u64,
xstate: core::ptr::null_mut(),
local: PhantomData,
}
}
pub const fn host_flags(&self) -> u64 {
self.host_rflags
}
pub unsafe fn run<M: ControlMemory>(
&mut self,
guest_save_area: PhysAddr,
xstate: &mut GuestXstate<M>,
) {
unsafe extern "C" {
fn __ax_cpu_svm_enter(context: *mut SvmEntryContext, guest: u64);
}
self.xstate = xstate.switch();
unsafe { __ax_cpu_svm_enter(self, guest_save_area.as_usize() as u64) };
self.xstate = core::ptr::null_mut();
}
}