断片

です・ます調が記事によって違ったりするブログ

eBPFでゲストのCPUIDをトレースする

これはMCC Advent Caleandar 20日目の記事です.

adventar.org

前日はUm6ra1さんによるMediBang Paintのmdpファイルを解析してみたでした.

はじめに

eBPFのチュートリアルとして,KVMゲストによるCPUID Instructionの実行をホスト側でeBPF(とTracepoints)を使ってトレースしてみる.ここでは,eBPFはBCCを使って書く.BCCサンプルソースには kvm_hypercall.py というのがあり,このサンプルの動きは以下のようになっている.

  • kvm_exitkvm_entrykvm_hypercall をフックする.

  • kvm_exit のフックにおいて,VMExit ReasonがVMCALLによるものであったら,eBPF Mapにフラグを立ててprintする.

  • kvm_hypercall のフックにおいて,eBPF Mapにフラグが立っていれば,args->nr (VCPU_REGS_RAX) をprintする.

  • kvm_entry のフックにおいて,eBPF Mapのフラグを0にし,args->vcpi_id をprintする.

例えば,ゲストで適当にVMCALL Instructionを実行すると以下のようなトレースが取れる.

$ sudo python kvm_hypercall.py 
TIME(s)            COMM             PID    EVENT
15163.410112000    qemu-system-x86  9819   KVM_EXIT exit_reason : 18
15163.410130000    qemu-system-x86  9819   HYPERCALL nr : 114514
15163.410132000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0

github.com

今回はこのサンプルをVMExit ReasonがCPUIDによるものかどうかのチェックに改変し,さらに kvm_cpuid をフックする.argsで取れる値については /sys/kernel/debug/tracing/events/kvm/kvm_xxx(イベント名)/format (TracepointsかつKVMイベントの場合) 辺りを見るとわかる.

環境

ホスト

  • OS : Ubuntu 18.04.1 LTS
  • Linux Kernel : 4.15.0-39-generic
  • CPU : Intel(R) Core(TM) i7-8700K CPU @ 3.70GHz
  • Memory : 32GB
  • QEMU-KVM : 2.11.1
  • Python : 2.7.15rc1
  • libbcc : 0.7.0-1
  • bcc-tools : 0.7.0-1

ゲスト

  • OS : Ubuntu 16.04.5 LTS
  • Linux Kernel : 4.4.0-131-generic

コード

ホスト

gist.github.com

ゲスト

CPUID Instructionのコードを適当に書いた. gist.github.com

結果

$ sudo python kvm_cpuid.py 
TIME(s)            COMM             PID    EVENT
20422.473108000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473128000    qemu-system-x86  9819   KVM_CPUID rax : 0xd, rbx : 0x756e6547, rcx : 0x6c65746e
20422.473132000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473142000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473144000    qemu-system-x86  9819   KVM_CPUID rax : 0x663, rbx : 0x800, rcx : 0x80202021
20422.473146000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473149000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473151000    qemu-system-x86  9819   KVM_CPUID rax : 0x0, rbx : 0x0, rcx : 0x0
20422.473153000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473688000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473702000    qemu-system-x86  9819   KVM_CPUID rax : 0x1, rbx : 0x0, rcx : 0x4d
20422.473704000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473714000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473718000    qemu-system-x86  9819   KVM_CPUID rax : 0x1, rbx : 0x0, rcx : 0x4d
20422.473719000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473722000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473725000    qemu-system-x86  9819   KVM_CPUID rax : 0x121, rbx : 0x1c0003f, rcx : 0x3f
20422.473726000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473729000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473731000    qemu-system-x86  9819   KVM_CPUID rax : 0x122, rbx : 0x1c0003f, rcx : 0x3f
20422.473733000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473735000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473738000    qemu-system-x86  9819   KVM_CPUID rax : 0x143, rbx : 0x3c0003f, rcx : 0xfff
20422.473742000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473747000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473750000    qemu-system-x86  9819   KVM_CPUID rax : 0x163, rbx : 0x3c0003f, rcx : 0x3fff
20422.473751000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.473760000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.473763000    qemu-system-x86  9819   KVM_CPUID rax : 0xd, rbx : 0x756e6547, rcx : 0x6c65746e
20422.473764000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.979395000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.979412000    qemu-system-x86  9819   KVM_CPUID rax : 0x663, rbx : 0x800, rcx : 0x80202021
20422.979414000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0
20422.979453000    qemu-system-x86  9819   KVM_EXIT exit_reason : 0xa
20422.979460000    qemu-system-x86  9819   KVM_CPUID rax : 0x663, rbx : 0x800, rcx : 0x80202021
20422.979462000    qemu-system-x86  9819   KVM_ENTRY vcpu_id : 0x0

参考