void ept_hw_set_pdtprs(GUEST_CPU_HANDLE gcpu, UINT64 pdptr[]) { VMCS_OBJECT *vmcs = gcpu_get_vmcs(gcpu); CHECK_EXECUTION_ON_LOCAL_HOST_CPU(gcpu); vmcs_write(vmcs, VMCS_GUEST_PDPTR0, pdptr[0]); vmcs_write(vmcs, VMCS_GUEST_PDPTR1, pdptr[1]); vmcs_write(vmcs, VMCS_GUEST_PDPTR2, pdptr[2]); vmcs_write(vmcs, VMCS_GUEST_PDPTR3, pdptr[3]); }
int vmcs_setdesc(int vcpuid, int seg, struct seg_desc *desc) { int error; uint32_t base, limit, access; error = vmcs_seg_desc_encoding(seg, &base, &limit, &access); if (error != 0) xhyve_abort("vmcs_setdesc: invalid segment register %d\n", seg); vmcs_write(vcpuid, base, desc->base); vmcs_write(vcpuid, limit, desc->limit); if (access != VMCS_INVALID_ENCODING) { vmcs_write(vcpuid, access, desc->access); } return (0); }
void ept_hw_disable_ept(GUEST_CPU_HANDLE gcpu) { PROCESSOR_BASED_VM_EXECUTION_CONTROLS2 proc_ctrls2; VMEXIT_CONTROL vmexit_request; CHECK_EXECUTION_ON_LOCAL_HOST_CPU(gcpu); ept_hw_invvpid_single_context(1 + gcpu->vcpu.guest_id); proc_ctrls2.Uint32 = 0; vmm_zeromem(&vmexit_request, sizeof(vmexit_request)); proc_ctrls2.Bits.EnableEPT = 1; #ifdef ENABLE_VPID proc_ctrls2.Bits.EnableVPID = 1; vmcs_write(gcpu_get_vmcs(gcpu), VMCS_VPID, 0); #endif vmexit_request.proc_ctrls2.bit_mask = proc_ctrls2.Uint32; vmexit_request.proc_ctrls2.bit_request = 0; // FIXME gcpu_control_setup( gcpu, &vmexit_request ); }
int vmcs_setreg(int vcpuid, int ident, uint64_t val) { uint32_t encoding; if (ident < 0) encoding = ident & 0x7fffffff; else encoding = vmcs_field_encoding(ident); if (encoding == (uint32_t)-1) return (EINVAL); val = vmcs_fix_regval(encoding, val); vmcs_write(vcpuid, encoding, val); return (0); }
// Function : vmdb_settings_apply_to_hw // Purpose : Update GCPU DRs from its guest's VMDB context // Arguments: GUEST_CPU_HANDLE gcpu // Returns : void void vmdb_settings_apply_to_hw ( GUEST_CPU_HANDLE gcpu) { VMDB_THREAD_CONTEXT *vmdb = gcpu_get_vmdb(gcpu); if (NULL != vmdb) { UINT64 rflags; VMCS_OBJECT *vmcs = gcpu_get_vmcs(gcpu); gcpu_set_debug_reg(gcpu, IA32_REG_DR7, vmdb->dr7); gcpu_set_debug_reg(gcpu, IA32_REG_DR0, vmdb->dr[0]); gcpu_set_debug_reg(gcpu, IA32_REG_DR1, vmdb->dr[1]); gcpu_set_debug_reg(gcpu, IA32_REG_DR2, vmdb->dr[2]); gcpu_set_debug_reg(gcpu, IA32_REG_DR3, vmdb->dr[3]); rflags = vmcs_read(vmcs, VMCS_GUEST_RFLAGS); if (vmdb->sstep) BIT_SET64(rflags, RFLAGS_TF_BIT); else BIT_CLR64(rflags, RFLAGS_TF_BIT); vmcs_write(vmcs, VMCS_GUEST_RFLAGS, rflags); } }
BOOLEAN ept_hw_set_eptp(GUEST_CPU_HANDLE gcpu, HPA ept_root_hpa, UINT32 gaw) { VMCS_OBJECT* vmcs = gcpu_get_vmcs(gcpu); EPTP eptp; UINT32 ept_gaw = 0; VMM_ASSERT(gcpu); VMM_ASSERT(vmcs); CHECK_EXECUTION_ON_LOCAL_HOST_CPU(gcpu); if(! ept_hw_is_ept_supported() || ept_root_hpa == 0) { return FALSE; } ept_gaw = ept_hw_get_guest_address_width(gaw); if(ept_gaw == (UINT32) -1) { return FALSE; } eptp.Uint64 = ept_root_hpa; eptp.Bits.ETMT = ept_hw_get_ept_memory_type(); eptp.Bits.GAW = ept_hw_get_guest_address_width_encoding(ept_gaw); eptp.Bits.Reserved = 0; vmcs_write( vmcs, VMCS_EPTP_ADDRESS, eptp.Uint64); return TRUE; }
BOOLEAN ept_hw_enable_ept(GUEST_CPU_HANDLE gcpu) { PROCESSOR_BASED_VM_EXECUTION_CONTROLS2 proc_ctrls2; VMEXIT_CONTROL vmexit_request; CHECK_EXECUTION_ON_LOCAL_HOST_CPU(gcpu); VMM_ASSERT(gcpu); if(! ept_hw_is_ept_supported()) { return FALSE; } proc_ctrls2.Uint32 = 0; vmm_zeromem(&vmexit_request, sizeof(vmexit_request)); proc_ctrls2.Bits.EnableEPT = 1; #ifdef ENABLE_VPID proc_ctrls2.Bits.EnableVPID = 1; vmcs_write(gcpu_get_vmcs(gcpu), VMCS_VPID, 1 + gcpu->vcpu.guest_id); #endif vmexit_request.proc_ctrls2.bit_mask = proc_ctrls2.Uint32; vmexit_request.proc_ctrls2.bit_request = UINT64_ALL_ONES; // FIXME gcpu_control_setup( gcpu, &vmexit_request ); return TRUE; }