[Fault-injection-developer] RFC: IRQ interceptor infrastructure
Status: Alpha
Brought to you by:
rustyl
From: Wang, S. <sta...@in...> - 2002-12-18 13:16:19
|
Hi folks, There is the IRQ interceptor infrastructure: KIRQ # This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.892 -> 1.894 # arch/i386/Kconfig 1.14 -> 1.15 # arch/i386/kernel/Makefile 1.31 -> 1.32 # (new) -> 1.3 arch/i386/kernel/kirq.c # (new) -> 1.2 include/asm-i386/kirq.h # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/12/18 st...@st... 1.893 # Add KIRQ Support # -------------------------------------------- # 02/12/18 st...@ma... 1.894 # Fix stupid bug. # -------------------------------------------- # diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Wed Dec 18 20:54:04 2002 +++ b/arch/i386/Kconfig Wed Dec 18 20:54:04 2002 @@ -1544,6 +1544,12 @@ best used in conjunction with the NMI watchdog so that spinlock deadlocks are also debuggable. +config KIRQ + bool "Kernel Irq interceptor" + depends on DEBUG_KERNEL + help + This option enable an IRQ interceptor. + config DEBUG_HIGHMEM bool "Highmem debugging" depends on DEBUG_KERNEL && HIGHMEM diff -Nru a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile --- a/arch/i386/kernel/Makefile Wed Dec 18 20:54:04 2002 +++ b/arch/i386/kernel/Makefile Wed Dec 18 20:54:04 2002 @@ -4,7 +4,7 @@ EXTRA_TARGETS := head.o init_task.o -export-objs := mca.o i386_ksyms.o time.o +export-objs := mca.o i386_ksyms.o time.o kirq.o obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ @@ -29,6 +29,7 @@ obj-$(CONFIG_PROFILING) += profile.o obj-$(CONFIG_EDD) += edd.o obj-$(CONFIG_MODULES) += module.o +obj-$(CONFIG_KIRQ) += kirq.o obj-y += sysenter.o EXTRA_AFLAGS := -traditional diff -Nru a/arch/i386/kernel/kirq.c b/arch/i386/kernel/kirq.c --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/arch/i386/kernel/kirq.c Wed Dec 18 20:54:04 2002 @@ -0,0 +1,99 @@ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/spinlock.h> +#include <linux/mm.h> +#include <linux/slab.h> +#include <linux/irq.h> +#include <linux/interrupt.h> +#include <asm/kirq.h> + +void kirq_handler(int irq, void *dev_id, struct pt_regs *regs) +{ + int i; + struct kirq *p = kirq_list + irq; + if (p->handler != NULL){ + i = (*(p->handler))(p, irq, dev_id, regs); + if ( i == 0 ) + (*(p->isr))(irq, dev_id, regs); + }else{ + printk(KERN_ERR "Miss KIRQ handler!\n"); + } + return; +} + +int register_kirq(int irq, char *devname, kirq_handler_t handler) +{ + struct irqaction *action; + irq_desc_t *desc = irq_desc + irq; + struct kirq *p = kirq_list + irq; + unsigned long flags; + + if (handler == NULL) { + printk(KERN_ERR "Register KIRQ failed: Missing handler!\n"); + } + + if (p->handler) { + printk(KERN_ERR "Register KIRQ failed: KIRQ already exist!\n"); + } + + spin_lock_irqsave(&desc->lock,flags); + + action = desc->action; + while (action) { + if (strcmp(action->name,devname)) { + action = action->next; + }else{ + break; + } + } + + if (!action) { + spin_unlock_irqrestore(&desc->lock,flags); + return -1; + } + + p->isr = action->handler; + p->handler = handler; + p->dev_id = action->dev_id; + + action->handler = kirq_handler; + + spin_unlock_irqrestore(&desc->lock,flags); + + return 0; +} + +int unregister_kirq(int irq) +{ + struct irqaction *action; + irq_desc_t *desc = irq_desc + irq; + struct kirq *p = kirq_list + irq; + unsigned long flags; + + spin_lock_irqsave(&desc->lock,flags); + + action = desc->action; + while ( action && action->dev_id != p->dev_id) { + action = action->next; + } + + if (!action) { + printk(KERN_ERR "Unregister KIRQ failed!\n"); + spin_unlock_irqrestore(&desc->lock,flags); + return -1; + } + + action->handler = p->isr; + + p->isr = NULL; + p->handler = NULL; + p->dev_id = NULL; + + spin_unlock_irqrestore(&desc->lock,flags); + + return 0; +} +EXPORT_SYMBOL_GPL(register_kirq); +EXPORT_SYMBOL_GPL(unregister_kirq); + diff -Nru a/include/asm-i386/kirq.h b/include/asm-i386/kirq.h --- /dev/null Wed Dec 31 16:00:00 1969 +++ b/include/asm-i386/kirq.h Wed Dec 18 20:54:04 2002 @@ -0,0 +1,24 @@ +#ifndef _ASM_KIRQ_H +#define _ASM_KIRQ_H + +#include <linux/errno.h> + +struct kirq; +typedef int (*kirq_handler_t)(struct kirq *, int, void *, struct pt_regs *); +struct kirq { + void *dev_id; + void (*isr)(int, void *, struct pt_regs *); + kirq_handler_t handler; +}; + +struct kirq kirq_list[NR_IRQS] = + { [0 ... NR_IRQS-1] = { NULL, NULL, NULL}}; + +#ifdef CONFIG_KIRQ +extern int register_kirq(int irq, char *devname, kirq_handler_t handler); +extern int unregister_kirq(int irq); +#else +int register_kirq(int irq, char *devname, kirq_handler_t handler) { return -ENOSYS; } +int unregister_kirq(int irq) {} +#endif /*CONFIG_KIRQ*/ +#endif /*_ASM_KIRQ_H*/ Your Sincerely, Stanley Wang SW Engineer, Intel Corporation. Intel China Software Lab. Tel: 021-52574545 ext. 1171 iNet: 8-752-1171 Opinions expressed are those of the author and do not represent Intel Corporation |