/*! * @fn void cpumon_Save_Cpu(param) * * @param param - Unused, set up to enable parallel calls * * @return None No return needed * * @brief Set up the interrupt handler. * @brief Save the old handler for restoration when done * */ static VOID cpumon_Save_Cpu ( PVOID parm ) { unsigned long eflags; IDTGDT_DESC idt_base; CPU_STATE pcpu = &pcb[CONTROL_THIS_CPU()]; GATE_STRUCT old_gate; GATE_STRUCT *idt; SYS_Local_Irq_Save(eflags); SYS_Get_IDT_Base((PVOID*)&idt_base); idt = idt_base.idtgdt_base; CPU_STATE_idt_base(pcpu) = idt; memcpy (&old_gate, &idt[CPU_PERF_VECTOR], 16); CPU_STATE_saved_ih(pcpu) = (PVOID) ((((U64) old_gate.offset_high) << 32) | (((U64) old_gate.offset_middle) << 16) | ((U64) old_gate.offset_low)); SEP_PRINT_DEBUG("saved_ih is 0x%llx\n", CPU_STATE_saved_ih(pcpu)); SYS_Local_Irq_Restore(eflags); return; }
/*! * @fn void cpumon_Init_Cpu(param) * * @param param unused parameter * * @return None No return needed * * @brief Set up the interrupt handler. * */ static VOID cpumon_Init_Cpu ( PVOID parm ) { unsigned long eflags; U64 *idt_base; CPU_STATE pcpu; local_handler_t lhandler; preempt_disable(); pcpu = &pcb[CONTROL_THIS_CPU()]; preempt_enable(); SYS_Local_Irq_Save(eflags); idt_base = CPU_STATE_idt_base(pcpu); // install perf. handler // These are the necessary steps to have an ISR entry // Note the changes in the data written lhandler.u64[0] = (unsigned long)SYS_Perfvec_Handler; lhandler.u16[3] = lhandler.u16[1]; lhandler.u16[1] = SYS_Get_cs(); lhandler.u16[2] = 0xee00; idt_base[CPU_PERF_VECTOR] = lhandler.u64[0]; SYS_Local_Irq_Restore(eflags); return; }
/*! * @fn void cpumon_Init_Cpu(param) * * @param param unused parameter * * @return None No return needed * * @brief Set up the interrupt handler. * */ static VOID cpumon_Init_Cpu ( PVOID parm ) { unsigned long eflags; CPU_STATE pcpu = &pcb[CONTROL_THIS_CPU()]; GATE_STRUCT *idt; SYS_Local_Irq_Save(eflags); idt = CPU_STATE_idt_base(pcpu); cpumon_Set_IDT_Func(idt, SYS_Perfvec_Handler); SYS_Local_Irq_Restore(eflags); return; }
/*! * @fn void cpumon_Destroy_Cpu(param) * * @param param unused parameter * * @return None No return needed * * @brief Restore the old handler * @brief Finish clean up of the apic * */ static VOID cpumon_Destroy_Cpu ( PVOID ctx ) { unsigned long eflags; CPU_STATE pcpu = &pcb[CONTROL_THIS_CPU()]; GATE_STRUCT *idt; SYS_Local_Irq_Save(eflags); APIC_Disable_PMI(); idt = CPU_STATE_idt_base(pcpu); cpumon_Set_IDT_Func(idt, CPU_STATE_saved_ih(pcpu)); SYS_Local_Irq_Restore(eflags); return; }
/*! * @fn void cpumon_Init_Cpu(param) * * @param param unused parameter * * @return None No return needed * * @brief Set up the interrupt handler. * */ static VOID cpumon_Init_Cpu ( PVOID parm ) { unsigned long eflags; U64 *idt_base; CPU_STATE pcpu; local_handler_t lhandler; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) unsigned long cr0_value; #endif preempt_disable(); pcpu = &pcb[CONTROL_THIS_CPU()]; preempt_enable(); SYS_Local_Irq_Save(eflags); idt_base = CPU_STATE_idt_base(pcpu); // install perf. handler // These are the necessary steps to have an ISR entry // Note the changes in the data written lhandler.u64[0] = (unsigned long)SYS_Perfvec_Handler; lhandler.u16[3] = lhandler.u16[1]; lhandler.u16[1] = SYS_Get_cs(); lhandler.u16[2] = 0xee00; // From 3.10 kernel, the IDT memory has been moved to a read-only location // which is controlled by the bit 16 in the CR0 register. // The write protection should be temporarily released to update the IDT. #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) cr0_value = read_cr0(); write_cr0(cr0_value & ~X86_CR0_WP); #endif idt_base[CPU_PERF_VECTOR] = lhandler.u64[0]; #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) write_cr0(cr0_value); #endif SYS_Local_Irq_Restore(eflags); return; }
/*! * @fn void cpumon_Save_Cpu(param) * * @param param unused parameter * * @return None No return needed * * @brief Save the old handler for restoration when done * */ static void cpumon_Save_Cpu ( PVOID parm ) { unsigned long eflags; U64 *idt_base; CPU_STATE pcpu; preempt_disable(); pcpu = &pcb[CONTROL_THIS_CPU()]; preempt_enable(); SYS_Local_Irq_Save(eflags); CPU_STATE_idt_base(pcpu) = idt_base = SYS_Get_IDT_Base(); // save original perf. vector CPU_STATE_saved_ih(pcpu) = idt_base[CPU_PERF_VECTOR]; SEP_PRINT_DEBUG("saved_ih is 0x%llx\n", CPU_STATE_saved_ih(pcpu)); SYS_Local_Irq_Restore(eflags); return; }