1b8f6afcdSPekka Enberg #include "kvm/cpu.h" 2b8f6afcdSPekka Enberg 36c7d8514SPekka Enberg #include <linux/kvm.h> 42da26a59SPekka Enberg #include <stdbool.h> 5b8f6afcdSPekka Enberg #include <stdlib.h> 6b8f6afcdSPekka Enberg #include <fcntl.h> 7b8f6afcdSPekka Enberg 89b1fb1c3SPekka Enberg struct kvm { 99b1fb1c3SPekka Enberg int fd; /* /dev/kvm */ 109b1fb1c3SPekka Enberg int vmfd; 11*2b0e3342SPekka Enberg int vcpu_fd; 129b1fb1c3SPekka Enberg }; 139b1fb1c3SPekka Enberg 14b8f6afcdSPekka Enberg static void die(const char *s) 15b8f6afcdSPekka Enberg { 16b8f6afcdSPekka Enberg perror(s); 17b8f6afcdSPekka Enberg exit(1); 18b8f6afcdSPekka Enberg } 19b8f6afcdSPekka Enberg 20b8f6afcdSPekka Enberg static void cpu__reset(struct cpu *self) 21b8f6afcdSPekka Enberg { 22b8f6afcdSPekka Enberg self->regs.eip = 0x000fff0UL; 23b8f6afcdSPekka Enberg self->regs.eflags = 0x0000002UL; 24b8f6afcdSPekka Enberg } 25b8f6afcdSPekka Enberg 26b8f6afcdSPekka Enberg static struct cpu *cpu__new(void) 27b8f6afcdSPekka Enberg { 28b8f6afcdSPekka Enberg return calloc(1, sizeof(struct cpu)); 29b8f6afcdSPekka Enberg } 30b8f6afcdSPekka Enberg 314076b041SPekka Enberg static inline bool kvm__supports_extension(struct kvm *self, unsigned int extension) 32b8f6afcdSPekka Enberg { 3328fa19c0SPekka Enberg int ret; 34b8f6afcdSPekka Enberg 354076b041SPekka Enberg ret = ioctl(self->fd, KVM_CHECK_EXTENSION, extension); 364076b041SPekka Enberg if (ret < 0) 374076b041SPekka Enberg return false; 384076b041SPekka Enberg 394076b041SPekka Enberg return ret; 404076b041SPekka Enberg } 414076b041SPekka Enberg 424076b041SPekka Enberg static struct kvm *kvm__new(void) 434076b041SPekka Enberg { 444076b041SPekka Enberg struct kvm *self = calloc(1, sizeof *self); 454076b041SPekka Enberg 464076b041SPekka Enberg if (!self) 474076b041SPekka Enberg die("out of memory"); 484076b041SPekka Enberg 494076b041SPekka Enberg return self; 504076b041SPekka Enberg } 514076b041SPekka Enberg 524076b041SPekka Enberg static struct kvm *kvm__init(void) 534076b041SPekka Enberg { 54*2b0e3342SPekka Enberg struct kvm_userspace_memory_region mem; 554076b041SPekka Enberg struct kvm *self; 564076b041SPekka Enberg int ret; 574076b041SPekka Enberg 584076b041SPekka Enberg self = kvm__new(); 594076b041SPekka Enberg 604076b041SPekka Enberg self->fd = open("/dev/kvm", O_RDWR); 614076b041SPekka Enberg if (self->fd < 0) 62b8f6afcdSPekka Enberg die("open"); 63b8f6afcdSPekka Enberg 644076b041SPekka Enberg ret = ioctl(self->fd, KVM_GET_API_VERSION, 0); 656c7d8514SPekka Enberg if (ret != KVM_API_VERSION) 666c7d8514SPekka Enberg die("ioctl"); 676c7d8514SPekka Enberg 684076b041SPekka Enberg self->vmfd = ioctl(self->fd, KVM_CREATE_VM, 0); 694076b041SPekka Enberg if (self->vmfd < 0) 7028fa19c0SPekka Enberg die("open"); 7128fa19c0SPekka Enberg 724076b041SPekka Enberg if (!kvm__supports_extension(self, KVM_CAP_USER_MEMORY)) 732da26a59SPekka Enberg die("KVM_CAP_USER_MEMORY"); 742da26a59SPekka Enberg 75*2b0e3342SPekka Enberg mem = (struct kvm_userspace_memory_region) { 76*2b0e3342SPekka Enberg .slot = 0, 77*2b0e3342SPekka Enberg .guest_phys_addr = 0x0UL, 78*2b0e3342SPekka Enberg .memory_size = 64UL * 1024UL * 1024UL, 79*2b0e3342SPekka Enberg }; 80*2b0e3342SPekka Enberg 81*2b0e3342SPekka Enberg ret = ioctl(self->vmfd, KVM_SET_USER_MEMORY_REGION, &mem, 1); 82*2b0e3342SPekka Enberg if (ret < 0) 83*2b0e3342SPekka Enberg die("ioctl(KVM_SET_USER_MEMORY_REGION)"); 84*2b0e3342SPekka Enberg 85*2b0e3342SPekka Enberg self->vcpu_fd = ioctl(self->vmfd, KVM_CREATE_VCPU, 0); 86*2b0e3342SPekka Enberg if (self->vcpu_fd < 0) 87*2b0e3342SPekka Enberg die("ioctl(KVM_CREATE_VCPU)"); 88*2b0e3342SPekka Enberg 894076b041SPekka Enberg return self; 904076b041SPekka Enberg } 914076b041SPekka Enberg 92*2b0e3342SPekka Enberg static void kvm__run(struct kvm *self) 93*2b0e3342SPekka Enberg { 94*2b0e3342SPekka Enberg int ret; 95*2b0e3342SPekka Enberg 96*2b0e3342SPekka Enberg ret = ioctl(self->vcpu_fd, KVM_RUN, 0); 97*2b0e3342SPekka Enberg if (ret < 0) 98*2b0e3342SPekka Enberg die("KVM_RUN"); 99*2b0e3342SPekka Enberg } 100*2b0e3342SPekka Enberg 1014076b041SPekka Enberg int main(int argc, char *argv[]) 1024076b041SPekka Enberg { 1034076b041SPekka Enberg struct cpu *cpu; 1044076b041SPekka Enberg struct kvm *kvm; 1054076b041SPekka Enberg int ret; 1064076b041SPekka Enberg 1074076b041SPekka Enberg kvm = kvm__init(); 1084076b041SPekka Enberg 109b8f6afcdSPekka Enberg cpu = cpu__new(); 110b8f6afcdSPekka Enberg 111b8f6afcdSPekka Enberg cpu__reset(cpu); 112b8f6afcdSPekka Enberg 113*2b0e3342SPekka Enberg kvm__run(kvm); 114*2b0e3342SPekka Enberg 115b8f6afcdSPekka Enberg return 0; 116b8f6afcdSPekka Enberg } 117