aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--executor/common_kvm_amd64_syzos.h21
-rw-r--r--sys/linux/dev_kvm_amd64.txt6
-rw-r--r--sys/linux/test/amd64-syz_kvm_setup_syzos_vm-cpuid17
3 files changed, 44 insertions, 0 deletions
diff --git a/executor/common_kvm_amd64_syzos.h b/executor/common_kvm_amd64_syzos.h
index b98b33337..706396d1a 100644
--- a/executor/common_kvm_amd64_syzos.h
+++ b/executor/common_kvm_amd64_syzos.h
@@ -21,6 +21,7 @@ extern char *__start_guest, *__stop_guest;
typedef enum {
SYZOS_API_UEXIT,
SYZOS_API_CODE,
+ SYZOS_API_CPUID,
SYZOS_API_STOP, // Must be the last one
} syzos_api_id;
@@ -39,8 +40,15 @@ struct api_call_code {
uint8 insns[];
};
+struct api_call_cpuid {
+ struct api_call_header header;
+ uint32 eax;
+ uint32 ecx;
+};
+
static void guest_uexit(uint64 exit_code);
static void guest_execute_code(uint8* insns, uint64 size);
+static void guest_cpuid(uint32 eax, uint32 ecx);
typedef enum {
UEXIT_END = (uint64)-1,
@@ -73,6 +81,10 @@ guest_main(uint64 size, uint64 cpu)
guest_execute_code(ccmd->insns, cmd->size - sizeof(struct api_call_header));
break;
}
+ case SYZOS_API_CPUID: {
+ struct api_call_cpuid* ccmd = (struct api_call_cpuid*)cmd;
+ guest_cpuid(ccmd->eax, ccmd->ecx);
+ }
}
addr += cmd->size;
size -= cmd->size;
@@ -94,3 +106,12 @@ GUEST_CODE static noinline void guest_uexit(uint64 exit_code)
volatile uint64* ptr = (volatile uint64*)X86_ADDR_UEXIT;
*ptr = exit_code;
}
+
+GUEST_CODE static noinline void guest_cpuid(uint32 eax, uint32 ecx)
+{
+ asm volatile(
+ "cpuid\n"
+ : // Currently ignore outputs
+ : "a"(eax), "c"(ecx)
+ : "rbx", "rdx");
+}
diff --git a/sys/linux/dev_kvm_amd64.txt b/sys/linux/dev_kvm_amd64.txt
index 0350f548d..65ae5cd2b 100644
--- a/sys/linux/dev_kvm_amd64.txt
+++ b/sys/linux/dev_kvm_amd64.txt
@@ -43,9 +43,15 @@ type syzos_api$x86[NUM, PAYLOAD] {
payload PAYLOAD
}
+syzos_api_cpuid {
+ eax int32
+ ecx int32
+}
+
syzos_api_call$x86 [
uexit syzos_api$x86[0, intptr]
code syzos_api$x86[1, syzos_api_code$x86]
+ cpuid syzos_api$x86[2, syzos_api_cpuid]
] [varlen]
kvm_text_x86 [
diff --git a/sys/linux/test/amd64-syz_kvm_setup_syzos_vm-cpuid b/sys/linux/test/amd64-syz_kvm_setup_syzos_vm-cpuid
new file mode 100644
index 000000000..34468c8cd
--- /dev/null
+++ b/sys/linux/test/amd64-syz_kvm_setup_syzos_vm-cpuid
@@ -0,0 +1,17 @@
+#
+# requires: arch=amd64 -threaded
+#
+r0 = openat$kvm(0, &AUTO='/dev/kvm\x00', 0x0, 0x0)
+r1 = ioctl$KVM_CREATE_VM(r0, AUTO, 0x0)
+r2 = syz_kvm_setup_syzos_vm$x86(r1, &(0x7f0000c00000/0x400000)=nil)
+#
+# 0x2 queries Cache and TLB information
+#
+r3 = syz_kvm_add_vcpu$x86(r2, &AUTO={0x0, &AUTO=[@cpuid={AUTO, AUTO, {0x1, 0x0}}], AUTO})
+r4 = ioctl$KVM_GET_VCPU_MMAP_SIZE(r0, AUTO)
+r5 = mmap$KVM_VCPU(&(0x7f0000009000/0x1000)=nil, r4, 0x3, 0x1, r3, 0x0)
+
+# Run till the end of guest_main(). 0xffffffffffffffff is UEXIT_END.
+#
+ioctl$KVM_RUN(r3, AUTO, 0x0)
+syz_kvm_assert_syzos_uexit$x86(r5, 0xffffffffffffffff)