/* Function Name: handler_initialize * Purpose: Initialize module specific handlers callback functions * * Input: num of cpus * Return value: TRUE=success, FALSE=failure */ boolean_t handler_initialize(uint16_t num_of_cpus) { ikgt_printf("HANDLER: Initializing Handler. Num of CPUs = %d\n", num_of_cpus); g_b_init_status = policy_initialize(); }
void policy_cr4_dump(void) { ikgt_printf("%s:\n", __func__); ikgt_printf("g_cr4_count=%u\n", g_cr4_count); ikgt_printf("g_cr4_allow_count=%u\n", g_cr4_allow_count); ikgt_printf("g_cr4_skip_count=%u\n", g_cr4_skip_count); ikgt_printf("g_cr4_sticky_count_allow=%u\n", g_cr4_sticky_count_allow); ikgt_printf("g_cr4_sticky_count_skip=%u\n", g_cr4_sticky_count_skip); ikgt_printf("\n"); }
void policy_cr4_debug(uint64_t command_code) { ikgt_printf("%s(%u)\n", __func__, command_code); policy_cr4_dump(); }
void handle_cr4_event(ikgt_event_info_t *event_info) { uint64_t new_cr4_value; uint64_t cur_cr4_value; uint64_t diff; ikgt_cpu_event_info_t *cpuinfo; ikgt_vmcs_guest_state_reg_id_t operand_reg_id; ikgt_status_t status; int i, tmp, str_count; policy_entry_t *entry; policy_cr4_ctx ctx; char log_entry_message[LOG_MESSAGE_SIZE]; char access[MAX_ACCESS_BUF_SIZE], action[MAX_ACTION_BUF_SIZE]; event_info->response = IKGT_EVENT_RESPONSE_ALLOW; g_cr4_count++; cpuinfo = (ikgt_cpu_event_info_t *) (event_info->event_specific_data); if (IKGT_CPU_REG_UNKNOWN == cpuinfo->operand_reg) { ikgt_printf("Error, cpuinfo->operand_reg=IKGT_CPU_REG_UNKNOWN\n"); return; } status = read_guest_reg(VMCS_GUEST_STATE_CR4, &cur_cr4_value); if (IKGT_STATUS_SUCCESS != status) { return; } /* get the VMCS reg ID for the operand */ status = get_vmcs_guest_reg_id(cpuinfo->operand_reg, &operand_reg_id); if (IKGT_STATUS_SUCCESS != status) { return; } /* read the guest register from VMCS * new_cr4_value contains the new value to be written to cr4 */ status = read_guest_reg(operand_reg_id, &new_cr4_value); if (IKGT_STATUS_SUCCESS != status) { return; } diff = cur_cr4_value ^ new_cr4_value; if (0 == diff) return; ctx.event_info = event_info; ctx.new_cr4_value = new_cr4_value; ctx.cur_cr4_value = cur_cr4_value; ctx.diff = diff; ctx.log = FALSE; for (i = 0; i < POLICY_MAX_ENTRIES; i++) { entry = policy_get_entry_by_index(i); if ((POLICY_GET_RESOURCE_ID(entry) == RESOURCE_ID_UNKNOWN) || !IS_CR4_ENTRY(entry)) continue; process_cr4_policy(entry, &ctx); } if (ctx.new_cr4_value == cur_cr4_value) { event_info->response = IKGT_EVENT_RESPONSE_REDIRECT; } if (ctx.log) { tmp = mon_sprintf_s(access, MAX_ACCESS_BUF_SIZE, "write"); action_to_string(&event_info->response, action); str_count = mon_sprintf_s(log_entry_message, LOG_MESSAGE_SIZE, "resource-name=CR4, access=%s, value=0x%016llx, RIP=0x%016llx, action=%s", access, new_cr4_value, event_info->vmcs_guest_state.ia32_reg_rip, action); log_event(log_entry_message, event_info->thread_id); } /* If response is skip then return */ if (event_info->response == IKGT_EVENT_RESPONSE_REDIRECT) return; status = write_guest_reg(operand_reg_id, ctx.new_cr4_value); if (IKGT_STATUS_SUCCESS != status) { ikgt_printf("error, write_guest_reg(%u)=%u\n", operand_reg_id, status); } event_info->response = IKGT_EVENT_RESPONSE_ALLOW; }