linux

virshのvcpupinとvcpuinfoで表示されるaffinityの違い

以前virsh vcpupin と virsh vcpuinfo で表示されるCPUのAffinity情報が違うということがありました. % sudo virsh vcpupin vm1 VCPU CPU Affinity ---------------------- 0 0-47 1 0-47 2 0-47 [...] % sudo virsh vcpuinfo vm1 VCPU: 0 CPU: 25 State: r…

BPF_PROG_TYPE_RAW_TRACEPOINT (raw tracepoint) について

BPFのプログラムタイプの一つにBPF_PROG_TYPE_RAW_TRACEPOINTがあります (commit).これを利用するとtracepointの変換前の引数にアクセスすることができます. 例としてkernel/sched/core.cで定義されるsched_swtich のtracepointを考えます. trace_sched_s…

BPFプログラムからカーネル内のデータ構造にアクセスする方法

kprobeやtracepointなどにアタッチしたBPFプログラムは,BPF_FUNC_probe_read()関数でカーネル内のデータ構造にアクセスすることができます.これはprobe_kernel_read()のラッパーで,もし変な領域にアクセスしようした場合(page faultが発生した場合)は-E…

RustでUnix Domain Socketを扱う方法

"rust domain socket"とかで検索するといろいろ引っかかるけどいかんせんライブラリの更新が早くて情報が古かったりするのでここに現状を書きます(この文章もすぐに古くなるかもしれないので後から読む人は注意してください..) 基本 std::os::unix::net 元…

Rustのasync/awaitを使ったecho serverの実装

rust 1.39でasync/await構文が安定化されます. 巷で話題の機能ですが,asycn/await何も分からん...ということで話題に乗り遅れないためにasync/awaitを利用してecho serverを実装してみます. OSはLinuxが対象です.ソースはここにあります. echo server a…

複数の仮想ページに同じ物理ページをマッピングする方法 (Linux)

小ネタ. Linuxで複数の仮想ページを一つの物理ページにマッピングする方法です. 連続した仮想ページを全て同じ物理ページにマッピングしたいということがあって,原理的にはページテーブルで同じ領域を指すだけです.でもユーザ空間からはどうするんだっけ…

KVMの準仮想化機能

KVMにはいくつか準仮想化インタフェースが存在します. KVMはHWによる仮想化支援機構を利用してゲストを実行するので,準仮想化機能を使用しなくても任意のOSが実行できますが,準仮想化機能を利用することでVMのパフォーマンスを向上できる場合があります.…

KVMにおけるcpuid命令の取り扱い

前提 x86/Intelの話です.AMDでも多分同様. cpuid命令の取り扱い cpuid命令はKVM内で処理されます. 具体的には arch/x86/kvm/vmx.c:handle_cpuid() => arch/x86/kvm/cpuid.c:kvm_emulate_cpuid() => arch/x86/kvm/cpuid.c:kvm_cpuid() => arch/x86/kvm/cpu…

QEMU/KVM上のゲストのハイパーコールをQEMU側に渡す方法

前回説明したように,KVMでは,ゲストのハイパーコール(Intel CPUの場合はVMCALL命令,AMDの場合はVMMCALL命令)はKVM側で処理され,ioctl側に戻ることなくゲストに戻ります. QEMU/KVMにおいて,独自にハイパーコールを追加してQEMU側で処理するには修正が…

QEMUコードリーディングメモ

主にイベントループとKVM周り. QEMU v3.1.0 Linux v4.20 ターゲット: x86 QEMU Main Loop QEMUの主処理はGLibを使ったイベントループ. ゲストのvCPUは別のスレッドで実行(後述) vl.c:main() => vl.c:main_loop() => util/main-loop.c:main_loop_wait() =…

VFIOによるデバイス操作

VFIO (Virtual Function I/O)はLinuxにおいてユーザスペースでデバイスを操作するためのフレームワークの一つです. ユザースペースドライバといえばuioもありますが,uioとVFIOの主要な違いの一つはVFIOはIOMMUを利用するという点です*1.uioはLinux 2.6.23…

KVM GPUパススルー設定

環境 i7-4790 (with VT-d) GeForce GTX 1080ti Linux Mint 18.3 Sylvia (Ubuntu xenial base) Cinnamon やりたいこと KVM上のWindowsにGPUをパススルーで接続する 現在GPUはcuda計算用に利用 (ディスプレイはi915).Windowsを使うときだけパススルーさせたい…

ACPI DMARメモ

IOMMUの情報はACPIのDMARに格納されている DMARのデータ構造は,Intel VT-d ドキュメント (Intel® Virtualization Technology for Directed I/O) の8章に書いてある ざっくり以下のような構造 DMAR (DMA Remapping Table) DRHD (DMA Remapping Hardware Unit…

perf, ftraceのしくみ

Linuxのトレーサーであるperfやftraceのツールの使い方に関する情報は結構ありますが,構造に関してはあまり見つけられなかったため,ここに簡単に調べたことをまとめようかと思います.(ツールの使い方の説明はあんまりしないです.) この文章はLinux 4.1…

SpectreとeBPF

新年早々巷にいろいろと賑わいをもたらしたSpectreとMeltdownですが,Google Project Zero (GPZ)が公表したSpectreの攻撃コード例の中でeBPFが使用されていました. 安全を謳っているものの昨年もいくつか脆弱性が発見されていたので,「またeBPFか」と思っ…

LinuxのBPF : (5) eBPFによるLinux Kernel Tracing

eBPFによるカーネルトレース 一番最初に書いた通り,eBPFはLinuxのトレーサとして利用できます. カーネルがeBPFプログラムを実行する場合,BPFインタプリタにctxが渡されます(jit化されている場合も同様です). https://github.com/torvalds/linux/blob/v…

LinuxのBPF : (4) ClangによるeBPFプログラムの作成と,BPF Compiler Collection (BCC)

Clangを利用したeBPFプログラムの作成 eBPFへのコンパイル llvm IRの出力 eBPFアセンブリの出力 eBPFプログラムの出力 カーネルで動作するeBPFプログラムの例 skbuffからのロード eBPF mapの処理 BPF Compiler Collection (BCC) インストール bccによるプロ…

LinuxのBPF : (3) eBPFの基礎

はじめに(注意) extended BPF (eBPF) eBPF map eBPFプログラムの例 eBPFのmapの作成 eBPFプログラムの作成 eBPFフィルタプログラムの利用 setsockoptの挙動 JIT ソース まとめ はじめに(注意) ちょうど一年ぐらい前にLinuxのBPFについて記事を書いていま…

DPDKのmbufの構造

DPDKではパケットをmbufというデータ構造で管理しています. mbufについては http://dpdk.org/doc/guides/prog_guide/mbuf_lib.html にまとまっていますが,ここでは具体的なmbufの構成や使われ方についてみていきたいと思います. mempoolのおさらい mbufは…

DPDKにおけるメモリ管理

DPDKにおいてどのようにメモリが使用されるかをここにまとめたいと思います. なお,ここに書いてあるものはあくまで私がコードを読んで解釈した結果になります. DPDKのバージョンは17.05,OSはLinuxを対象としています. 全体像 DPDKでは独自のメモリアロ…

DPDKにおけるhugepageの初期化部分

DPDKはhugepageをデフォルトで利用しています.ここではDPDKにおけるhugepageの初期化部分についてまとめようと思います. OSはLinux , DPDKのバージョンはv17.05-rc2です. 初期化のおおまかな流れ librte_eal/linuxapp/eal/eal.c:rte_eal_init()がDPDKの基…

/proc/pid/pagemapの話

前回 /proc/pid/pagemap について簡単に触れたので,実際にpagemapを読み取るときどういうことが起きるか少し追ってみようと思います. /proc/pid/pagemapに関する操作はカーネルのfs/proc/task_mmu.c内でproc_pagemap_operationsに定義してあります. https…

仮想アドレスから物理アドレスを求める

××な理由で仮想アドレスではなく実際の物理アドレスを求めたいことがあると思います. linuxの場合,カーネルからならvirt2phys()等使えますが,ユーザランドからはそのような関数はありません. その代わり, /proc/self/pagemap を参照して解決することが…

I/O APICについて

前回LAPICについて書きました.LAPICは今ではCPU内に埋め込まれており,IntelのSDMにその使用方法が書いてあります.一方でI/O APICは今ではチップセットに埋め込まれているため,I/O APICに関して知りたい場合はチップセットのデータシートを見ることになり…

per cpu data シンボルのアドレス

kallsymsを見てみると,メモリ先頭のユーザ空間のアドレスにあるシンボルが複数存在していることが確認できます. % sudo cat /proc/kallsyms | head 0000000000000000 A irq_stack_union 0000000000000000 A __per_cpu_start 0000000000004000 A exception_…

X540のMSI-X設定

実際のデバイスでMSI-Xの設定の確認をしてみます. 今手元にX540があるので,それで実際に確認してみます. 文献 X540の仕様は以下から入手できます. Intel Ethernet Controller X540: Datasheet 7.3章にX540におけるMSI-Xについて書いてあります.また,9.…

x86_64 Linuxでの仮想アドレス/物理アドレス

Linux Device Driver Chapter 15では Linuxで利用されるアドレスを以下の5種類に分類しています. User virtual address Physical address Bus address Kernel logical address Kenerl virtual address User virtual addressはその名の通りユーザプロセスが…