/*! * @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_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; unsigned long long *idt_base; CPU_STATE pcpu; preempt_disable(); pcpu = &pcb[CONTROL_THIS_CPU()]; preempt_enable(); SYS_Local_Irq_Save(eflags); // restore perf. vector (to a safe stub pointer) idt_base = SYS_Get_IDT_Base(); APIC_Disable_PMI(); idt_base[CPU_PERF_VECTOR] = CPU_STATE_saved_ih(pcpu); 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; unsigned long long *idt_base; CPU_STATE pcpu; #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); // restore perf. vector (to a safe stub pointer) idt_base = SYS_Get_IDT_Base(); APIC_Disable_PMI(); // 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] = CPU_STATE_saved_ih(pcpu); #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0) write_cr0(cr0_value); #endif SYS_Local_Irq_Restore(eflags); return; }