/*! * @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; 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; }