cvs commit: src/sys/compat/ndis hal_var.h kern_ndis.c kern_windrv.c ndis_var.h ntoskrnl_var.h pe_var.h subr_hal.c subr_ndis.c subr_ntoskrnl.c subr_usbd.c winx32_wrap.S src/sys/modules/ndis Makefile src/sys/dev/if_ndis if_ndis.c

Bill Paul wpaul at FreeBSD.org
Sun Apr 10 19:02:36 PDT 2005


wpaul       2005-04-11 02:02:35 UTC

  FreeBSD src repository

  Modified files:
    sys/compat/ndis      hal_var.h kern_ndis.c kern_windrv.c 
                         ndis_var.h ntoskrnl_var.h pe_var.h 
                         subr_hal.c subr_ndis.c subr_ntoskrnl.c 
                         subr_usbd.c 
    sys/modules/ndis     Makefile 
    sys/dev/if_ndis      if_ndis.c 
  Added files:
    sys/compat/ndis      winx32_wrap.S 
  Log:
  Create new i386 windows/bsd thunking layer, similar to the amd64 thunking
  layer, but with a twist.
  
  The twist has to do with the fact that Microsoft supports structured
  exception handling in kernel mode. On the i386 arch, exception handling
  is implemented by hanging an exception registration list off the
  Thread Environment Block (TEB), and the TEB is accessed via the %fs
  register. The problem is, we use %fs as a pointer to the pcpu stucture,
  which means any driver that tries to write through %fs:0 will overwrite
  the curthread pointer and make a serious mess of things.
  
  To get around this, Project Evil now creates a special entry in
  the GDT on each processor. When we call into Windows code, a context
  switch routine will fix up %fs so it points to our new descriptor,
  which in turn points to a fake TEB. When the Windows code returns,
  or calls out to an external routine, we swap %fs back again. Currently,
  Project Evil makes use of GDT slot 7, which is all 0s by default.
  I fully expect someone to jump up and say I can't do that, but I
  couldn't find any code that makes use of this entry anywhere. Sadly,
  this was the only method I could come up with that worked on both
  UP and SMP. (Modifying the LDT works on UP, but becomes incredibly
  complicated on SMP.) If necessary, the context switching stuff can
  be yanked out while preserving the convention calling wrappers.
  
  (Fortunately, it looks like Microsoft uses some special epilog/prolog
  code on amd64 to implement exception handling, so the same nastiness
  won't be necessary on that arch.)
  
  The advantages are:
  
  - Any driver that uses %fs as though it were a TEB pointer won't
    clobber pcpu.
  - All the __stdcall/__fastcall/__regparm stuff that's specific to
    gcc goes away.
  
  Also, while I'm here, switch NdisGetSystemUpTime() back to using
  nanouptime() again. It turns out nanouptime() is way more accurate
  than just using ticks(). On slower machines, the Atheros drivers
  I tested seem to take a long time to associate due to the loss
  in accuracy.
  
  Revision  Changes    Path
  1.8       +5 -5      src/sys/compat/ndis/hal_var.h
  1.77      +39 -39    src/sys/compat/ndis/kern_ndis.c
  1.6       +400 -14   src/sys/compat/ndis/kern_windrv.c
  1.37      +9 -9      src/sys/compat/ndis/ndis_var.h
  1.32      +65 -56    src/sys/compat/ndis/ntoskrnl_var.h
  1.13      +46 -79    src/sys/compat/ndis/pe_var.h
  1.20      +66 -61    src/sys/compat/ndis/subr_hal.c
  1.84      +353 -341  src/sys/compat/ndis/subr_ndis.c
  1.64      +349 -335  src/sys/compat/ndis/subr_ntoskrnl.c
  1.2       +11 -9     src/sys/compat/ndis/subr_usbd.c
  1.1       +354 -0    src/sys/compat/ndis/winx32_wrap.S (new)
  1.86      +26 -17    src/sys/dev/if_ndis/if_ndis.c
  1.10      +4 -0      src/sys/modules/ndis/Makefile


More information about the cvs-all mailing list