Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bhyvectl/amd64/bhyvectl_machdep.c
108736 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2011 NetApp, Inc.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/types.h>
30
#include <sys/mman.h>
31
32
#include <machine/cpufunc.h>
33
#include <machine/specialreg.h>
34
35
#include <err.h>
36
#include <fcntl.h>
37
#include <getopt.h>
38
#include <stdbool.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <string.h>
42
#include <time.h>
43
#include <unistd.h>
44
45
#include <vmmapi.h>
46
#include "amd/vmcb.h"
47
#include "intel/vmcs.h"
48
49
#include "bhyvectl.h"
50
51
enum {
52
SET_EFER = OPT_START_MD,
53
SET_CR0,
54
SET_CR2,
55
SET_CR3,
56
SET_CR4,
57
SET_DR0,
58
SET_DR1,
59
SET_DR2,
60
SET_DR3,
61
SET_DR6,
62
SET_DR7,
63
SET_RSP,
64
SET_RIP,
65
SET_RAX,
66
SET_RFLAGS,
67
DESC_BASE,
68
DESC_LIMIT,
69
DESC_ACCESS,
70
SET_CS,
71
SET_DS,
72
SET_ES,
73
SET_FS,
74
SET_GS,
75
SET_SS,
76
SET_TR,
77
SET_LDTR,
78
SET_X2APIC_STATE,
79
UNASSIGN_PPTDEV,
80
GET_GPA_PMAP,
81
ASSERT_LAPIC_LVT,
82
SET_RTC_TIME,
83
SET_RTC_NVRAM,
84
RTC_NVRAM_OFFSET,
85
};
86
87
static int get_rtc_time, set_rtc_time;
88
static int get_rtc_nvram, set_rtc_nvram;
89
static int rtc_nvram_offset;
90
static uint8_t rtc_nvram_value;
91
static time_t rtc_secs;
92
static int get_gpa_pmap;
93
static vm_paddr_t gpa_pmap;
94
static int inject_nmi, assert_lapic_lvt = -1;
95
static int get_intinfo;
96
static int set_cr0, get_cr0, set_cr2, get_cr2, set_cr3, get_cr3;
97
static int set_cr4, get_cr4;
98
static uint64_t set_cr0_val, set_cr2_val, set_cr3_val, set_cr4_val;
99
static int set_efer, get_efer;
100
static uint64_t set_efer_val;
101
static int set_dr0, get_dr0;
102
static int set_dr1, get_dr1;
103
static int set_dr2, get_dr2;
104
static int set_dr3, get_dr3;
105
static int set_dr6, get_dr6;
106
static int set_dr7, get_dr7;
107
static uint64_t set_dr0_val, set_dr1_val, set_dr2_val, set_dr3_val, set_dr6_val;
108
static uint64_t set_dr7_val;
109
static int set_rsp, get_rsp, set_rip, get_rip, set_rflags, get_rflags;
110
static int set_rax, get_rax;
111
static uint64_t set_rsp_val, set_rip_val, set_rflags_val, set_rax_val;
112
static int get_rbx, get_rcx, get_rdx, get_rsi, get_rdi, get_rbp;
113
static int get_r8, get_r9, get_r10, get_r11, get_r12, get_r13, get_r14, get_r15;
114
static int set_desc_ds, get_desc_ds;
115
static int set_desc_es, get_desc_es;
116
static int set_desc_fs, get_desc_fs;
117
static int set_desc_gs, get_desc_gs;
118
static int set_desc_cs, get_desc_cs;
119
static int set_desc_ss, get_desc_ss;
120
static int set_desc_gdtr, get_desc_gdtr;
121
static int set_desc_idtr, get_desc_idtr;
122
static int set_desc_tr, get_desc_tr;
123
static int set_desc_ldtr, get_desc_ldtr;
124
static int set_cs, set_ds, set_es, set_fs, set_gs, set_ss, set_tr, set_ldtr;
125
static int get_cs, get_ds, get_es, get_fs, get_gs, get_ss, get_tr, get_ldtr;
126
static uint64_t set_cs_val, set_ds_val, set_es_val, set_fs_val, set_gs_val;
127
static uint64_t set_ss_val, set_tr_val, set_ldtr_val;
128
static int set_x2apic_state, get_x2apic_state;
129
static enum x2apic_state x2apic_state;
130
static int unassign_pptdev, bus, slot, func;
131
132
static uint64_t desc_base;
133
static uint32_t desc_limit, desc_access;
134
135
/*
136
* VMCB specific.
137
*/
138
static int get_vmcb_intercept, get_vmcb_exit_details, get_vmcb_tlb_ctrl;
139
static int get_vmcb_virq, get_avic_table;
140
141
/*
142
* VMCS-specific fields
143
*/
144
static int get_pinbased_ctls, get_procbased_ctls, get_procbased_ctls2;
145
static int get_eptp, get_io_bitmap, get_tsc_offset;
146
static int get_vmcs_entry_interruption_info;
147
static int get_vmcs_interruptibility;
148
static int get_vmcs_gpa, get_vmcs_gla;
149
static int get_exception_bitmap;
150
static int get_cr0_mask, get_cr0_shadow;
151
static int get_cr4_mask, get_cr4_shadow;
152
static int get_cr3_targets;
153
static int get_apic_access_addr, get_virtual_apic_addr, get_tpr_threshold;
154
static int get_msr_bitmap, get_msr_bitmap_address;
155
static int get_vpid_asid;
156
static int get_inst_err, get_exit_ctls, get_entry_ctls;
157
static int get_host_cr0, get_host_cr3, get_host_cr4;
158
static int get_host_rip, get_host_rsp;
159
static int get_guest_pat, get_host_pat;
160
static int get_guest_sysenter, get_vmcs_link;
161
static int get_exit_reason, get_vmcs_exit_qualification;
162
static int get_vmcs_exit_interruption_info, get_vmcs_exit_interruption_error;
163
static int get_vmcs_exit_inst_length;
164
165
static bool
166
cpu_vendor_intel(void)
167
{
168
u_int regs[4], v[3];
169
170
do_cpuid(0, regs);
171
v[0] = regs[1];
172
v[1] = regs[3];
173
v[2] = regs[2];
174
175
if (memcmp(v, "GenuineIntel", sizeof(v)) == 0)
176
return (true);
177
if (memcmp(v, "AuthenticAMD", sizeof(v)) == 0 ||
178
memcmp(v, "HygonGenuine", sizeof(v)) == 0)
179
return (false);
180
fprintf(stderr, "Unknown cpu vendor \"%s\"\n", (const char *)v);
181
exit(1);
182
}
183
184
void
185
bhyvectl_dump_vm_run_exitcode(struct vm_exit *vmexit, int vcpu)
186
{
187
printf("vm exit[%d]\n", vcpu);
188
printf("\trip\t\t0x%016lx\n", vmexit->rip);
189
printf("\tinst_length\t%d\n", vmexit->inst_length);
190
switch (vmexit->exitcode) {
191
case VM_EXITCODE_INOUT:
192
printf("\treason\t\tINOUT\n");
193
printf("\tdirection\t%s\n", vmexit->u.inout.in ? "IN" : "OUT");
194
printf("\tbytes\t\t%d\n", vmexit->u.inout.bytes);
195
printf("\tflags\t\t%s%s\n",
196
vmexit->u.inout.string ? "STRING " : "",
197
vmexit->u.inout.rep ? "REP " : "");
198
printf("\tport\t\t0x%04x\n", vmexit->u.inout.port);
199
printf("\teax\t\t0x%08x\n", vmexit->u.inout.eax);
200
break;
201
case VM_EXITCODE_VMX:
202
printf("\treason\t\tVMX\n");
203
printf("\tstatus\t\t%d\n", vmexit->u.vmx.status);
204
printf("\texit_reason\t0x%08x (%u)\n",
205
vmexit->u.vmx.exit_reason, vmexit->u.vmx.exit_reason);
206
printf("\tqualification\t0x%016lx\n",
207
vmexit->u.vmx.exit_qualification);
208
printf("\tinst_type\t\t%d\n", vmexit->u.vmx.inst_type);
209
printf("\tinst_error\t\t%d\n", vmexit->u.vmx.inst_error);
210
break;
211
case VM_EXITCODE_SVM:
212
printf("\treason\t\tSVM\n");
213
printf("\texit_reason\t\t%#lx\n", vmexit->u.svm.exitcode);
214
printf("\texitinfo1\t\t%#lx\n", vmexit->u.svm.exitinfo1);
215
printf("\texitinfo2\t\t%#lx\n", vmexit->u.svm.exitinfo2);
216
break;
217
default:
218
printf("*** unknown vm run exitcode %d\n", vmexit->exitcode);
219
break;
220
}
221
}
222
223
static const char *
224
wday_str(int idx)
225
{
226
static const char *weekdays[] = {
227
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
228
};
229
230
if (idx >= 0 && idx < 7)
231
return (weekdays[idx]);
232
else
233
return ("UNK");
234
}
235
236
static const char *
237
mon_str(int idx)
238
{
239
static const char *months[] = {
240
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
241
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
242
};
243
244
if (idx >= 0 && idx < 12)
245
return (months[idx]);
246
else
247
return ("UNK");
248
}
249
250
static void
251
print_intinfo(const char *banner, uint64_t info)
252
{
253
int type;
254
255
printf("%s:\t", banner);
256
if (info & VM_INTINFO_VALID) {
257
type = info & VM_INTINFO_TYPE;
258
switch (type) {
259
case VM_INTINFO_HWINTR:
260
printf("extint");
261
break;
262
case VM_INTINFO_NMI:
263
printf("nmi");
264
break;
265
case VM_INTINFO_SWINTR:
266
printf("swint");
267
break;
268
default:
269
printf("exception");
270
break;
271
}
272
printf(" vector %d", (int)VM_INTINFO_VECTOR(info));
273
if (info & VM_INTINFO_DEL_ERRCODE)
274
printf(" errcode %#x", (u_int)(info >> 32));
275
} else {
276
printf("n/a");
277
}
278
printf("\n");
279
}
280
281
/* AMD 6th generation and Intel compatible MSRs */
282
#define MSR_AMD6TH_START 0xC0000000
283
#define MSR_AMD6TH_END 0xC0001FFF
284
/* AMD 7th and 8th generation compatible MSRs */
285
#define MSR_AMD7TH_START 0xC0010000
286
#define MSR_AMD7TH_END 0xC0011FFF
287
288
static const char *
289
msr_name(uint32_t msr)
290
{
291
static char buf[32];
292
293
switch (msr) {
294
case MSR_TSC:
295
return ("MSR_TSC");
296
case MSR_EFER:
297
return ("MSR_EFER");
298
case MSR_STAR:
299
return ("MSR_STAR");
300
case MSR_LSTAR:
301
return ("MSR_LSTAR");
302
case MSR_CSTAR:
303
return ("MSR_CSTAR");
304
case MSR_SF_MASK:
305
return ("MSR_SF_MASK");
306
case MSR_FSBASE:
307
return ("MSR_FSBASE");
308
case MSR_GSBASE:
309
return ("MSR_GSBASE");
310
case MSR_KGSBASE:
311
return ("MSR_KGSBASE");
312
case MSR_SYSENTER_CS_MSR:
313
return ("MSR_SYSENTER_CS_MSR");
314
case MSR_SYSENTER_ESP_MSR:
315
return ("MSR_SYSENTER_ESP_MSR");
316
case MSR_SYSENTER_EIP_MSR:
317
return ("MSR_SYSENTER_EIP_MSR");
318
case MSR_PAT:
319
return ("MSR_PAT");
320
}
321
snprintf(buf, sizeof(buf), "MSR %#08x", msr);
322
323
return (buf);
324
}
325
326
static inline void
327
print_msr_pm(uint64_t msr, int vcpu, int readable, int writeable)
328
{
329
330
if (readable || writeable) {
331
printf("%-20s[%d]\t\t%c%c\n", msr_name(msr), vcpu,
332
readable ? 'R' : '-', writeable ? 'W' : '-');
333
}
334
}
335
336
/*
337
* Reference APM vol2, section 15.11 MSR Intercepts.
338
*/
339
static void
340
dump_amd_msr_pm(const char *bitmap, int vcpu)
341
{
342
int byte, bit, readable, writeable;
343
uint32_t msr;
344
345
for (msr = 0; msr < 0x2000; msr++) {
346
byte = msr / 4;
347
bit = (msr % 4) * 2;
348
349
/* Look at MSRs in the range 0x00000000 to 0x00001FFF */
350
readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
351
writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1;
352
print_msr_pm(msr, vcpu, readable, writeable);
353
354
/* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */
355
byte += 2048;
356
readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
357
writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1;
358
print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable,
359
writeable);
360
361
/* MSR 0xC0010000 to 0xC0011FF is only for AMD */
362
byte += 4096;
363
readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
364
writeable = (bitmap[byte] & (2 << bit)) ? 0 : 1;
365
print_msr_pm(msr + MSR_AMD7TH_START, vcpu, readable,
366
writeable);
367
}
368
}
369
370
/*
371
* Reference Intel SDM Vol3 Section 24.6.9 MSR-Bitmap Address
372
*/
373
static void
374
dump_intel_msr_pm(const char *bitmap, int vcpu)
375
{
376
int byte, bit, readable, writeable;
377
uint32_t msr;
378
379
for (msr = 0; msr < 0x2000; msr++) {
380
byte = msr / 8;
381
bit = msr & 0x7;
382
383
/* Look at MSRs in the range 0x00000000 to 0x00001FFF */
384
readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
385
writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1;
386
print_msr_pm(msr, vcpu, readable, writeable);
387
388
/* Look at MSRs in the range 0xC0000000 to 0xC0001FFF */
389
byte += 1024;
390
readable = (bitmap[byte] & (1 << bit)) ? 0 : 1;
391
writeable = (bitmap[2048 + byte] & (1 << bit)) ? 0 : 1;
392
print_msr_pm(msr + MSR_AMD6TH_START, vcpu, readable,
393
writeable);
394
}
395
}
396
397
static int
398
dump_msr_bitmap(int vcpu, uint64_t addr, bool cpu_intel)
399
{
400
char *bitmap;
401
int error, fd, map_size;
402
403
error = -1;
404
bitmap = MAP_FAILED;
405
406
fd = open("/dev/mem", O_RDONLY, 0);
407
if (fd < 0) {
408
perror("Couldn't open /dev/mem");
409
goto done;
410
}
411
412
if (cpu_intel)
413
map_size = PAGE_SIZE;
414
else
415
map_size = 2 * PAGE_SIZE;
416
417
bitmap = mmap(NULL, map_size, PROT_READ, MAP_SHARED, fd, addr);
418
if (bitmap == MAP_FAILED) {
419
perror("mmap failed");
420
goto done;
421
}
422
423
if (cpu_intel)
424
dump_intel_msr_pm(bitmap, vcpu);
425
else
426
dump_amd_msr_pm(bitmap, vcpu);
427
428
error = 0;
429
done:
430
if (bitmap != MAP_FAILED)
431
munmap((void *)bitmap, map_size);
432
if (fd >= 0)
433
close(fd);
434
435
return (error);
436
}
437
438
static int
439
vm_get_vmcs_field(struct vcpu *vcpu, int field, uint64_t *ret_val)
440
{
441
442
return (vm_get_register(vcpu, VMCS_IDENT(field), ret_val));
443
}
444
445
static int
446
vm_get_vmcb_field(struct vcpu *vcpu, int off, int bytes,
447
uint64_t *ret_val)
448
{
449
450
return (vm_get_register(vcpu, VMCB_ACCESS(off, bytes), ret_val));
451
}
452
453
static int
454
get_all_registers(struct vcpu *vcpu, int vcpuid, bool get_all)
455
{
456
uint64_t cr0, cr2, cr3, cr4, dr0, dr1, dr2, dr3, dr6, dr7;
457
uint64_t rsp, rip, rflags, efer;
458
uint64_t rax, rbx, rcx, rdx, rsi, rdi, rbp;
459
uint64_t r8, r9, r10, r11, r12, r13, r14, r15;
460
int error = 0;
461
462
if (!error && (get_efer || get_all)) {
463
error = vm_get_register(vcpu, VM_REG_GUEST_EFER, &efer);
464
if (error == 0)
465
printf("efer[%d]\t\t0x%016lx\n", vcpuid, efer);
466
}
467
468
if (!error && (get_cr0 || get_all)) {
469
error = vm_get_register(vcpu, VM_REG_GUEST_CR0, &cr0);
470
if (error == 0)
471
printf("cr0[%d]\t\t0x%016lx\n", vcpuid, cr0);
472
}
473
474
if (!error && (get_cr2 || get_all)) {
475
error = vm_get_register(vcpu, VM_REG_GUEST_CR2, &cr2);
476
if (error == 0)
477
printf("cr2[%d]\t\t0x%016lx\n", vcpuid, cr2);
478
}
479
480
if (!error && (get_cr3 || get_all)) {
481
error = vm_get_register(vcpu, VM_REG_GUEST_CR3, &cr3);
482
if (error == 0)
483
printf("cr3[%d]\t\t0x%016lx\n", vcpuid, cr3);
484
}
485
486
if (!error && (get_cr4 || get_all)) {
487
error = vm_get_register(vcpu, VM_REG_GUEST_CR4, &cr4);
488
if (error == 0)
489
printf("cr4[%d]\t\t0x%016lx\n", vcpuid, cr4);
490
}
491
492
if (!error && (get_dr0 || get_all)) {
493
error = vm_get_register(vcpu, VM_REG_GUEST_DR0, &dr0);
494
if (error == 0)
495
printf("dr0[%d]\t\t0x%016lx\n", vcpuid, dr0);
496
}
497
498
if (!error && (get_dr1 || get_all)) {
499
error = vm_get_register(vcpu, VM_REG_GUEST_DR1, &dr1);
500
if (error == 0)
501
printf("dr1[%d]\t\t0x%016lx\n", vcpuid, dr1);
502
}
503
504
if (!error && (get_dr2 || get_all)) {
505
error = vm_get_register(vcpu, VM_REG_GUEST_DR2, &dr2);
506
if (error == 0)
507
printf("dr2[%d]\t\t0x%016lx\n", vcpuid, dr2);
508
}
509
510
if (!error && (get_dr3 || get_all)) {
511
error = vm_get_register(vcpu, VM_REG_GUEST_DR3, &dr3);
512
if (error == 0)
513
printf("dr3[%d]\t\t0x%016lx\n", vcpuid, dr3);
514
}
515
516
if (!error && (get_dr6 || get_all)) {
517
error = vm_get_register(vcpu, VM_REG_GUEST_DR6, &dr6);
518
if (error == 0)
519
printf("dr6[%d]\t\t0x%016lx\n", vcpuid, dr6);
520
}
521
522
if (!error && (get_dr7 || get_all)) {
523
error = vm_get_register(vcpu, VM_REG_GUEST_DR7, &dr7);
524
if (error == 0)
525
printf("dr7[%d]\t\t0x%016lx\n", vcpuid, dr7);
526
}
527
528
if (!error && (get_rsp || get_all)) {
529
error = vm_get_register(vcpu, VM_REG_GUEST_RSP, &rsp);
530
if (error == 0)
531
printf("rsp[%d]\t\t0x%016lx\n", vcpuid, rsp);
532
}
533
534
if (!error && (get_rip || get_all)) {
535
error = vm_get_register(vcpu, VM_REG_GUEST_RIP, &rip);
536
if (error == 0)
537
printf("rip[%d]\t\t0x%016lx\n", vcpuid, rip);
538
}
539
540
if (!error && (get_rax || get_all)) {
541
error = vm_get_register(vcpu, VM_REG_GUEST_RAX, &rax);
542
if (error == 0)
543
printf("rax[%d]\t\t0x%016lx\n", vcpuid, rax);
544
}
545
546
if (!error && (get_rbx || get_all)) {
547
error = vm_get_register(vcpu, VM_REG_GUEST_RBX, &rbx);
548
if (error == 0)
549
printf("rbx[%d]\t\t0x%016lx\n", vcpuid, rbx);
550
}
551
552
if (!error && (get_rcx || get_all)) {
553
error = vm_get_register(vcpu, VM_REG_GUEST_RCX, &rcx);
554
if (error == 0)
555
printf("rcx[%d]\t\t0x%016lx\n", vcpuid, rcx);
556
}
557
558
if (!error && (get_rdx || get_all)) {
559
error = vm_get_register(vcpu, VM_REG_GUEST_RDX, &rdx);
560
if (error == 0)
561
printf("rdx[%d]\t\t0x%016lx\n", vcpuid, rdx);
562
}
563
564
if (!error && (get_rsi || get_all)) {
565
error = vm_get_register(vcpu, VM_REG_GUEST_RSI, &rsi);
566
if (error == 0)
567
printf("rsi[%d]\t\t0x%016lx\n", vcpuid, rsi);
568
}
569
570
if (!error && (get_rdi || get_all)) {
571
error = vm_get_register(vcpu, VM_REG_GUEST_RDI, &rdi);
572
if (error == 0)
573
printf("rdi[%d]\t\t0x%016lx\n", vcpuid, rdi);
574
}
575
576
if (!error && (get_rbp || get_all)) {
577
error = vm_get_register(vcpu, VM_REG_GUEST_RBP, &rbp);
578
if (error == 0)
579
printf("rbp[%d]\t\t0x%016lx\n", vcpuid, rbp);
580
}
581
582
if (!error && (get_r8 || get_all)) {
583
error = vm_get_register(vcpu, VM_REG_GUEST_R8, &r8);
584
if (error == 0)
585
printf("r8[%d]\t\t0x%016lx\n", vcpuid, r8);
586
}
587
588
if (!error && (get_r9 || get_all)) {
589
error = vm_get_register(vcpu, VM_REG_GUEST_R9, &r9);
590
if (error == 0)
591
printf("r9[%d]\t\t0x%016lx\n", vcpuid, r9);
592
}
593
594
if (!error && (get_r10 || get_all)) {
595
error = vm_get_register(vcpu, VM_REG_GUEST_R10, &r10);
596
if (error == 0)
597
printf("r10[%d]\t\t0x%016lx\n", vcpuid, r10);
598
}
599
600
if (!error && (get_r11 || get_all)) {
601
error = vm_get_register(vcpu, VM_REG_GUEST_R11, &r11);
602
if (error == 0)
603
printf("r11[%d]\t\t0x%016lx\n", vcpuid, r11);
604
}
605
606
if (!error && (get_r12 || get_all)) {
607
error = vm_get_register(vcpu, VM_REG_GUEST_R12, &r12);
608
if (error == 0)
609
printf("r12[%d]\t\t0x%016lx\n", vcpuid, r12);
610
}
611
612
if (!error && (get_r13 || get_all)) {
613
error = vm_get_register(vcpu, VM_REG_GUEST_R13, &r13);
614
if (error == 0)
615
printf("r13[%d]\t\t0x%016lx\n", vcpuid, r13);
616
}
617
618
if (!error && (get_r14 || get_all)) {
619
error = vm_get_register(vcpu, VM_REG_GUEST_R14, &r14);
620
if (error == 0)
621
printf("r14[%d]\t\t0x%016lx\n", vcpuid, r14);
622
}
623
624
if (!error && (get_r15 || get_all)) {
625
error = vm_get_register(vcpu, VM_REG_GUEST_R15, &r15);
626
if (error == 0)
627
printf("r15[%d]\t\t0x%016lx\n", vcpuid, r15);
628
}
629
630
if (!error && (get_rflags || get_all)) {
631
error = vm_get_register(vcpu, VM_REG_GUEST_RFLAGS,
632
&rflags);
633
if (error == 0)
634
printf("rflags[%d]\t0x%016lx\n", vcpuid, rflags);
635
}
636
637
return (error);
638
}
639
640
static int
641
get_all_segments(struct vcpu *vcpu, int vcpuid, bool get_all)
642
{
643
uint64_t cs, ds, es, fs, gs, ss, tr, ldtr;
644
int error = 0;
645
646
if (!error && (get_desc_ds || get_all)) {
647
error = vm_get_desc(vcpu, VM_REG_GUEST_DS,
648
&desc_base, &desc_limit, &desc_access);
649
if (error == 0) {
650
printf("ds desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
651
vcpuid, desc_base, desc_limit, desc_access);
652
}
653
}
654
655
if (!error && (get_desc_es || get_all)) {
656
error = vm_get_desc(vcpu, VM_REG_GUEST_ES,
657
&desc_base, &desc_limit, &desc_access);
658
if (error == 0) {
659
printf("es desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
660
vcpuid, desc_base, desc_limit, desc_access);
661
}
662
}
663
664
if (!error && (get_desc_fs || get_all)) {
665
error = vm_get_desc(vcpu, VM_REG_GUEST_FS,
666
&desc_base, &desc_limit, &desc_access);
667
if (error == 0) {
668
printf("fs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
669
vcpuid, desc_base, desc_limit, desc_access);
670
}
671
}
672
673
if (!error && (get_desc_gs || get_all)) {
674
error = vm_get_desc(vcpu, VM_REG_GUEST_GS,
675
&desc_base, &desc_limit, &desc_access);
676
if (error == 0) {
677
printf("gs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
678
vcpuid, desc_base, desc_limit, desc_access);
679
}
680
}
681
682
if (!error && (get_desc_ss || get_all)) {
683
error = vm_get_desc(vcpu, VM_REG_GUEST_SS,
684
&desc_base, &desc_limit, &desc_access);
685
if (error == 0) {
686
printf("ss desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
687
vcpuid, desc_base, desc_limit, desc_access);
688
}
689
}
690
691
if (!error && (get_desc_cs || get_all)) {
692
error = vm_get_desc(vcpu, VM_REG_GUEST_CS,
693
&desc_base, &desc_limit, &desc_access);
694
if (error == 0) {
695
printf("cs desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
696
vcpuid, desc_base, desc_limit, desc_access);
697
}
698
}
699
700
if (!error && (get_desc_tr || get_all)) {
701
error = vm_get_desc(vcpu, VM_REG_GUEST_TR,
702
&desc_base, &desc_limit, &desc_access);
703
if (error == 0) {
704
printf("tr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
705
vcpuid, desc_base, desc_limit, desc_access);
706
}
707
}
708
709
if (!error && (get_desc_ldtr || get_all)) {
710
error = vm_get_desc(vcpu, VM_REG_GUEST_LDTR,
711
&desc_base, &desc_limit, &desc_access);
712
if (error == 0) {
713
printf("ldtr desc[%d]\t0x%016lx/0x%08x/0x%08x\n",
714
vcpuid, desc_base, desc_limit, desc_access);
715
}
716
}
717
718
if (!error && (get_desc_gdtr || get_all)) {
719
error = vm_get_desc(vcpu, VM_REG_GUEST_GDTR,
720
&desc_base, &desc_limit, &desc_access);
721
if (error == 0) {
722
printf("gdtr[%d]\t\t0x%016lx/0x%08x\n",
723
vcpuid, desc_base, desc_limit);
724
}
725
}
726
727
if (!error && (get_desc_idtr || get_all)) {
728
error = vm_get_desc(vcpu, VM_REG_GUEST_IDTR,
729
&desc_base, &desc_limit, &desc_access);
730
if (error == 0) {
731
printf("idtr[%d]\t\t0x%016lx/0x%08x\n",
732
vcpuid, desc_base, desc_limit);
733
}
734
}
735
736
if (!error && (get_cs || get_all)) {
737
error = vm_get_register(vcpu, VM_REG_GUEST_CS, &cs);
738
if (error == 0)
739
printf("cs[%d]\t\t0x%04lx\n", vcpuid, cs);
740
}
741
742
if (!error && (get_ds || get_all)) {
743
error = vm_get_register(vcpu, VM_REG_GUEST_DS, &ds);
744
if (error == 0)
745
printf("ds[%d]\t\t0x%04lx\n", vcpuid, ds);
746
}
747
748
if (!error && (get_es || get_all)) {
749
error = vm_get_register(vcpu, VM_REG_GUEST_ES, &es);
750
if (error == 0)
751
printf("es[%d]\t\t0x%04lx\n", vcpuid, es);
752
}
753
754
if (!error && (get_fs || get_all)) {
755
error = vm_get_register(vcpu, VM_REG_GUEST_FS, &fs);
756
if (error == 0)
757
printf("fs[%d]\t\t0x%04lx\n", vcpuid, fs);
758
}
759
760
if (!error && (get_gs || get_all)) {
761
error = vm_get_register(vcpu, VM_REG_GUEST_GS, &gs);
762
if (error == 0)
763
printf("gs[%d]\t\t0x%04lx\n", vcpuid, gs);
764
}
765
766
if (!error && (get_ss || get_all)) {
767
error = vm_get_register(vcpu, VM_REG_GUEST_SS, &ss);
768
if (error == 0)
769
printf("ss[%d]\t\t0x%04lx\n", vcpuid, ss);
770
}
771
772
if (!error && (get_tr || get_all)) {
773
error = vm_get_register(vcpu, VM_REG_GUEST_TR, &tr);
774
if (error == 0)
775
printf("tr[%d]\t\t0x%04lx\n", vcpuid, tr);
776
}
777
778
if (!error && (get_ldtr || get_all)) {
779
error = vm_get_register(vcpu, VM_REG_GUEST_LDTR, &ldtr);
780
if (error == 0)
781
printf("ldtr[%d]\t\t0x%04lx\n", vcpuid, ldtr);
782
}
783
784
return (error);
785
}
786
787
static int
788
get_misc_vmcs(struct vcpu *vcpu, int vcpuid, bool get_all)
789
{
790
uint64_t ctl, cr0, cr3, cr4, rsp, rip, pat, addr, u64;
791
int error = 0;
792
793
if (!error && (get_cr0_mask || get_all)) {
794
uint64_t cr0mask;
795
error = vm_get_vmcs_field(vcpu, VMCS_CR0_MASK, &cr0mask);
796
if (error == 0)
797
printf("cr0_mask[%d]\t\t0x%016lx\n", vcpuid, cr0mask);
798
}
799
800
if (!error && (get_cr0_shadow || get_all)) {
801
uint64_t cr0shadow;
802
error = vm_get_vmcs_field(vcpu, VMCS_CR0_SHADOW,
803
&cr0shadow);
804
if (error == 0)
805
printf("cr0_shadow[%d]\t\t0x%016lx\n", vcpuid, cr0shadow);
806
}
807
808
if (!error && (get_cr4_mask || get_all)) {
809
uint64_t cr4mask;
810
error = vm_get_vmcs_field(vcpu, VMCS_CR4_MASK, &cr4mask);
811
if (error == 0)
812
printf("cr4_mask[%d]\t\t0x%016lx\n", vcpuid, cr4mask);
813
}
814
815
if (!error && (get_cr4_shadow || get_all)) {
816
uint64_t cr4shadow;
817
error = vm_get_vmcs_field(vcpu, VMCS_CR4_SHADOW,
818
&cr4shadow);
819
if (error == 0)
820
printf("cr4_shadow[%d]\t\t0x%016lx\n", vcpuid, cr4shadow);
821
}
822
823
if (!error && (get_cr3_targets || get_all)) {
824
uint64_t target_count, target_addr;
825
error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET_COUNT,
826
&target_count);
827
if (error == 0) {
828
printf("cr3_target_count[%d]\t0x%016lx\n",
829
vcpuid, target_count);
830
}
831
832
error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET0,
833
&target_addr);
834
if (error == 0) {
835
printf("cr3_target0[%d]\t\t0x%016lx\n",
836
vcpuid, target_addr);
837
}
838
839
error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET1,
840
&target_addr);
841
if (error == 0) {
842
printf("cr3_target1[%d]\t\t0x%016lx\n",
843
vcpuid, target_addr);
844
}
845
846
error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET2,
847
&target_addr);
848
if (error == 0) {
849
printf("cr3_target2[%d]\t\t0x%016lx\n",
850
vcpuid, target_addr);
851
}
852
853
error = vm_get_vmcs_field(vcpu, VMCS_CR3_TARGET3,
854
&target_addr);
855
if (error == 0) {
856
printf("cr3_target3[%d]\t\t0x%016lx\n",
857
vcpuid, target_addr);
858
}
859
}
860
861
if (!error && (get_pinbased_ctls || get_all)) {
862
error = vm_get_vmcs_field(vcpu, VMCS_PIN_BASED_CTLS, &ctl);
863
if (error == 0)
864
printf("pinbased_ctls[%d]\t0x%016lx\n", vcpuid, ctl);
865
}
866
867
if (!error && (get_procbased_ctls || get_all)) {
868
error = vm_get_vmcs_field(vcpu,
869
VMCS_PRI_PROC_BASED_CTLS, &ctl);
870
if (error == 0)
871
printf("procbased_ctls[%d]\t0x%016lx\n", vcpuid, ctl);
872
}
873
874
if (!error && (get_procbased_ctls2 || get_all)) {
875
error = vm_get_vmcs_field(vcpu,
876
VMCS_SEC_PROC_BASED_CTLS, &ctl);
877
if (error == 0)
878
printf("procbased_ctls2[%d]\t0x%016lx\n", vcpuid, ctl);
879
}
880
881
if (!error && (get_vmcs_gla || get_all)) {
882
error = vm_get_vmcs_field(vcpu,
883
VMCS_GUEST_LINEAR_ADDRESS, &u64);
884
if (error == 0)
885
printf("gla[%d]\t\t0x%016lx\n", vcpuid, u64);
886
}
887
888
if (!error && (get_vmcs_gpa || get_all)) {
889
error = vm_get_vmcs_field(vcpu,
890
VMCS_GUEST_PHYSICAL_ADDRESS, &u64);
891
if (error == 0)
892
printf("gpa[%d]\t\t0x%016lx\n", vcpuid, u64);
893
}
894
895
if (!error && (get_vmcs_entry_interruption_info ||
896
get_all)) {
897
error = vm_get_vmcs_field(vcpu, VMCS_ENTRY_INTR_INFO,&u64);
898
if (error == 0) {
899
printf("entry_interruption_info[%d]\t0x%016lx\n",
900
vcpuid, u64);
901
}
902
}
903
904
if (!error && (get_tpr_threshold || get_all)) {
905
uint64_t threshold;
906
error = vm_get_vmcs_field(vcpu, VMCS_TPR_THRESHOLD,
907
&threshold);
908
if (error == 0)
909
printf("tpr_threshold[%d]\t0x%016lx\n", vcpuid, threshold);
910
}
911
912
if (!error && (get_inst_err || get_all)) {
913
uint64_t insterr;
914
error = vm_get_vmcs_field(vcpu, VMCS_INSTRUCTION_ERROR,
915
&insterr);
916
if (error == 0) {
917
printf("instruction_error[%d]\t0x%016lx\n",
918
vcpuid, insterr);
919
}
920
}
921
922
if (!error && (get_exit_ctls || get_all)) {
923
error = vm_get_vmcs_field(vcpu, VMCS_EXIT_CTLS, &ctl);
924
if (error == 0)
925
printf("exit_ctls[%d]\t\t0x%016lx\n", vcpuid, ctl);
926
}
927
928
if (!error && (get_entry_ctls || get_all)) {
929
error = vm_get_vmcs_field(vcpu, VMCS_ENTRY_CTLS, &ctl);
930
if (error == 0)
931
printf("entry_ctls[%d]\t\t0x%016lx\n", vcpuid, ctl);
932
}
933
934
if (!error && (get_host_pat || get_all)) {
935
error = vm_get_vmcs_field(vcpu, VMCS_HOST_IA32_PAT, &pat);
936
if (error == 0)
937
printf("host_pat[%d]\t\t0x%016lx\n", vcpuid, pat);
938
}
939
940
if (!error && (get_host_cr0 || get_all)) {
941
error = vm_get_vmcs_field(vcpu, VMCS_HOST_CR0, &cr0);
942
if (error == 0)
943
printf("host_cr0[%d]\t\t0x%016lx\n", vcpuid, cr0);
944
}
945
946
if (!error && (get_host_cr3 || get_all)) {
947
error = vm_get_vmcs_field(vcpu, VMCS_HOST_CR3, &cr3);
948
if (error == 0)
949
printf("host_cr3[%d]\t\t0x%016lx\n", vcpuid, cr3);
950
}
951
952
if (!error && (get_host_cr4 || get_all)) {
953
error = vm_get_vmcs_field(vcpu, VMCS_HOST_CR4, &cr4);
954
if (error == 0)
955
printf("host_cr4[%d]\t\t0x%016lx\n", vcpuid, cr4);
956
}
957
958
if (!error && (get_host_rip || get_all)) {
959
error = vm_get_vmcs_field(vcpu, VMCS_HOST_RIP, &rip);
960
if (error == 0)
961
printf("host_rip[%d]\t\t0x%016lx\n", vcpuid, rip);
962
}
963
964
if (!error && (get_host_rsp || get_all)) {
965
error = vm_get_vmcs_field(vcpu, VMCS_HOST_RSP, &rsp);
966
if (error == 0)
967
printf("host_rsp[%d]\t\t0x%016lx\n", vcpuid, rsp);
968
}
969
970
if (!error && (get_vmcs_link || get_all)) {
971
error = vm_get_vmcs_field(vcpu, VMCS_LINK_POINTER, &addr);
972
if (error == 0)
973
printf("vmcs_pointer[%d]\t0x%016lx\n", vcpuid, addr);
974
}
975
976
if (!error && (get_vmcs_exit_interruption_info || get_all)) {
977
error = vm_get_vmcs_field(vcpu, VMCS_EXIT_INTR_INFO, &u64);
978
if (error == 0) {
979
printf("vmcs_exit_interruption_info[%d]\t0x%016lx\n",
980
vcpuid, u64);
981
}
982
}
983
984
if (!error && (get_vmcs_exit_interruption_error || get_all)) {
985
error = vm_get_vmcs_field(vcpu, VMCS_EXIT_INTR_ERRCODE, &u64);
986
if (error == 0) {
987
printf("vmcs_exit_interruption_error[%d]\t0x%016lx\n",
988
vcpuid, u64);
989
}
990
}
991
992
if (!error && (get_vmcs_interruptibility || get_all)) {
993
error = vm_get_vmcs_field(vcpu,
994
VMCS_GUEST_INTERRUPTIBILITY, &u64);
995
if (error == 0) {
996
printf("vmcs_guest_interruptibility[%d]\t0x%016lx\n",
997
vcpuid, u64);
998
}
999
}
1000
1001
if (!error && (get_vmcs_exit_inst_length || get_all)) {
1002
error = vm_get_vmcs_field(vcpu,
1003
VMCS_EXIT_INSTRUCTION_LENGTH, &u64);
1004
if (error == 0)
1005
printf("vmcs_exit_inst_length[%d]\t0x%08x\n", vcpuid,
1006
(uint32_t)u64);
1007
}
1008
1009
if (!error && (get_vmcs_exit_qualification || get_all)) {
1010
error = vm_get_vmcs_field(vcpu, VMCS_EXIT_QUALIFICATION,
1011
&u64);
1012
if (error == 0)
1013
printf("vmcs_exit_qualification[%d]\t0x%016lx\n",
1014
vcpuid, u64);
1015
}
1016
1017
return (error);
1018
}
1019
1020
static int
1021
get_misc_vmcb(struct vcpu *vcpu, int vcpuid, bool get_all)
1022
{
1023
uint64_t ctl, addr;
1024
int error = 0;
1025
1026
if (!error && (get_vmcb_intercept || get_all)) {
1027
error = vm_get_vmcb_field(vcpu, VMCB_OFF_CR_INTERCEPT, 4,
1028
&ctl);
1029
if (error == 0)
1030
printf("cr_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);
1031
1032
error = vm_get_vmcb_field(vcpu, VMCB_OFF_DR_INTERCEPT, 4,
1033
&ctl);
1034
if (error == 0)
1035
printf("dr_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);
1036
1037
error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXC_INTERCEPT, 4,
1038
&ctl);
1039
if (error == 0)
1040
printf("exc_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);
1041
1042
error = vm_get_vmcb_field(vcpu, VMCB_OFF_INST1_INTERCEPT,
1043
4, &ctl);
1044
if (error == 0)
1045
printf("inst1_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);
1046
1047
error = vm_get_vmcb_field(vcpu, VMCB_OFF_INST2_INTERCEPT,
1048
4, &ctl);
1049
if (error == 0)
1050
printf("inst2_intercept[%d]\t0x%08x\n", vcpuid, (int)ctl);
1051
}
1052
1053
if (!error && (get_vmcb_tlb_ctrl || get_all)) {
1054
error = vm_get_vmcb_field(vcpu, VMCB_OFF_TLB_CTRL,
1055
4, &ctl);
1056
if (error == 0)
1057
printf("TLB ctrl[%d]\t0x%016lx\n", vcpuid, ctl);
1058
}
1059
1060
if (!error && (get_vmcb_exit_details || get_all)) {
1061
error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXITINFO1,
1062
8, &ctl);
1063
if (error == 0)
1064
printf("exitinfo1[%d]\t0x%016lx\n", vcpuid, ctl);
1065
error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXITINFO2,
1066
8, &ctl);
1067
if (error == 0)
1068
printf("exitinfo2[%d]\t0x%016lx\n", vcpuid, ctl);
1069
error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXITINTINFO,
1070
8, &ctl);
1071
if (error == 0)
1072
printf("exitintinfo[%d]\t0x%016lx\n", vcpuid, ctl);
1073
}
1074
1075
if (!error && (get_vmcb_virq || get_all)) {
1076
error = vm_get_vmcb_field(vcpu, VMCB_OFF_VIRQ,
1077
8, &ctl);
1078
if (error == 0)
1079
printf("v_irq/tpr[%d]\t0x%016lx\n", vcpuid, ctl);
1080
}
1081
1082
if (!error && (get_apic_access_addr || get_all)) {
1083
error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_BAR, 8,
1084
&addr);
1085
if (error == 0)
1086
printf("AVIC apic_bar[%d]\t0x%016lx\n", vcpuid, addr);
1087
}
1088
1089
if (!error && (get_virtual_apic_addr || get_all)) {
1090
error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_PAGE, 8,
1091
&addr);
1092
if (error == 0)
1093
printf("AVIC backing page[%d]\t0x%016lx\n", vcpuid, addr);
1094
}
1095
1096
if (!error && (get_avic_table || get_all)) {
1097
error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_LT, 8,
1098
&addr);
1099
if (error == 0)
1100
printf("AVIC logical table[%d]\t0x%016lx\n",
1101
vcpuid, addr);
1102
error = vm_get_vmcb_field(vcpu, VMCB_OFF_AVIC_PT, 8,
1103
&addr);
1104
if (error == 0)
1105
printf("AVIC physical table[%d]\t0x%016lx\n",
1106
vcpuid, addr);
1107
}
1108
1109
return (error);
1110
}
1111
1112
struct option *
1113
bhyvectl_opts(const struct option *options, size_t count)
1114
{
1115
const struct option common_opts[] = {
1116
{ "set-efer", REQ_ARG, 0, SET_EFER },
1117
{ "set-cr0", REQ_ARG, 0, SET_CR0 },
1118
{ "set-cr2", REQ_ARG, 0, SET_CR2 },
1119
{ "set-cr3", REQ_ARG, 0, SET_CR3 },
1120
{ "set-cr4", REQ_ARG, 0, SET_CR4 },
1121
{ "set-dr0", REQ_ARG, 0, SET_DR0 },
1122
{ "set-dr1", REQ_ARG, 0, SET_DR1 },
1123
{ "set-dr2", REQ_ARG, 0, SET_DR2 },
1124
{ "set-dr3", REQ_ARG, 0, SET_DR3 },
1125
{ "set-dr6", REQ_ARG, 0, SET_DR6 },
1126
{ "set-dr7", REQ_ARG, 0, SET_DR7 },
1127
{ "set-rsp", REQ_ARG, 0, SET_RSP },
1128
{ "set-rip", REQ_ARG, 0, SET_RIP },
1129
{ "set-rax", REQ_ARG, 0, SET_RAX },
1130
{ "set-rflags", REQ_ARG, 0, SET_RFLAGS },
1131
{ "desc-base", REQ_ARG, 0, DESC_BASE },
1132
{ "desc-limit", REQ_ARG, 0, DESC_LIMIT },
1133
{ "desc-access",REQ_ARG, 0, DESC_ACCESS },
1134
{ "set-cs", REQ_ARG, 0, SET_CS },
1135
{ "set-ds", REQ_ARG, 0, SET_DS },
1136
{ "set-es", REQ_ARG, 0, SET_ES },
1137
{ "set-fs", REQ_ARG, 0, SET_FS },
1138
{ "set-gs", REQ_ARG, 0, SET_GS },
1139
{ "set-ss", REQ_ARG, 0, SET_SS },
1140
{ "set-tr", REQ_ARG, 0, SET_TR },
1141
{ "set-ldtr", REQ_ARG, 0, SET_LDTR },
1142
{ "set-x2apic-state",REQ_ARG, 0, SET_X2APIC_STATE },
1143
{ "unassign-pptdev", REQ_ARG, 0, UNASSIGN_PPTDEV },
1144
{ "get-gpa-pmap", REQ_ARG, 0, GET_GPA_PMAP },
1145
{ "assert-lapic-lvt", REQ_ARG, 0, ASSERT_LAPIC_LVT },
1146
{ "get-rtc-time", NO_ARG, &get_rtc_time, 1 },
1147
{ "set-rtc-time", REQ_ARG, 0, SET_RTC_TIME },
1148
{ "rtc-nvram-offset", REQ_ARG, 0, RTC_NVRAM_OFFSET },
1149
{ "get-rtc-nvram", NO_ARG, &get_rtc_nvram, 1 },
1150
{ "set-rtc-nvram", REQ_ARG, 0, SET_RTC_NVRAM },
1151
{ "get-desc-ds",NO_ARG, &get_desc_ds, 1 },
1152
{ "set-desc-ds",NO_ARG, &set_desc_ds, 1 },
1153
{ "get-desc-es",NO_ARG, &get_desc_es, 1 },
1154
{ "set-desc-es",NO_ARG, &set_desc_es, 1 },
1155
{ "get-desc-ss",NO_ARG, &get_desc_ss, 1 },
1156
{ "set-desc-ss",NO_ARG, &set_desc_ss, 1 },
1157
{ "get-desc-cs",NO_ARG, &get_desc_cs, 1 },
1158
{ "set-desc-cs",NO_ARG, &set_desc_cs, 1 },
1159
{ "get-desc-fs",NO_ARG, &get_desc_fs, 1 },
1160
{ "set-desc-fs",NO_ARG, &set_desc_fs, 1 },
1161
{ "get-desc-gs",NO_ARG, &get_desc_gs, 1 },
1162
{ "set-desc-gs",NO_ARG, &set_desc_gs, 1 },
1163
{ "get-desc-tr",NO_ARG, &get_desc_tr, 1 },
1164
{ "set-desc-tr",NO_ARG, &set_desc_tr, 1 },
1165
{ "set-desc-ldtr", NO_ARG, &set_desc_ldtr, 1 },
1166
{ "get-desc-ldtr", NO_ARG, &get_desc_ldtr, 1 },
1167
{ "set-desc-gdtr", NO_ARG, &set_desc_gdtr, 1 },
1168
{ "get-desc-gdtr", NO_ARG, &get_desc_gdtr, 1 },
1169
{ "set-desc-idtr", NO_ARG, &set_desc_idtr, 1 },
1170
{ "get-desc-idtr", NO_ARG, &get_desc_idtr, 1 },
1171
{ "get-efer", NO_ARG, &get_efer, 1 },
1172
{ "get-cr0", NO_ARG, &get_cr0, 1 },
1173
{ "get-cr2", NO_ARG, &get_cr2, 1 },
1174
{ "get-cr3", NO_ARG, &get_cr3, 1 },
1175
{ "get-cr4", NO_ARG, &get_cr4, 1 },
1176
{ "get-dr0", NO_ARG, &get_dr0, 1 },
1177
{ "get-dr1", NO_ARG, &get_dr1, 1 },
1178
{ "get-dr2", NO_ARG, &get_dr2, 1 },
1179
{ "get-dr3", NO_ARG, &get_dr3, 1 },
1180
{ "get-dr6", NO_ARG, &get_dr6, 1 },
1181
{ "get-dr7", NO_ARG, &get_dr7, 1 },
1182
{ "get-rsp", NO_ARG, &get_rsp, 1 },
1183
{ "get-rip", NO_ARG, &get_rip, 1 },
1184
{ "get-rax", NO_ARG, &get_rax, 1 },
1185
{ "get-rbx", NO_ARG, &get_rbx, 1 },
1186
{ "get-rcx", NO_ARG, &get_rcx, 1 },
1187
{ "get-rdx", NO_ARG, &get_rdx, 1 },
1188
{ "get-rsi", NO_ARG, &get_rsi, 1 },
1189
{ "get-rdi", NO_ARG, &get_rdi, 1 },
1190
{ "get-rbp", NO_ARG, &get_rbp, 1 },
1191
{ "get-r8", NO_ARG, &get_r8, 1 },
1192
{ "get-r9", NO_ARG, &get_r9, 1 },
1193
{ "get-r10", NO_ARG, &get_r10, 1 },
1194
{ "get-r11", NO_ARG, &get_r11, 1 },
1195
{ "get-r12", NO_ARG, &get_r12, 1 },
1196
{ "get-r13", NO_ARG, &get_r13, 1 },
1197
{ "get-r14", NO_ARG, &get_r14, 1 },
1198
{ "get-r15", NO_ARG, &get_r15, 1 },
1199
{ "get-rflags", NO_ARG, &get_rflags, 1 },
1200
{ "get-cs", NO_ARG, &get_cs, 1 },
1201
{ "get-ds", NO_ARG, &get_ds, 1 },
1202
{ "get-es", NO_ARG, &get_es, 1 },
1203
{ "get-fs", NO_ARG, &get_fs, 1 },
1204
{ "get-gs", NO_ARG, &get_gs, 1 },
1205
{ "get-ss", NO_ARG, &get_ss, 1 },
1206
{ "get-tr", NO_ARG, &get_tr, 1 },
1207
{ "get-ldtr", NO_ARG, &get_ldtr, 1 },
1208
{ "get-eptp", NO_ARG, &get_eptp, 1 },
1209
{ "get-exception-bitmap", NO_ARG, &get_exception_bitmap, 1 },
1210
{ "get-io-bitmap-address", NO_ARG, &get_io_bitmap, 1 },
1211
{ "get-tsc-offset", NO_ARG, &get_tsc_offset, 1 },
1212
{ "get-msr-bitmap", NO_ARG, &get_msr_bitmap, 1 },
1213
{ "get-msr-bitmap-address", NO_ARG, &get_msr_bitmap_address, 1},
1214
{ "get-guest-pat", NO_ARG, &get_guest_pat, 1 },
1215
{ "get-guest-sysenter", NO_ARG, &get_guest_sysenter, 1 },
1216
{ "get-exit-reason", NO_ARG, &get_exit_reason, 1 },
1217
{ "get-x2apic-state", NO_ARG, &get_x2apic_state, 1 },
1218
{ "inject-nmi", NO_ARG, &inject_nmi, 1 },
1219
{ "get-intinfo", NO_ARG, &get_intinfo, 1 },
1220
};
1221
const struct option intel_opts[] = {
1222
{ "get-vmcs-pinbased-ctls",
1223
NO_ARG, &get_pinbased_ctls, 1 },
1224
{ "get-vmcs-procbased-ctls",
1225
NO_ARG, &get_procbased_ctls, 1 },
1226
{ "get-vmcs-procbased-ctls2",
1227
NO_ARG, &get_procbased_ctls2, 1 },
1228
{ "get-vmcs-guest-linear-address",
1229
NO_ARG, &get_vmcs_gla, 1 },
1230
{ "get-vmcs-guest-physical-address",
1231
NO_ARG, &get_vmcs_gpa, 1 },
1232
{ "get-vmcs-entry-interruption-info",
1233
NO_ARG, &get_vmcs_entry_interruption_info, 1},
1234
{ "get-vmcs-cr0-mask", NO_ARG, &get_cr0_mask, 1 },
1235
{ "get-vmcs-cr0-shadow", NO_ARG,&get_cr0_shadow, 1 },
1236
{ "get-vmcs-cr4-mask", NO_ARG, &get_cr4_mask, 1 },
1237
{ "get-vmcs-cr4-shadow", NO_ARG, &get_cr4_shadow, 1 },
1238
{ "get-vmcs-cr3-targets", NO_ARG, &get_cr3_targets, 1 },
1239
{ "get-vmcs-tpr-threshold",
1240
NO_ARG, &get_tpr_threshold, 1 },
1241
{ "get-vmcs-vpid", NO_ARG, &get_vpid_asid, 1 },
1242
{ "get-vmcs-exit-ctls", NO_ARG, &get_exit_ctls, 1 },
1243
{ "get-vmcs-entry-ctls",
1244
NO_ARG, &get_entry_ctls, 1 },
1245
{ "get-vmcs-instruction-error",
1246
NO_ARG, &get_inst_err, 1 },
1247
{ "get-vmcs-host-pat", NO_ARG, &get_host_pat, 1 },
1248
{ "get-vmcs-host-cr0",
1249
NO_ARG, &get_host_cr0, 1 },
1250
{ "get-vmcs-exit-qualification",
1251
NO_ARG, &get_vmcs_exit_qualification, 1 },
1252
{ "get-vmcs-exit-inst-length",
1253
NO_ARG, &get_vmcs_exit_inst_length, 1 },
1254
{ "get-vmcs-interruptibility",
1255
NO_ARG, &get_vmcs_interruptibility, 1 },
1256
{ "get-vmcs-exit-interruption-error",
1257
NO_ARG, &get_vmcs_exit_interruption_error, 1 },
1258
{ "get-vmcs-exit-interruption-info",
1259
NO_ARG, &get_vmcs_exit_interruption_info, 1 },
1260
{ "get-vmcs-link", NO_ARG, &get_vmcs_link, 1 },
1261
{ "get-vmcs-host-cr3",
1262
NO_ARG, &get_host_cr3, 1 },
1263
{ "get-vmcs-host-cr4",
1264
NO_ARG, &get_host_cr4, 1 },
1265
{ "get-vmcs-host-rip",
1266
NO_ARG, &get_host_rip, 1 },
1267
{ "get-vmcs-host-rsp",
1268
NO_ARG, &get_host_rsp, 1 },
1269
{ "get-apic-access-address",
1270
NO_ARG, &get_apic_access_addr, 1},
1271
{ "get-virtual-apic-address",
1272
NO_ARG, &get_virtual_apic_addr, 1}
1273
};
1274
const struct option amd_opts[] = {
1275
{ "get-vmcb-intercepts",
1276
NO_ARG, &get_vmcb_intercept, 1 },
1277
{ "get-vmcb-asid",
1278
NO_ARG, &get_vpid_asid, 1 },
1279
{ "get-vmcb-exit-details",
1280
NO_ARG, &get_vmcb_exit_details, 1 },
1281
{ "get-vmcb-tlb-ctrl",
1282
NO_ARG, &get_vmcb_tlb_ctrl, 1 },
1283
{ "get-vmcb-virq",
1284
NO_ARG, &get_vmcb_virq, 1 },
1285
{ "get-avic-apic-bar",
1286
NO_ARG, &get_apic_access_addr, 1 },
1287
{ "get-avic-backing-page",
1288
NO_ARG, &get_virtual_apic_addr, 1 },
1289
{ "get-avic-table",
1290
NO_ARG, &get_avic_table, 1 }
1291
};
1292
const struct option null_opt = {
1293
NULL, 0, NULL, 0
1294
};
1295
1296
struct option *all_opts;
1297
char *cp;
1298
int optlen;
1299
bool cpu_intel;
1300
1301
cpu_intel = cpu_vendor_intel();
1302
optlen = count * sizeof(struct option) + sizeof(common_opts);
1303
1304
if (cpu_intel)
1305
optlen += sizeof(intel_opts);
1306
else
1307
optlen += sizeof(amd_opts);
1308
1309
optlen += sizeof(null_opt);
1310
1311
all_opts = malloc(optlen);
1312
if (all_opts == NULL)
1313
err(1, "malloc");
1314
1315
cp = (char *)all_opts;
1316
memcpy(cp, options, count * sizeof(struct option));
1317
cp += count * sizeof(struct option);
1318
memcpy(cp, common_opts, sizeof(common_opts));
1319
cp += sizeof(common_opts);
1320
1321
if (cpu_intel) {
1322
memcpy(cp, intel_opts, sizeof(intel_opts));
1323
cp += sizeof(intel_opts);
1324
} else {
1325
memcpy(cp, amd_opts, sizeof(amd_opts));
1326
cp += sizeof(amd_opts);
1327
}
1328
1329
memcpy(cp, &null_opt, sizeof(null_opt));
1330
cp += sizeof(null_opt);
1331
1332
return (all_opts);
1333
}
1334
1335
void
1336
bhyvectl_handle_opt(const struct option *opts, int opt)
1337
{
1338
switch (opt) {
1339
case SET_EFER:
1340
set_efer_val = strtoul(optarg, NULL, 0);
1341
set_efer = 1;
1342
break;
1343
case SET_CR0:
1344
set_cr0_val = strtoul(optarg, NULL, 0);
1345
set_cr0 = 1;
1346
break;
1347
case SET_CR2:
1348
set_cr2_val = strtoul(optarg, NULL, 0);
1349
set_cr2 = 1;
1350
break;
1351
case SET_CR3:
1352
set_cr3_val = strtoul(optarg, NULL, 0);
1353
set_cr3 = 1;
1354
break;
1355
case SET_CR4:
1356
set_cr4_val = strtoul(optarg, NULL, 0);
1357
set_cr4 = 1;
1358
break;
1359
case SET_DR0:
1360
set_dr0_val = strtoul(optarg, NULL, 0);
1361
set_dr0 = 1;
1362
break;
1363
case SET_DR1:
1364
set_dr1_val = strtoul(optarg, NULL, 0);
1365
set_dr1 = 1;
1366
break;
1367
case SET_DR2:
1368
set_dr2_val = strtoul(optarg, NULL, 0);
1369
set_dr2 = 1;
1370
break;
1371
case SET_DR3:
1372
set_dr3_val = strtoul(optarg, NULL, 0);
1373
set_dr3 = 1;
1374
break;
1375
case SET_DR6:
1376
set_dr6_val = strtoul(optarg, NULL, 0);
1377
set_dr6 = 1;
1378
break;
1379
case SET_DR7:
1380
set_dr7_val = strtoul(optarg, NULL, 0);
1381
set_dr7 = 1;
1382
break;
1383
case SET_RSP:
1384
set_rsp_val = strtoul(optarg, NULL, 0);
1385
set_rsp = 1;
1386
break;
1387
case SET_RIP:
1388
set_rip_val = strtoul(optarg, NULL, 0);
1389
set_rip = 1;
1390
break;
1391
case SET_RAX:
1392
set_rax_val = strtoul(optarg, NULL, 0);
1393
set_rax = 1;
1394
break;
1395
case SET_RFLAGS:
1396
set_rflags_val = strtoul(optarg, NULL, 0);
1397
set_rflags = 1;
1398
break;
1399
case DESC_BASE:
1400
desc_base = strtoul(optarg, NULL, 0);
1401
break;
1402
case DESC_LIMIT:
1403
desc_limit = strtoul(optarg, NULL, 0);
1404
break;
1405
case DESC_ACCESS:
1406
desc_access = strtoul(optarg, NULL, 0);
1407
break;
1408
case SET_CS:
1409
set_cs_val = strtoul(optarg, NULL, 0);
1410
set_cs = 1;
1411
break;
1412
case SET_DS:
1413
set_ds_val = strtoul(optarg, NULL, 0);
1414
set_ds = 1;
1415
break;
1416
case SET_ES:
1417
set_es_val = strtoul(optarg, NULL, 0);
1418
set_es = 1;
1419
break;
1420
case SET_FS:
1421
set_fs_val = strtoul(optarg, NULL, 0);
1422
set_fs = 1;
1423
break;
1424
case SET_GS:
1425
set_gs_val = strtoul(optarg, NULL, 0);
1426
set_gs = 1;
1427
break;
1428
case SET_SS:
1429
set_ss_val = strtoul(optarg, NULL, 0);
1430
set_ss = 1;
1431
break;
1432
case SET_TR:
1433
set_tr_val = strtoul(optarg, NULL, 0);
1434
set_tr = 1;
1435
break;
1436
case SET_LDTR:
1437
set_ldtr_val = strtoul(optarg, NULL, 0);
1438
set_ldtr = 1;
1439
break;
1440
case SET_X2APIC_STATE:
1441
x2apic_state = strtol(optarg, NULL, 0);
1442
set_x2apic_state = 1;
1443
break;
1444
case SET_RTC_TIME:
1445
rtc_secs = strtoul(optarg, NULL, 0);
1446
set_rtc_time = 1;
1447
break;
1448
case SET_RTC_NVRAM:
1449
rtc_nvram_value = (uint8_t)strtoul(optarg, NULL, 0);
1450
set_rtc_nvram = 1;
1451
break;
1452
case RTC_NVRAM_OFFSET:
1453
rtc_nvram_offset = strtoul(optarg, NULL, 0);
1454
break;
1455
case GET_GPA_PMAP:
1456
gpa_pmap = strtoul(optarg, NULL, 0);
1457
get_gpa_pmap = 1;
1458
break;
1459
case UNASSIGN_PPTDEV:
1460
unassign_pptdev = 1;
1461
if (sscanf(optarg, "%d/%d/%d", &bus, &slot, &func) != 3)
1462
usage(opts);
1463
break;
1464
case ASSERT_LAPIC_LVT:
1465
assert_lapic_lvt = atoi(optarg);
1466
break;
1467
}
1468
}
1469
1470
const char *
1471
bhyvectl_opt_desc(int opt)
1472
{
1473
switch (opt) {
1474
case SET_EFER:
1475
return ("EFER");
1476
case SET_CR0:
1477
return ("CR0");
1478
case SET_CR2:
1479
return ("CR2");
1480
case SET_CR3:
1481
return ("CR3");
1482
case SET_CR4:
1483
return ("CR4");
1484
case SET_DR0:
1485
return ("DR0");
1486
case SET_DR1:
1487
return ("DR1");
1488
case SET_DR2:
1489
return ("DR2");
1490
case SET_DR3:
1491
return ("DR3");
1492
case SET_DR6:
1493
return ("DR6");
1494
case SET_DR7:
1495
return ("DR7");
1496
case SET_RSP:
1497
return ("RSP");
1498
case SET_RIP:
1499
return ("RIP");
1500
case SET_RAX:
1501
return ("RAX");
1502
case SET_RFLAGS:
1503
return ("RFLAGS");
1504
case DESC_BASE:
1505
return ("BASE");
1506
case DESC_LIMIT:
1507
return ("LIMIT");
1508
case DESC_ACCESS:
1509
return ("ACCESS");
1510
case SET_CS:
1511
return ("CS");
1512
case SET_DS:
1513
return ("DS");
1514
case SET_ES:
1515
return ("ES");
1516
case SET_FS:
1517
return ("FS");
1518
case SET_GS:
1519
return ("GS");
1520
case SET_SS:
1521
return ("SS");
1522
case SET_TR:
1523
return ("TR");
1524
case SET_LDTR:
1525
return ("LDTR");
1526
case SET_X2APIC_STATE:
1527
return ("state");
1528
case UNASSIGN_PPTDEV:
1529
return ("bus/slot.func");
1530
case GET_GPA_PMAP:
1531
return ("gpa");
1532
case ASSERT_LAPIC_LVT:
1533
return ("pin");
1534
case SET_RTC_TIME:
1535
return ("secs");
1536
case SET_RTC_NVRAM:
1537
return ("val");
1538
case RTC_NVRAM_OFFSET:
1539
return ("offset");
1540
default:
1541
return ("???");
1542
}
1543
}
1544
1545
void
1546
bhyvectl_md_main(struct vmctx *ctx, struct vcpu *vcpu, int vcpuid, bool get_all)
1547
{
1548
struct tm tm;
1549
uint64_t info[2], pteval[4], *pte;
1550
uint64_t addr, bm, eptp, u64;
1551
uint64_t cs, rsp, rip, pat;
1552
int error, ptenum;
1553
bool cpu_intel;
1554
1555
cpu_intel = cpu_vendor_intel();
1556
error = 0;
1557
1558
if (!error && set_efer)
1559
error = vm_set_register(vcpu, VM_REG_GUEST_EFER, set_efer_val);
1560
1561
if (!error && set_cr0)
1562
error = vm_set_register(vcpu, VM_REG_GUEST_CR0, set_cr0_val);
1563
1564
if (!error && set_cr2)
1565
error = vm_set_register(vcpu, VM_REG_GUEST_CR2, set_cr2_val);
1566
1567
if (!error && set_cr3)
1568
error = vm_set_register(vcpu, VM_REG_GUEST_CR3, set_cr3_val);
1569
1570
if (!error && set_cr4)
1571
error = vm_set_register(vcpu, VM_REG_GUEST_CR4, set_cr4_val);
1572
1573
if (!error && set_dr0)
1574
error = vm_set_register(vcpu, VM_REG_GUEST_DR0, set_dr0_val);
1575
1576
if (!error && set_dr1)
1577
error = vm_set_register(vcpu, VM_REG_GUEST_DR1, set_dr1_val);
1578
1579
if (!error && set_dr2)
1580
error = vm_set_register(vcpu, VM_REG_GUEST_DR2, set_dr2_val);
1581
1582
if (!error && set_dr3)
1583
error = vm_set_register(vcpu, VM_REG_GUEST_DR3, set_dr3_val);
1584
1585
if (!error && set_dr6)
1586
error = vm_set_register(vcpu, VM_REG_GUEST_DR6, set_dr6_val);
1587
1588
if (!error && set_dr7)
1589
error = vm_set_register(vcpu, VM_REG_GUEST_DR7, set_dr7_val);
1590
1591
if (!error && set_rsp)
1592
error = vm_set_register(vcpu, VM_REG_GUEST_RSP, set_rsp_val);
1593
1594
if (!error && set_rip)
1595
error = vm_set_register(vcpu, VM_REG_GUEST_RIP, set_rip_val);
1596
1597
if (!error && set_rax)
1598
error = vm_set_register(vcpu, VM_REG_GUEST_RAX, set_rax_val);
1599
1600
if (!error && set_rflags)
1601
error = vm_set_register(vcpu, VM_REG_GUEST_RFLAGS,
1602
set_rflags_val);
1603
1604
if (!error && set_desc_ds) {
1605
error = vm_set_desc(vcpu, VM_REG_GUEST_DS,
1606
desc_base, desc_limit, desc_access);
1607
}
1608
1609
if (!error && set_desc_es) {
1610
error = vm_set_desc(vcpu, VM_REG_GUEST_ES,
1611
desc_base, desc_limit, desc_access);
1612
}
1613
1614
if (!error && set_desc_ss) {
1615
error = vm_set_desc(vcpu, VM_REG_GUEST_SS,
1616
desc_base, desc_limit, desc_access);
1617
}
1618
1619
if (!error && set_desc_cs) {
1620
error = vm_set_desc(vcpu, VM_REG_GUEST_CS,
1621
desc_base, desc_limit, desc_access);
1622
}
1623
1624
if (!error && set_desc_fs) {
1625
error = vm_set_desc(vcpu, VM_REG_GUEST_FS,
1626
desc_base, desc_limit, desc_access);
1627
}
1628
1629
if (!error && set_desc_gs) {
1630
error = vm_set_desc(vcpu, VM_REG_GUEST_GS,
1631
desc_base, desc_limit, desc_access);
1632
}
1633
1634
if (!error && set_desc_tr) {
1635
error = vm_set_desc(vcpu, VM_REG_GUEST_TR,
1636
desc_base, desc_limit, desc_access);
1637
}
1638
1639
if (!error && set_desc_ldtr) {
1640
error = vm_set_desc(vcpu, VM_REG_GUEST_LDTR,
1641
desc_base, desc_limit, desc_access);
1642
}
1643
1644
if (!error && set_desc_gdtr) {
1645
error = vm_set_desc(vcpu, VM_REG_GUEST_GDTR,
1646
desc_base, desc_limit, 0);
1647
}
1648
1649
if (!error && set_desc_idtr) {
1650
error = vm_set_desc(vcpu, VM_REG_GUEST_IDTR,
1651
desc_base, desc_limit, 0);
1652
}
1653
1654
if (!error && set_cs)
1655
error = vm_set_register(vcpu, VM_REG_GUEST_CS, set_cs_val);
1656
1657
if (!error && set_ds)
1658
error = vm_set_register(vcpu, VM_REG_GUEST_DS, set_ds_val);
1659
1660
if (!error && set_es)
1661
error = vm_set_register(vcpu, VM_REG_GUEST_ES, set_es_val);
1662
1663
if (!error && set_fs)
1664
error = vm_set_register(vcpu, VM_REG_GUEST_FS, set_fs_val);
1665
1666
if (!error && set_gs)
1667
error = vm_set_register(vcpu, VM_REG_GUEST_GS, set_gs_val);
1668
1669
if (!error && set_ss)
1670
error = vm_set_register(vcpu, VM_REG_GUEST_SS, set_ss_val);
1671
1672
if (!error && set_tr)
1673
error = vm_set_register(vcpu, VM_REG_GUEST_TR, set_tr_val);
1674
1675
if (!error && set_ldtr)
1676
error = vm_set_register(vcpu, VM_REG_GUEST_LDTR, set_ldtr_val);
1677
1678
if (!error && set_x2apic_state)
1679
error = vm_set_x2apic_state(vcpu, x2apic_state);
1680
1681
if (!error && unassign_pptdev)
1682
error = vm_unassign_pptdev(ctx, bus, slot, func);
1683
1684
if (!error && inject_nmi)
1685
error = vm_inject_nmi(vcpu);
1686
1687
if (!error && assert_lapic_lvt != -1)
1688
error = vm_lapic_local_irq(vcpu, assert_lapic_lvt);
1689
1690
if (!error)
1691
error = get_all_registers(vcpu, vcpuid, get_all);
1692
1693
if (!error)
1694
error = get_all_segments(vcpu, vcpuid, get_all);
1695
1696
if (!error) {
1697
if (cpu_intel)
1698
error = get_misc_vmcs(vcpu, vcpuid, get_all);
1699
else
1700
error = get_misc_vmcb(vcpu, vcpuid, get_all);
1701
}
1702
1703
if (!error && (get_x2apic_state || get_all)) {
1704
error = vm_get_x2apic_state(vcpu, &x2apic_state);
1705
if (error == 0)
1706
printf("x2apic_state[%d]\t%d\n", vcpuid, x2apic_state);
1707
}
1708
1709
if (!error && (get_eptp || get_all)) {
1710
if (cpu_intel)
1711
error = vm_get_vmcs_field(vcpu, VMCS_EPTP, &eptp);
1712
else
1713
error = vm_get_vmcb_field(vcpu, VMCB_OFF_NPT_BASE, 8,
1714
&eptp);
1715
if (error == 0)
1716
printf("%s[%d]\t\t0x%016lx\n",
1717
cpu_intel ? "eptp" : "rvi/npt", vcpuid, eptp);
1718
}
1719
1720
if (!error && (get_exception_bitmap || get_all)) {
1721
if (cpu_intel)
1722
error = vm_get_vmcs_field(vcpu, VMCS_EXCEPTION_BITMAP,
1723
&bm);
1724
else
1725
error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXC_INTERCEPT,
1726
4, &bm);
1727
if (error == 0)
1728
printf("exception_bitmap[%d]\t%#lx\n", vcpuid, bm);
1729
}
1730
1731
if (!error && (get_io_bitmap || get_all)) {
1732
if (cpu_intel) {
1733
error = vm_get_vmcs_field(vcpu, VMCS_IO_BITMAP_A, &bm);
1734
if (error == 0)
1735
printf("io_bitmap_a[%d]\t%#lx\n", vcpuid, bm);
1736
error = vm_get_vmcs_field(vcpu, VMCS_IO_BITMAP_B, &bm);
1737
if (error == 0)
1738
printf("io_bitmap_b[%d]\t%#lx\n", vcpuid, bm);
1739
} else {
1740
error = vm_get_vmcb_field(vcpu, VMCB_OFF_IO_PERM, 8,
1741
&bm);
1742
if (error == 0)
1743
printf("io_bitmap[%d]\t%#lx\n", vcpuid, bm);
1744
}
1745
}
1746
1747
if (!error && (get_tsc_offset || get_all)) {
1748
uint64_t tscoff;
1749
1750
if (cpu_intel)
1751
error = vm_get_vmcs_field(vcpu, VMCS_TSC_OFFSET,
1752
&tscoff);
1753
else
1754
error = vm_get_vmcb_field(vcpu, VMCB_OFF_TSC_OFFSET, 8,
1755
&tscoff);
1756
if (error == 0)
1757
printf("tsc_offset[%d]\t0x%016lx\n", vcpuid, tscoff);
1758
}
1759
1760
if (!error && (get_msr_bitmap_address || get_all)) {
1761
if (cpu_intel)
1762
error = vm_get_vmcs_field(vcpu, VMCS_MSR_BITMAP, &addr);
1763
else
1764
error = vm_get_vmcb_field(vcpu, VMCB_OFF_MSR_PERM, 8,
1765
&addr);
1766
if (error == 0)
1767
printf("msr_bitmap[%d]\t\t%#lx\n", vcpuid, addr);
1768
}
1769
1770
if (!error && (get_msr_bitmap || get_all)) {
1771
if (cpu_intel) {
1772
error = vm_get_vmcs_field(vcpu, VMCS_MSR_BITMAP, &addr);
1773
} else {
1774
error = vm_get_vmcb_field(vcpu, VMCB_OFF_MSR_PERM, 8,
1775
&addr);
1776
}
1777
1778
if (error == 0)
1779
error = dump_msr_bitmap(vcpuid, addr, cpu_intel);
1780
}
1781
1782
if (!error && (get_vpid_asid || get_all)) {
1783
uint64_t vpid;
1784
1785
if (cpu_intel)
1786
error = vm_get_vmcs_field(vcpu, VMCS_VPID, &vpid);
1787
else
1788
error = vm_get_vmcb_field(vcpu, VMCB_OFF_ASID, 4,
1789
&vpid);
1790
if (error == 0)
1791
printf("%s[%d]\t\t0x%04lx\n",
1792
cpu_intel ? "vpid" : "asid", vcpuid, vpid);
1793
}
1794
1795
if (!error && (get_guest_pat || get_all)) {
1796
if (cpu_intel)
1797
error = vm_get_vmcs_field(vcpu, VMCS_GUEST_IA32_PAT,
1798
&pat);
1799
else
1800
error = vm_get_vmcb_field(vcpu, VMCB_OFF_GUEST_PAT, 8,
1801
&pat);
1802
if (error == 0)
1803
printf("guest_pat[%d]\t\t0x%016lx\n", vcpuid, pat);
1804
}
1805
1806
if (!error && (get_guest_sysenter || get_all)) {
1807
if (cpu_intel)
1808
error = vm_get_vmcs_field(vcpu,
1809
VMCS_GUEST_IA32_SYSENTER_CS, &cs);
1810
else
1811
error = vm_get_vmcb_field(vcpu,
1812
VMCB_OFF_SYSENTER_CS, 8, &cs);
1813
1814
if (error == 0)
1815
printf("guest_sysenter_cs[%d]\t%#lx\n", vcpuid, cs);
1816
if (cpu_intel)
1817
error = vm_get_vmcs_field(vcpu,
1818
VMCS_GUEST_IA32_SYSENTER_ESP, &rsp);
1819
else
1820
error = vm_get_vmcb_field(vcpu, VMCB_OFF_SYSENTER_ESP,
1821
8, &rsp);
1822
1823
if (error == 0)
1824
printf("guest_sysenter_sp[%d]\t%#lx\n", vcpuid, rsp);
1825
if (cpu_intel)
1826
error = vm_get_vmcs_field(vcpu,
1827
VMCS_GUEST_IA32_SYSENTER_EIP, &rip);
1828
else
1829
error = vm_get_vmcb_field(vcpu, VMCB_OFF_SYSENTER_EIP,
1830
8, &rip);
1831
if (error == 0)
1832
printf("guest_sysenter_ip[%d]\t%#lx\n", vcpuid, rip);
1833
}
1834
1835
if (!error && (get_exit_reason || get_all)) {
1836
if (cpu_intel)
1837
error = vm_get_vmcs_field(vcpu, VMCS_EXIT_REASON, &u64);
1838
else
1839
error = vm_get_vmcb_field(vcpu, VMCB_OFF_EXIT_REASON, 8,
1840
&u64);
1841
if (error == 0)
1842
printf("exit_reason[%d]\t%#lx\n", vcpuid, u64);
1843
}
1844
1845
if (!error && get_gpa_pmap) {
1846
error = vm_get_gpa_pmap(ctx, gpa_pmap, pteval, &ptenum);
1847
if (error == 0) {
1848
printf("gpa %#lx:", gpa_pmap);
1849
pte = &pteval[0];
1850
while (ptenum-- > 0)
1851
printf(" %#lx", *pte++);
1852
printf("\n");
1853
}
1854
}
1855
1856
if (!error && set_rtc_nvram)
1857
error = vm_rtc_write(ctx, rtc_nvram_offset, rtc_nvram_value);
1858
1859
if (!error && (get_rtc_nvram || get_all)) {
1860
error = vm_rtc_read(ctx, rtc_nvram_offset, &rtc_nvram_value);
1861
if (error == 0) {
1862
printf("rtc nvram[%03d]: 0x%02x\n", rtc_nvram_offset,
1863
rtc_nvram_value);
1864
}
1865
}
1866
1867
if (!error && set_rtc_time)
1868
error = vm_rtc_settime(ctx, rtc_secs);
1869
1870
if (!error && (get_rtc_time || get_all)) {
1871
error = vm_rtc_gettime(ctx, &rtc_secs);
1872
if (error == 0) {
1873
gmtime_r(&rtc_secs, &tm);
1874
printf("rtc time %#lx: %s %s %02d %02d:%02d:%02d %d\n",
1875
rtc_secs, wday_str(tm.tm_wday), mon_str(tm.tm_mon),
1876
tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,
1877
1900 + tm.tm_year);
1878
}
1879
}
1880
1881
if (!error && (get_intinfo || get_all)) {
1882
error = vm_get_intinfo(vcpu, &info[0], &info[1]);
1883
if (!error) {
1884
print_intinfo("pending", info[0]);
1885
print_intinfo("current", info[1]);
1886
}
1887
}
1888
}
1889
1890