Commit | Line | Data |
---|---|---|
d4697afa MD |
1 | /* |
2 | * ltt/probes/kvm-trace.c | |
3 | * | |
4 | * KVM tracepoint probes. | |
5 | * | |
6 | * (C) Copyright 2010 - Julien Desfossez <julien.desfossez@polymtl.ca> | |
7 | * Dual LGPL v2.1/GPL v2 license. | |
8 | * | |
9 | */ | |
10 | ||
11 | #include <linux/module.h> | |
12 | #include <asm/vmx.h> | |
13 | #include <linux/kvm_host.h> | |
14 | #include <asm/kvm-trace.h> | |
15 | ||
16 | void probe_kvm_entry(void *_data, unsigned int vcpu_id) | |
17 | { | |
18 | trace_mark_tp(kvm, kvm_entry, kvm_entry, | |
19 | probe_kvm_entry, | |
20 | "vcpu %u", | |
21 | vcpu_id); | |
22 | } | |
23 | ||
24 | void probe_kvm_hypercall(void *_data, unsigned long nr, unsigned long a0, | |
25 | unsigned long a1, unsigned long a2, unsigned long a3) | |
26 | { | |
27 | trace_mark_tp(kvm, kvm_hypercall, kvm_hypercall, | |
28 | probe_kvm_hypercall, | |
29 | "nr 0x%lx a0 0x%lx a1 0x%lx a2 0x%lx a3 0x%lx", | |
30 | nr, a0, a1, a2, a3); | |
31 | } | |
32 | ||
33 | void probe_kvm_pio(void *_data, unsigned int rw, unsigned int port, | |
34 | unsigned int size, unsigned int count) | |
35 | { | |
36 | trace_mark_tp(kvm, kvm_pio, kvm_pio, | |
37 | probe_kvm_pio, | |
38 | "pio_%s at 0x%x size %d count %d", | |
39 | rw ? "write" : "read", | |
40 | port, size, count); | |
41 | } | |
42 | ||
43 | void probe_kvm_cpuid(void *_data, unsigned int function, unsigned long rax, | |
44 | unsigned long rbx, unsigned long rcx, unsigned long rdx) | |
45 | { | |
46 | trace_mark_tp(kvm, kvm_cpuid, kvm_cpuid, | |
47 | probe_kvm_cpuid, | |
48 | "func %x rax %lx rbx %lx rcx %lx rdx %lx", | |
49 | function, rax, rbx, rcx, rdx); | |
50 | } | |
51 | ||
52 | void probe_kvm_apic (void *_data, unsigned int rw, unsigned int reg, | |
53 | unsigned int val) | |
54 | { | |
55 | trace_mark_tp(kvm, kvm_apic, kvm_apic, | |
56 | probe_kvm_apic, | |
57 | "apic_%s reg %d = 0x%x", | |
58 | rw ? "write" : "read", | |
59 | reg, val); | |
60 | } | |
61 | ||
62 | void probe_kvm_exit(void *_data, unsigned int exit_reason, struct kvm_vcpu *vcpu) | |
63 | { | |
64 | trace_mark_tp(kvm, kvm_exit, kvm_exit, | |
65 | probe_kvm_exit, | |
66 | "reason %d", | |
67 | exit_reason); | |
68 | } | |
69 | ||
70 | void probe_kvm_inj_virq(void *_data, unsigned int irq) | |
71 | { | |
72 | trace_mark_tp(kvm, kvm_inj_virq, kvm_inj_virq, | |
73 | probe_kvm_inj_virq, | |
74 | "irq %u", irq); | |
75 | } | |
76 | ||
77 | void probe_kvm_page_fault(void *_data, unsigned long fault_address, | |
78 | unsigned int error_code) | |
79 | { | |
80 | trace_mark_tp(kvm, kvm_page_fault, kvm_page_fault, | |
81 | probe_kvm_page_fault, | |
82 | "address %lx error_code %x", | |
83 | fault_address, error_code); | |
84 | } | |
85 | ||
86 | void probe_kvm_msr(void *_data, unsigned int rw, __u32 ecx, __u64 data, bool exception) | |
87 | { | |
88 | trace_mark_tp(kvm, kvm_msr, kvm_msr, | |
89 | probe_kvm_msr, | |
90 | "msr_%s %x = 0x%llx", | |
91 | rw ? "read" : "write", | |
92 | ecx, data); | |
93 | } | |
94 | ||
95 | void probe_kvm_cr(void *_data, unsigned int rw, unsigned int cr, unsigned long val) | |
96 | { | |
97 | trace_mark_tp(kvm, kvm_cr, kvm_cr, | |
98 | probe_kvm_cr, | |
99 | "cr_%s %x = 0x%lx", | |
100 | rw ? "read" : "write", | |
101 | cr, val); | |
102 | } | |
103 | ||
104 | void probe_kvm_pic_set_irq(void *_data, __u8 chip, __u8 pin, __u8 elcr, | |
105 | __u8 imr, bool coalesced) | |
106 | { | |
107 | trace_mark_tp(kvm, kvm_pic_set_irq, kvm_pic_set_irq, | |
108 | probe_kvm_pic_set_irq, | |
109 | "chip %u pin %u (%s%s)%s", | |
110 | chip, pin, | |
111 | (elcr & (1 << pin)) ? "level":"edge", | |
112 | (imr & (1 << pin)) ? "|masked":"", | |
113 | coalesced ? " (coalesced)" : ""); | |
114 | } | |
115 | ||
116 | void probe_kvm_apic_ipi(void *_data, __u32 icr_low, __u32 dest_id) | |
117 | { | |
118 | trace_mark_tp(kvm, kvm_apic_ipi, kvm_apic_ipi, | |
119 | probe_kvm_apic_ipi, | |
120 | "dst %x vec %u (%x|%s|%s|%s|%x)", | |
121 | dest_id, icr_low, | |
122 | icr_low >> 8 & 0x7, | |
123 | (icr_low & (1<<11)) ? "logical" : "physical", | |
124 | (icr_low & (1<<14)) ? "assert" : "de-assert", | |
125 | (icr_low & (1<<15)) ? "level" : "edge", | |
126 | icr_low >> 18 & 0x3); | |
127 | } | |
128 | ||
129 | void probe_kvm_apic_accept_irq(void *_data, __u32 apicid, __u16 dm, __u8 tm, | |
130 | __u8 vec, bool coalesced) | |
131 | { | |
132 | trace_mark_tp(kvm, kvm_apic_accept_irq, kvm_apic_accept_irq, | |
133 | probe_kvm_apic_accept_irq, | |
134 | "apicid %x vec %u (%x|%s)%s", | |
135 | apicid, vec, dm >> 8 & 0x7, | |
136 | tm ? "level" : "edge", | |
137 | coalesced ? " (coalesced)" : ""); | |
138 | } | |
139 | ||
140 | void probe_kvm_nested_vmrun(void *_data, __u64 rip, __u64 vmcb, __u64 nested_rip, | |
141 | __u32 int_ctl, __u32 event_inj, bool npt) | |
142 | { | |
143 | trace_mark_tp(kvm, kvm_nested_vmrun, kvm_nested_vmrun, | |
144 | probe_kvm_nested_vmrun, | |
145 | "rip 0x%Lx vmcb 0x%Lx nrip 0x%Lx int_ctl 0x%x " | |
146 | "event_inj 0x%x npt %s", | |
147 | (unsigned long long)rip, | |
148 | (unsigned long long)vmcb, | |
149 | (unsigned long long)nested_rip, | |
150 | int_ctl, event_inj, | |
151 | npt ? "on" : "off"); | |
152 | } | |
153 | ||
154 | void probe_kvm_nested_vmexit(void *_data, __u64 rip, __u32 exit_code, | |
155 | __u64 exit_info1, __u64 exit_info2, | |
156 | __u32 exit_int_info, __u32 exit_int_info_err) | |
157 | { | |
158 | trace_mark_tp(kvm, kvm_nested_vmexit, kvm_nested_vmexit, | |
159 | probe_kvm_nested_vmexit, | |
160 | "rip 0x%Lx reason %d ext_inf1 0x%Lx " | |
161 | "ext_inf2 0x%Lx ext_int 0x%x ext_int_err 0x%x", | |
162 | (unsigned long long)rip, | |
163 | exit_code, | |
164 | (unsigned long long)exit_info1, | |
165 | (unsigned long long)exit_info2, | |
166 | exit_int_info, exit_int_info_err); | |
167 | } | |
168 | ||
169 | void probe_kvm_nested_vmexit_inject(void *_data, __u32 exit_code, | |
170 | __u64 exit_info1, __u64 exit_info2, | |
171 | __u32 exit_int_info, __u32 exit_int_info_err) | |
172 | { | |
173 | trace_mark_tp(kvm, kvm_nested_vmexit_inject, kvm_nested_vmexit_inject, | |
174 | probe_kvm_nested_vmexit_inject, | |
175 | "reason %d ext_inf1 0x%Lx " | |
176 | "ext_inf2 0x%Lx ext_int 0x%x ext_int_err 0x%x", | |
177 | exit_code, | |
178 | (unsigned long long)exit_info1, | |
179 | (unsigned long long)exit_info2, | |
180 | exit_int_info, exit_int_info_err); | |
181 | } | |
182 | ||
183 | void probe_kvm_nested_intr_vmexit(void *_data, __u64 rip) | |
184 | { | |
185 | trace_mark_tp(kvm, kvm_nested_intr_vmexit, kvm_nested_intr_vmexit, | |
186 | probe_kvm_nested_intr_vmexit, | |
187 | "rip 0x%Lx", (unsigned long long)rip ); | |
188 | } | |
189 | ||
190 | void probe_kvm_invlpga(void *_data, __u64 rip, int asid, u64 address) | |
191 | { | |
192 | trace_mark_tp(kvm, kvm_invlpga, kvm_invlpga, | |
193 | probe_kvm_invlpga, | |
194 | "rip 0x%Lx asid %d address 0x%Lx", | |
195 | (unsigned long long)rip, | |
196 | asid, | |
197 | (unsigned long long)address); | |
198 | } | |
199 | ||
200 | void probe_kvm_skinit(void *_data, __u64 rip, __u32 slb) | |
201 | { | |
202 | trace_mark_tp(kvm, kvm_skinit, kvm_skinit, | |
203 | probe_kvm_skinit, | |
204 | "rip 0x%Lx slb 0x%x", | |
205 | (unsigned long long)rip, slb); | |
206 | } | |
207 | ||
208 | MODULE_LICENSE("GPL and additional rights"); | |
209 | MODULE_AUTHOR("Julien Desfossez"); | |
210 | MODULE_DESCRIPTION("KVM Tracepoint Probes"); |