xref: /kvmtool/kvm.c (revision 4076b0411d4309c16bed3aa58a38fd74b3de7ee9)
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;
119b1fb1c3SPekka Enberg };
129b1fb1c3SPekka Enberg 
13b8f6afcdSPekka Enberg static void die(const char *s)
14b8f6afcdSPekka Enberg {
15b8f6afcdSPekka Enberg 	perror(s);
16b8f6afcdSPekka Enberg 	exit(1);
17b8f6afcdSPekka Enberg }
18b8f6afcdSPekka Enberg 
19b8f6afcdSPekka Enberg static void cpu__reset(struct cpu *self)
20b8f6afcdSPekka Enberg {
21b8f6afcdSPekka Enberg 	self->regs.eip		= 0x000fff0UL;
22b8f6afcdSPekka Enberg 	self->regs.eflags	= 0x0000002UL;
23b8f6afcdSPekka Enberg }
24b8f6afcdSPekka Enberg 
25b8f6afcdSPekka Enberg static struct cpu *cpu__new(void)
26b8f6afcdSPekka Enberg {
27b8f6afcdSPekka Enberg 	return calloc(1, sizeof(struct cpu));
28b8f6afcdSPekka Enberg }
29b8f6afcdSPekka Enberg 
30*4076b041SPekka Enberg static inline bool kvm__supports_extension(struct kvm *self, unsigned int extension)
31b8f6afcdSPekka Enberg {
3228fa19c0SPekka Enberg 	int ret;
33b8f6afcdSPekka Enberg 
34*4076b041SPekka Enberg 	ret = ioctl(self->fd, KVM_CHECK_EXTENSION, extension);
35*4076b041SPekka Enberg 	if (ret < 0)
36*4076b041SPekka Enberg 		return false;
37*4076b041SPekka Enberg 
38*4076b041SPekka Enberg 	return ret;
39*4076b041SPekka Enberg }
40*4076b041SPekka Enberg 
41*4076b041SPekka Enberg static struct kvm *kvm__new(void)
42*4076b041SPekka Enberg {
43*4076b041SPekka Enberg 	struct kvm *self = calloc(1, sizeof *self);
44*4076b041SPekka Enberg 
45*4076b041SPekka Enberg 	if (!self)
46*4076b041SPekka Enberg 		die("out of memory");
47*4076b041SPekka Enberg 
48*4076b041SPekka Enberg 	return self;
49*4076b041SPekka Enberg }
50*4076b041SPekka Enberg 
51*4076b041SPekka Enberg static struct kvm *kvm__init(void)
52*4076b041SPekka Enberg {
53*4076b041SPekka Enberg 	struct kvm *self;
54*4076b041SPekka Enberg 	int ret;
55*4076b041SPekka Enberg 
56*4076b041SPekka Enberg 	self = kvm__new();
57*4076b041SPekka Enberg 
58*4076b041SPekka Enberg 	self->fd = open("/dev/kvm", O_RDWR);
59*4076b041SPekka Enberg 	if (self->fd < 0)
60b8f6afcdSPekka Enberg 		die("open");
61b8f6afcdSPekka Enberg 
62*4076b041SPekka Enberg 	ret = ioctl(self->fd, KVM_GET_API_VERSION, 0);
636c7d8514SPekka Enberg 	if (ret != KVM_API_VERSION)
646c7d8514SPekka Enberg 		die("ioctl");
656c7d8514SPekka Enberg 
66*4076b041SPekka Enberg 	self->vmfd = ioctl(self->fd, KVM_CREATE_VM, 0);
67*4076b041SPekka Enberg 	if (self->vmfd < 0)
6828fa19c0SPekka Enberg 		die("open");
6928fa19c0SPekka Enberg 
70*4076b041SPekka Enberg 	if (!kvm__supports_extension(self, KVM_CAP_USER_MEMORY))
712da26a59SPekka Enberg 		die("KVM_CAP_USER_MEMORY");
722da26a59SPekka Enberg 
73*4076b041SPekka Enberg 	return self;
74*4076b041SPekka Enberg }
75*4076b041SPekka Enberg 
76*4076b041SPekka Enberg int main(int argc, char *argv[])
77*4076b041SPekka Enberg {
78*4076b041SPekka Enberg 	struct cpu *cpu;
79*4076b041SPekka Enberg 	struct kvm *kvm;
80*4076b041SPekka Enberg 	int ret;
81*4076b041SPekka Enberg 
82*4076b041SPekka Enberg 	kvm = kvm__init();
83*4076b041SPekka Enberg 
84b8f6afcdSPekka Enberg 	cpu = cpu__new();
85b8f6afcdSPekka Enberg 
86b8f6afcdSPekka Enberg 	cpu__reset(cpu);
87b8f6afcdSPekka Enberg 
88b8f6afcdSPekka Enberg 	return 0;
89b8f6afcdSPekka Enberg }
90