Skip to content

Commit f85be0a

Browse files
authored
add a D script to report VMs' CPUID queries (#934)
it'd be nice to elide the subleaf for leaves that do not have subleaves, but that more careful treatment of CPUID leaves is motivated elsewhere first (e.g. actual usage in Propolis) and might end up here via automatic translation or something later on.
1 parent 9948508 commit f85be0a

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

scripts/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ individual files for details.
1313
of a live migration.
1414
- `vm_exit_codes.d`: Measure VM exits and information about them both for
1515
#VMEXIT events and returns to Propolis.
16+
- `cpuid-queries.d`: Report guest CPUID queries and returned leaves.

scripts/cpuid-queries.d

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#pragma D option defaultargs
2+
#pragma D option quiet
3+
4+
/*
5+
* Report guest CPUID queries and returned leaves.
6+
*
7+
* Usage: ./cpuid-queries.d <target VM's struct vm*>
8+
*
9+
* You probably have a VM name you care about, not its `struct vm*`. How do you
10+
* go from the name to the pointer required here? And why?
11+
*
12+
* To the first question, something like this will get you the `vmm_vm` pointer
13+
* to use with this script:
14+
* ```
15+
* mdb -ke '::walk vmm | ::print struct vmm_softc vmm_vm vmm_name ! grep -B 1 <VM_NAME>'
16+
* ```
17+
*
18+
* Why? Because the VM's name is on vmm_softc, which has a reference to the
19+
* structure used in CPUID emulation and so on, but there's no back reference.
20+
* So this is slightly less convoluted than capturing the `struct vm` pointer at
21+
* some earlier point when we still have a softc. This may well get simplified
22+
* with a backref in the future.
23+
*/
24+
25+
BEGIN {
26+
if ($$1 == "") {
27+
printf("target `struct vm*` required");
28+
exit(1);
29+
}
30+
31+
target_vm = $1;
32+
}
33+
34+
fbt::vcpu_emulate_cpuid:entry / arg0 == target_vm / {
35+
self->rax = (uint64_t*)arg2;
36+
self->rbx = (uint64_t*)arg3;
37+
self->rcx = (uint64_t*)arg4;
38+
self->rdx = (uint64_t*)arg5;
39+
self->leaf = (uint32_t)*self->rax;
40+
self->subleaf = (uint32_t)*self->rcx;
41+
}
42+
43+
fbt::vcpu_emulate_cpuid:return / self->rax != NULL / {
44+
printf("CPUID query: leaf/subleaf 0x%08x/0x%08x, returns rax = 0x%08x, rbx = 0x%08x, rcx = 0x%08x, rdx = 0x%08x\n",
45+
self->leaf,
46+
self->subleaf,
47+
*self->rax,
48+
*self->rbx,
49+
*self->rcx,
50+
*self->rdx
51+
);
52+
self->rax = 0;
53+
}

0 commit comments

Comments
 (0)