/*! * @fn void cpumon_Set_IDT_Func(idt, func) * * @param GATE_STRUCT* - address of the idt vector * @param PVOID - function to set in IDT * * @return None No return needed * * @brief Set up the interrupt handler. * @brief Save the old handler for restoration when done * */ static VOID cpumon_Set_IDT_Func ( GATE_STRUCT *idt, PVOID func ) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) _set_gate(&idt[CPU_PERF_VECTOR], GATE_INTERRUPT, (unsigned long) func, 3, 0); #else #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) unsigned long cr0_value; #endif GATE_STRUCT local; // _set_gate() cannot be used because the IDT table is not exported. pack_gate(&local, GATE_INTERRUPT, (unsigned long)func, 3, 0, __KERNEL_CS); // 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 write_idt_entry((idt), CPU_PERF_VECTOR, &local); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) write_cr0(cr0_value); #endif #endif return; }
static void __init set_trap_gate(unsigned int n, void *addr) { /** * DESCTYPE_TRAP es el tipo de gate, addr es * el handler, __KERNEL_CS es el selector donde * va a estar el codigo */ _set_gate(n, DESCTYPE_TRAP, addr, __KERNEL_CS); }
/*! * @fn void cpumon_Set_IDT_Func(idt, func) * * @param GATE_STRUCT* - address of the idt vector * @param PVOID - function to set in IDT * * @return None No return needed * * @brief Set up the interrupt handler. * @brief Save the old handler for restoration when done * */ static VOID cpumon_Set_IDT_Func ( GATE_STRUCT *idt, PVOID func ) { #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,25) _set_gate(&idt[CPU_PERF_VECTOR], GATE_INTERRUPT, (unsigned long) func, 3, 0); #else GATE_STRUCT local; // _set_gate() cannot be used because the IDT table is not exported. pack_gate(&local, GATE_INTERRUPT, (unsigned long)func, 3, 0, __KERNEL_CS); write_idt_entry(idt, CPU_PERF_VECTOR, &local); #endif return; }