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

John Baldwin jhb at FreeBSD.org
Tue Apr 12 10:08:16 PDT 2005


On Monday 11 April 2005 09:15 pm, Bill Paul wrote:
> [Charset iso-8859-1 unsupported, filtering to ASCII...]
>
> > On Monday 11 April 2005 02:54 pm, Julian Elischer wrote:
> > > Bill Paul wrote:
> > > >wpaul       2005-04-11 02:02:35 UTC
> > > >
> > > >
> > > >  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.
> > >
> > > Maybe we could emulate $soft and use %fs as a thread pointer instead
> > > and have pcpu
> > > pointed to via that :-)
> >
> > I think NDIS drivers want %fs to point to a Windows-specific structure
> > rather than a 'struct thread' so I don't think that would buy us anything
> > except for even more memory indirects when we do a pcpu lookup.
>
> John is correct. %fs points to the Windows TEB. I haven't dug up the
> exact structure definition for the TEB yet, but I know that the first
> DWORD in the TEB structure is a pointer to the exception handler
> list. So when Windows drivers do, say, mov %eax,%fs:0 and think
> they're writing to the exception list pointer in struct TEB, they're
> actually writing to curthread in struct pcpu.
>
> Now, we could have dodged the bullet by modifying struct pcpu slightly
> so that the first thing in is a dummy unused pointer, which would shift
> curthread down out of the way. Then Windows drivers could scribble on
> %fs:0 all they want and there'd be no problems. But I'm not about to
> redefine a core OS structure just to make Windows drivers happy.
>
> It also occured to me that what I could have done was save the
> curthread pointer somewhere during the UNIX-to-Windows context
> switch, let the drivers trash it, then restore it when switching
> from Windows-to-UNIX again. But if an interrupt occured while the CPU
> happened to be in 'Windows' context, there would be no way to restore
> the curthread pointer before entering interrupt context (whereas %fs
> is saved/restored when entering interrupt context).

Also, going ahead and faking up a TEB means that it's easier to handle the 
case of drivers trying to use or modify other TEB fields later if you run 
into it.

-- 
John Baldwin <jhb at FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
"Power Users Use the Power to Serve"  =  http://www.FreeBSD.org


More information about the cvs-src mailing list