Skip to content

executor/kvm: add SYZOS support for CPUID #5998

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions executor/common_kvm_amd64_syzos.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand All @@ -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");
}
6 changes: 6 additions & 0 deletions sys/linux/dev_kvm_amd64.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 [
Expand Down
17 changes: 17 additions & 0 deletions sys/linux/test/amd64-syz_kvm_setup_syzos_vm-cpuid
Original file line number Diff line number Diff line change
@@ -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)