if_ndis: kernel trap 9 with interrupts disabled

Peter Edwards peadar.edwards at gmail.com
Sun Apr 17 11:10:46 PDT 2005


On 4/17/05, Yuriy Tsibizov <Yuriy.Tsibizov at gfk.ru> wrote:

> On -CURRENT from Saturday, D-Link DWL-G650+ (TNET1130 chipset) NDIS
[snip]
> ndis0: <D-Link AirPlus G+ DWL-G520+ Wireless PCI Adapter> mem
>  0xe6000000-0xe6001fff,0xe5800000-0xe581ffff irq 9 at device 10.0 on pci0
> ndis0: [GIANT-LOCKED]
> ndis0: NDIS API version: 5.0
> kernel trap 9 with interrupts disabled

Noticed this today myself with

> ndis0: <Intel(R) PRO/Wireless 2200BG Network Connection> mem 0xfcffe000-0xfcffefff irq 9 at device 3.0 on pci1
> ndis0: NDIS API version: 5.1
> ndis0: Ethernet address: 00:0e:35:17:f2:88
> ndis0: couldn't retrieve channel info: 19
> ndis0: link up

My x86 foo is a little rusty, but I think Peter Wemm's changes to the
segment layout conflicted with the NDIS driver, such that the NDIS
driver now tramples on the code segment for the process's user mode,
rather than it's own private GDT entry. The attached patch works for
me: can you try it?
Peter/Bill: does this look correct?

Cheers,
Peadar.
-------------- next part --------------
Index: compat/ndis/kern_windrv.c
===================================================================
RCS file: /usr/cvs/FreeBSD-CVS/src/sys/compat/ndis/kern_windrv.c,v
retrieving revision 1.6
diff -u -r1.6 kern_windrv.c
--- compat/ndis/kern_windrv.c	11 Apr 2005 02:02:34 -0000	1.6
+++ compat/ndis/kern_windrv.c	17 Apr 2005 18:08:33 -0000
@@ -59,6 +59,9 @@
 #include <compat/ndis/ndis_var.h>
 #include <compat/ndis/hal_var.h>
 #include <compat/ndis/usbd_var.h>
+#ifdef __i386__
+#include <machine/segments.h>
+#endif
 
 struct windrv_type {
 	uint16_t		windrv_vid;	/* for PCI or USB */
@@ -545,7 +548,6 @@
 
 #define SEL_LDT	4		/* local descriptor table */
 #define SEL_TO_FS(x)		(((x) << 3))
-#define FREEBSD_EMPTYSEL	7
 
 /*
  * The meanings of various bits in a descriptor vary a little
@@ -794,7 +796,7 @@
 	/* Find the slot we updated. */
 
 	gdt = gtable.base;
-	gdt += FREEBSD_EMPTYSEL;
+	gdt += GNDIS_SEL;
 
 	/* Empty it out. */
 
@@ -832,11 +834,11 @@
 
 	/* Get pointer to empty slot */
 
-	l += FREEBSD_EMPTYSEL;
+	l += GNDIS_SEL;
 
 	/* Initialize TID for this CPU. */
 
-	my_tids[t->td_oncpu].tid_selector = FREEBSD_EMPTYSEL;
+	my_tids[t->td_oncpu].tid_selector = GNDIS_SEL;
 	my_tids[t->td_oncpu].tid_self = &my_tids[t->td_oncpu];
 
 	/* Set up new GDT entry. */


More information about the freebsd-current mailing list