pub const VPID_TAG: u16 = 0x1;
#[repr(u64)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum InvvpidType {
IndividualAddress = 0,
SingleContext = 1,
AllContextsIncludingGlobals = 2,
AllContexts = 3,
}
#[repr(C)]
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct InvvpidDescriptor {
pub vpid: u16,
pub reserved: [u16; 3],
pub linear_address: u64,
}
fn invvpid(invvpid_type: InvvpidType, descriptor: &InvvpidDescriptor) {
let descriptor_ptr = descriptor as *const _ as u64;
unsafe {
core::arch::asm!(
"invvpid {0}, [{1}]",
in(reg) invvpid_type as u64,
in(reg) descriptor_ptr,
options(nostack)
);
}
}
pub fn invvpid_individual_address(vpid: u16, linear_address: u64) {
let descriptor = InvvpidDescriptor {
vpid,
reserved: [0; 3], linear_address,
};
invvpid(InvvpidType::IndividualAddress, &descriptor);
}
pub fn invvpid_single_context(vpid: u16) {
let descriptor = InvvpidDescriptor {
vpid, reserved: [0; 3], linear_address: 0, };
invvpid(InvvpidType::SingleContext, &descriptor);
}
pub fn invvpid_all_contexts() {
let descriptor = InvvpidDescriptor {
vpid: 0, reserved: [0; 3], linear_address: 0, };
invvpid(InvvpidType::AllContexts, &descriptor);
}