From 269dfbe780494bcc4bfe593fbb8d8e272f5c270e Mon Sep 17 00:00:00 2001 From: Bill Paul Date: Mon, 28 Mar 2005 19:27:58 +0000 Subject: [PATCH] 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. --- sys/compat/ndis/subr_ntoskrnl.c | 46 ++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index 1222397fa73..a02bde289ec 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -178,6 +178,7 @@ __stdcall static ndis_status ObReferenceObjectByHandle(ndis_handle, __fastcall static void ObfDereferenceObject(REGARGS1(void *object)); __stdcall static uint32_t ZwClose(ndis_handle); static void *ntoskrnl_memset(void *, int, size_t); +static funcptr ntoskrnl_findwrap(funcptr); static uint32_t DbgPrint(char *, ...); __stdcall static void DbgBreakPoint(void); __stdcall static void dummy(void); @@ -1502,6 +1503,33 @@ ntoskrnl_popsl(head) return(first); } +/* + * We need this to make lookaside lists work for amd64. + * We pass a pointer to ExAllocatePoolWithTag() the lookaside + * list structure. For amd64 to work right, this has to be a + * pointer to the wrapped version of the routine, not the + * original. Letting the Windows driver invoke the original + * function directly will result in a convention calling + * mismatch and a pretty crash. On x86, this effectively + * becomes a no-op since ipt_func and ipt_wrap are the same. + */ + +static funcptr +ntoskrnl_findwrap(func) + funcptr func; +{ + image_patch_table *patch; + + patch = ntoskrnl_functbl; + while (patch->ipt_func != NULL) { + if ((funcptr)patch->ipt_func == func) + return((funcptr)patch->ipt_wrap); + patch++; + } + + return(NULL); +} + __stdcall static void ExInitializePagedLookasideList(lookaside, allocfunc, freefunc, flags, size, tag, depth) @@ -1521,12 +1549,14 @@ ExInitializePagedLookasideList(lookaside, allocfunc, freefunc, lookaside->nll_l.gl_size = size; lookaside->nll_l.gl_tag = tag; if (allocfunc == NULL) - lookaside->nll_l.gl_allocfunc = ExAllocatePoolWithTag; + lookaside->nll_l.gl_allocfunc = + ntoskrnl_findwrap((funcptr)ExAllocatePoolWithTag); else lookaside->nll_l.gl_allocfunc = allocfunc; if (freefunc == NULL) - lookaside->nll_l.gl_freefunc = ExFreePool; + lookaside->nll_l.gl_freefunc = + ntoskrnl_findwrap((funcptr)ExFreePool); else lookaside->nll_l.gl_freefunc = freefunc; @@ -1534,7 +1564,8 @@ ExInitializePagedLookasideList(lookaside, allocfunc, freefunc, KeInitializeSpinLock(&lookaside->nll_obsoletelock); #endif - lookaside->nll_l.gl_depth = LOOKASIDE_DEPTH; + lookaside->nll_l.gl_type = NonPagedPool; + lookaside->nll_l.gl_depth = depth; lookaside->nll_l.gl_maxdepth = LOOKASIDE_DEPTH; return; @@ -1573,12 +1604,14 @@ ExInitializeNPagedLookasideList(lookaside, allocfunc, freefunc, lookaside->nll_l.gl_size = size; lookaside->nll_l.gl_tag = tag; if (allocfunc == NULL) - lookaside->nll_l.gl_allocfunc = ExAllocatePoolWithTag; + lookaside->nll_l.gl_allocfunc = + ntoskrnl_findwrap((funcptr)ExAllocatePoolWithTag); else lookaside->nll_l.gl_allocfunc = allocfunc; if (freefunc == NULL) - lookaside->nll_l.gl_freefunc = ExFreePool; + lookaside->nll_l.gl_freefunc = + ntoskrnl_findwrap((funcptr)ExFreePool); else lookaside->nll_l.gl_freefunc = freefunc; @@ -1586,7 +1619,8 @@ ExInitializeNPagedLookasideList(lookaside, allocfunc, freefunc, KeInitializeSpinLock(&lookaside->nll_obsoletelock); #endif - lookaside->nll_l.gl_depth = LOOKASIDE_DEPTH; + lookaside->nll_l.gl_type = NonPagedPool; + lookaside->nll_l.gl_depth = depth; lookaside->nll_l.gl_maxdepth = LOOKASIDE_DEPTH; return;