Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}