#ifdef __x86_64__
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <linux/kvm.h>
#include <unistd.h>
int boxlite_kvm_smoke_test(int kvm_fd) {
int vm_fd = ioctl(kvm_fd, KVM_CREATE_VM, 0);
if (vm_fd < 0)
return -1;
void *guest_mem = mmap(NULL, 4096, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
if (guest_mem == MAP_FAILED) {
close(vm_fd);
return -1;
}
*(unsigned char *)guest_mem = 0xF4;
struct kvm_userspace_memory_region region = {
.slot = 0,
.guest_phys_addr = 0,
.memory_size = 4096,
.userspace_addr = (unsigned long)guest_mem,
};
if (ioctl(vm_fd, KVM_SET_USER_MEMORY_REGION, ®ion) < 0) {
munmap(guest_mem, 4096);
close(vm_fd);
return -1;
}
int vcpu_fd = ioctl(vm_fd, KVM_CREATE_VCPU, 0);
if (vcpu_fd < 0) {
munmap(guest_mem, 4096);
close(vm_fd);
return -1;
}
struct kvm_sregs sregs;
ioctl(vcpu_fd, KVM_GET_SREGS, &sregs);
sregs.cs.base = 0;
sregs.cs.selector = 0;
ioctl(vcpu_fd, KVM_SET_SREGS, &sregs);
struct kvm_regs regs;
memset(®s, 0, sizeof(regs));
regs.rip = 0;
regs.rflags = 0x2;
ioctl(vcpu_fd, KVM_SET_REGS, ®s);
int mmap_size = ioctl(kvm_fd, KVM_GET_VCPU_MMAP_SIZE, 0);
struct kvm_run *run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,
MAP_SHARED, vcpu_fd, 0);
if (run == MAP_FAILED) {
close(vcpu_fd);
munmap(guest_mem, 4096);
close(vm_fd);
return -1;
}
ioctl(vcpu_fd, KVM_RUN, 0);
int exit_reason = run->exit_reason;
munmap(run, mmap_size);
close(vcpu_fd);
munmap(guest_mem, 4096);
close(vm_fd);
return exit_reason;
}
#else
int boxlite_kvm_smoke_test(int kvm_fd) {
(void)kvm_fd;
return 5;
}
#endif