[Fault-injection-developer] RFC: Update KIRQ patch
Status: Alpha
Brought to you by:
rustyl
From: Wang, S. <sta...@in...> - 2002-12-26 10:38:15
|
Hi, folks, Here is the lastest KIRQ patch, I add a dispatch function. # 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.954 -> 1.956 # arch/i386/Kconfig 1.14 -> 1.16 # arch/i386/kernel/Makefile 1.31 -> 1.32 # (new) -> 1.6 arch/i386/kernel/kirq.c # (new) -> 1.4 include/asm-i386/kirq.h # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/12/26 st...@ma... 1.955 # Merge manticore.sh.intel.com:/home/stanley/linux-2.5 # into manticore.sh.intel.com:/home/stanley/work/2.5-kirq # -------------------------------------------- # 02/12/26 st...@ma... 1.956 # Add dispatch_kirq # -------------------------------------------- # diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig --- a/arch/i386/Kconfig Thu Dec 26 18:29:23 2002 +++ b/arch/i386/Kconfig Thu Dec 26 18:29:23 2002 @@ -1544,6 +1544,14 @@ best used in conjunction with the NMI watchdog so that spinlock deadlocks are also debuggable. +config KIRQ + bool "Kernel Irq interceptor for X86(experimental)" + depends on DEBUG_KERNEL && EXPERIMENTAL + help + This option enable an IRQ interceptor. You can get the control + before any specified ISR is executing and decide whether it + should be executing through "register_kirq/unregister_kirq". + 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 Thu Dec 26 18:29:23 2002 +++ b/arch/i386/kernel/Makefile Thu Dec 26 18:29:23 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 Thu Dec 26 18:29:23 2002 @@ -0,0 +1,120 @@ +/* Support for kernel irq interceptor. + (C) 2002 Stanley Wang <sta...@in...>. +*/ + +#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 "%s: Dropping unexpected interrupt #%i\n", + __FUNCTION__, irq); + } + 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 "%s: Missing handler!\n", __FUNCTION__); + return -EINVAL; + } + + if (p->handler) { + printk(KERN_ERR "%s: KIRQ was regitsered already!\n", __FUNCTION__); + return -EINVAL; + } + + 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 "%s: Unregister KIRQ failed!\n", __FUNCTION__); + 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; +} + +void dispatch_kirq(int irq, struct pt_regs *regs) +{ + struct kirq *p = kirq_list + irq; + if (p->isr != NULL){ + (*(p->isr))(irq, p->dev_id, regs); + }else{ + printk(KERN_ERR "%s: Dropping wrong interrupt #%i\n", + __FUNCTION__, irq); + } + return; +} + +EXPORT_SYMBOL_GPL(register_kirq); +EXPORT_SYMBOL_GPL(unregister_kirq); +EXPORT_SYMBOL_GPL(dispatch_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 Thu Dec 26 18:29:23 2002 @@ -0,0 +1,30 @@ +#ifndef _ASM_KIRQ_H +#define _ASM_KIRQ_H + +#include <linux/errno.h> + +/* Define return value for kirq handler. */ +#define KIRQ_CONTINUE 0 +#define KIRQ_SKIP 1 + +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); +extern void dispatch_kirq(int irq, struct pt_regs* regs); +#else +int register_kirq(int irq, char *devname, kirq_handler_t handler) { return -ENOSYS; } +int unregister_kirq(int irq) { return -ENOSYS; } +void dispatch_kirq(int irq, struct pt_regs* regs) {} +#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 |