aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2010-11-23 05:58:26 -0500
committerSteven Rostedt <rostedt@goodmis.org>2010-11-23 12:03:10 -0500
commit8cadc3e20fe7da3d49a8e2e57d6564bf4fff3dc8 (patch)
treead3f344125150f586e5a122612adf87036ffc5d5
parent112b5bb4a69dddf88a7d4607566e67ff80910083 (diff)
kvm: Parse svm exit reason
svm exit reasons use different code than vmx; use the new "isa" trace field to select the instruction set and display the strings accordingly. Signed-off-by: Avi Kivity <avi@redhat.com> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--plugin_kvm.c114
1 files changed, 107 insertions, 7 deletions
diff --git a/plugin_kvm.c b/plugin_kvm.c
index 724143d..c8e8b8c 100644
--- a/plugin_kvm.c
+++ b/plugin_kvm.c
@@ -120,6 +120,80 @@ static const char *disassemble(unsigned char *insn, int len, uint64_t rip,
120 _ER(EPT_MISCONFIG, 49) \ 120 _ER(EPT_MISCONFIG, 49) \
121 _ER(WBINVD, 54) 121 _ER(WBINVD, 54)
122 122
123#define SVM_EXIT_REASONS \
124 _ER(EXIT_READ_CR0, 0x000) \
125 _ER(EXIT_READ_CR3, 0x003) \
126 _ER(EXIT_READ_CR4, 0x004) \
127 _ER(EXIT_READ_CR8, 0x008) \
128 _ER(EXIT_WRITE_CR0, 0x010) \
129 _ER(EXIT_WRITE_CR3, 0x013) \
130 _ER(EXIT_WRITE_CR4, 0x014) \
131 _ER(EXIT_WRITE_CR8, 0x018) \
132 _ER(EXIT_READ_DR0, 0x020) \
133 _ER(EXIT_READ_DR1, 0x021) \
134 _ER(EXIT_READ_DR2, 0x022) \
135 _ER(EXIT_READ_DR3, 0x023) \
136 _ER(EXIT_READ_DR4, 0x024) \
137 _ER(EXIT_READ_DR5, 0x025) \
138 _ER(EXIT_READ_DR6, 0x026) \
139 _ER(EXIT_READ_DR7, 0x027) \
140 _ER(EXIT_WRITE_DR0, 0x030) \
141 _ER(EXIT_WRITE_DR1, 0x031) \
142 _ER(EXIT_WRITE_DR2, 0x032) \
143 _ER(EXIT_WRITE_DR3, 0x033) \
144 _ER(EXIT_WRITE_DR4, 0x034) \
145 _ER(EXIT_WRITE_DR5, 0x035) \
146 _ER(EXIT_WRITE_DR6, 0x036) \
147 _ER(EXIT_WRITE_DR7, 0x037) \
148 _ER(EXIT_EXCP_BASE, 0x040) \
149 _ER(EXIT_INTR, 0x060) \
150 _ER(EXIT_NMI, 0x061) \
151 _ER(EXIT_SMI, 0x062) \
152 _ER(EXIT_INIT, 0x063) \
153 _ER(EXIT_VINTR, 0x064) \
154 _ER(EXIT_CR0_SEL_WRITE, 0x065) \
155 _ER(EXIT_IDTR_READ, 0x066) \
156 _ER(EXIT_GDTR_READ, 0x067) \
157 _ER(EXIT_LDTR_READ, 0x068) \
158 _ER(EXIT_TR_READ, 0x069) \
159 _ER(EXIT_IDTR_WRITE, 0x06a) \
160 _ER(EXIT_GDTR_WRITE, 0x06b) \
161 _ER(EXIT_LDTR_WRITE, 0x06c) \
162 _ER(EXIT_TR_WRITE, 0x06d) \
163 _ER(EXIT_RDTSC, 0x06e) \
164 _ER(EXIT_RDPMC, 0x06f) \
165 _ER(EXIT_PUSHF, 0x070) \
166 _ER(EXIT_POPF, 0x071) \
167 _ER(EXIT_CPUID, 0x072) \
168 _ER(EXIT_RSM, 0x073) \
169 _ER(EXIT_IRET, 0x074) \
170 _ER(EXIT_SWINT, 0x075) \
171 _ER(EXIT_INVD, 0x076) \
172 _ER(EXIT_PAUSE, 0x077) \
173 _ER(EXIT_HLT, 0x078) \
174 _ER(EXIT_INVLPG, 0x079) \
175 _ER(EXIT_INVLPGA, 0x07a) \
176 _ER(EXIT_IOIO, 0x07b) \
177 _ER(EXIT_MSR, 0x07c) \
178 _ER(EXIT_TASK_SWITCH, 0x07d) \
179 _ER(EXIT_FERR_FREEZE, 0x07e) \
180 _ER(EXIT_SHUTDOWN, 0x07f) \
181 _ER(EXIT_VMRUN, 0x080) \
182 _ER(EXIT_VMMCALL, 0x081) \
183 _ER(EXIT_VMLOAD, 0x082) \
184 _ER(EXIT_VMSAVE, 0x083) \
185 _ER(EXIT_STGI, 0x084) \
186 _ER(EXIT_CLGI, 0x085) \
187 _ER(EXIT_SKINIT, 0x086) \
188 _ER(EXIT_RDTSCP, 0x087) \
189 _ER(EXIT_ICEBP, 0x088) \
190 _ER(EXIT_WBINVD, 0x089) \
191 _ER(EXIT_MONITOR, 0x08a) \
192 _ER(EXIT_MWAIT, 0x08b) \
193 _ER(EXIT_MWAIT_COND, 0x08c) \
194 _ER(EXIT_NPF, 0x400) \
195 _ER(EXIT_ERR, -1)
196
123#define _ER(reason, val) { #reason, val }, 197#define _ER(reason, val) { #reason, val },
124struct str_values { 198struct str_values {
125 const char *str; 199 const char *str;
@@ -131,27 +205,53 @@ static struct str_values vmx_exit_reasons[] = {
131 { NULL, -1} 205 { NULL, -1}
132}; 206};
133 207
134static const char *find_vmx_reason(int val) 208static struct str_values svm_exit_reasons[] = {
209 SVM_EXIT_REASONS
210 { NULL, -1}
211};
212
213static struct isa_exit_reasons {
214 unsigned isa;
215 struct str_values *strings;
216} isa_exit_reasons[] = {
217 { .isa = 1, .strings = vmx_exit_reasons },
218 { .isa = 2, .strings = svm_exit_reasons },
219 { }
220};
221
222static const char *find_exit_reason(unsigned isa, int val)
135{ 223{
224 struct str_values *strings = NULL;
136 int i; 225 int i;
137 226
138 for (i = 0; vmx_exit_reasons[i].val >= 0; i++) 227 for (i = 0; isa_exit_reasons[i].strings; ++i)
139 if (vmx_exit_reasons[i].val == val) 228 if (isa_exit_reasons[i].isa == isa) {
229 strings = isa_exit_reasons[i].strings;
140 break; 230 break;
141 if (vmx_exit_reasons[i].str) 231 }
142 return vmx_exit_reasons[i].str; 232 if (!strings)
233 return "UNKNOWN-ISA";
234 for (i = 0; strings[i].val >= 0; i++)
235 if (strings[i].val == val)
236 break;
237 if (strings[i].str)
238 return strings[i].str;
143 return "UNKOWN"; 239 return "UNKOWN";
144} 240}
145 241
146static int kvm_exit_handler(struct trace_seq *s, struct record *record, 242static int kvm_exit_handler(struct trace_seq *s, struct record *record,
147 struct event_format *event, void *context) 243 struct event_format *event, void *context)
148{ 244{
245 unsigned long long isa;
149 unsigned long long val; 246 unsigned long long val;
150 247
151 if (pevent_get_field_val(s, event, "exit_reason", record, &val, 1) < 0) 248 if (pevent_get_field_val(s, event, "exit_reason", record, &val, 1) < 0)
152 return -1; 249 return -1;
153 250
154 trace_seq_printf(s, "reason %s", find_vmx_reason(val)); 251 if (pevent_get_field_val(s, event, "isa", record, &isa, 1) < 0)
252 isa = 1;
253
254 trace_seq_printf(s, "reason %s", find_exit_reason(isa, val));
155 255
156 pevent_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1); 256 pevent_print_num_field(s, " rip 0x%lx", event, "guest_rip", record, 1);
157 257
@@ -213,7 +313,7 @@ static int kvm_nested_vmexit_inject_handler(struct trace_seq *s, struct record *
213 if (pevent_get_field_val(s, event, "exit_code", record, &val, 1) < 0) 313 if (pevent_get_field_val(s, event, "exit_code", record, &val, 1) < 0)
214 return -1; 314 return -1;
215 315
216 trace_seq_printf(s, "reason %s", find_vmx_reason(val)); 316 trace_seq_printf(s, "reason %s", find_exit_reason(2, val));
217 317
218 pevent_print_num_field(s, " ext_inf1: %0x016llx", event, "exit_info1", record, 1); 318 pevent_print_num_field(s, " ext_inf1: %0x016llx", event, "exit_info1", record, 1);
219 pevent_print_num_field(s, " ext_inf2: %0x016llx", event, "exit_info2", record, 1); 319 pevent_print_num_field(s, " ext_inf2: %0x016llx", event, "exit_info2", record, 1);