2017-10-19 13 views
3

WIFI Marvell pcieドライバのinsmodでクラッシュしています。 私はARCH = arc OS = linuxとlittle endianでWIFIドライバを実行しています。 クラッシュバックトレースは、アドレスの不一致がクラッシュすることを示しています。 私はいくつかの調査を行い、クラッシュの場所を見つけました。以下はコードスニペットです。アークプラットフォーム上のlinux wifiドライバでアドレスの不一致が発生する

case NullPktPeriod_i: 
     /** keep alive null data pkt interval in full power mode */ 
     psnmp_mib->oid = wlan_cpu_to_le16((t_u16)NullPktPeriod_i); 
     if (cmd_action == HostCmd_ACT_GEN_SET) { 
      psnmp_mib->query_type = 
       wlan_cpu_to_le16(HostCmd_ACT_GEN_SET); 
      psnmp_mib->buf_size = wlan_cpu_to_le16(sizeof(t_u32)); 
      ul_temp = *((t_u32 *)pdata_buf); 
      *((t_u32 *)(psnmp_mib->value)) = 
       wlan_cpu_to_le32((t_u32)ul_temp); 
      cmd->size += sizeof(t_u32); 
     } 
     break; 

クラッシュpsnmp_mib->valueがunsigned char型であるとunsigned long intにtypecast'dのでライン*((t_u32 *)(psnmp_mib->value)) = wlan_cpu_to_le32((t_u32)ul_temp);です。しかし、pdata_bufから割り当てられる値は、1バイト値ul_temp = *((t_u32 *)pdata_buf);のみです。

ul_temp (unsigned long int variable)をゼロ(任意の値)に初期化して実行すると、クラッシュが表示されません。 get_hardware_specコマンドを取得してカーネルがハングすると、PCIコマンドのタイムアウトが発生します。

私はこの問題を解決する手がかりがありません。さらに移動するためにいくつかの入力を提供してください。

フェラを助けてください、私のクラッシュログ、

[ 29.920000] Path: (null) 
[ 29.930000] CPU: 0 PID: 1047 Comm: kworker/u3:1 Tainted: P   O 3.12.0 #103 
[ 29.930000] Workqueue: MOAL_WORK_QUEUE woal_main_work_queue [pcie8xxx] 
[ 29.940000] task: 9f0e02c0 ti: 9d192000 task.ti: 9d192000 
[ 29.940000] 
[ECR ]: 0x00230400 => Misaligned r/w from 0x9d451072 
[ 29.950000] [EFA ]: 0x9d451072 
[ 29.950000] [BLINK ]: wlan_prepare_cmd+0x1be/0x478 [mlan] 
[ 29.950000] [ERET ]: wlan_ops_sta_prepare_cmd+0x1fe0/0x37dc [mlan] 
[ 29.950000] [STAT32]: 0x00000a06 :   E2 E1 
[ 29.970000] BTA: 0x78571ccc SP: 0x9d193c34 FP: 0x00000000 
[ 29.980000] LPS: 0x982de26c LPE: 0x982de270 LPC: 0x00000000 
[ 29.980000] r00: 0x00000000 r01: 0x00000016 r02: 0x00000012 
r03: 0x0000001e r04: 0x00000000 r05: 0x9d193cb4 
r06: 0x9d451064 r07: 0x7857129c r08: 0xfffffffe 
r09: 0x00000000 r10: 0x000004cf r11: 0x00000002 
r12: 0x00000000 
[ 29.990000] 
[ 29.990000] Stack Trace: 

です。

+0

* "この問題を解決する手掛かりはありません..." * - これを修正するには、おそらくカーネルのメーリングリストに持って行かなければならないでしょう。 [Linux Kernel Newbies](https://kernelnewbies.org/)は、カーネル開発者がそこにぶら下がり、比較的優しいのですばらしい場所です。サイトには[Found a Bug](https://kernelnewbies.org/FoundBug)に関するセクションもあります。あなたの次のステップはおそらく適切なメーリングリストに報告することです。 – jww

答えて

3

シンプルです。ちょうど正しいことをしてください。一般的なケースでは、1はmemcpyを使用します。

t_u32 value = wlan_cpu_to_le32((t_u32)ul_temp); 
memcpy(psnmp_mib->value, &value, sizeof (t_u32)); 

としては、put_unalignedがここで使用することができ0andriyが指摘:C規格はbehaviour is undefined whenという状態を行いますので、

put_unaligned(wlan_cpu_to_le32((t_u32)ul_temp), (t_u32*)psnmp_mib->value); 

しかし、これは非常に気になります:

2つのポインタ型の間で変換を行うと、結果が正しく整列されません(6.3.2.3)。

このようにキャスト(t_u32*)のも、単なる存在ポインタpsnmp_mib->valueはとにかくt_u32の整列条件に合っていること「を実現」するために、コンパイラにつながることができます。


アンアラインドアクセス - 偶数または整列されていない構造体へのポインタをキャストするには - さえ"supposedly" allow unaligned access "everywhere"プラットフォーム上での動作を未定義ました。

+1

カーネルに* get_unaligned()*と* put_unaligned()*ヘルパーがあります。それらを使用してパッチをアップストリームに送信する方がよいでしょう。 – 0andriy

+0

私は再び投稿を読んで、今は* memcpy()*アプローチがオーバーヘッドだと言うことさえできます。 – 0andriy

+0

@ 0andriy私は "put_unaligned" APIを見ました。*非常に気になるのは、* too *です(https://www.kernel.org/doc/Documentation/unaligned-memory-accessにあります)。txt)には未定義の動作があります。 'put_unaligned(value、(u32 *)data);' - 'data'がアライメントされていないときは、キャストは無効です。 –

関連する問題