ソースコードリーディング: KVM_CREATE_VM / KVM_CREATE_VCPU

Linux カーネルソースコードはちょいちょい読んできていたが、KVM 周辺は全くふれていなかったので、ソースを追いかけている

KVM_CREATE_VM

github.com

KVM_CREATE_VCPU

github.com

O'Reilly の『詳解 Linux カーネル』 のような 凶器 書籍が無いので、Web 上のあれこれや Linux カーネルのドキュメントをエントリポイントにして読んでいる。なお「解説」を目指したものではなく、メモ書きが飛散している程度で第三者の閲覧に耐えうる感じでは書けていない。ご勘弁を

感想

KVMAPI を把握するにあたって https://kernel.org/doc/Documentation/virtual/kvm/api.txt をとっかかりとした。 1章と2章を読んで ioctl(2) で /dev/kvm, struct kvm, struct kvm_vcpu をどう扱うかを整理すると、ソースを読む道筋を立てやすいと思う

アーキテクチャ依存のコードが強敵。syuu1228 さんの「ハイパーバイザの作り方」シリーズを眺めると Intel VT-x の全体像をつかみやすい

syuu1228.github.io

さらに Intel のマニュアル読んで更に詳細を追っている ( システム・プログラミング・ガイド の 23章あたり )

www.intel.co.jp


まだまだ序盤なので、せっせと読んでいく

デバッグ: VirtualBox +CentOS7 で kdb/kgdb の 素振り

Linux カーネルデバッグ方法を各種 抑えておきたいと思って kdb/kgdb を扱う方法を調べていた (正確には kgdboc = kgdb over consol を試した )

kdb/kgdb とは

kgdb, kdb の使い方と、カーネルデバッガーの内部 - kandamotohiro から引用

Kdb は、単純なシェルスタイルのインタフェースであり、キーボードのあるシステムコンソールあるいはシリアルコンソールで使えます。メモリーレジスター、プロセス一覧、dmesg を見ることができます。指定した位置で止まるようにブレークポイントをかけることもできます。ブレークポイントをかけたり、基本的なカーネルの実行制御ができますが、Kdb は、ソースレベルデバッガーではありません


Kgdb は、 Linux カーネルのためのソースレベルデバッガーとして使われるためのものです。Linux カーネルデバッグするために、 gdb とともに使われます。アプリケーションの開発者が、アプリケーションをデバッグするために gdb を使うのと同じように、 gdbカーネルに「割り込んで」メモリーや変数を調べ、コールスタック情報を見ることができるようにしてあります。カーネルコードにブレークポイントをかけたり、いくつかの制限された実行ステップをすることができます。

続きを読む

トレーニングライド・別府選手の Madone みてきた

二日酔いで午後までボロ雑巾、夕方にトレーニング走

レックストア六本木

皇居周辺を走った後に、リアディレイラーの不調をみてもらうべく トレックストア六本木に立ち寄り

ジャパンカップツール・ド・フランスさいたまクリテリウム で別府選手が乗っていた Madone が展示されていた。ラッキ〜

BEPPU のロゴ、見えるかな?

しばし鑑賞。差色の赤がよい感じにアクセントになってネオンカラーを引き締めている

もはや「自転車」のイメージからかけ離れているね。戦闘機やF1 のようなシルエット。相当に速く走れないと似合わなそうだ!!!

二連覇、おめでとうございました。ぱちぱち


リアディレイラーの不調はシフトケーブルが錆びて断線気味だったのが原因らしい。修理費用は交換のケーブル代だけで格安 (900円) 。加えて、BB周りが錆びにやられていたとのことでオーバーホールもすすめられた。(ついでにコラムカットも一緒にやれますよ とお得情報) 。アフターケアが手厚い。

錆びの原因を思い返してみたが、以前に 大雨の宇都宮〜日光を走っていて 予後のメンテナンスが不十分で内部まで浸水していたのだろう。がーん

デバッグ: CentOS7 BUG: unable to handle kernel NULL pointer dereference at (null)

CentOS7 で BUG: unable to handle kernel NULL pointer dereference at (null) で kernel panic したのを深追いで調べていた

バックトレース

[705327.823158] BUG: unable to handle kernel NULL pointer dereference at           (null)
[705327.824009] IP: [<ffffffff81573762>] skb_entail+0x52/0xd0
[705327.828140] PGD 18fe72067 PUD 18fe73067 PMD 0 
[705327.828140] Oops: 0002 [#1] SMP 
[705327.828140] Modules linked in: dccp_diag dccp tcp_diag udp_diag inet_diag unix_diag af_packet_diag netlink_diag nls_utf8 isofs ppdev i2c_piix4 sg parport_pc virtio_balloon parport pcspkr nfsd auth_rpcgss nfs_acl lockd grace sunrpc ip_tables xfs libcrc32c sr_mod cdrom ata_generic pata_acpi cirrus virtio_blk virtio_net syscopyarea sysfillrect sysimgblt drm_kms_helper ttm ata_piix crc32c_intel drm virtio_pci virtio_ring serio_raw libata virtio i2c_core floppy dm_mirror dm_region_hash dm_log dm_mod
[705327.837099] CPU: 0 PID: 2790 Comm: nginx Not tainted 3.10.0-327.36.1.el7.x86_64 #1
[705327.837099] Hardware name: Red Hat Inc. OpenStack Nova, BIOS 0.5.1 01/01/2007
[705327.837099] task: ffff880036a1dc00 ti: ffff88018fcbc000 task.ti: ffff88018fcbc000
[705327.837099] RIP: 0010:[<ffffffff81573762>]  [<ffffffff81573762>] skb_entail+0x52/0xd0
[705327.837099] RSP: 0018:ffff88018fcbfb88  EFLAGS: 00010202
[705327.837099] RAX: 0000000000000000 RBX: 0000000000003890 RCX: 00000000ffffffff
[705327.837099] RDX: ffff8801089c9038 RSI: ffff8801089c9038 RDI: ffff8801089c8f00
[705327.837099] RBP: ffff88018fcbfb88 R08: 00000000000006c0 R09: 0000000000000900
[705327.837099] R10: ffff880217001400 R11: 8883e3b982e39d83 R12: 0000000000000000
[705327.837099] R13: ffff8801089c8f00 R14: ffff8801089c9038 R15: 0000000000000fb0
[705327.837099] FS:  00007fca72598840(0000) GS:ffff88021fc00000(0000) knlGS:0000000000000000
[705327.837099] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[705327.837099] CR2: 0000000000000000 CR3: 000000018fe71000 CR4: 00000000000007f0
[705327.837099] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[705327.837099] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[705327.837099] Stack:
[705327.837099]  ffff88018fcbfc50 ffffffff81577bf2 ffff880036a1e688 ffff880000000001
[705327.837099]  0000000000000050 ffff88018fcbffd8 0000000000000000 ffff880036a1dc00
[705327.837099]  ffff88018fcbffd8 ffff88018fcbfe70 00000000011b4df9 0000000000000501
[705327.837099] Call Trace:
[705327.837099]  [<ffffffff81577bf2>] tcp_sendmsg+0x6f2/0xc20
[705327.837099]  [<ffffffff815a1c04>] inet_sendmsg+0x64/0xb0
[705327.837099]  [<ffffffff815103d7>] sock_aio_write+0x157/0x180
[705327.837099]  [<ffffffff811de5d9>] do_sync_readv_writev+0x79/0xd0
[705327.837099]  [<ffffffff811dfbae>] do_readv_writev+0xce/0x260
[705327.837099]  [<ffffffff81058aaf>] ? kvm_clock_get_cycles+0x1f/0x30
[705327.837099]  [<ffffffff810d896a>] ? __getnstimeofday64+0x3a/0xd0
[705327.837099]  [<ffffffff811dfdd5>] vfs_writev+0x35/0x60
[705327.837099]  [<ffffffff811dff8f>] SyS_writev+0x7f/0x110
[705327.837099]  [<ffffffff81646a09>] system_call_fastpath+0x16/0x1b
[705327.837099] Code: 4d 00 89 46 44 89 46 40 8b 86 dc 00 00 00 c7 44 02 24 01 00 01 00 48 8b 87 40 01 00 00 48 8d 97 38 01 00 00 48 89 16 48 89 46 08 <48> 89 30 83 87 48 01 00 00 01 48 83 bf 68 02 00 00 00 48 89 b7 
[705327.837099] RIP  [<ffffffff81573762>] skb_entail+0x52/0xd0
[705327.837099]  RSP <ffff88018fcbfb88>
[705327.837099] CR2: 0000000000000000

以下、調べてみてのわかったことと推測

  • sk_stream_alloc_skb で新規に割り当てた struct sk_buffer skb と、 sk->write_queue のアドレスが なぜか同一 になっている
    • sk_stream_alloc_skb が返す skb は memset でゼロクリアされているので、skb->next, skb->prev 共に NULL となっている
    • skb と sk->write_queue が同じアドレスを指しいるので、つまり、sk->write_queue->next, sk->write_queue->prev も NULL となっている
  • 以上の状況で __skb_insert でリスト操作をする際に NULL pointer dereference が起きた

NULL pointer dereference が起きた状況は整理できたが、なぜこうなったのか、根本的な原因はよくわからない。ググってみても「これ」といったものは発見できず

調べていったログを記しておく (全体を整頓しきれていないので、情報が飛散しているのはご了承を)

続きを読む

ソースコードリーディング: ipcs -m で 「対象」と翻訳されているソースを追う

CentOS7 で ipcs-m を実行すると下記のような出力になる

$ ipcs -m

------ 共有メモリセグメント --------
キー     shmid      所有者  権限     バイト  nattch     状態      
0x00000000 113934337  root       600        40         9          対象   🍣   

🍣 部分の 対象 って訳されているのが何なのだろうと気になってしょうがない

$ LANG=C ipcs -m

------ Shared Memory Segments --------
key        shmid      owner      perms      bytes      nattch     status      
0x00000000 113934337  root       600        40         9          dest         

デフォルトロケールでみてみると dest となっている

dest は何ですと?

続きを読む