Exemple #1
0
/*!
 * @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;
}