e1000カード用のネットワークドライバーを書いています。受信部分を実行しているときに、netif_rx(skb)呼び出しに到達するたびにカーネルがフリーズすることを確認しました。skbデータをハードコード化するベアボーンドライバーを使用した場合にも、同じエラーを再現できました。
以下のそのテスト関数のコードを参照してください。データはTCPパケット(IPおよびイーサネットヘッダー付き)のデータです。ドライバーを仮想マシンにロードすると、VMプロセスがホストマシンで100%を超えるCPUを使用していることがわかります。この後、OSは入力に応答しません。netif_rx行をコメントアウトすると、正常に機能しているようです。
static void test_skb(void){
unsigned char t[] = {0x52,0x54,0x00,0x12,0x34,0x56,0x52,0x55,0x0a,0x00,0x02,0x02,0x08,0x00,0x45,0x00,0x00,0x2c,0x00,0x1c,0x00,0x00,0x40,0x06,0x62,0xa0,0x0a,0x00,0x02,0x02,0x0a,0x00,0x02,0x0f,0xc6,0x1a,0x1e,0xdb,0x4c,0x81,0x18,0x01,0x00,0x00,0x00,0x00,0x60,0x02,0x22,0x38,0x14,0x66,0x00,0x00,0x02,0x04,0x05,0xb4};
int len = 58;
struct sk_buff *skb;
skb = dev_alloc_skb (len + 2);
if (skb) {
printk("Allocated skb buffer\n");
memcpy(skb_put(skb, len), t, len);
printk("step1\n");
//skb_put(skb, len);
//skb->dev = dev;
printk("step2\n");
//skb->protocol = eth_type_trans(skb, dev);
skb->protocol = ETH_P_IP;
printk("step3\n");
skb->ip_summed = CHECKSUM_UNNECESSARY;
printk("step4\n");
//netif_rx (skb);
printk("step5\n");
}
printk(KERN_INFO"All Done");
if(skb){
dev_kfree_skb(skb);
}
}