implement setvcpucontext, it's not working properly yet

This commit is contained in:
Alex Zenla
2024-01-11 21:10:59 -08:00
parent 492a836213
commit 4b4f22ffcd
6 changed files with 218 additions and 42 deletions

View File

@ -1,8 +1,9 @@
use crate::sys::{
ArchDomainConfig, CreateDomain, DomCtl, DomCtlValue, GetDomainInfo, HypercallInit, MaxMem,
MaxVcpus, HYPERVISOR_DOMCTL, XEN_DOMCTL_CREATEDOMAIN, XEN_DOMCTL_DESTROYDOMAIN,
XEN_DOMCTL_GETDOMAININFO, XEN_DOMCTL_HYPERCALL_INIT, XEN_DOMCTL_INTERFACE_VERSION,
XEN_DOMCTL_MAX_MEM, XEN_DOMCTL_MAX_VCPUS,
ArchDomainConfig, CreateDomain, DomCtl, DomCtlValue, DomCtlVcpuContext, GetDomainInfo,
HypercallInit, MaxMem, MaxVcpus, VcpuGuestContext, VcpuGuestContextAny, HYPERVISOR_DOMCTL,
XEN_DOMCTL_CREATEDOMAIN, XEN_DOMCTL_DESTROYDOMAIN, XEN_DOMCTL_GETDOMAININFO,
XEN_DOMCTL_HYPERCALL_INIT, XEN_DOMCTL_INTERFACE_VERSION, XEN_DOMCTL_MAX_MEM,
XEN_DOMCTL_MAX_VCPUS, XEN_DOMCTL_SETVCPUCONTEXT,
};
use crate::{XenCall, XenCallError};
use log::trace;
@ -116,6 +117,39 @@ impl DomainControl<'_> {
Ok(())
}
pub fn set_vcpu_context(
&self,
domid: u32,
vcpu: u32,
context: Option<&VcpuGuestContext>,
) -> Result<(), XenCallError> {
trace!(
"domctl fd={} set_vcpu_context domid={} context={:?}",
self.call.handle.as_raw_fd(),
domid,
context,
);
let mut wrapper = context.map(|ctx| VcpuGuestContextAny { value: *ctx });
let mut domctl = DomCtl {
cmd: XEN_DOMCTL_SETVCPUCONTEXT,
interface_version: XEN_DOMCTL_INTERFACE_VERSION,
domid,
value: DomCtlValue {
vcpu_context: DomCtlVcpuContext {
vcpu,
ctx: if wrapper.is_some() {
addr_of_mut!(wrapper) as c_ulong
} else {
0
},
},
},
};
self.call
.hypercall1(HYPERVISOR_DOMCTL, addr_of_mut!(domctl) as c_ulong)?;
Ok(())
}
pub fn hypercall_init(&self, domid: u32, gmfn: u64) -> Result<(), XenCallError> {
trace!(
"domctl fd={} hypercall_init domid={} max_vcpus={}",

View File

@ -200,6 +200,13 @@ pub struct DomCtl {
pub value: DomCtlValue,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct DomCtlVcpuContext {
pub vcpu: u32,
pub ctx: u64,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union DomCtlValue {
@ -209,6 +216,7 @@ pub union DomCtlValue {
pub max_cpus: MaxVcpus,
pub hypercall_init: HypercallInit,
pub pad: [u8; 128],
pub vcpu_context: DomCtlVcpuContext,
}
#[repr(C)]
@ -327,3 +335,113 @@ pub struct MultiCallEntry {
}
pub const XEN_MEM_POPULATE_PHYSMAP: u32 = 6;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct VcpuGuestContextFpuCtx {
pub x: [c_char; 512],
}
impl Default for VcpuGuestContextFpuCtx {
fn default() -> Self {
VcpuGuestContextFpuCtx { x: [0; 512] }
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct CpuUserRegs {
pub r15: u64,
pub r14: u64,
pub r13: u64,
pub r12: u64,
pub rbp: u64,
pub rbx: u64,
pub r11: u64,
pub r10: u64,
pub r9: u64,
pub r8: u64,
pub rax: u64,
pub rcx: u64,
pub rdx: u64,
pub rsi: u64,
pub rdi: u64,
pub error_code: u32,
pub entry_vector: u32,
pub rip: u64,
pub cs: u16,
_pad0: [u16; 1],
pub saved_upcall_mask: u8,
_pad1: [u8; 3],
pub rflags: u64,
pub rsp: u64,
pub ss: u16,
_pad2: [u16; 3],
pub es: u16,
_pad3: [u16; 3],
pub ds: u16,
_pad4: [u16; 3],
pub fs: u16,
_pad5: [u16; 3],
pub gs: u16,
_pad6: [u16; 3],
}
#[repr(C)]
#[derive(Copy, Clone, Debug, Default)]
pub struct TrapInfo {
pub vector: u8,
pub flags: u8,
pub cs: u16,
pub address: u64,
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct VcpuGuestContext {
pub fpu_ctx: VcpuGuestContextFpuCtx,
pub flags: c_ulong,
pub user_regs: CpuUserRegs,
pub trap_ctx: [TrapInfo; 256],
pub ldt_base: u64,
pub ldt_ents: u64,
pub gdt_frames: [u64; 16],
pub gdt_ents: u64,
pub kernel_ss: u64,
pub kernel_sp: u64,
pub ctrlreg: [u64; 8],
pub debugreg: [u64; 8],
pub syscall_callback_eip: u64,
pub vm_assist: u64,
pub fs_base: u64,
pub gs_base_kernel: u64,
pub gs_base_user: u64,
}
impl Default for VcpuGuestContext {
fn default() -> Self {
VcpuGuestContext {
fpu_ctx: Default::default(),
flags: 0,
user_regs: Default::default(),
trap_ctx: [TrapInfo::default(); 256],
ldt_base: 0,
ldt_ents: 0,
gdt_frames: [0; 16],
gdt_ents: 0,
kernel_ss: 0,
kernel_sp: 0,
ctrlreg: [0; 8],
debugreg: [0; 8],
syscall_callback_eip: 0,
vm_assist: 0,
fs_base: 0,
gs_base_kernel: 0,
gs_base_user: 0,
}
}
}
pub union VcpuGuestContextAny {
pub value: VcpuGuestContext,
}