From owner-freebsd-bugs@FreeBSD.ORG Fri Mar 2 13:50:09 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id C121D1065670 for ; Fri, 2 Mar 2012 13:50:09 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 994B78FC1B for ; Fri, 2 Mar 2012 13:50:09 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q22Do9xN035388 for ; Fri, 2 Mar 2012 13:50:09 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q22Do9pi035387; Fri, 2 Mar 2012 13:50:09 GMT (envelope-from gnats) Resent-Date: Fri, 2 Mar 2012 13:50:09 GMT Resent-Message-Id: <201203021350.q22Do9pi035387@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Vladislav Movchan Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 49B9F106564A for ; Fri, 2 Mar 2012 13:49:19 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id 33B068FC19 for ; Fri, 2 Mar 2012 13:49:19 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q22DnJZA002269 for ; Fri, 2 Mar 2012 13:49:19 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id q22DnIaS002268; Fri, 2 Mar 2012 13:49:18 GMT (envelope-from nobody) Message-Id: <201203021349.q22DnIaS002268@red.freebsd.org> Date: Fri, 2 Mar 2012 13:49:18 GMT From: Vladislav Movchan To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/165622: [ndis][panic][patch] Unregistered use of FPU in kernel on amd64 X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Mar 2012 13:50:09 -0000 >Number: 165622 >Category: kern >Synopsis: [ndis][panic][patch] Unregistered use of FPU in kernel on amd64 >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Fri Mar 02 13:50:09 UTC 2012 >Closed-Date: >Last-Modified: >Originator: Vladislav Movchan >Release: FreeBSD 10.0-CURRENT >Organization: >Environment: FreeBSD starlight 10.0-CURRENT FreeBSD 10.0-CURRENT #0 r232379: Fri Mar 2 13:24:25 EET 2012 root@starlight:/usr/obj/usr/src/sys/Mephistopheles amd64 >Description: Some miniport drivers (windows NIC drivers) could use FPU in kernel what cause "Unregistered use of FPU in kernel" panic. I've seen this only in amd64 case; i386 seems to be not affected. Same is mentioned in this two messages: http://lists.freebsd.org/pipermail/svn-src-all/2010-March/021770.html http://lists.freebsd.org/pipermail/svn-src-all/2010-March/021773.html Point when panic occurs depends on the driver. In my case it happening during the first attempt to transmit a packet. Panic message: panic: Unregistered use of FPU in kernel cpuid = 3 KDB: stack backtrace: db_trace_self_wrapper() at db_trace_self_wrapper+0x2a kdb_backtrace() at kdb_backtrace+0x37 panic() at panic+0x1cd trap() at trap+0x71f calltrap() at calltrap+0x8 --- trap 0x16, rip = 0xffffffff83c37e0e, rsp = 0xffffff80d116d7c0, rbp = 0xffffff80075df520 --- __stop_set_sysinit_set() at __stop_set_sysinit_set+0xe6ee dmapbase() at 0xfffffe0040fb5180 (null)() at 0xffffff80075df520 dmapbase() at 0xfffffe0040f83d00 dmapbase() at 0xfffffe0040f83e00 dmapbase() at 0xfffffe0040f8b080 dmapbase() at 0xfffffe0040f8b180 dmapbase() at 0xfffffe0040f8b280 .. dmapbase() at 0xfffffe0040fb4600 dmapbase() at 0xfffffe0040fb4700 dmapbase() at 0xfffffe0040fb4800 dmapbase() at 0xfffffe0040fb4900 dmapbase() at 0xfffffe0040fb4a00 Backtrace: #0 doadump (textdump=-787033584) at /usr/src/sys/kern/kern_shutdown.c:268 268 if (textdump && textdump_pending) { (kgdb) #0 doadump (textdump=-787033584) at /usr/src/sys/kern/kern_shutdown.c:268 #1 0xffffffff802de36c in db_fncall (dummy1=Variable "dummy1" is not available. ) at /usr/src/sys/ddb/db_command.c:573 #2 0xffffffff802de6a1 in db_command (last_cmdp=0xffffffff80dcd560, cmd_table=Variable "cmd_table" is not available. ) at /usr/src/sys/ddb/db_command.c:449 #3 0xffffffff802de8f0 in db_command_loop () at /usr/src/sys/ddb/db_command.c:502 #4 0xffffffff802e0ad4 in db_trap (type=Variable "type" is not available. ) at /usr/src/sys/ddb/db_main.c:229 #5 0xffffffff806d3bb1 in kdb_trap (type=3, code=0, tf=0xffffff80d116d440) at /usr/src/sys/kern/subr_kdb.c:629 #6 0xffffffff80942f68 in trap (frame=0xffffff80d116d440) at /usr/src/sys/amd64/amd64/trap.c:591 #7 0xffffffff8092c1cf in calltrap () at /usr/src/sys/amd64/amd64/exception.S:228 #8 0xffffffff806d36ab in kdb_enter (why=0xffffffff80a3fb16 "panic", msg=0x80
) at cpufunc.h:63 #9 0xffffffff8069aea6 in panic (fmt=Variable "fmt" is not available. ) at /usr/src/sys/kern/kern_shutdown.c:633 #10 0xffffffff809434ef in trap (frame=Variable "frame" is not available. ) at /usr/src/sys/amd64/amd64/trap.c:478 #11 0xffffffff8092c1cf in calltrap () at /usr/src/sys/amd64/amd64/exception.S:228 #12 0xffffffff83c37e0e in ndis_Rtenic64_sys_drv_data_start () from /boot/modules/Rtenic64_sys.ko #13 0xffffffffffffffff in ?? () #14 0xffffffff80a40a28 in __func__.17200 () #15 0x0000074200000001 in ?? () #16 0xffffffff80a42b69 in link_elf_methods () #17 0xffffff80d116d800 in ?? () #18 0x0000000000000000 in ?? () #19 0x0000000000000000 in ?? () #20 0x0000000000000000 in ?? () .. #79 0x0000000000000000 in ?? () #80 0x0000000000000000 in ?? () #81 0x0000000000000000 in ?? () #82 0x0000000000000000 in ?? () #83 0xffffff80d116dad0 in ?? () #84 0xfffffe007b2b1348 in ?? () #85 0xffffff80075de000 in ?? () #86 0xfffffe0008410800 in ?? () #87 0xffffff80075deff0 in ?? () #88 0xffffff80075de000 in ?? () #89 0xffffff80075de000 in ?? () #90 0xffffff80d116dad0 in ?? () #91 0x0000000000000000 in ?? () #92 0xffffffff83c3d3ce in ndis_Rtenic64_sys_drv_data_start () from /boot/modules/Rtenic64_sys.ko #93 0xffffff80d1160000 in ?? () #94 0xfffffe0000000000 in ?? () #95 0xffffff8000000000 in ?? () #96 0xffffff80d116d900 in ?? () #97 0xffffffff83c3d284 in ndis_Rtenic64_sys_drv_data_start () from /boot/modules/Rtenic64_sys.ko #98 0xffffffff840e07b9 in x86_64_call1 () at /usr/src/sys/modules/ndis/../../compat/ndis/winx64_wrap.S:130 #99 0xfffffe007b2b1328 in ?? () #100 0xfffffe007b154000 in ?? () #101 0xffffff80075deff8 in ?? () #102 0xfffffe007b2b1328 in ?? () #103 0xffffff80d116dad0 in ?? () #104 0xffffffff840d3e87 in ndis_intrhand (dpc=Variable "dpc" is not available. ) at /usr/src/sys/modules/ndis/../../compat/ndis/subr_ndis.c:2234 Previous frame inner to this frame (corrupt stack?) (kgdb) Core/process which triggers this panic: cpuid = 3 dynamic pcpu = 0xffffff807f453100 curthread = 0xfffffe0008bbd000: pid 1547 "Windows DPC 0" curpcb = 0xffffff80d116dd00 fpcurthread = none idlethread = 0xfffffe00046b0480: tid 100006 "idle: cpu3" curpmap = 0xffffffff80df4c50 tssp = 0xffffffff82609718 commontssp = 0xffffffff82609718 rsp0 = 0xffffff80d116dd00 gs32p = 0xffffffff82607870 ldt = 0xffffffff826078b0 tss = 0xffffffff826078a0 spin locks held: >How-To-Repeat: Use ndis on amd64: kldload module created with ndisgen; assign ip address; try to ping something. I believe not every miniport driver is affected, but drivers of both devices I've tested could trigger this panic. >Fix: Attached patch fixed this problem for me. Original version of this patch was written by Paul B Mahol (many thanks to Paul!) Patch attached with submission follows: Index: /usr/src/sys/compat/ndis/pe_var.h =================================================================== --- /usr/src/sys/compat/ndis/pe_var.h (revision 232379) +++ /usr/src/sys/compat/ndis/pe_var.h (working copy) @@ -460,22 +460,30 @@ extern uint64_t x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t); +uint64_t _x86_64_call1(void *, uint64_t); +uint64_t _x86_64_call2(void *, uint64_t, uint64_t); +uint64_t _x86_64_call3(void *, uint64_t, uint64_t, uint64_t); +uint64_t _x86_64_call4(void *, uint64_t, uint64_t, uint64_t, uint64_t); +uint64_t _x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t); +uint64_t _x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t, uint64_t); #define MSCALL1(fn, a) \ - x86_64_call1((fn), (uint64_t)(a)) + _x86_64_call1((fn), (uint64_t)(a)) #define MSCALL2(fn, a, b) \ - x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b)) + _x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b)) #define MSCALL3(fn, a, b, c) \ - x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \ + _x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \ (uint64_t)(c)) #define MSCALL4(fn, a, b, c, d) \ - x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \ + _x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \ (uint64_t)(c), (uint64_t)(d)) #define MSCALL5(fn, a, b, c, d, e) \ - x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \ + _x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \ (uint64_t)(c), (uint64_t)(d), (uint64_t)(e)) #define MSCALL6(fn, a, b, c, d, e, f) \ - x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \ + _x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \ (uint64_t)(c), (uint64_t)(d), (uint64_t)(e), (uint64_t)(f)) #endif /* __amd64__ */ Index: /usr/src/sys/compat/ndis/kern_windrv.c =================================================================== --- /usr/src/sys/compat/ndis/kern_windrv.c (revision 232379) +++ /usr/src/sys/compat/ndis/kern_windrv.c (working copy) @@ -56,6 +56,10 @@ #include #endif +#ifdef __amd64__ +#include +#endif + #include #include @@ -573,6 +577,109 @@ return (0); } +uint64_t +_x86_64_call1(void *fn, uint64_t a) +{ + struct fpu_kern_ctx *fpu_ctx_save; + uint64_t ret; + + fpu_ctx_save = fpu_kern_alloc_ctx(FPU_KERN_NORMAL | FPU_KERN_NOWAIT); + if (fpu_ctx_save == NULL) + return (ENOMEM); + fpu_kern_enter(curthread, fpu_ctx_save, FPU_KERN_NORMAL); + ret = x86_64_call1(fn, a); + fpu_kern_leave(curthread, fpu_ctx_save); + fpu_kern_free_ctx(fpu_ctx_save); + + return (ret); +} + +uint64_t +_x86_64_call2(void *fn, uint64_t a, uint64_t b) +{ + struct fpu_kern_ctx *fpu_ctx_save; + uint64_t ret; + + fpu_ctx_save = fpu_kern_alloc_ctx(FPU_KERN_NORMAL | FPU_KERN_NOWAIT); + if (fpu_ctx_save == NULL) + return (ENOMEM); + fpu_kern_enter(curthread, fpu_ctx_save, FPU_KERN_NORMAL); + ret = x86_64_call2(fn, a, b); + fpu_kern_leave(curthread, fpu_ctx_save); + fpu_kern_free_ctx(fpu_ctx_save); + + return (ret); +} + +uint64_t +_x86_64_call3(void *fn, uint64_t a, uint64_t b, uint64_t c) +{ + struct fpu_kern_ctx *fpu_ctx_save; + uint64_t ret; + + fpu_ctx_save = fpu_kern_alloc_ctx(FPU_KERN_NORMAL | FPU_KERN_NOWAIT); + if (fpu_ctx_save == NULL) + return (ENOMEM); + fpu_kern_enter(curthread, fpu_ctx_save, FPU_KERN_NORMAL); + ret = x86_64_call3(fn, a, b, c); + fpu_kern_leave(curthread, fpu_ctx_save); + fpu_kern_free_ctx(fpu_ctx_save); + + return (ret); +} + +uint64_t +_x86_64_call4(void *fn, uint64_t a, uint64_t b, uint64_t c, uint64_t d) +{ + struct fpu_kern_ctx *fpu_ctx_save; + uint64_t ret; + + fpu_ctx_save = fpu_kern_alloc_ctx(FPU_KERN_NORMAL | FPU_KERN_NOWAIT); + if (fpu_ctx_save == NULL) + return (ENOMEM); + fpu_kern_enter(curthread, fpu_ctx_save, FPU_KERN_NORMAL); + ret = x86_64_call4(fn, a, b, c, d); + fpu_kern_leave(curthread, fpu_ctx_save); + fpu_kern_free_ctx(fpu_ctx_save); + + return (ret); +} + +uint64_t +_x86_64_call5(void *fn, uint64_t a, uint64_t b, uint64_t c, uint64_t d, + uint64_t e) +{ + struct fpu_kern_ctx *fpu_ctx_save; + uint64_t ret; + + fpu_ctx_save = fpu_kern_alloc_ctx(FPU_KERN_NORMAL | FPU_KERN_NOWAIT); + if (fpu_ctx_save == NULL) + return (ENOMEM); + fpu_kern_enter(curthread, fpu_ctx_save, FPU_KERN_NORMAL); + ret = x86_64_call5(fn, a, b, c, d, e); + fpu_kern_leave(curthread, fpu_ctx_save); + fpu_kern_free_ctx(fpu_ctx_save); + + return (ret); +} + +uint64_t +_x86_64_call6(void *fn, uint64_t a, uint64_t b, uint64_t c, uint64_t d, + uint64_t e, uint64_t f) +{ + struct fpu_kern_ctx *fpu_ctx_save; + uint64_t ret; + + fpu_ctx_save = fpu_kern_alloc_ctx(FPU_KERN_NORMAL | FPU_KERN_NOWAIT); + if (fpu_ctx_save == NULL) + return (ENOMEM); + fpu_kern_enter(curthread, fpu_ctx_save, FPU_KERN_NORMAL); + ret = x86_64_call6(fn, a, b, c, d, e, f); + fpu_kern_leave(curthread, fpu_ctx_save); + fpu_kern_free_ctx(fpu_ctx_save); + + return (ret); +} #ifdef __amd64__ extern void x86_64_wrap(void); >Release-Note: >Audit-Trail: >Unformatted: