IBM Token Ring OOPS with 2.0.29

Petri Mattila (petri@prihateam.fi)
Mon, 9 Jun 1997 15:51:50 +0300 (EEST)


Hi,

I get this OOPS every time if I first insmod ibmtr.o, rmmod it and
then insmod it again.

Unfortunately I don't have enough knowledge about kernel internals,
so I am only including here full bug report, but no fix.

I think this one should be fixed before 2.0.31

-- petri

general protection: 0000
CPU: 0
EIP: 0010:[<02829a0d>]
EFLAGS: 00010206
eax: 0000000a ebx: 0009e778 ecx: fffffffb edx: 00000000
esi: f000f84d edi: 0000000a ebp: 00000000 esp: 01a22dd8
ds: 0018 es: 0018 fs: 002b gs: 002b ss: 0018
Process insmod (pid: 163, process nr: 11, stackpage=01a22000)
Stack: 0009e778 00000000 0000000a 01a22e18 00000000 0010c8ad 0000000a 00000000
01a22e18 01a22e18 0000000a 00000000 0009e778 0010c09f 0000000a 01a22e18
00193254 fffffffb 00108e00 0000000a 00000000 0009e778 ffffff00 00000018
Call Trace: [do_IRQ+45/80] [IRQ10_interrupt+95/144] [setup_x86_irq+281/292] [<028299f8>] [request_irq+104/132] [<028296f8>] [<028299f8>]
[<0282ae0a>] [<0282aa84>] [<0282a992>] [register_netdev+83/216] [<0282aa84>] [<0282b544>] [<0282aa7f>] [<0282a9a6>]
[<0282aa84>] [sys_init_module+976/1028] [do_no_page+259/808] [do_no_page+391/808] [<0282a944>] [<0282a9cc>] [do_page_fault+284/716] [do_page_fault+0/716]
[error_code+64/80] [system_call+85/128]
Code: 0f b6 56 2f 83 fa 01 0f 84 b6 07 00 00 83 fa 02 0f 85 c1 07
Aiee, killing interrupt handler

Code: movzbl 0x2f(%esi),%edx
Code: cmpl $0x1,%edx
Code: je 000007c3 <_EIP+7c3>
Code: cmpl $0x2,%edx
Code: jne 900007d7 <_EIP+900007d7>
Code: nop
Code: nop

>From ibmtr.o:

000009f4 <tok_interrupt> subl $0x4,%esp
000009f7 <tok_interrupt+3> pushl %ebp
000009f8 <tok_interrupt+4> pushl %edi
000009f9 <tok_interrupt+5> pushl %esi
000009fa <tok_interrupt+6> pushl %ebx
000009fb <tok_interrupt+7> movl 0x18(%esp,1),%eax
000009ff <tok_interrupt+b> movl 0x0(,%eax,4),%ebp
00000a06 <tok_interrupt+12> movl 0x44(%ebp),%esi
=> 00000a09 <tok_interrupt+15> movzbl 0x2f(%esi),%edx
00000a0d <tok_interrupt+19> cmpl $0x1,%edx
00000a10 <tok_interrupt+1c> je 000011cc <tok_interrupt+7d8>
00000a16 <tok_interrupt+22> cmpl $0x2,%edx
00000a19 <tok_interrupt+25> jne 000011e0 <tok_interrupt+7ec>
00000a1f <tok_interrupt+2b> movb $0x1,0x1a(%ebp)
00000a23 <tok_interrupt+2f> movl 0x4(%esi),%eax
00000a26 <tok_interrupt+32> movb $0xbf,0x1e28(%eax)
00000a2d <tok_interrupt+39> movw 0x56(%esi),%dx
00000a31 <tok_interrupt+3d> testw %dx,%dx
00000a34 <tok_interrupt+40> je 00000a39 <tok_interrupt+45>
00000a36 <tok_interrupt+42> xorb %al,%al
00000a38 <tok_interrupt+44> outb %al,(%dx)
00000a39 <tok_interrupt+45> movl 0x4(%esi),%edx
00000a3c <tok_interrupt+48> movb 0x1e09(%edx),%al
00000a42 <tok_interrupt+4e> movb %al,0x10(%esp,1)

void tok_interrupt (int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char status;
struct tok_info *ti;
struct device *dev = (struct device *)(irq2dev_map[irq]);

#if TR_VERBOSE
DPRINTK("Int from tok_driver, dev : %p\n",dev);
#endif

ti=(struct tok_info *) dev->priv;

HERE: ti is null !

=> switch (ti->do_tok_int) {

case NOT_FIRST:

/* Begin the regular interrupt handler HERE inline to avoid
the extra levels of logic and call depth for the
original solution. */

dev->interrupt=1;

/* Disable interrupts till processing is finished */