forked from iovisor/bcc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
KVM hypercall analysis example (iovisor#1082)
* KVM hypercall analysis example * Update README with KVM analysis example
- Loading branch information
Showing
3 changed files
with
101 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
#!/usr/bin/env python | ||
# | ||
# kvm_hypercall.py | ||
# | ||
# Demonstrates stateful kvm_entry and kvm_exit recording along with the | ||
# associated hypercall when exit_reason is VMCALL. See kvm_hypercall.txt | ||
# for usage | ||
# | ||
# REQUIRES: Linux 4.7+ (BPF_PROG_TYPE_TRACEPOINT support) | ||
# | ||
# Copyright (c) 2017 ShiftLeft Inc. | ||
# | ||
# Author(s): | ||
# Suchakrapani Sharma <[email protected]> | ||
|
||
|
||
from __future__ import print_function | ||
from bcc import BPF | ||
|
||
# load BPF program | ||
b = BPF(text=""" | ||
#define EXIT_REASON 18 | ||
BPF_HASH(start, u8, u8); | ||
TRACEPOINT_PROBE(kvm, kvm_exit) { | ||
u8 e = EXIT_REASON; | ||
u8 one = 1; | ||
if (args->exit_reason == EXIT_REASON) { | ||
bpf_trace_printk("KVM_EXIT exit_reason : %d\\n", args->exit_reason); | ||
start.update(&e, &one); | ||
} | ||
return 0; | ||
} | ||
TRACEPOINT_PROBE(kvm, kvm_entry) { | ||
u8 e = EXIT_REASON; | ||
u8 zero = 0; | ||
u8 *s = start.lookup(&e); | ||
if (s != NULL && *s == 1) { | ||
bpf_trace_printk("KVM_ENTRY vcpu_id : %u\\n", args->vcpu_id); | ||
start.update(&e, &zero); | ||
} | ||
return 0; | ||
} | ||
TRACEPOINT_PROBE(kvm, kvm_hypercall) { | ||
u8 e = EXIT_REASON; | ||
u8 zero = 0; | ||
u8 *s = start.lookup(&e); | ||
if (s != NULL && *s == 1) { | ||
bpf_trace_printk("HYPERCALL nr : %d\\n", args->nr); | ||
} | ||
return 0; | ||
}; | ||
""") | ||
|
||
# header | ||
print("%-18s %-16s %-6s %s" % ("TIME(s)", "COMM", "PID", "EVENT")) | ||
|
||
# format output | ||
while 1: | ||
try: | ||
(task, pid, cpu, flags, ts, msg) = b.trace_fields() | ||
except ValueError: | ||
continue | ||
print("%-18.9f %-16s %-6d %s" % (ts, task, pid, msg)) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
Demonstrations of kvm_hypercall.py, showing eBPF/bcc based hypercall analysis | ||
|
||
This example demonstrates how we can statefully save static tracepoint | ||
events based on conditions being met for other events with which they are | ||
associated. Here, we wish to record kvm_exit and kvm_entry events which are | ||
linked to the kvm_hypercall event. We are interested in kvm_exit with exit | ||
reason as VMCALL (18). This may be useful to analyze latency caused by a | ||
hypercall itself. | ||
|
||
To test this, while the python script is run, induce a hypercall from a | ||
guest based on the following example: | ||
https://gist.github.com/abenbachir/344822b5ba9fc5ac384cdec3f087e018 | ||
|
||
# ./kvm_hypercall.py | ||
TIME(s) COMM PID MESSAGE | ||
2445.577087000 CPU 0/KVM 8896 KVM_EXIT exit_reason : 18 | ||
2445.577122000 CPU 0/KVM 8896 HYPERCALL nr : 0 | ||
2445.577129000 CPU 0/KVM 8896 KVM_ENTRY vcpu_id : 0 | ||
2445.577136000 CPU 0/KVM 8896 KVM_EXIT exit_reason : 18 | ||
2445.577145000 CPU 0/KVM 8896 HYPERCALL nr : 1 | ||
2445.577149000 CPU 0/KVM 8896 KVM_ENTRY vcpu_id : 0 | ||
2445.577155000 CPU 0/KVM 8896 KVM_EXIT exit_reason : 18 | ||
2445.577160000 CPU 0/KVM 8896 HYPERCALL nr : 2 | ||
2445.577164000 CPU 0/KVM 8896 KVM_ENTRY vcpu_id : 0 | ||
2445.577170000 CPU 0/KVM 8896 KVM_EXIT exit_reason : 18 | ||
2445.577175000 CPU 0/KVM 8896 HYPERCALL nr : 3 | ||
2445.577179000 CPU 0/KVM 8896 KVM_ENTRY vcpu_id : 0 | ||
2445.577185000 CPU 0/KVM 8896 KVM_EXIT exit_reason : 18 | ||
2445.577190000 CPU 0/KVM 8896 HYPERCALL nr : 4 | ||
2445.577194000 CPU 0/KVM 8896 KVM_ENTRY vcpu_id : 0 | ||
|
||
This output shows a sequence of exit -> hypercall -> entry where the | ||
exit_reason was VMCALL. |