Commit Graph

1056 Commits

Author SHA1 Message Date
peter
0cf2f68921 Fix 32 bit signals on amd64. It turns out that I was sign extending
the register values coming back from sigreturn(2).  Normally this wouldn't
matter because the 32 bit environment would truncate the upper 32 bits
and re-save the truncated values at the next trap.  However, if we got
a fast second signal and it was pending while we were returning from
sigreturn(2) in the signal trampoline, we'd never have had a chance to
truncate the bogus values in 32 bit mode, and the new sendsig would get
an EFAULT when trying to write to the bogus user stack address.
2005-04-05 22:41:49 +00:00
jhb
a3c6b782c3 - Change the vm_mmap() function to accept an objtype_t parameter specifying
the type of object represented by the handle argument.
- Allow vm_mmap() to map device memory via cdev objects in addition to
  vnodes and anonymous memory.  Note that mmaping a cdev directly does not
  currently perform any MAC checks like mapping a vnode does.
- Unbreak the DRM getbufs ioctl by having it call vm_mmap() directly on the
  cdev the ioctl is acting on rather than trying to find a suitable vnode
  to map from.

Reviewed by:	alc, arch@
2005-04-01 20:00:11 +00:00
wpaul
5f091f4a37 Fix another KeInitializeDpc()/amd64 calling convention issue:
ndis_intrhand() has to be wrapped for the same reason as ndis_timercall().
2005-04-01 16:40:22 +00:00
jhb
38bfdc988f - Use a custom version of copyinuio() to implement readv/writev using
kern_readv/writev.
- Use kern_settimeofday() and kern_adjtime() rather than stackgapping it.
2005-03-31 22:58:13 +00:00
wpaul
6848972c73 Apparently I'm cursed. ndis_findwrap() should be searching ndis_functbl,
not ntoskrnl_functbl.
2005-03-31 21:20:19 +00:00
wpaul
123cbe5f9b Fix an amd64 issue I overlooked. When setting up a callout to
ndis_timercall() in NdisMInitializeTimer(), we can't use the raw
function pointer. This is because ntoskrnl_run_dpc() expects to
invoke a function with Microsoft calling conventions. On i386,
this works because ndis_timercall() is declared with the __stdcall
attribute, but this is a no-op on amd64. To do it correctly, we
have to generate a wrapper for ndis_timercall() and us the wrapper
instead of of the raw function pointer.

Fix this by adding ndis_timercall() to the funcptr table in subr_ndis.c,
and create ndis_findwrap() to extract the wrapped function from the
table in NdisMInitializeTimer() instead of just passing ndis_timercall()
to KeInitializeDpc() directly.
2005-03-31 16:38:48 +00:00
wpaul
2e83169800 Fix a possible mutex leak in KeSetTimerEx(): if timer is NULL, we
bail out without releasing the dispatcher lock. Move the lock acquisition
after the pointer test to avoid this.
2005-03-30 16:22:48 +00:00
wpaul
0257351eba Remove a couple of #ifdef 0'ed code blocks left over from Atheros debugging.
Remember to reset ndis_pendingreq to NULL when bailing out of
ndis_set_info() or ndis_get_info() due to miniportadapterctx not
being set.
2005-03-30 02:50:06 +00:00
jeff
bcbda3d771 - Initial cn_lkflags to LK_EXCLUSIVE.
Sponsored by:	Isilon Systems, Inc.
2005-03-29 10:16:12 +00:00
wpaul
bb3714b327 The filehandle allocated in NdisOpenFile() is allocated using
ExAllocatePoolWithTag(), not malloc(), so it should be released
with ExFreePool(), not free(). Fix a couple if instances of
free(fh, ...) that got overlooked.
2005-03-28 22:03:47 +00:00
wpaul
9920f4f146 Another Coverity fix from Sam: add NULL pointer test in
NdisMFreeSharedMemory() (if the list is already empty, just bail).
2005-03-28 21:09:00 +00:00
wpaul
3e1273271d More additions for amd64:
- On amd64, InterlockedPushEntrySList() and InterlockedPopEntrySList()
  are mapped to ExpInterlockedPushEntrySList and
  ExpInterlockedPopEntrySList() via macros (which do the same thing).
  Add IMPORT_FUNC_MAP()s for these.

- Implement ExQueryDepthSList().
2005-03-28 20:46:08 +00:00
wpaul
386c0634e4 Fix resource leak found by Coverity (via Sam Leffler). 2005-03-28 20:16:26 +00:00
wpaul
7f6e70f819 Fix for amd64. 2005-03-28 20:13:14 +00:00
wpaul
b1238bf60e Fix another amd64 issue with lookaside lists: we initialize the
alloc and free routine pointers in the lookaside list with pointers
to ExAllocatePoolWithTag() and ExFreePool() (in the case where the
driver does not provide its own alloc and free routines). For amd64,
this is wrong: we have to use pointers to the wrapped versions of these
functions, not the originals.
2005-03-28 19:27:58 +00:00
wpaul
12c3eeb4fa Tweak to hopefully make lookaside lists work on amd64: in Windows, the
nll_obsoletelock field in the lookaside list structure is only defined
for the i386 arch. For amd64, the field is gone, and different list
update routines are used which do their locking internally. Apparently
the Inprocomm amd64 driver uses lookaside lists. I'm not positive this
will make it work yet since I don't have an Inprocomm NIC to test, but
this needs to be fixed anyway.
2005-03-28 17:36:06 +00:00
wpaul
913253e3c7 Spell '0' as 'FALSE' when initializing npp_validcounts. (Doesn't change
the code, but emphasises that this field is used as a boolean.)
2005-03-28 17:06:47 +00:00
wpaul
a8513e48c5 Unbreak the build: correct the resource list traversal code for
__FreeBSD_version >= 600022.
2005-03-28 16:49:27 +00:00
wpaul
74837aa85b Argh. PCI resource list became an STAILQ instead of an SLIST. Try to
deal with this while maintaining backards source compatibility with
stable.
2005-03-27 10:35:07 +00:00
wpaul
e41bbf9219 Check in ntoskrnl_var.h, which should have been included in the
previous commit.
2005-03-27 10:16:45 +00:00
wpaul
959879757b Finally bring an end to the great "make the Atheros NDIS driver
work on SMP" saga. After several weeks and much gnashing of teeth,
I have finally tracked down all the problems, despite their best
efforts to confound and annoy me.

Problem nunmber one: the Atheros windows driver is _NOT_ a de-serialized
miniport! It used to be that NDIS drivers relied on the NDIS library
itself for all their locking and serialization needs. Transmit packet
queues were all handled internally by NDIS, and all calls to
MiniportXXX() routines were guaranteed to be appropriately serialized.
This proved to be a performance problem however, and Microsoft
introduced de-serialized miniports with the NDIS 5.x spec. Microsoft
still supports serialized miniports, but recommends that all new drivers
written for Windows XP and later be deserialized. Apparently Atheros
wasn't listening when they said this.

This means (among other things) that we have to serialize calls to
MiniportSendPackets(). We also have to serialize calls to MiniportTimer()
that are triggered via the NdisMInitializeTimer() routine. It finally
dawned on me why NdisMInitializeTimer() takes a special
NDIS_MINIPORT_TIMER structure and a pointer to the miniport block:
the timer callback must be serialized, and it's only by saving the
miniport block handle that we can get access to the serialization
lock during the timer callback.

Problem number two: haunted hardware. The thing that was _really_
driving me absolutely bonkers for the longest time is that, for some
reason I couldn't understand, my test machine would occasionally freeze
or more frustratingly, reset completely. That's reset and in *pow!*
back to the BIOS startup. No panic, no crashdump, just a reset. This
appeared to happen most often when MiniportReset() was called. (As
to why MiniportReset() was being called, see problem three below.)
I thought maybe I had created some sort of horrible deadlock
condition in the process of adding the serialization, but after three
weeks, at least 6 different locking implementations and heroic efforts
to debug the spinlock code, the machine still kept resetting. Finally,
I started single stepping through the MiniportReset() routine in
the driver using the kernel debugger, and this ultimately led me to
the source of the problem.

One of the last things the Atheros MiniportReset() routine does is
call NdisReadPciSlotInformation() several times to inspect a portion
of the device's PCI config space. It reads the same chunk of config
space repeatedly, in rapid succession. Presumeably, it's polling
the hardware for some sort of event. The reset occurs partway through
this process. I discovered that when I single-stepped through this
portion of the routine, the reset didn't occur. So I inserted a 1
microsecond delay into the read loop in NdisReadPciSlotInformation().
Suddenly, the reset was gone!!

I'm still very puzzled by the whole thing. What I suspect is happening
is that reading the PCI config space so quickly is causing a severe
PCI bus error. My test system is a Sun w2100z dual Opteron system,
and the NIC is a miniPCI card mounted in a miniPCI-to-PCI carrier card,
plugged into a 100Mhz PCI slot. It's possible that this combination of
hardware causes a bus protocol violation in this scenario which leads
to a fatal machine check. This is pure speculation though. Really all I
know for sure is that inserting the delay makes the problem go away.
(To quote Homer Simpson: "I don't know how it works, but fire makes
it good!")

Problem number three: NdisAllocatePacket() needs to make sure to
initialize the npp_validcounts field in the 'private' section of
the NDIS_PACKET structure. The reason if_ndis was calling the
MiniportReset() routine in the first place is that packet transmits
were sometimes hanging. When sending a packet, an NDIS driver will
call NdisQueryPacket() to learn how many physical buffers the packet
resides in. NdisQueryPacket() is actually a macro, which traverses
the NDIS_BUFFER list attached to the NDIS_PACKET and stashes some
of the results in the 'private' section of the NDIS_PACKET. It also
sets the npp_validcounts field to TRUE To indicate that the results are
now valid. The problem is, now that if_ndis creates a pool of transmit
packets via NdisAllocatePacketPool(), it's important that each time
a new packet is allocated via NdisAllocatePacket() that validcounts
be initialized to FALSE. If it isn't, and a previously transmitted
NDIS_PACKET is pulled out of the pool, it may contain stale data
from a previous transmission which won't get updated by NdisQueryPacket().
This would cause the driver to miscompute the number of fragments
for a given packet, and botch the transmission.

Fixing these three problems seems to make the Atheros driver happy
on SMP, which hopefully means other serialized miniports will be
happy too.

And there was much rejoicing.

Other stuff fixed along the way:

- Modified ndis_thsuspend() to take a mutex as an argument. This
  allows KeWaitForSingleObject() and KeWaitForMultipleObjects() to
  avoid any possible race conditions with other routines that
  use the dispatcher lock.

- Fixed KeCancelTimer() so that it returns the correct value for
  'pending' according to the Microsoft documentation

- Modfied NdisGetSystemUpTime() to use ticks and hz rather than
  calling nanouptime(). Also added comment that this routine wraps
  after 49.7 days.

- Added macros for KeAcquireSpinLock()/KeReleaseSpinLock() to hide
  all the MSCALL() goop.

- For x86, KeAcquireSpinLockRaiseToDpc() needs to be a separate
  function. This is because it's supposed to be _stdcall on the x86
  arch, whereas KeAcquireSpinLock() is supposed to be _fastcall.
  On amd64, all routines use the same calling convention so we can
  just map KeAcquireSpinLockRaiseToDpc() directly to KfAcquireSpinLock()
  and it will work. (The _fastcall attribute is a no-op on amd64.)

- Implement and use IoInitializeDpcRequest() and IoRequestDpc() (they're
  just macros) and use them for interrupt handling. This allows us to
  move the ndis_intrtask() routine from if_ndis.c to kern_ndis.c.

- Fix the MmInitializeMdl() macro so that is uses sizeof(vm_offset_t)
  when computing mdl_size instead of uint32_t, so that it matches the
  MmSizeOfMdl() routine.

- Change a could of M_WAITOKs to M_NOWAITs in the unicode routines in
  subr_ndis.c.

- Use the dispatcher lock a little more consistently in subr_ntoskrnl.c.

- Get rid of the "wait for link event" hack in ndis_init(). Now that
  I fixed NdisReadPciSlotInformation(), it seems I don't need it anymore.
  This should fix the witness panic a couple of people have reported.

- Use MSCALL1() when calling the MiniportHangCheck() function in
  ndis_ticktask(). I accidentally missed this one when adding the
  wrapping for amd64.
2005-03-27 10:14:36 +00:00
brooks
f16c448930 Use the CTASSERT() macro instead of rolling my own, non-portable one
using #error.

Suggested by:	jhb
2005-03-24 19:26:50 +00:00
brooks
b25337dcb4 Compile errors are way more useful then panics later.
Replace a KASSERT of LINUX_IFNAMSIZ == IFNAMSIZ with a preprocessor
check and #error message.  This will prevent nasty suprises if users
change IFNAMSIZ without updating the linux code appropriatly.
2005-03-24 17:51:15 +00:00
das
6a2a1d9492 Bounds check the user-supplied length used in a copyout() in
svr4_do_getmsg().  In principle this bug could disclose data from
kernel memory, but in practice, the SVR4 emulation layer is probably
not functional enough to cause the relevant code path to be executed.
In any case, the emulator has been disconnected from the build since
5.0-RELEASE.

Found by:	Coverity Prevent analysis tool
2005-03-23 08:28:06 +00:00
das
fbf7a9b2ee Reject packets larger than IP_MAXPACKET in linux_sendto() for sockets
with the IP_HDRINCL option set.  Without this change, a Linux process
with access to a raw socket could cause a kernel panic.  Raw sockets
must be created by root, and are generally not consigned to untrusted
applications; hence, the security implications of this bug are
minimal.  I believe this only affects 6-CURRENT on or after 2005-01-30.

Found by:	Coverity Prevent analysis tool
Security:	Local DOS
2005-03-23 08:28:00 +00:00
phk
00a6eab3e5 s/SLIST/STAILQ/
/imp/a\
pointy hat
.
2005-03-18 11:57:44 +00:00
phk
9cea99e06b Neuter the duplicated disk-device magic code for now. Somebody with
serious linux-clue is necessary to fix this properly.
2005-03-15 11:58:40 +00:00
sobomax
b795e2430a Add kernel-only flag MSG_NOSIGNAL to be used in emulation layers to surpress
SIGPIPE signal for the duration of the sento-family syscalls. Use it to
replace previously added hack in Linux layer based on temporarily setting
SO_NOSIGPIPE flag.

Suggested by:	alfred
2005-03-08 16:11:41 +00:00
sobomax
a5d845fec6 Handle MSG_NOSIGNAL flag in linux_send() by setting SO_NOSIGPIPE on socket
for the duration of the send() call. Such approach may be less than ideal
in threading environment, when several threads share the same socket and it
might happen that several of them are calling linux_send() at the same time
with and without SO_NOSIGPIPE set.

However, such race condition is very unlikely in practice, therefore this
change provides practical improvement compared to the previous behaviour.

PR:		kern/76426
Submitted by:	Steven Hartland <killing@multiplay.co.uk>
MFC after:	3 days
2005-03-07 07:26:42 +00:00
wpaul
a72168b811 When you call MiniportInitialize() for an 802.11 driver, it will
at some point result in a status event being triggered (it should
be a link down event: the Microsoft driver design guide says you
should generate one when the NIC is initialized). Some drivers
generate the event during MiniportInitialize(), such that by the
time MiniportInitialize() completes, the NIC is ready to go. But
some drivers, in particular the ones for Atheros wireless NICs,
don't generate the event until after a device interrupt occurs
at some point after MiniportInitialize() has completed.

The gotcha is that you have to wait until the link status event
occurs one way or the other before you try to fiddle with any
settings (ssid, channel, etc...). For the drivers that set the
event sycnhronously this isn't a problem, but for the others
we have to pause after calling ndis_init_nic() and wait for the event
to arrive before continuing. Failing to wait can cause big trouble:
on my SMP system, calling ndis_setstate_80211() after ndis_init_nic()
completes, but _before_ the link event arrives, will lock up or
reset the system.

What we do now is check to see if a link event arrived while
ndis_init_nic() was running, and if it didn't we msleep() until
it does.

Along the way, I discovered a few other problems:

- Defered procedure calls run at PASSIVE_LEVEL, not DISPATCH_LEVEL.
  ntoskrnl_run_dpc() has been fixed accordingly. (I read the documentation
  wrong.)

- Similarly, the NDIS interrupt handler, which is essentially a
  DPC, also doesn't need to run at DISPATCH_LEVEL. ndis_intrtask()
  has been fixed accordingly.

- MiniportQueryInformation() and MiniportSetInformation() run at
  DISPATCH_LEVEL, and each request must complete before another
  can be submitted. ndis_get_info() and ndis_set_info() have been
  fixed accordingly.

- Turned the sleep lock that guards the NDIS thread job list into
  a spin lock. We never do anything with this lock held except manage
  the job list (no other locks are held), so it's safe to do this,
  and it's possible that ndis_sched() and ndis_unsched() can be
  called from DISPATCH_LEVEL, so using a sleep lock here is
  semantically incorrect. Also updated subr_witness.c to add the
  lock to the order list.
2005-03-07 03:05:31 +00:00
sobomax
f706f4bce8 Handle unimplemented syscall by instantly returning ENOSYS instead of sending
signal first and only then returning ENOSYS to match what real linux does.

PR:		kern/74302
Submitted by:	Travis Poppe <tlp@LiquidX.org>
2005-03-07 00:18:06 +00:00
sobomax
6f0b5d23e8 Always produce cpuX entries, even in the case when there is only one CPU
in the system. This is consistent with what real linuxes do.

PR:		kern/75848
Submitted by:	Andriy Gapon <avg@icyb.net.ua>
MFC after:	3 days
2005-03-06 22:28:14 +00:00
wpaul
593ae58297 MAXPATHLEN is 1024, which means NdisOpenFile() and ndis_find_sym() were
both consuming 1K of stack space. This is unfriendly. Allocate the buffers
off the heap instead. It's a little slower, but these aren't performance
critical routines.

Also, add a spinlock to NdisAllocatePacketPool(), NdisAllocatePacket(),
NdisFreePacketPool() and NdisFreePacket(). The pool is maintained as a
linked list. I don't know for a fact that it can be corrupted, but why
take chances.
2005-03-03 03:51:02 +00:00
jhb
407a285a6f Remove linux_emul_find() and the CHECKALT*() macros as they are no longer
used.
2005-03-01 17:57:45 +00:00
ps
90b32391ca Use kern_kevent instead of the stackgap for 32bit syscall wrapping.
Submitted by:	jhb
Tested on:	amd64
2005-03-01 17:45:55 +00:00
wpaul
88eacaa717 In windrv_load(), I was allocating the driver object using
malloc(sizeof(device_object), ...) by mistake. Correct this, and
rename "dobj" to "drv" to make it a bit clearer what this variable
is supposed to be.

Spotted by: Mikore Li at Sun dot comnospamplzkthx
2005-03-01 17:21:25 +00:00
ps
3477112899 Ooops. I will compile test before committing. The stackgap version
of kevent32 will be going away shortly, so this is temporary until
I commit the non-stackgap version.
2005-03-01 13:50:57 +00:00
ps
7f5f318c48 Correct the freebsd32_kevent prototype. 2005-03-01 06:32:53 +00:00
wpaul
d20416c2fe Don't need to do MmInitializeMdl() in ndis_mtop() anymore:
IoInitializeMdl() does it internally (and doing it again here
messes things up).
2005-02-26 07:11:17 +00:00
wpaul
15a925bf93 MDLs are supposed to be variable size (they include an array of pages
that describe a buffer of variable size). The problem is, allocating
MDLs off the heap is slow, and it can happen that drivers will allocate
lots and lots of lots of MDLs as they run.

As a compromise, we now do the following: we pre-allocate a zone for
MDLs big enough to describe any buffer with 16 or less pages. If
IoAllocateMdl() needs a MDL for a buffer with 16 or less pages, we'll
allocate it from the zone. Otherwise, we allocate it from the heap.
MDLs allocate from the zone have a flag set in their mdl_flags field.
When the MDL is released, IoMdlFree() will uma_zfree() the MDL if
it has the MDL_ZONE_ALLOCED flag set, otherwise it will release it
to the heap.

The assumption is that 16 pages is a "big number" and we will rarely
need MDLs larger than that.

- Moved the ndis_buffer zone to subr_ntoskrnl.c from kern_ndis.c
  and named it mdl_zone.

- Modified IoAllocateMdl() and IoFreeMdl() to use uma_zalloc() and
  uma_zfree() if necessary.

- Made ndis_mtop() use IoAllocateMdl() instead of calling uma_zalloc()
  directly.

Inspired by: discussion with Giridhar Pemmasani
2005-02-26 00:22:16 +00:00
sam
b3f1395f0d fixup signal mapping:
o change the mapping arrays to have a zero offset rather than base 1;
  this eliminates lots of signo adjustments and brings the code
  back inline with the original netbsd code
o purge use of SVR4_SIGTBLZ; SVR4_NSIG is the only definition for
  how big a mapping array is
o change the mapping loops to explicitly ignore signal 0
o purge some bogus code from bsd_to_svr4_sigset
o adjust svr4_sysentvec to deal with the mapping table change

Enticed into fixing by:	Coverity Prevent analysis tool
Glanced at by:	marcel, jhb
2005-02-25 19:34:10 +00:00
wpaul
371673aec8 Add macros to construct Windows IOCTL codes, and to extract function
codes from an IOCTL. (The USB module will need them later.)
2005-02-25 18:25:48 +00:00
wpaul
64968e6acf Fix a couple of callback instances that should have been wrapped with
MSCALLx().

Add definition for STATUS_PENDING error code.
2005-02-25 08:34:32 +00:00
wpaul
7a502b7309 Compute the right length to use with bzero() when initializing an IRP
in IoInitializeIrp() (must use IoSizeOfIrp() to account for the stack
locations).
2005-02-25 06:31:45 +00:00
wpaul
efb3e8caac - Correct one aspect of the driver_object/device_object/IRP framework:
when we create a PDO, the driver_object associated with it is that
  of the parent driver, not the driver we're trying to attach. For
  example, if we attach a PCI device, the PDO we pass to the NdisAddDevice()
  function should contain a pointer to fake_pci_driver, not to the NDIS
  driver itself. For PCI or PCMCIA devices this doesn't matter because
  the child never needs to talk to the parent bus driver, but for USB,
  the child needs to be able to send IRPs to the parent USB bus driver, and
  for that to work the parent USB bus driver has to be hung off the PDO.

  This involves modifying windrv_lookup() so that we can search for
  bus drivers by name, if necessary. Our fake bus drivers attach themselves
  as "PCI Bus," "PCCARD Bus" and "USB Bus," so we can search for them
  using those names.

  The individual attachment stubs now create and attach PDOs to the
  parent bus drivers instead of hanging them off the NDIS driver's
  object, and in if_ndis.c, we now search for the correct driver
  object depending on the bus type, and use that to find the correct PDO.

  With this fix, I can get my sample USB ethernet driver to deliver
  an IRP to my fake parent USB bus driver's dispatch routines.

- Add stub modules for USB support: subr_usbd.c, usbd_var.h and
  if_ndis_usb.c. The subr_usbd.c module is hooked up the build
  but currently doesn't do very much. It provides the stub USB
  parent driver object and a dispatch routine for
  IRM_MJ_INTERNAL_DEVICE_CONTROL. The only exported function at
  the moment is USBD_GetUSBDIVersion(). The if_ndis_usb.c stub
  compiles, but is not hooked up to the build yet. I'm putting
  these here so I can keep them under source code control as I
  flesh them out.
2005-02-24 21:49:14 +00:00
jhb
54ea9f1912 Regen. 2005-02-24 18:24:29 +00:00
jhb
aa85f8d747 Use msync() to implement msync() for freebsd32 emulation. This isn't quite
right for certain MAP_FIXED mappings on ia64 but it will work fine for all
other mappings and works fine on amd64.

Requested by:	ps, Christian Zander
MFC after:	1 week
2005-02-24 18:24:16 +00:00
wpaul
6e74cf6e34 Couple of lessons learned during USB driver testing:
- In kern_ndis.c:ndis_unload_driver(), test that ndis_block->nmb_rlist
  is not NULL before trying to free() it.

- In subr_pe.c:pe_get_import_descriptor(), do a case-insensitive
  match on the import module name. Most drivers I have encountered
  link against "ntoskrnl.exe" but the ASIX USB ethernet driver I'm
  testing with wants "NTOSKRNL.EXE."

- In subr_ntoskrnl.c:IoAllocateIrp(), return a pointer to the IRP
  instead of NULL. (Stub code leftover.)

- Also in subr_ntoskrnl.c, add ExAllocatePoolWithTag() and ExFreePool()
  to the function table list so they'll get exported to drivers properly.
2005-02-24 17:58:27 +00:00
wpaul
954c02c21f Implement IoCancelIrp(), IoAcquireCancelSpinLock(), IoReleaseCancelSpinLock()
and a machine-independent though inefficient InterlockedExchange().
In Windows, InterlockedExchange() appears to be implemented in header
files via inline assembly. I would prefer using an atomic.h macro for
this, but there doesn't seem to be one that just does a plain old
atomic exchange (as opposed to compare and exchange). Also implement
IoSetCancelRoutine(), which is just a macro that uses InterlockedExchange().

Fill in IoBuildSynchronousFsdRequest(), IoBuildAsynchronousFsdRequest()
and IoBuildDeviceIoControlRequest() so that they do something useful,
and add a bunch of #defines to ntoskrnl_var.h to help make these work.
These may require some tweaks later.
2005-02-23 16:44:33 +00:00
phk
5bbf7f6810 Neuter linux_ustat() until somebody finds time to try to fix it.
The fundamental problem is that we get only the lower 8 bits of the
minor device number so there is no guarantee that we can actually
find the disk device in question at all.

This was probably a bigger issue pre-GEOM where the upper bits
signaled which slice were in use.

The secondary problem is how we get from (partial) dev_t to vnode.

The correct implementation will involve traversing the mount list
looking for a perfect match or a possible match (for truncated
minor).
2005-02-22 13:39:46 +00:00
sam
340ab0ebcb remove dead code
Submitted by:	Coverity Prevent analysis tool
2005-02-22 01:26:48 +00:00
jhb
847763ff6e - Add a custom version of exec_copyin_args() to deal with the 32-bit
pointers in argv and envv in userland and use that together with
  kern_execve() and exec_free_args() to implement freebsd32_execve()
  without using the stackgap.
- Fix freebsd32_adjtime() to call adjtime() rather than utimes().  Still
  uses stackgap for now.
- Use kern_setitimer(), kern_getitimer(), kern_select(), kern_utimes(),
  kern_statfs(), kern_fstatfs(), kern_fhstatfs(), kern_stat(),
  kern_fstat(), and kern_lstat().

Tested by:	cokane (amd64)
Silence on:	amd64, ia64
2005-02-18 18:56:04 +00:00
wpaul
359989e277 Fix a couple of u_int_foos that should have been uint_foos. 2005-02-18 04:33:34 +00:00
wpaul
cb91ac4b68 Make the Win64 -> ELF64 template a little smaller by using a string
copy op to shift arguments on the stack instead of transfering each
argument one by one through a register. Probably doesn't affect overall
operation, but makes the code a little less grotty and easier to update
later if I choose to make the wrapper handle more args. Also add
comments.
2005-02-18 03:22:37 +00:00
wpaul
90e2d970fc Remove redundant label. 2005-02-16 21:24:04 +00:00
wpaul
61fae0841d Fix freeing of custom driver extensions. (ExFreePool() was being
called with the wrong pointer.)
2005-02-16 19:21:07 +00:00
wpaul
a372ba85ce KeAcquireSpinLockRaiseToDpc() and KeReleaseSpinLock() are (at least
for now) exactly the same as KfAcquireSpinLock() and KfReleaseSpinLock().
I implemented the former as small routines in subr_ntoskrnl.c that just
turned around and invoked the latter. But I don't really need the wrapper
routines: I can just create an entries in the ntoskrnl func table that
map KeAcquireSpinLockRaiseToDpc() and KeReleaseSpinLock() to
KfAcquireSpinLock() and KfReleaseSpinLock() directly. This means
the stubs can go away.
2005-02-16 18:18:30 +00:00
wpaul
07b632956a Add support for Windows/x86-64 binaries to Project Evil.
Ville-Pertti Keinonen (will at exomi dot comohmygodnospampleasekthx)
deserves a big thanks for submitting initial patches to make it
work. I have mangled his contributions appropriately.

The main gotcha with Windows/x86-64 is that Microsoft uses a different
calling convention than everyone else. The standard ABI requires using
6 registers for argument passing, with other arguments on the stack.
Microsoft uses only 4 registers, and requires the caller to leave room
on the stack for the register arguments incase the callee needs to
spill them. Unlike x86, where Microsoft uses a mix of _cdecl, _stdcall
and _fastcall, all routines on Windows/x86-64 uses the same convention.
This unfortunately means that all the functions we export to the
driver require an intermediate translation wrapper. Similarly, we have
to wrap all calls back into the driver binary itself.

The original patches provided macros to wrap every single routine at
compile time, providing a secondary jump table with a customized
wrapper for each exported routine. I decided to use a different approach:
the call wrapper for each function is created from a template at
runtime, and the routine to jump to is patched into the wrapper as
it is created. The subr_pe module has been modified to patch in the
wrapped function instead of the original. (On x86, the wrapping
routine is a no-op.)

There are some minor API differences that had to be accounted for:

- KeAcquireSpinLock() is a real function on amd64, not a macro wrapper
  around KfAcquireSpinLock()
- NdisFreeBuffer() is actually IoFreeMdl(). I had to change the whole
  NDIS_BUFFER API a bit to accomodate this.

Bugs fixed along the way:
- IoAllocateMdl() always returned NULL
- kern_windrv.c:windrv_unload() wasn't releasing private driver object
  extensions correctly (found thanks to memguard)

This has only been tested with the driver for the Broadcom 802.11g
chipset, which was the only Windows/x86-64 driver I could find.
2005-02-16 05:41:18 +00:00
njl
25c48f7867 Unbreak the kernel build. Pointy hat to: sobomax. 2005-02-13 19:50:57 +00:00
sobomax
52ae2ac0b9 Backout previous change (disabling of security checks for signals delivered
in emulation layers), since it appears to be too broad.

Requested by:   rwatson
2005-02-13 17:37:20 +00:00
sobomax
1d558007d0 Split out kill(2) syscall service routine into user-level and kernel part, the
former is callable from user space and the latter from the kernel one. Make
kernel version take additional argument which tells if the respective call
should check for additional restrictions for sending signals to suid/sugid
applications or not.

Make all emulation layers using non-checked version, since signal numbers in
emulation layers can have different meaning that in native mode and such
protection can cause misbehaviour.

As a result remove LIBTHR from the signals allowed to be delivered to a
suid/sugid application.

Requested (sorta) by:	rwatson
MFC after:	2 weeks
2005-02-13 16:42:08 +00:00
sobomax
22b03e0f5d Semctl with IPC_STAT command should return zero in case of success.
PR:		73778
Submitted by:	Andriy Gapon <avg@icyb.net.ua>
MFC after:	2 weeks
2005-02-11 13:46:55 +00:00
wpaul
df89b62698 Next step on the road to IRPs: create and use an imitation of the
Windows DRIVER_OBJECT and DEVICE_OBJECT mechanism so that we can
simulate driver stacking.

In Windows, each loaded driver image is attached to a DRIVER_OBJECT
structure. Windows uses the registry to match up a given vendor/device
ID combination with a corresponding DRIVER_OBJECT. When a driver image
is first loaded, its DriverEntry() routine is invoked, which sets up
the AddDevice() function pointer in the DRIVER_OBJECT and creates
a dispatch table (based on IRP major codes). When a Windows bus driver
detects a new device, it creates a Physical Device Object (PDO) for
it. This is a DEVICE_OBJECT structure, with semantics analagous to
that of a device_t in FreeBSD. The Windows PNP manager will invoke
the driver's AddDevice() function and pass it pointers to the DRIVER_OBJECT
and the PDO.

The AddDevice() function then creates a new DRIVER_OBJECT structure of
its own. This is known as the Functional Device Object (FDO) and
corresponds roughly to a private softc instance. The driver uses
IoAttachDeviceToDeviceStack() to add this device object to the
driver stack for this PDO. Subsequent drivers (called filter drivers
in Windows-speak) can be loaded which add themselves to the stack.
When someone issues an IRP to a device, it travel along the stack
passing through several possible filter drivers until it reaches
the functional driver (which actually knows how to talk to the hardware)
at which point it will be completed. This is how Windows achieves
driver layering.

Project Evil now simulates most of this. if_ndis now has a modevent
handler which will use MOD_LOAD and MOD_UNLOAD events to drive the
creation and destruction of DRIVER_OBJECTs. (The load event also
does the relocation/dynalinking of the image.) We don't have a registry,
so the DRIVER_OBJECTS are stored in a linked list for now. Eventually,
the list entry will contain the vendor/device ID list extracted from
the .INF file. When ndis_probe() is called and detectes a supported
device, it will create a PDO for the device instance and attach it
to the DRIVER_OBJECT just as in Windows. ndis_attach() will then call
our NdisAddDevice() handler to create the FDO. The NDIS miniport block
is now a device extension hung off the FDO, just as it is in Windows.
The miniport characteristics table is now an extension hung off the
DRIVER_OBJECT as well (the characteristics are the same for all devices
handled by a given driver, so they don't need to be per-instance.)
We also do an IoAttachDeviceToDeviceStack() to put the FDO on the
stack for the PDO. There are a couple of fake bus drivers created
for the PCI and pccard buses. Eventually, there will be one for USB,
which will actually accept USB IRP.s

Things should still work just as before, only now we do things in
the proper order and maintain the correct framework to support passing
IRPs between drivers.

Various changes:

- corrected the comments about IRQL handling in subr_hal.c to more
  accurately reflect reality
- update ndiscvt to make the drv_data symbol in ndis_driver_data.h a
  global so that if_ndis_pci.o and/or if_ndis_pccard.o can see it.
- Obtain the softc pointer from the miniport block by referencing
  the PDO rather than a private pointer of our own (nmb_ifp is no
  longer used)
- implement IoAttachDeviceToDeviceStack(), IoDetachDevice(),
  IoGetAttachedDevice(), IoAllocateDriverObjectExtension(),
  IoGetDriverObjectExtension(), IoCreateDevice(), IoDeleteDevice(),
  IoAllocateIrp(), IoReuseIrp(), IoMakeAssociatedIrp(), IoFreeIrp(),
  IoInitializeIrp()
- fix a few mistakes in the driver_object and device_object definitions
- add a new module, kern_windrv.c, to handle the driver registration
  and relocation/dynalinkign duties (which don't really belong in
  kern_ndis.c).
- made ndis_block and ndis_chars in the ndis_softc stucture pointers
  and modified all references to it
- fixed NdisMRegisterMiniport() and NdisInitializeWrapper() so they
  work correctly with the new driver_object mechanism
- changed ndis_attach() to call NdisAddDevice() instead of ndis_load_driver()
  (which is now deprecated)
- used ExAllocatePoolWithTag()/ExFreePool() in lookaside list routines
  instead of kludged up alloc/free routines
- added kern_windrv.c to sys/modules/ndis/Makefile and files.i386.
2005-02-08 17:23:25 +00:00
jhb
b03a8bb21b - Implement svr4_emul_find() using kern_alternate_path(). This changes
the semantics in that the returned filename to use is now a kernel
  pointer rather than a user space pointer.  This required changing the
  arguments to the CHECKALT*() macros some and changing the various system
  calls that used pathnames to use the kern_foo() functions that can accept
  kernel space filename pointers instead of calling the system call
  directly.
- Use kern_open(), kern_access(), kern_msgctl(), kern_execve(),
  kern_mkfifo(), kern_mknod(), kern_statfs(), kern_fstatfs(),
  kern_setitimer(), kern_stat(), kern_lstat(), kern_fstat(), kern_utimes(),
  kern_pathconf(), and kern_unlink().
2005-02-07 21:53:42 +00:00
jhb
3c3db95194 - Use kern_{l,f,}stat() and kern_{f,}statfs() functions rather than
duplicating the contents of the same functions inline.
- Consolidate common code to convert a BSD statfs struct to a Linux struct
  into a static worker function.
2005-02-07 18:47:28 +00:00
jhb
6fab308776 Make linux_emul_convpath() a simple wrapper for kern_alternate_path(). 2005-02-07 18:46:05 +00:00
jhb
71c05d27c0 - Tweak kern_msgctl() to return a copy of the requested message queue id
structure in the struct pointed to by the 3rd argument for IPC_STAT and
  get rid of the 4th argument.  The old way returned a pointer into the
  kernel array that the calling function would then access afterwards
  without holding the appropriate locks and doing non-lock-safe things like
  copyout() with the data anyways.  This change removes that unsafeness and
  resulting race conditions as well as simplifying the interface.
- Implement kern_foo wrappers for stat(), lstat(), fstat(), statfs(),
  fstatfs(), and fhstatfs().  Use these wrappers to cut out a lot of
  code duplication for freebsd4 and netbsd compatability system calls.
- Add a new lookup function kern_alternate_path() that looks up a filename
  under an alternate prefix and determines which filename should be used.
  This is basically a more general version of linux_emul_convpath() that
  can be shared by all the ABIs thus allowing for further reduction of
  code duplication.
2005-02-07 18:44:55 +00:00
jhb
6e2f7d4c8e Use kern_setitimer() to implement linux_alarm() instead of fondling the
real interval timer directly.
2005-02-07 18:36:21 +00:00
sobomax
69aa6843ef Boot away another stackgap (one of the lest ones in linuxlator/i386) by
providing special version of CDIOCREADSUBCHANNEL ioctl(), which assumes that
result has to be placed into kernel space not user space. In the long run
more generic solution has to be designed WRT emulating various ioctl()s
that operate on userspace buffers, but right now there is only one such
ioctl() is emulated, so that it makes little sense.

MFC after:	2 weeks
2005-01-30 08:12:37 +00:00
sobomax
68d0bd2186 Extend kern_sendit() to take another enum uio_seg argument, which specifies
where the buffer to send lies and use it to eliminate yet another stackgap
in linuxlator.

MFC after:	2 weeks
2005-01-30 07:20:36 +00:00
sobomax
f489acaf0f o Split out kernel part of execve(2) syscall into two parts: one that
copies arguments into the kernel space and one that operates
  completely in the kernel space;

o use kernel-only version of execve(2) to kill another stackgap in
  linuxlator/i386.

Obtained from:  DragonFlyBSD (partially)
MFC after:      2 weeks
2005-01-29 23:12:00 +00:00
sobomax
896df27c1a Split out kernel side of msgctl(2) into two parts: the first that pops data
from the userland and pushes results back and the second which does
actual processing. Use the latter to eliminate stackgap in the linux wrapper
of that syscall.

MFC after:      2 weeks
2005-01-26 00:46:36 +00:00
sobomax
35611d3699 Split out kernel side of {get,set}itimer(2) into two parts: the first that
pops data from the userland and pushes results back and the second which does
actual processing. Use the latter to eliminate stackgap in the linux wrappers
of those syscalls.

MFC after:	2 weeks
2005-01-25 21:28:28 +00:00
wpaul
e00c1df907 Apparently, the Intel icc compiler doesn't like it when you use
attributes in casts (i.e. foo = (__stdcall sometype)bar). This only
happens in two places where we need to set up function pointers, so
work around the problem with some void pointer magic.
2005-01-25 17:00:54 +00:00
wpaul
361515a412 Begin the first phase of trying to add IRP support (and ultimately
USB device support):

- Convert all of my locally chosen function names to their actual
  Windows equivalents, where applicable. This is a big no-op change
  since it doesn't affect functionality, but it helps avoid a bit
  of confusion (it's now a lot easier to see which functions are
  emulated Windows API routines and which are just locally defined).

- Turn ndis_buffer into an mdl, like it should have been. The structure
  is the same, but now it belongs to the subr_ntoskrnl module.

- Implement a bunch of MDL handling macros from Windows and use them where
  applicable.

- Correct the implementation of IoFreeMdl().

- Properly implement IoAllocateMdl() and MmBuildMdlForNonPagedPool().

- Add the definitions for struct irp and struct driver_object.

- Add IMPORT_FUNC() and IMPORT_FUNC_MAP() macros to make formatting
  the module function tables a little cleaner. (Should also help
  with AMD64 support later on.)

- Fix if_ndis.c to use KeRaiseIrql() and KeLowerIrql() instead of
  the previous calls to hal_raise_irql() and hal_lower_irql() which
  have been renamed.

The function renaming generated a lot of churn here, but there should
be very little operational effect.
2005-01-24 18:18:12 +00:00
ps
87f1a6a1a6 Add a 32bit syscall wrapper for modstat
Obtained from:	Yahoo!
2005-01-19 17:53:06 +00:00
ps
db53196a48 - rename nanosleep1 to kern_nanosleep
- Add a 32bit syscall entry for nanosleep

Reviewed by:	peter
Obtained from:	Yahoo!
2005-01-19 17:44:59 +00:00
wpaul
2fe7b09cb1 Fix a problem reported by Pierre Beyssac. Sometinmes when ndis_get_info()
calls MiniportQueryInformation(), it will return NDIS_STATUS_PENDING.
When this happens, ndis_get_info() will sleep waiting for a completion
event. If two threads call ndis_get_info() and both end up having to
sleep, they will both end up waiting on the same wait channel, which
can cause a panic in sleepq_add() if INVARIANTS are turned on.

Fix this by having ndis_get_info() use a common mutex rather than
using the process mutex with PROC_LOCK(). Also do the same for
ndis_set_info(). Note that Pierre's original patch also made ndis_thsuspend()
use the new mutex, but ndis_thsuspend() shouldn't need this since
it will make each thread that calls it sleep on a unique wait channel.

Also, it occured to me that we probably don't want to enter
MiniportQueryInformation() or MiniportSetInformation() from more
than one thread at any given time, so now we acquire a Windows
spinlock before calling either of them. The Microsoft documentation
says that MiniportQueryInformation() and MiniportSetInformation()
are called at DISPATCH_LEVEL, and previously we would call
KeRaiseIrql() to set the IRQL to DISPATCH_LEVEL before entering
either routine, but this only guarantees mutual exclusion on
uniprocessor machines. To make it SMP safe, we need to use a real
spinlock. For now, I'm abusing the spinlock embedded in the
NDIS_MINIPORT_BLOCK structure for this purpose. (This may need to be
applied to some of the other routines in kern_ndis.c at a later date.)

Export ntoskrnl_init_lock() (KeInitializeSpinlock()) from subr_ntoskrnl.c
since we need to use in in kern_ndis.c, and since it's technically part
of the Windows kernel DDK API along with the other spinlock routines. Use
it in subr_ndis.c too rather than frobbing the spinlock directly.
2005-01-14 22:39:44 +00:00
obrien
98e2482a94 Match the LINUX32's style with existing style
Submitted by:	Jung-uk Kim <jkim@niksun.com>

Use positive, not negative logic.
2005-01-14 04:44:56 +00:00
obrien
98c3a8a894 Fix Linux compat 'uname -m' on AMD64.
Submitted by:	Jung-uk Kim <jkim@niksun.com>
		(patch reworked by me)
2005-01-14 03:45:26 +00:00
phk
108b39b837 Remove duplicate code. 2005-01-13 19:27:28 +00:00
imp
362fcfc1e2 Start each of the license/copyright comments with /*- 2005-01-05 22:34:37 +00:00
jhb
3ec0dff7ad - Move the function prototypes for kern_setrlimit() and kern_wait() to
sys/syscallsubr.h where all the other kern_foo() prototypes live.
- Resort kern_execve() while I'm there.
2005-01-05 22:19:44 +00:00
jhb
830736d271 Regenerate. 2005-01-04 18:54:40 +00:00
jhb
adb721c906 Partial sync up to the master syscalls.master file:
- Mark mount, unmount and nmount MPSAFE.
- Add a stub for _umtx_op().
- Mark open(), link(), unlink(), and freebsd32_sigaction() MPSAFE.

Pointy hats to:	several
2005-01-04 18:53:32 +00:00
jhb
7b611b0cb2 Stop explicitly touching td_base_pri outside of the scheduler and simply
set a thread's priority via sched_prio() when that is the desired action.
The schedulers will start managing td_base_pri internally shortly.
2004-12-30 20:29:58 +00:00
phk
b0e48f2258 Do not blindly pass linux filesystem specific mount data across. 2004-12-03 18:14:22 +00:00
cperciva
ebbf4e4bde Fix unvalidated pointer dereference. This is FreeBSD-SA-04:17.procfs. 2004-12-01 21:33:02 +00:00
das
130bed6547 Don't include sys/user.h merely for its side-effect of recursively
including other headers.
2004-11-27 06:51:39 +00:00
das
7f13dc5af0 Axe the semblance of support for PECOFF and Linux a.out core dumps. 2004-11-27 06:46:45 +00:00
phk
e2512dff3e Ignore MNT_NODEV option, it is implicit in choice of filesystem. 2004-11-26 07:39:20 +00:00
das
8d8b5ace18 Maintain the broken state of backwards compatibilty for a.out (and
PECOFF!) core dumps.  None of the old versions of gdb I tried were
able to read a.out core dumps before or after this change.

Reviewed by:	arch@
2004-11-20 02:32:04 +00:00
marks
dca89dc1d6 Rebuild from compat/freebsd32/syscalls.master:1.43
Reviewed by:	imp, phk, njl, peter
Approved by:	njl
2004-11-18 23:56:09 +00:00
marks
60b0534c96 32-bit FreeBSD ABI compatibility stubs from syscalls.master:1.179
Reviewed by:	imp, phk, njl, peter
Approved by:	njl
2004-11-18 23:54:26 +00:00
phk
216166ee0d Introduce an alias for FILEDESC_{UN}LOCK() with the suffix _FAST.
Use this in all the places where sleeping with the lock held is not
an issue.

The distinction will become significant once we finalize the exact
lock-type to use for this kind of case.
2004-11-13 11:53:02 +00:00
phk
d09bec0098 Pick up the inode number using VOP_GETATTR() rather than caching it
in all vnodes on the off chance that linprocfs needs it.  If we can afford
to call vn_fullpath() we can afford the much cheaper VOP_GETATTR().
2004-11-10 07:25:37 +00:00
phk
e65c41f01e More sensible FILEDESC_ locking. 2004-11-07 15:59:27 +00:00
rwatson
e095dbaea3 Rebuild from FreeBSD32 syscalls.master:1.42. 2004-10-23 20:05:42 +00:00
rwatson
8bec59acae 32-bit FreeBSD ABI compatibility stubs from syscalls.master:1.178. 2004-10-23 20:04:56 +00:00
peter
09964b7499 Put on my peril sensitive sunglasses and add a flags field to the internal
sysctl routines and state.  Add some code to use it for signalling the need
to downconvert a data structure to 32 bits on a 64 bit OS when requested by
a 32 bit app.

I tried to do this in a generic abi wrapper that intercepted the sysctl
oid's, or looked up the format string etc, but it was a real can of worms
that turned into a fragile mess before I even got it partially working.

With this, we can now run 'sysctl -a' on a 32 bit sysctl binary and have
it not abort.  Things like netstat, ps, etc have a long way to go.

This also fixes a bug in the kern.ps_strings and kern.usrstack hacks.
These do matter very much because they are used by libc_r and other things.
2004-10-11 22:04:16 +00:00