PATCH: more fixes to interrupt code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

    I found these problems in the interrupt code:

1. In irq.c, function remap_irq(). The function must return the value
 of the remapped irq number, but does not return anything. The irq
 number gets lost.

2. Prototypes and definitions of interrupt service routines are different
 in each case. The prototype uses a pointer to struct pt_regs, not
 defined anywhere.

3. In irqtab.c, before switching to user stack and returning back to
 user code, there are a few instructions bracketed by
 #ifdef CONFIG_ADVANCED_MM. This code corrupts data of the task_struct
 next to current. By good luck, corrupted data is not presently used.
 But if currents happens to be the last element of the task array, may
 produce a crash.

4. In irqtab.c, it should pass a pointer to pt_regs to do_IRQ. Instead,
 passes a near pointer to far pointer to pt_regs.

The next patch fixes problems 1 and 2. For 3, commented out the
offending instructions
and write a note. Problem 4 is lengthy to fix because bcc has no
notion of far pointers.

greetings,

Juan

diff -Nurb elks.orig/arch/i86/drivers/char/serial.c
elks/arch/i86/drivers/char/serial.c
--- elks.orig/arch/i86/drivers/char/serial.c	2012-02-07 14:05:36.000000000 -0600
+++ elks/arch/i86/drivers/char/serial.c	2012-02-10 19:13:35.000000000 -0600
@@ -260,7 +260,7 @@
     wake_up(&q->wq);
 }

-int rs_irq(int irq, struct pt_regs *regs, void *dev_id)
+void rs_irq(int irq, struct pt_regs *regs, void *dev_id)
 {
     register struct serial_info *sp;
     register char *statusp;
diff -Nurb elks.orig/arch/i86/drivers/char/sibo_key.c
elks/arch/i86/drivers/char/sibo_key.c
--- elks.orig/arch/i86/drivers/char/sibo_key.c	2012-02-07
14:05:36.000000000 -0600
+++ elks/arch/i86/drivers/char/sibo_key.c	2012-02-10 19:13:35.000000000 -0600
@@ -44,7 +44,7 @@
  *  something going. Simon Wood 12th June 1999
  */

-void keyboard_irq(int irq, struct pt_regs *regs)
+void keyboard_irq(int irq, struct pt_regs *regs, void *data)
 {
     int modifiers;
     int key;
diff -Nurb elks.orig/arch/i86/kernel/irq.c elks/arch/i86/kernel/irq.c
--- elks.orig/arch/i86/kernel/irq.c	2012-02-07 14:05:36.000000000 -0600
+++ elks/arch/i86/kernel/irq.c	2012-02-10 19:13:35.000000000 -0600
@@ -100,12 +100,9 @@

 void enable_irq(unsigned int irq)
 {
-    flag_t flags;
     unsigned char mask;

     mask = ~(1 << (irq & 7));
-    save_flags(flags);
-    clr_irq();
     if (irq < 8) {
 	cache_21 &= mask;
 	outb(cache_21,((void *) 0x21));
@@ -113,7 +110,6 @@
 	cache_A1 &= mask;
 	outb(cache_A1,((void *) 0xA1));
     }
-    restore_flags(flags);
 }


@@ -125,6 +121,7 @@
 	return -EINVAL;			/* AT interrupt line on an XT */
     if (irq == 2 && arch_cpu>1)
 	irq = 9;			/* Map IRQ 9/2 over */
+    return irq;
 }

 /*  These 8253/8254 macros generate proper timer constants based on the
@@ -220,7 +217,7 @@
 #endasm
 #endif

-int request_irq(int irq, void (*handler)(), void *dev_id)
+int request_irq(int irq, void (*handler)(int,struct pt_regs *,void
*), void *dev_id)
 {
     register struct irqaction *action;
     flag_t flags;
@@ -285,6 +282,7 @@

 void init_IRQ(void)
 {
+    flag_t flags;

 #ifdef CONFIG_HW_259_USE_ORIGINAL_MASK       /* for example Debugger :-) */
     cache_21 = inb_p(0x21);
@@ -312,7 +310,12 @@
     if (request_irq(1, keyboard_irq, NULL))
 	panic("Unable to get keyboard");

-#else
+#endif
+
+    save_flags(flags);
+    clr_irq();
+
+#ifndef CONFIG_CONSOLE_DIRECT
     enable_irq(1);		/* BIOS Keyboard */
 #endif

@@ -327,5 +330,7 @@
     enable_irq(2);		/* Cascade */
     enable_irq(6);		/* Floppy */

+    restore_flags(flags);
+
 #endif
 }
diff -Nurb elks.orig/arch/i86/kernel/irqtab.c elks/arch/i86/kernel/irqtab.c
--- elks.orig/arch/i86/kernel/irqtab.c	2012-02-07 14:05:36.000000000 -0600
+++ elks/arch/i86/kernel/irqtab.c	2012-02-10 19:14:18.000000000 -0600
@@ -588,8 +588,9 @@
 #ifdef CONFIG_ADVANCED_MM
 	mov ax, 4[bx]	! user ds
 	mov bp, sp
-	mov 12[bp], ax	! change the es in the stack
-	mov 14[bp], ax	! change the ds in the stack
+; /*FIXME: SS:SP points to kernel stack, NOT user stack*/
+;	mov 12[bp], ax	! change the es in the stack
+;	mov 14[bp], ax	! change the ds in the stack
 #endif
 	mov	[bx],sp
 	j	noschedpop
diff -Nurb elks.orig/arch/i86/kernel/timer.c elks/arch/i86/kernel/timer.c
--- elks.orig/arch/i86/kernel/timer.c	2012-02-07 14:05:36.000000000 -0600
+++ elks/arch/i86/kernel/timer.c	2012-02-10 19:13:35.000000000 -0600
@@ -8,8 +8,9 @@
 unsigned long jiffies=0;

 extern void do_timer(struct pt_regs *);
+extern void keyboard_irq(int, struct pt_regs *, void *);

-void timer_tick(struct pt_regs * regs)
+void timer_tick(int irq, struct pt_regs *regs, void *data)
 {
 #ifndef CONFIG_ARCH_SIBO

@@ -75,7 +76,7 @@

 #endif

-    keyboard_irq();
+    keyboard_irq(1, regs, NULL);

 #endif
 }
diff -Nurb elks.orig/include/arch/irq.h elks/include/arch/irq.h
--- elks.orig/include/arch/irq.h	2012-02-07 14:05:36.000000000 -0600
+++ elks/include/arch/irq.h	2012-02-10 19:13:35.000000000 -0600
@@ -32,7 +32,7 @@
 extern void enable_irq(unsigned int);
 extern void do_IRQ(int,void *);
 extern void restore_flags(flag_t);
-extern int request_irq(int,void (*)(),void *);
+extern int request_irq(int,void (*)(int,struct pt_regs *,void *),void *);
 extern void free_irq(unsigned int);
 extern void init_IRQ(void);
 extern void do_bottom_half(void);
diff -Nurb elks.orig/include/arch/types.h elks/include/arch/types.h
--- elks.orig/include/arch/types.h	2012-02-07 14:05:36.000000000 -0600
+++ elks/include/arch/types.h	2012-02-10 19:13:35.000000000 -0600
@@ -30,6 +30,11 @@

 typedef struct _registers		__registers,	*__pregisters;

+struct pt_regs {
+    __u16	bp, di, si, dx, cx, bx,
+		es, ds, ax, ip, cs, flags;
+};
+
 /* Changed to unsigned short int as that is what it is here.
  */

diff -Nurb elks.orig/include/linuxmt/timer.h elks/include/linuxmt/timer.h
--- elks.orig/include/linuxmt/timer.h	2012-02-07 14:05:36.000000000 -0600
+++ elks/include/linuxmt/timer.h	2012-02-10 19:13:35.000000000 -0600
@@ -87,7 +87,7 @@
 extern void init_timer(struct timer_list *);
 extern void add_timer(struct timer_list *);
 extern int del_timer(struct timer_list *);
-extern void timer_tick(struct pt_regs *);
+extern void timer_tick(int, struct pt_regs *, void *);
 extern void enable_timer_tick(void);

 #endif
--
To unsubscribe from this list: send the line "unsubscribe linux-8086" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Kernel]     [Linux ia64]     [DCCP]     [Linux for ARM]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux