void __regparm__(2) __vmcs_force_flush(raw64_t *val, vmcs_field_enc_t enc) { if(!enc.fake) { vmx_insn_err_t vmx_err; if(!vmx_vmwrite(&vmx_err, val->raw, enc.raw)) panic("vmwrite(0x%x, 0x%x) err %d\n", val->raw, enc.raw, vmx_err.raw); return; } if(val == (raw64_t*)&vm_state.cr2) set_cr2(vm_state.cr2.raw); else if(val == (raw64_t*)&vm_state.dr6) set_dr6(vm_state.dr6.raw); }
vmx_error_t cpu_vmx_run(struct vcpu_t *vcpu, struct hax_tunnel *htun) { uint64 rflags = 0; mword host_rip; /* prepare the RIP */ hax_debug("vm entry!\n"); vcpu_save_host_state(vcpu); hax_disable_irq(); /* * put the vmwrite before is_running, so that the vcpu->cpu_id is set * when we check vcpu->is_running in vcpu_pause */ host_rip = get_rip(); vmwrite(vcpu, HOST_RIP, (mword)host_rip); vcpu->is_running = 1; #ifdef DEBUG_HOST_STATE vcpu_get_host_state(vcpu, 1); #endif /* Must ensure the IRQ is disabled before setting CR2 */ set_cr2(vcpu->state->_cr2); load_guest_msr(vcpu); rflags = __vmx_run(vcpu->state, vcpu->launched); vcpu->is_running = 0; save_guest_msr(vcpu); vcpu_load_host_state(vcpu); #ifdef DEBUG_HOST_STATE vcpu_get_host_state(vcpu, 0); compare_host_state(vcpu); #endif hax_debug("\ncpu_vmx_run %llx, FAIL %llx\n", rflags, rflags & VMX_FAIL_MASK); if (rflags & VMX_FAIL_MASK) { cpu_vmentry_failed(vcpu, rflags & VMX_FAIL_MASK); htun->_exit_reason = 0; htun->_exit_status = HAX_EXIT_UNKNOWN; } return (rflags & VMX_FAIL_MASK); }
void __regparm__(2) __vmcs_force_flush(raw64_t *val, vmcs_field_enc_t enc) { if(!enc.fake) { vmx_insn_err_t vmx_err; if(!vmx_vmwrite(&vmx_err, val->raw, enc.raw)) panic("vmwrite(0x%x, 0x%x) err %d\n", val->raw, enc.raw, vmx_err.raw); /* ** don't use debug, since some fields might have not been read */ #ifdef CONFIG_VMX_ACC_DBG printf("vmwrite(0x%x) = 0x%X\n", enc.raw, val->raw); #endif return; } if(val == (raw64_t*)&vm_state.cr2) set_cr2(vm_state.cr2.raw); else if(val == (raw64_t*)&vm_state.dr6) set_dr6(vm_state.dr6.raw); }