static int emulate_sysexit() { seg_sel_t cs; __pre_access(__sysenter_cs); cs.raw = __sysenter_cs.wlow; if(__cpl || !__cr0.pe || !cs.index) { debug(EMU_INSN, "sysexit fault: cpl %d cr0.pe %d cs.index %d\n" , __cpl, __cr0.pe, cs.index); __inject_exception(GP_EXCP, 0, 0); return VM_FAULT; } __cs.selector.raw = __sysenter_cs.wlow + 16; __cs.selector.rpl = 3; __cs.base.raw = 0ULL; __cs.limit.raw = 0xffffffff; __cs.attributes.g = 1; __cs.attributes.s = 1; __cs.attributes.type = SEG_DESC_CODE_XRA; __cs.attributes.d = 1; __cs.attributes.dpl = 3; __cs.attributes.p = 1; __cpl = 3; __ss.selector.raw = __sysenter_cs.wlow + 24; __ss.selector.rpl = 3; __ss.base.raw = 0ULL; __ss.limit.raw = 0xffffffff; __ss.attributes.g = 1; __ss.attributes.s = 1; __ss.attributes.type = SEG_DESC_DATA_RWA; __ss.attributes.d = 1; __ss.attributes.dpl = 3; __ss.attributes.p = 1; info->vm.cpu.gpr->rsp.low = info->vm.cpu.gpr->rcx.low; __rip.low = info->vm.cpu.gpr->rdx.low; __post_access(__rip); __post_access(__cs.selector); __post_access(__cs.base); __post_access(__cs.limit); __post_access(__cs.attributes); __post_access(__ss.selector); __post_access(__ss.base); __post_access(__ss.limit); __post_access(__ss.attributes); return VM_DONE_LET_RIP; }
static int __resolve_exception(uint32_t vector, uint32_t error, uint64_t fault) { int rc; info->vm.cpu.fault.excp.err.raw = error; if((rc=ctrl_evt_excp(vector)) == VM_IGNORE) { debug(EXCP, "ignored excp, injecting\n"); __inject_exception(vector, error, fault); } return rc; }
int emulate_clts() { cr0_reg_t guest; if(__cpl) { __inject_exception(GP_EXCP, 0, 0); return VM_FAULT; } guest.low = __cr0.low & ~(CR0_TS); __cr0_update(&guest); return VM_DONE; }
static int __vmx_vmexit_resolve_msr_efer(uint8_t wr) { if(wr) { ia32_efer_msr_t update; update.low = info->vm.efer.low ^ info->vm.cpu.gpr->rax.low; info->vm.efer.low = info->vm.cpu.gpr->rax.low; info->vm.efer.high = info->vm.cpu.gpr->rdx.low; vm_state.ia32_efer.low = info->vm.efer.low; vm_state.ia32_efer.high = info->vm.efer.high; vmcs_read(vm_entry_ctrls.entry); vm_state.ia32_efer.lme = vm_state.ia32_efer.lma = vm_entry_ctrls.entry.ia32e; vmcs_dirty(vm_state.ia32_efer); if(info->vm.efer.lma && !info->vm.efer.lme) info->vm.efer.lma = 0; if(update.lme && __cr0.pg) { debug(VMX_MSR, "modifying LME while paging-on #GP\n"); __inject_exception(GP_EXCP, 0, 0); return VM_FAULT; } } else { info->vm.cpu.gpr->rax.low = info->vm.efer.low; info->vm.cpu.gpr->rdx.low = info->vm.efer.high; } return VM_DONE; }