Example #1
0
/*
 * 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;
}
Example #2
0
BOOLEAN vmcs_read_nmi_window_bit(struct _VMCS_OBJECT *vmcs)
{
    UINT64 value = vmcs_read(vmcs, VMCS_CONTROL_VECTOR_PROCESSOR_EVENTS);
    return (0 != BIT_GET64(value, NMI_WINDOW_BIT));
}
Example #3
0
BOOLEAN vmdb_exception_handler(GUEST_CPU_HANDLE gcpu)
    {
    VMDB_THREAD_CONTEXT    *vmdb = gcpu_get_vmdb(gcpu);
    VMCS_OBJECT            *vmcs = gcpu_get_vmcs(gcpu);
    IA32_VMX_EXIT_QUALIFICATION qualification;
    ADDRESS                 guest_rflags;
    int                     i;
#if defined DEBUG || defined ENABLE_RELEASE_VMM_LOG
    const VIRTUAL_CPU_ID   *vcpu = guest_vcpu(gcpu);
    VMM_ASSERT(vcpu);
#endif

    VMM_ASSERT(vmdb);

    qualification.Uint64 = vmcs_read(vmcs, VMCS_EXIT_INFO_QUALIFICATION);

    if (qualification.DbgException.DbgRegAccess) {
        VMDB_LOG(level_print_always,"[vmdb] Debug Registers Access is NOT supported\n");
        }

    if (qualification.DbgException.SingleStep) {
        vmdb_thread_log(gcpu, "VMDB Single Step Break occurred on thread", __FUNCTION__);

        if (FALSE == event_raise(EVENT_GUEST_CPU_BREAKPOINT, gcpu, 0)) {
            VMM_DEADLOOP();
            }
        }
    else {
            for (i = 0; i < NUMBER_OF_HW_BREAKPOINTS; ++i) {
                if (BIT_GET64(qualification.DbgException.BreakPoints, i)) {
#if defined DEBUG || defined ENABLE_RELEASE_VMM_LOG
                    UINT32 db_type = (UINT32) DR7_RW_GET(vmdb->dr7, i);
#endif

                    if (0 != vmdb->skip_counter[i]) {
		      (void)vmdb->skip_counter[i];
                        continue;
                        }

		    (void)bp_type_name;
		    (void)bp_actual_length;
                    VMDB_LOG(level_print_always,"[vmdb] %s break occurred at address(%P) on thread(%d,%d)\n",
                        bp_type_name[db_type], vmdb->dr[i],
                        vcpu->guest_id, vcpu->guest_id);

                    // If it is breakpoint for the VMDB STUB, then propagate it.
                    if (FALSE == event_raise(EVENT_GUEST_CPU_SINGLE_STEP, gcpu, 0)) {
                        VMM_DEADLOOP();
                        }
                    }
                }
        }

    // Set Resume Flag to prevent breakpoint stucking
    guest_rflags = gcpu_get_native_gp_reg(gcpu, IA32_REG_RFLAGS);
    BIT_SET64(guest_rflags, RFLAGS_RF_BIT);
    gcpu_set_native_gp_reg(gcpu, IA32_REG_RFLAGS, guest_rflags);

    gcpu_vmexit_exception_resolve(gcpu);

    return TRUE;
    }