mirror of
https://github.com/mii443/nel_os.git
synced 2025-08-22 16:15:38 +00:00
msr
This commit is contained in:
134
src/vmm/cpuid.rs
134
src/vmm/cpuid.rs
@ -9,6 +9,28 @@ pub fn handle_cpuid_exit(vcpu: &mut VCpu) {
|
|||||||
let vendor: &[u8; 12] = b"miimiimiimii";
|
let vendor: &[u8; 12] = b"miimiimiimii";
|
||||||
let vendor = unsafe { core::mem::transmute::<&[u8; 12], &[u32; 3]>(vendor) };
|
let vendor = unsafe { core::mem::transmute::<&[u8; 12], &[u32; 3]>(vendor) };
|
||||||
match VmxLeaf::from(regs.rax) {
|
match VmxLeaf::from(regs.rax) {
|
||||||
|
VmxLeaf::EXTENDED_FEATURE => match regs.rcx {
|
||||||
|
0 => {
|
||||||
|
info!("CPUID extended feature");
|
||||||
|
let mut ebx = ExtFeatureEbx0::default();
|
||||||
|
ebx.smep = true;
|
||||||
|
ebx.invpcid = false;
|
||||||
|
ebx.smap = true;
|
||||||
|
regs.rax = 1;
|
||||||
|
regs.rbx = ebx.as_u32() as u64;
|
||||||
|
regs.rcx = 0;
|
||||||
|
regs.rdx = 0;
|
||||||
|
}
|
||||||
|
1 => {
|
||||||
|
invalid(vcpu);
|
||||||
|
}
|
||||||
|
2 => {
|
||||||
|
invalid(vcpu);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
panic!("Unhandled CPUID leaf: {:#x}.{:#x}", regs.rax, regs.rcx);
|
||||||
|
}
|
||||||
|
},
|
||||||
VmxLeaf::EXTENDED_PROCESSOR_SIGNATURE => {
|
VmxLeaf::EXTENDED_PROCESSOR_SIGNATURE => {
|
||||||
info!("CPUID extended processor signature");
|
info!("CPUID extended processor signature");
|
||||||
let signature = cpuid!(0x80000001, 0);
|
let signature = cpuid!(0x80000001, 0);
|
||||||
@ -270,3 +292,115 @@ impl FeatureInfoEdx {
|
|||||||
| (self.pbe as u32) << 31
|
| (self.pbe as u32) << 31
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ExtFeatureEbx0 {
|
||||||
|
pub fsgsbase: bool,
|
||||||
|
pub tsc_adjust: bool,
|
||||||
|
pub sgx: bool,
|
||||||
|
pub bmi1: bool,
|
||||||
|
pub hle: bool,
|
||||||
|
pub avx2: bool,
|
||||||
|
pub fdp: bool,
|
||||||
|
pub smep: bool,
|
||||||
|
pub bmi2: bool,
|
||||||
|
pub erms: bool,
|
||||||
|
pub invpcid: bool,
|
||||||
|
pub rtm: bool,
|
||||||
|
pub rdtm: bool,
|
||||||
|
pub fpucsds: bool,
|
||||||
|
pub mpx: bool,
|
||||||
|
pub rdta: bool,
|
||||||
|
pub avx512f: bool,
|
||||||
|
pub avx512dq: bool,
|
||||||
|
pub rdseed: bool,
|
||||||
|
pub adx: bool,
|
||||||
|
pub smap: bool,
|
||||||
|
pub avx512ifma: bool,
|
||||||
|
pub _reserved1: bool,
|
||||||
|
pub clflushopt: bool,
|
||||||
|
pub clwb: bool,
|
||||||
|
pub pt: bool,
|
||||||
|
pub avx512pf: bool,
|
||||||
|
pub avx512er: bool,
|
||||||
|
pub avx512cd: bool,
|
||||||
|
pub sha: bool,
|
||||||
|
pub avx512bw: bool,
|
||||||
|
pub avx512vl: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ExtFeatureEbx0 {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
fsgsbase: false,
|
||||||
|
tsc_adjust: false,
|
||||||
|
sgx: false,
|
||||||
|
bmi1: false,
|
||||||
|
hle: false,
|
||||||
|
avx2: false,
|
||||||
|
fdp: false,
|
||||||
|
smep: false,
|
||||||
|
bmi2: false,
|
||||||
|
erms: false,
|
||||||
|
invpcid: false,
|
||||||
|
rtm: false,
|
||||||
|
rdtm: false,
|
||||||
|
fpucsds: false,
|
||||||
|
mpx: false,
|
||||||
|
rdta: false,
|
||||||
|
avx512f: false,
|
||||||
|
avx512dq: false,
|
||||||
|
rdseed: false,
|
||||||
|
adx: false,
|
||||||
|
smap: false,
|
||||||
|
avx512ifma: false,
|
||||||
|
_reserved1: false,
|
||||||
|
clflushopt: false,
|
||||||
|
clwb: false,
|
||||||
|
pt: false,
|
||||||
|
avx512pf: false,
|
||||||
|
avx512er: false,
|
||||||
|
avx512cd: false,
|
||||||
|
sha: false,
|
||||||
|
avx512bw: false,
|
||||||
|
avx512vl: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtFeatureEbx0 {
|
||||||
|
pub fn as_u32(&self) -> u32 {
|
||||||
|
(self.fsgsbase as u32)
|
||||||
|
| (self.tsc_adjust as u32) << 1
|
||||||
|
| (self.sgx as u32) << 2
|
||||||
|
| (self.bmi1 as u32) << 3
|
||||||
|
| (self.hle as u32) << 4
|
||||||
|
| (self.avx2 as u32) << 5
|
||||||
|
| (self.fdp as u32) << 6
|
||||||
|
| (self.smep as u32) << 7
|
||||||
|
| (self.bmi2 as u32) << 8
|
||||||
|
| (self.erms as u32) << 9
|
||||||
|
| (self.invpcid as u32) << 10
|
||||||
|
| (self.rtm as u32) << 11
|
||||||
|
| (self.rdtm as u32) << 12
|
||||||
|
| (self.fpucsds as u32) << 13
|
||||||
|
| (self.mpx as u32) << 14
|
||||||
|
| (self.rdta as u32) << 15
|
||||||
|
| (self.avx512f as u32) << 16
|
||||||
|
| (self.avx512dq as u32) << 17
|
||||||
|
| (self.rdseed as u32) << 18
|
||||||
|
| (self.adx as u32) << 19
|
||||||
|
| (self.smap as u32) << 20
|
||||||
|
| (self.avx512ifma as u32) << 21
|
||||||
|
| (self._reserved1 as u32) << 22
|
||||||
|
| (self.clflushopt as u32) << 23
|
||||||
|
| (self.clwb as u32) << 24
|
||||||
|
| (self.pt as u32) << 25
|
||||||
|
| (self.avx512pf as u32) << 26
|
||||||
|
| (self.avx512er as u32) << 27
|
||||||
|
| (self.avx512cd as u32) << 28
|
||||||
|
| (self.sha as u32) << 29
|
||||||
|
| (self.avx512bw as u32) << 30
|
||||||
|
| (self.avx512vl as u32) << 31
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ pub mod cpuid;
|
|||||||
pub mod ept;
|
pub mod ept;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod linux;
|
pub mod linux;
|
||||||
|
pub mod msr;
|
||||||
pub mod register;
|
pub mod register;
|
||||||
pub mod support;
|
pub mod support;
|
||||||
pub mod vcpu;
|
pub mod vcpu;
|
||||||
|
165
src/vmm/msr.rs
Normal file
165
src/vmm/msr.rs
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
use core::u64;
|
||||||
|
|
||||||
|
use alloc::vec;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use x86::bits64::vmx::{vmread, vmwrite};
|
||||||
|
use x86::vmx::vmcs;
|
||||||
|
use x86_64::structures::paging::{OffsetPageTable, Translate};
|
||||||
|
use x86_64::{PhysAddr, VirtAddr};
|
||||||
|
|
||||||
|
use super::vcpu::VCpu;
|
||||||
|
|
||||||
|
type MsrIndex = u32;
|
||||||
|
|
||||||
|
const MAX_NUM_ENTS: usize = 512;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
#[repr(C, packed)]
|
||||||
|
pub struct SavedMsr {
|
||||||
|
pub index: MsrIndex,
|
||||||
|
pub reserved: u32,
|
||||||
|
pub data: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for SavedMsr {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
index: 0,
|
||||||
|
reserved: 0,
|
||||||
|
data: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ShadowMsr {
|
||||||
|
ents: Vec<SavedMsr>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum MsrError {
|
||||||
|
TooManyEntries,
|
||||||
|
BitmapAllocationFailed,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ShadowMsr {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let ents = vec![SavedMsr::default(); MAX_NUM_ENTS];
|
||||||
|
|
||||||
|
ShadowMsr { ents }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set(&mut self, index: MsrIndex, data: u64) -> Result<(), MsrError> {
|
||||||
|
self.set_by_index(index, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_by_index(&mut self, index: MsrIndex, data: u64) -> Result<(), MsrError> {
|
||||||
|
if let Some(entry) = self.ents.iter_mut().find(|e| e.index == index) {
|
||||||
|
entry.data = data;
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.ents.len() >= MAX_NUM_ENTS {
|
||||||
|
return Err(MsrError::TooManyEntries);
|
||||||
|
}
|
||||||
|
self.ents.push(SavedMsr {
|
||||||
|
index,
|
||||||
|
reserved: 0,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn saved_ents(&self) -> &[SavedMsr] {
|
||||||
|
&self.ents
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn find(&self, index: MsrIndex) -> Option<&SavedMsr> {
|
||||||
|
self.ents.iter().find(|e| e.index == index)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn phys(&self, mapper: &OffsetPageTable<'static>) -> PhysAddr {
|
||||||
|
mapper
|
||||||
|
.translate_addr(VirtAddr::from_ptr(&self.ents))
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn concat(r1: u64, r2: u64) -> u64 {
|
||||||
|
((r1 & 0xFFFFFFFF) << 32) | (r2 & 0xFFFFFFFF)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_ret_val(vcpu: &mut VCpu, val: u64) {
|
||||||
|
vcpu.guest_registers.rdx = (val >> 32) as u32 as u64;
|
||||||
|
vcpu.guest_registers.rax = val as u32 as u64;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shadow_read(vcpu: &mut VCpu, msr_kind: MsrIndex) {
|
||||||
|
if let Some(msr) = vcpu.guest_msr.find(msr_kind) {
|
||||||
|
Self::set_ret_val(vcpu, msr.data);
|
||||||
|
} else {
|
||||||
|
panic!("MSR not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn shadow_write(vcpu: &mut VCpu, msr_kind: MsrIndex) {
|
||||||
|
let regs = &vcpu.guest_registers;
|
||||||
|
if vcpu.guest_msr.find(msr_kind).is_some() {
|
||||||
|
vcpu.guest_msr
|
||||||
|
.set(msr_kind, Self::concat(regs.rdx, regs.rax))
|
||||||
|
.unwrap();
|
||||||
|
} else {
|
||||||
|
panic!("MSR not found");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_rdmsr_vmexit(vcpu: &mut VCpu) {
|
||||||
|
let msr_kind = vcpu.guest_registers.rcx as u32;
|
||||||
|
|
||||||
|
match msr_kind {
|
||||||
|
x86::msr::APIC_BASE => Self::set_ret_val(vcpu, u64::MAX),
|
||||||
|
x86::msr::IA32_EFER => Self::set_ret_val(vcpu, unsafe {
|
||||||
|
vmread(vmcs::guest::IA32_EFER_FULL).unwrap()
|
||||||
|
}),
|
||||||
|
x86::msr::IA32_FS_BASE => {
|
||||||
|
Self::set_ret_val(vcpu, unsafe { vmread(vmcs::guest::FS_BASE).unwrap() })
|
||||||
|
}
|
||||||
|
x86::msr::IA32_GS_BASE => {
|
||||||
|
Self::set_ret_val(vcpu, unsafe { vmread(vmcs::guest::GS_BASE).unwrap() })
|
||||||
|
}
|
||||||
|
x86::msr::IA32_KERNEL_GSBASE => Self::shadow_read(vcpu, msr_kind),
|
||||||
|
_ => {
|
||||||
|
panic!("Unhandled RDMSR: {}", msr_kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_wrmsr_vmexit(vcpu: &mut VCpu) {
|
||||||
|
let regs = &vcpu.guest_registers;
|
||||||
|
let value = Self::concat(regs.rdx, regs.rax);
|
||||||
|
let msr_kind: MsrIndex = regs.rcx as MsrIndex;
|
||||||
|
|
||||||
|
match msr_kind {
|
||||||
|
x86::msr::IA32_STAR => Self::shadow_write(vcpu, msr_kind),
|
||||||
|
x86::msr::IA32_LSTAR => Self::shadow_write(vcpu, msr_kind),
|
||||||
|
x86::msr::IA32_CSTAR => Self::shadow_write(vcpu, msr_kind),
|
||||||
|
x86::msr::IA32_TSC_AUX => Self::shadow_write(vcpu, msr_kind),
|
||||||
|
x86::msr::IA32_FMASK => Self::shadow_write(vcpu, msr_kind),
|
||||||
|
x86::msr::IA32_KERNEL_GSBASE => Self::shadow_write(vcpu, msr_kind),
|
||||||
|
x86::msr::SYSENTER_CS_MSR => unsafe {
|
||||||
|
vmwrite(vmcs::guest::IA32_SYSENTER_CS, value).unwrap()
|
||||||
|
},
|
||||||
|
x86::msr::SYSENTER_EIP_MSR => unsafe {
|
||||||
|
vmwrite(vmcs::guest::IA32_SYSENTER_EIP, value).unwrap()
|
||||||
|
},
|
||||||
|
x86::msr::SYSENTER_ESP_MSR => unsafe {
|
||||||
|
vmwrite(vmcs::guest::IA32_SYSENTER_ESP, value).unwrap()
|
||||||
|
},
|
||||||
|
x86::msr::IA32_EFER => unsafe { vmwrite(vmcs::guest::IA32_EFER_FULL, value).unwrap() },
|
||||||
|
x86::msr::IA32_FS_BASE => unsafe { vmwrite(vmcs::guest::FS_BASE, value).unwrap() },
|
||||||
|
x86::msr::IA32_GS_BASE => unsafe { vmwrite(vmcs::guest::GS_BASE, value).unwrap() },
|
||||||
|
_ => {
|
||||||
|
panic!("Unhandled WRMSR: {}", msr_kind);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
103
src/vmm/vcpu.rs
103
src/vmm/vcpu.rs
@ -6,13 +6,13 @@ use x86::{
|
|||||||
msr::{rdmsr, IA32_EFER, IA32_FS_BASE},
|
msr::{rdmsr, IA32_EFER, IA32_FS_BASE},
|
||||||
vmx::{vmcs, VmFail},
|
vmx::{vmcs, VmFail},
|
||||||
};
|
};
|
||||||
use x86_64::{registers::control::Cr4Flags, VirtAddr};
|
use x86_64::{registers::control::Cr4Flags, structures::paging::OffsetPageTable, VirtAddr};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
info,
|
info,
|
||||||
memory::BootInfoFrameAllocator,
|
memory::BootInfoFrameAllocator,
|
||||||
vmm::{
|
vmm::{
|
||||||
cpuid,
|
cpuid, msr,
|
||||||
vmcs::{
|
vmcs::{
|
||||||
DescriptorType, EntryControls, Granularity, PrimaryExitControls,
|
DescriptorType, EntryControls, Granularity, PrimaryExitControls,
|
||||||
PrimaryProcessorBasedVmExecutionControls, SecondaryProcessorBasedVmExecutionControls,
|
PrimaryProcessorBasedVmExecutionControls, SecondaryProcessorBasedVmExecutionControls,
|
||||||
@ -24,6 +24,7 @@ use crate::{
|
|||||||
use super::{
|
use super::{
|
||||||
ept::{EPT, EPTP},
|
ept::{EPT, EPTP},
|
||||||
linux::{self, BootParams, E820Type},
|
linux::{self, BootParams, E820Type},
|
||||||
|
msr::ShadowMsr,
|
||||||
register::GuestRegisters,
|
register::GuestRegisters,
|
||||||
vmcs::{InstructionError, PinBasedVmExecutionControls, Vmcs},
|
vmcs::{InstructionError, PinBasedVmExecutionControls, Vmcs},
|
||||||
vmxon::Vmxon,
|
vmxon::Vmxon,
|
||||||
@ -38,6 +39,8 @@ pub struct VCpu {
|
|||||||
pub launch_done: bool,
|
pub launch_done: bool,
|
||||||
pub ept: EPT,
|
pub ept: EPT,
|
||||||
pub eptp: EPTP,
|
pub eptp: EPTP,
|
||||||
|
pub host_msr: ShadowMsr,
|
||||||
|
pub guest_msr: ShadowMsr,
|
||||||
}
|
}
|
||||||
|
|
||||||
const TEMP_STACK_SIZE: usize = 4096;
|
const TEMP_STACK_SIZE: usize = 4096;
|
||||||
@ -59,6 +62,8 @@ impl VCpu {
|
|||||||
launch_done: false,
|
launch_done: false,
|
||||||
ept,
|
ept,
|
||||||
eptp,
|
eptp,
|
||||||
|
host_msr: ShadowMsr::new(),
|
||||||
|
guest_msr: ShadowMsr::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,6 +196,88 @@ impl VCpu {
|
|||||||
unsafe { vmwrite(vmcs::control::EPTP_FULL, eptp.0).unwrap() };
|
unsafe { vmwrite(vmcs::control::EPTP_FULL, eptp.0).unwrap() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn register_msrs(&mut self, mapper: OffsetPageTable<'static>) {
|
||||||
|
unsafe {
|
||||||
|
// tsc_aux, star, lstar, cstar, fmask, kernel_gs_base.
|
||||||
|
self.host_msr
|
||||||
|
.set(x86::msr::IA32_TSC_AUX, rdmsr(x86::msr::IA32_TSC_AUX) as u64)
|
||||||
|
.unwrap();
|
||||||
|
self.host_msr
|
||||||
|
.set(x86::msr::IA32_STAR, rdmsr(x86::msr::IA32_STAR) as u64)
|
||||||
|
.unwrap();
|
||||||
|
self.host_msr
|
||||||
|
.set(x86::msr::IA32_LSTAR, rdmsr(x86::msr::IA32_LSTAR) as u64)
|
||||||
|
.unwrap();
|
||||||
|
self.host_msr
|
||||||
|
.set(x86::msr::IA32_CSTAR, rdmsr(x86::msr::IA32_CSTAR) as u64)
|
||||||
|
.unwrap();
|
||||||
|
self.host_msr
|
||||||
|
.set(x86::msr::IA32_FMASK, rdmsr(x86::msr::IA32_FMASK) as u64)
|
||||||
|
.unwrap();
|
||||||
|
self.host_msr
|
||||||
|
.set(
|
||||||
|
x86::msr::IA32_KERNEL_GSBASE,
|
||||||
|
rdmsr(x86::msr::IA32_KERNEL_GSBASE) as u64,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
self.guest_msr.set(x86::msr::IA32_TSC_AUX, 0).unwrap();
|
||||||
|
self.guest_msr.set(x86::msr::IA32_STAR, 0).unwrap();
|
||||||
|
self.guest_msr.set(x86::msr::IA32_LSTAR, 0).unwrap();
|
||||||
|
self.guest_msr.set(x86::msr::IA32_CSTAR, 0).unwrap();
|
||||||
|
self.guest_msr.set(x86::msr::IA32_FMASK, 0).unwrap();
|
||||||
|
self.guest_msr.set(x86::msr::IA32_KERNEL_GSBASE, 0).unwrap();
|
||||||
|
|
||||||
|
vmwrite(
|
||||||
|
vmcs::control::VMEXIT_MSR_LOAD_ADDR_FULL,
|
||||||
|
self.host_msr.phys(&mapper).as_u64(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
vmwrite(
|
||||||
|
vmcs::control::VMEXIT_MSR_STORE_ADDR_FULL,
|
||||||
|
self.guest_msr.phys(&mapper).as_u64(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
vmwrite(
|
||||||
|
vmcs::control::VMENTRY_MSR_LOAD_ADDR_FULL,
|
||||||
|
self.guest_msr.phys(&mapper).as_u64(),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_msrs(&mut self) {
|
||||||
|
let indices_to_update: alloc::vec::Vec<u32> = self
|
||||||
|
.host_msr
|
||||||
|
.saved_ents()
|
||||||
|
.iter()
|
||||||
|
.map(|entry| entry.index)
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
for index in indices_to_update {
|
||||||
|
let value = unsafe { rdmsr(index) };
|
||||||
|
self.host_msr.set_by_index(index, value).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
vmwrite(
|
||||||
|
vmcs::control::VMEXIT_MSR_LOAD_COUNT,
|
||||||
|
self.host_msr.saved_ents().len() as u64,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
vmwrite(
|
||||||
|
vmcs::control::VMEXIT_MSR_STORE_COUNT,
|
||||||
|
self.guest_msr.saved_ents().len() as u64,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
vmwrite(
|
||||||
|
vmcs::control::VMENTRY_MSR_LOAD_COUNT,
|
||||||
|
self.guest_msr.saved_ents().len() as u64,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn setup_exec_ctrls(&mut self) -> Result<(), VmFail> {
|
pub fn setup_exec_ctrls(&mut self) -> Result<(), VmFail> {
|
||||||
info!("Setting up pin based execution controls");
|
info!("Setting up pin based execution controls");
|
||||||
let basic_msr = unsafe { rdmsr(x86::msr::IA32_VMX_BASIC) };
|
let basic_msr = unsafe { rdmsr(x86::msr::IA32_VMX_BASIC) };
|
||||||
@ -222,6 +309,7 @@ impl VCpu {
|
|||||||
primary_exec_ctrl.set_hlt(false);
|
primary_exec_ctrl.set_hlt(false);
|
||||||
primary_exec_ctrl.set_activate_secondary_controls(true);
|
primary_exec_ctrl.set_activate_secondary_controls(true);
|
||||||
primary_exec_ctrl.set_use_tpr_shadow(true);
|
primary_exec_ctrl.set_use_tpr_shadow(true);
|
||||||
|
primary_exec_ctrl.set_use_msr_bitmap(false);
|
||||||
|
|
||||||
primary_exec_ctrl.write();
|
primary_exec_ctrl.write();
|
||||||
|
|
||||||
@ -555,10 +643,19 @@ impl VCpu {
|
|||||||
info!("HLT instruction executed");
|
info!("HLT instruction executed");
|
||||||
}
|
}
|
||||||
VmxExitReason::CPUID => {
|
VmxExitReason::CPUID => {
|
||||||
info!("CPUID instruction executed");
|
|
||||||
cpuid::handle_cpuid_exit(self);
|
cpuid::handle_cpuid_exit(self);
|
||||||
self.step_next_inst().unwrap();
|
self.step_next_inst().unwrap();
|
||||||
}
|
}
|
||||||
|
VmxExitReason::RDMSR => {
|
||||||
|
info!("RDMSR instruction executed");
|
||||||
|
msr::ShadowMsr::handle_rdmsr_vmexit(self);
|
||||||
|
self.step_next_inst().unwrap();
|
||||||
|
}
|
||||||
|
VmxExitReason::WRMSR => {
|
||||||
|
info!("WRMSR instruction executed");
|
||||||
|
msr::ShadowMsr::handle_wrmsr_vmexit(self);
|
||||||
|
self.step_next_inst().unwrap();
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("VMExit reason: {:?}", info.get_reason());
|
panic!("VMExit reason: {:?}", info.get_reason());
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user