/* * Get 64bit mask + flags set. For each 1-bit in mask consult flags bit. * If flags bit is 1 - increase count, esle - decrease count * Return bit set with 1bit for each non-zero counter */ static uint64_t gcpu_update_control_counters(uint64_t flags, uint64_t mask, gcpu_vmexit_control_field_counters_t *counters) { uint32_t idx; while (mask) { idx = (uint32_t)-1; hw_scan_bit_forward64(&idx, mask); MON_ASSERT(idx < 64); BIT_CLR64(mask, idx); if (1 == BIT_GET64(flags, idx)) { if (0 == counters->counters[idx]) { BIT_SET64(counters->bit_field, idx); } MON_ASSERT(counters->counters[idx] < 255); ++(counters->counters[idx]); } else { MON_ASSERT(counters->counters[idx] > 0); --(counters->counters[idx]); if (0 == counters->counters[idx]) { BIT_CLR64(counters->bit_field, idx); } } } return counters->bit_field; }
// 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); } }