This commit is contained in:
@ -1,4 +1,7 @@
|
|||||||
use crate::vmm::x86_64::{common, intel::vmcs};
|
use crate::vmm::x86_64::{
|
||||||
|
common,
|
||||||
|
intel::{vmcs, vmwrite},
|
||||||
|
};
|
||||||
|
|
||||||
pub fn setup_exec_controls() -> Result<(), &'static str> {
|
pub fn setup_exec_controls() -> Result<(), &'static str> {
|
||||||
let basic_msr = common::read_msr(0x480);
|
let basic_msr = common::read_msr(0x480);
|
||||||
@ -12,8 +15,8 @@ pub fn setup_exec_controls() -> Result<(), &'static str> {
|
|||||||
raw_pin_exec_ctrl |= (reserved_bits & 0xFFFFFFFF) as u32;
|
raw_pin_exec_ctrl |= (reserved_bits & 0xFFFFFFFF) as u32;
|
||||||
raw_pin_exec_ctrl &= (reserved_bits >> 32) as u32;
|
raw_pin_exec_ctrl &= (reserved_bits >> 32) as u32;
|
||||||
|
|
||||||
let pin_exec_ctrl = vmcs::controls::PinBasedVmExecutionControls::from(raw_pin_exec_ctrl);
|
let mut pin_exec_ctrl = vmcs::controls::PinBasedVmExecutionControls::from(raw_pin_exec_ctrl);
|
||||||
//pin_exec_ctrl.set_external_interrupt_exiting(false);
|
pin_exec_ctrl.set_external_interrupt_exiting(false);
|
||||||
|
|
||||||
pin_exec_ctrl.write()?;
|
pin_exec_ctrl.write()?;
|
||||||
|
|
||||||
@ -55,6 +58,9 @@ pub fn setup_exec_controls() -> Result<(), &'static str> {
|
|||||||
|
|
||||||
secondary_exec_ctrl.write()?;
|
secondary_exec_ctrl.write()?;
|
||||||
|
|
||||||
|
vmwrite(x86::vmx::vmcs::control::CR0_GUEST_HOST_MASK, u64::MAX)?;
|
||||||
|
vmwrite(x86::vmx::vmcs::control::CR4_GUEST_HOST_MASK, u64::MAX)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +107,13 @@ pub fn setup_exit_controls() -> Result<(), &'static str> {
|
|||||||
|
|
||||||
exit_ctrl.write()?;
|
exit_ctrl.write()?;
|
||||||
|
|
||||||
//vmwrite(0x4004, 1u64 << 6)?; // EXCEPTION_BITMAP
|
/*vmwrite(
|
||||||
|
0x4004,
|
||||||
|
1u64 << x86::irq::DOUBLE_FAULT_VECTOR
|
||||||
|
| 1u64 << x86::irq::GENERAL_PROTECTION_FAULT_VECTOR
|
||||||
|
| 1u64 << x86::irq::PAGE_FAULT_VECTOR
|
||||||
|
| 1u64 << x86::irq::X87_FPU_VECTOR,
|
||||||
|
)?;*/
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,6 @@ pub fn update_msrs(vcpu: &mut IntelVCpu) -> Result<(), MsrError> {
|
|||||||
.map(|entry| entry.index)
|
.map(|entry| entry.index)
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
info!("1");
|
|
||||||
|
|
||||||
for index in indices_to_update {
|
for index in indices_to_update {
|
||||||
info!("{}", index);
|
info!("{}", index);
|
||||||
let value = read_msr(index);
|
let value = read_msr(index);
|
||||||
@ -110,25 +108,21 @@ pub fn update_msrs(vcpu: &mut IntelVCpu) -> Result<(), MsrError> {
|
|||||||
vcpu.host_msr.set_by_index(index, value).unwrap();
|
vcpu.host_msr.set_by_index(index, value).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("2");
|
|
||||||
vmwrite(
|
vmwrite(
|
||||||
vmcs::control::VMEXIT_MSR_LOAD_COUNT,
|
vmcs::control::VMEXIT_MSR_LOAD_COUNT,
|
||||||
vcpu.host_msr.saved_ents().len() as u64,
|
vcpu.host_msr.saved_ents().len() as u64,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
info!("3");
|
|
||||||
vmwrite(
|
vmwrite(
|
||||||
vmcs::control::VMEXIT_MSR_STORE_COUNT,
|
vmcs::control::VMEXIT_MSR_STORE_COUNT,
|
||||||
vcpu.guest_msr.saved_ents().len() as u64,
|
vcpu.guest_msr.saved_ents().len() as u64,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
info!("4");
|
|
||||||
vmwrite(
|
vmwrite(
|
||||||
vmcs::control::VMENTRY_MSR_LOAD_COUNT,
|
vmcs::control::VMENTRY_MSR_LOAD_COUNT,
|
||||||
vcpu.guest_msr.saved_ents().len() as u64,
|
vcpu.guest_msr.saved_ents().len() as u64,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
info!("5");
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,6 +93,32 @@ impl IntelVCpu {
|
|||||||
info!("EPT Violation at guest address: {:#x}", guest_address);
|
info!("EPT Violation at guest address: {:#x}", guest_address);
|
||||||
return Err("EPT Violation");
|
return Err("EPT Violation");
|
||||||
}
|
}
|
||||||
|
VmxExitReason::TRIPLE_FAULT => {
|
||||||
|
info!("Triple fault detected");
|
||||||
|
return Err("Triple fault");
|
||||||
|
}
|
||||||
|
VmxExitReason::EXCEPTION => {
|
||||||
|
let vmexit_intr_info = vmread(vmcs::ro::VMEXIT_INTERRUPTION_INFO)?;
|
||||||
|
let vector = (vmexit_intr_info & 0xFF) as u8;
|
||||||
|
let error_code = (vmexit_intr_info >> 8) & 0b111;
|
||||||
|
let error_code_valid = (vmexit_intr_info >> 11) & 0b1 != 0;
|
||||||
|
|
||||||
|
let idt_vectoring_info = vmread(vmcs::ro::IDT_VECTORING_INFO)?;
|
||||||
|
info!("idt valid: {}", idt_vectoring_info >> 31 & 0b1 != 0);
|
||||||
|
|
||||||
|
let rip = vmread(vmcs::guest::RIP)?;
|
||||||
|
let hpa = self.ept.get_phys_addr(rip).unwrap();
|
||||||
|
|
||||||
|
if error_code_valid {
|
||||||
|
info!(
|
||||||
|
"VM exit due to exception: vector {}, error code {}, at RIP {:#x} (hpa: {:#x})",
|
||||||
|
vector, error_code, rip, hpa
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
info!("VM exit due to exception: vector {}", vector);
|
||||||
|
}
|
||||||
|
return Err("VM exit due to exception");
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
info!("VM exit reason: {:?}", exit_reason);
|
info!("VM exit reason: {:?}", exit_reason);
|
||||||
return Err("Unhandled VM exit reason");
|
return Err("Unhandled VM exit reason");
|
||||||
@ -114,8 +140,6 @@ impl IntelVCpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn vmentry(&mut self) -> Result<(), InstructionError> {
|
fn vmentry(&mut self) -> Result<(), InstructionError> {
|
||||||
msr::update_msrs(self).unwrap();
|
|
||||||
|
|
||||||
auditor::controls::check_vmcs_control_fields().unwrap();
|
auditor::controls::check_vmcs_control_fields().unwrap();
|
||||||
|
|
||||||
let success = {
|
let success = {
|
||||||
@ -233,14 +257,18 @@ impl IntelVCpu {
|
|||||||
|
|
||||||
fn setup_guest_state(&mut self) -> Result<(), &'static str> {
|
fn setup_guest_state(&mut self) -> Result<(), &'static str> {
|
||||||
use x86::{controlregs::*, vmx::vmcs};
|
use x86::{controlregs::*, vmx::vmcs};
|
||||||
let cr0 = Cr0::empty()
|
let cr0 = (Cr0::empty()
|
||||||
| Cr0::CR0_PROTECTED_MODE
|
| Cr0::CR0_PROTECTED_MODE
|
||||||
| Cr0::CR0_NUMERIC_ERROR & !Cr0::CR0_ENABLE_PAGING;
|
| Cr0::CR0_NUMERIC_ERROR
|
||||||
|
| Cr0::CR0_EXTENSION_TYPE)
|
||||||
|
& !Cr0::CR0_ENABLE_PAGING;
|
||||||
vmwrite(vmcs::guest::CR0, cr0.bits() as u64)?;
|
vmwrite(vmcs::guest::CR0, cr0.bits() as u64)?;
|
||||||
vmwrite(vmcs::guest::CR3, unsafe { cr3() })?;
|
vmwrite(vmcs::guest::CR3, 0)?;
|
||||||
vmwrite(
|
vmwrite(
|
||||||
vmcs::guest::CR4,
|
vmcs::guest::CR4,
|
||||||
vmread(vmcs::guest::CR4)? & !Cr4Flags::VIRTUAL_MACHINE_EXTENSIONS.bits(),
|
vmread(vmcs::guest::CR4)?
|
||||||
|
| Cr4Flags::VIRTUAL_MACHINE_EXTENSIONS.bits()
|
||||||
|
& !Cr4Flags::PHYSICAL_ADDRESS_EXTENSION.bits(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
vmwrite(vmcs::guest::CS_BASE, 0)?;
|
vmwrite(vmcs::guest::CS_BASE, 0)?;
|
||||||
|
Reference in New Issue
Block a user