mirror of
https://github.com/opnsense/src.git
synced 2026-02-22 01:11:30 -05:00
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.
This commit is contained in:
parent
a1b193b540
commit
621b33fc5b
1 changed files with 26 additions and 3 deletions
|
|
@ -271,6 +271,7 @@ __stdcall static void NdisMIndicateStatusComplete(ndis_handle);
|
|||
__stdcall static void NdisMIndicateStatus(ndis_handle, ndis_status,
|
||||
void *, uint32_t);
|
||||
static void ndis_workfunc(void *);
|
||||
static funcptr ndis_findwrap(funcptr);
|
||||
__stdcall static ndis_status NdisScheduleWorkItem(ndis_work_item *);
|
||||
__stdcall static void NdisCopyFromPacketToPacket(ndis_packet *,
|
||||
uint32_t, uint32_t, ndis_packet *, uint32_t, uint32_t *);
|
||||
|
|
@ -327,6 +328,22 @@ ndis_libfini()
|
|||
return(0);
|
||||
}
|
||||
|
||||
static funcptr
|
||||
ndis_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);
|
||||
}
|
||||
|
||||
/*
|
||||
* NDIS deals with strings in unicode format, so we have
|
||||
* do deal with them that way too. For now, we only handle
|
||||
|
|
@ -1188,10 +1205,15 @@ NdisMInitializeTimer(timer, handle, func, ctx)
|
|||
timer->nmt_timerctx = ctx;
|
||||
timer->nmt_block = handle;
|
||||
|
||||
/* Set up the timer so it will call our intermediate DPC. */
|
||||
|
||||
/*
|
||||
* Set up the timer so it will call our intermediate DPC.
|
||||
* Be sure to use the wrapped entry point, since
|
||||
* ntoskrnl_run_dpc() expects to invoke a function with
|
||||
* Microsoft calling conventions.
|
||||
*/
|
||||
KeInitializeTimer(&timer->nmt_ktimer);
|
||||
KeInitializeDpc(&timer->nmt_kdpc, ndis_timercall, timer);
|
||||
KeInitializeDpc(&timer->nmt_kdpc,
|
||||
ndis_findwrap((funcptr)ndis_timercall), timer);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -3266,6 +3288,7 @@ image_patch_table ndis_functbl[] = {
|
|||
IMPORT_FUNC(NdisMDeregisterDevice),
|
||||
IMPORT_FUNC(NdisMQueryAdapterInstanceName),
|
||||
IMPORT_FUNC(NdisMRegisterUnloadHandler),
|
||||
IMPORT_FUNC(ndis_timercall),
|
||||
|
||||
/*
|
||||
* This last entry is a catch-all for any function we haven't
|
||||
|
|
|
|||
Loading…
Reference in a new issue