__GFP_ZERO と 0 初期化

kvm のソースを読んでたら kvm_kvzalloc() なる関数が出てきた

/*
 * Avoid using vmalloc for a small buffer.
 * Should not be used when the size is statically known.
 */
void *kvm_kvzalloc(unsigned long size)
{
    if (size > PAGE_SIZE)
        return vzalloc(size);
    else
        return kzalloc(size, GFP_KERNEL);
}

割り当てたいサイズによって vzalloc() と kzalloc() を使い分ける。 kzalloc() は下記のような感じ

/**
 * kzalloc - allocate memory. The memory is set to zero.
 * @size: how many bytes of memory are required.
 * @flags: the type of memory to allocate (see kmalloc).
 */
static inline void *kzalloc(size_t size, gfp_t flags)
{
    return kmalloc(size, flags | __GFP_ZERO);

__GFP_ZERO を指定すると 割り当てた領域は 0 で初期化済みで返してくれる。

#define __GFP_ZERO  ((__force gfp_t)___GFP_ZERO)    /* Return zeroed page on success */

疑問

ここんところの実装がどうなってるかを追ってみた

github.com

といっても memset() しているだけだった。ちょっと面白みがないので下記のような検証を加えた

続きを読む

Linux カーネル API: anon_inode_getfd, misc_register

KVM のソースを呼んでる中で anon_inode_getfd という API を知ったので、 KVMソースコードを写経しながらカーネルモジュールを作ってみた

github.com

... といってもユーザランドに向けて ioctl(2) のインタフェースを作るだけのモジュールで実用的なものでない。KVM API を理解するための写経 📝

続きを読む

ソースコードリーディング: KVM_GET_API_VERSION

前回 の続き。KVMAPI を読んでいる

KVM_GET_API_VERSION

github.com

定数を返すだけの非常にシンプルな APIユーザランド側でどう扱うかが疑問になったので、qemu のソースも一緒に読んだ

qemu と一緒に読む

KVM_GET_API_VERSION といった定数は qemu でも同名で定義されているので、

  1. APIのドキュメントKVM_FOO_BAR の 説明を読む
  2. Linux kernel のソース で KVM_FOO_BAR が参照されている箇所を gtags で探して読み進める
  3. qemu のソースで KVM_FOO_BAR が参照されている箇所を gtags で探して読み進める

として、ユーザランドから見る KVM のインタフェースとカーネルでの KVM の実装を筋立ててソースを読んでいける ( a, b, c の順序は問わない )

Using the KVM API [LWN.net]

加えて、他の API と組み合わせて KVM を操作していく術について、骨格を掴むには lwn.net の過去記事を読むとよい

Using the KVM API [LWN.net]

ソースコードリーディング: 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カーネルに「割り込んで」メモリーや変数を調べ、コールスタック情報を見ることができるようにしてあります。カーネルコードにブレークポイントをかけたり、いくつかの制限された実行ステップをすることができます。

続きを読む