Skip to content

Commit 9d3f6f6

Browse files
committed
executor/kvm: add SYZOS support for CPUID
This commit adds support for CPUID instructions on AMD64. It also adds a relevant test.
1 parent b0714e3 commit 9d3f6f6

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

executor/common_kvm_amd64_syzos.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern char *__start_guest, *__stop_guest;
2121
typedef enum {
2222
SYZOS_API_UEXIT,
2323
SYZOS_API_CODE,
24+
SYZOS_API_CPUID,
2425
SYZOS_API_STOP, // Must be the last one
2526
} syzos_api_id;
2627

@@ -39,8 +40,15 @@ struct api_call_code {
3940
uint8 insns[];
4041
};
4142

43+
struct api_call_cpuid {
44+
struct api_call_header header;
45+
uint32 eax;
46+
uint32 ecx;
47+
};
48+
4249
static void guest_uexit(uint64 exit_code);
4350
static void guest_execute_code(uint8* insns, uint64 size);
51+
static void guest_cpuid(uint32 eax, uint32 ecx);
4452

4553
typedef enum {
4654
UEXIT_END = (uint64)-1,
@@ -73,6 +81,10 @@ guest_main(uint64 size, uint64 cpu)
7381
guest_execute_code(ccmd->insns, cmd->size - sizeof(struct api_call_header));
7482
break;
7583
}
84+
case SYZOS_API_CPUID: {
85+
struct api_call_cpuid* ccmd = (struct api_call_cpuid*)cmd;
86+
guest_cpuid(ccmd->eax, ccmd->ecx);
87+
}
7688
}
7789
addr += cmd->size;
7890
size -= cmd->size;
@@ -94,3 +106,12 @@ GUEST_CODE static noinline void guest_uexit(uint64 exit_code)
94106
volatile uint64* ptr = (volatile uint64*)X86_ADDR_UEXIT;
95107
*ptr = exit_code;
96108
}
109+
110+
GUEST_CODE static noinline void guest_cpuid(uint32 eax, uint32 ecx)
111+
{
112+
asm volatile(
113+
"cpuid\n"
114+
: // Currently ignore outputs
115+
: "a"(eax), "c"(ecx)
116+
: "rbx", "rdx");
117+
}

sys/linux/dev_kvm_amd64.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,15 @@ type syzos_api$x86[NUM, PAYLOAD] {
4343
payload PAYLOAD
4444
}
4545

46+
syzos_api_cpuid {
47+
eax int32
48+
ecx int32
49+
}
50+
4651
syzos_api_call$x86 [
4752
uexit syzos_api$x86[0, intptr]
4853
code syzos_api$x86[1, syzos_api_code$x86]
54+
cpuid syzos_api$x86[2, syzos_api_cpuid]
4955
] [varlen]
5056

5157
kvm_text_x86 [
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#
2+
# requires: arch=amd64 -threaded
3+
#
4+
r0 = openat$kvm(0, &AUTO='/dev/kvm\x00', 0x0, 0x0)
5+
r1 = ioctl$KVM_CREATE_VM(r0, AUTO, 0x0)
6+
r2 = syz_kvm_setup_syzos_vm$x86(r1, &(0x7f0000c00000/0x400000)=nil)
7+
#
8+
# 0x2 queries Cache and TLB information
9+
#
10+
r3 = syz_kvm_add_vcpu$x86(r2, &AUTO={0x0, &AUTO=[@cpuid={AUTO, AUTO, {0x1, 0x0}}], AUTO})
11+
r4 = ioctl$KVM_GET_VCPU_MMAP_SIZE(r0, AUTO)
12+
r5 = mmap$KVM_VCPU(&(0x7f0000009000/0x1000)=nil, r4, 0x3, 0x1, r3, 0x0)
13+
14+
# Run till the end of guest_main(). 0xffffffffffffffff is UEXIT_END.
15+
#
16+
ioctl$KVM_RUN(r3, AUTO, 0x0)
17+
syz_kvm_assert_syzos_uexit$x86(r5, 0xffffffffffffffff)

0 commit comments

Comments
 (0)