Make KVMSlot a real structure
[qemu] / kvm-all.c
1 /*
2  * QEMU KVM support
3  *
4  * Copyright IBM, Corp. 2008
5  *
6  * Authors:
7  *  Anthony Liguori   <aliguori@us.ibm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2 or later.
10  * See the COPYING file in the top-level directory.
11  *
12  */
13
14 #include <sys/types.h>
15 #include <sys/ioctl.h>
16 #include <sys/mman.h>
17 #include <stdarg.h>
18
19 #include <linux/kvm.h>
20
21 #include "qemu-common.h"
22 #include "sysemu.h"
23 #include "kvm.h"
24
25 //#define DEBUG_KVM
26
27 #ifdef DEBUG_KVM
28 #define dprintf(fmt, ...) \
29     do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0)
30 #else
31 #define dprintf(fmt, ...) \
32     do { } while (0)
33 #endif
34
35 typedef struct KVMSlot
36 {
37     target_phys_addr_t start_addr;
38     ram_addr_t memory_size;
39     ram_addr_t phys_offset;
40     int slot;
41     int flags;
42 } KVMSlot;
43
44 int kvm_allowed = 0;
45
46 struct KVMState
47 {
48     KVMSlot slots[32];
49     int fd;
50     int vmfd;
51 };
52
53 static KVMState *kvm_state;
54
55 static KVMSlot *kvm_alloc_slot(KVMState *s)
56 {
57     int i;
58
59     for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
60         /* KVM private memory slots */
61         if (i >= 8 && i < 12)
62             continue;
63         if (s->slots[i].memory_size == 0)
64             return &s->slots[i];
65     }
66
67     return NULL;
68 }
69
70 static KVMSlot *kvm_lookup_slot(KVMState *s, target_phys_addr_t start_addr)
71 {
72     int i;
73
74     for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
75         KVMSlot *mem = &s->slots[i];
76
77         if (start_addr >= mem->start_addr &&
78             start_addr < (mem->start_addr + mem->memory_size))
79             return mem;
80     }
81
82     return NULL;
83 }
84
85 int kvm_init_vcpu(CPUState *env)
86 {
87     KVMState *s = kvm_state;
88     long mmap_size;
89     int ret;
90
91     dprintf("kvm_init_vcpu\n");
92
93     ret = kvm_vm_ioctl(s, KVM_CREATE_VCPU, env->cpu_index);
94     if (ret < 0) {
95         dprintf("kvm_create_vcpu failed\n");
96         goto err;
97     }
98
99     env->kvm_fd = ret;
100     env->kvm_state = s;
101
102     mmap_size = kvm_ioctl(s, KVM_GET_VCPU_MMAP_SIZE, 0);
103     if (mmap_size < 0) {
104         dprintf("KVM_GET_VCPU_MMAP_SIZE failed\n");
105         goto err;
106     }
107
108     env->kvm_run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, MAP_SHARED,
109                         env->kvm_fd, 0);
110     if (env->kvm_run == MAP_FAILED) {
111         ret = -errno;
112         dprintf("mmap'ing vcpu state failed\n");
113         goto err;
114     }
115
116     ret = kvm_arch_init_vcpu(env);
117
118 err:
119     return ret;
120 }
121
122 int kvm_init(int smp_cpus)
123 {
124     KVMState *s;
125     int ret;
126     int i;
127
128     if (smp_cpus > 1)
129         return -EINVAL;
130
131     s = qemu_mallocz(sizeof(KVMState));
132     if (s == NULL)
133         return -ENOMEM;
134
135     for (i = 0; i < ARRAY_SIZE(s->slots); i++)
136         s->slots[i].slot = i;
137
138     s->vmfd = -1;
139     s->fd = open("/dev/kvm", O_RDWR);
140     if (s->fd == -1) {
141         fprintf(stderr, "Could not access KVM kernel module: %m\n");
142         ret = -errno;
143         goto err;
144     }
145
146     ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0);
147     if (ret < KVM_API_VERSION) {
148         if (ret > 0)
149             ret = -EINVAL;
150         fprintf(stderr, "kvm version too old\n");
151         goto err;
152     }
153
154     if (ret > KVM_API_VERSION) {
155         ret = -EINVAL;
156         fprintf(stderr, "kvm version not supported\n");
157         goto err;
158     }
159
160     s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0);
161     if (s->vmfd < 0)
162         goto err;
163
164     /* initially, KVM allocated its own memory and we had to jump through
165      * hooks to make phys_ram_base point to this.  Modern versions of KVM
166      * just use a user allocated buffer so we can use phys_ram_base
167      * unmodified.  Make sure we have a sufficiently modern version of KVM.
168      */
169     ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY);
170     if (ret <= 0) {
171         if (ret == 0)
172             ret = -EINVAL;
173         fprintf(stderr, "kvm does not support KVM_CAP_USER_MEMORY\n");
174         goto err;
175     }
176
177     ret = kvm_arch_init(s, smp_cpus);
178     if (ret < 0)
179         goto err;
180
181     kvm_state = s;
182
183     return 0;
184
185 err:
186     if (s) {
187         if (s->vmfd != -1)
188             close(s->vmfd);
189         if (s->fd != -1)
190             close(s->fd);
191     }
192     qemu_free(s);
193
194     return ret;
195 }
196
197 static int kvm_handle_io(CPUState *env, uint16_t port, void *data,
198                          int direction, int size, uint32_t count)
199 {
200     int i;
201     uint8_t *ptr = data;
202
203     for (i = 0; i < count; i++) {
204         if (direction == KVM_EXIT_IO_IN) {
205             switch (size) {
206             case 1:
207                 stb_p(ptr, cpu_inb(env, port));
208                 break;
209             case 2:
210                 stw_p(ptr, cpu_inw(env, port));
211                 break;
212             case 4:
213                 stl_p(ptr, cpu_inl(env, port));
214                 break;
215             }
216         } else {
217             switch (size) {
218             case 1:
219                 cpu_outb(env, port, ldub_p(ptr));
220                 break;
221             case 2:
222                 cpu_outw(env, port, lduw_p(ptr));
223                 break;
224             case 4:
225                 cpu_outl(env, port, ldl_p(ptr));
226                 break;
227             }
228         }
229
230         ptr += size;
231     }
232
233     return 1;
234 }
235
236 int kvm_cpu_exec(CPUState *env)
237 {
238     struct kvm_run *run = env->kvm_run;
239     int ret;
240
241     dprintf("kvm_cpu_exec()\n");
242
243     do {
244         kvm_arch_pre_run(env, run);
245
246         if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) {
247             dprintf("interrupt exit requested\n");
248             ret = 0;
249             break;
250         }
251
252         ret = kvm_vcpu_ioctl(env, KVM_RUN, 0);
253         kvm_arch_post_run(env, run);
254
255         if (ret == -EINTR || ret == -EAGAIN) {
256             dprintf("io window exit\n");
257             ret = 0;
258             break;
259         }
260
261         if (ret < 0) {
262             dprintf("kvm run failed %s\n", strerror(-ret));
263             abort();
264         }
265
266         ret = 0; /* exit loop */
267         switch (run->exit_reason) {
268         case KVM_EXIT_IO:
269             dprintf("handle_io\n");
270             ret = kvm_handle_io(env, run->io.port,
271                                 (uint8_t *)run + run->io.data_offset,
272                                 run->io.direction,
273                                 run->io.size,
274                                 run->io.count);
275             break;
276         case KVM_EXIT_MMIO:
277             dprintf("handle_mmio\n");
278             cpu_physical_memory_rw(run->mmio.phys_addr,
279                                    run->mmio.data,
280                                    run->mmio.len,
281                                    run->mmio.is_write);
282             ret = 1;
283             break;
284         case KVM_EXIT_IRQ_WINDOW_OPEN:
285             dprintf("irq_window_open\n");
286             break;
287         case KVM_EXIT_SHUTDOWN:
288             dprintf("shutdown\n");
289             qemu_system_reset_request();
290             ret = 1;
291             break;
292         case KVM_EXIT_UNKNOWN:
293             dprintf("kvm_exit_unknown\n");
294             break;
295         case KVM_EXIT_FAIL_ENTRY:
296             dprintf("kvm_exit_fail_entry\n");
297             break;
298         case KVM_EXIT_EXCEPTION:
299             dprintf("kvm_exit_exception\n");
300             break;
301         case KVM_EXIT_DEBUG:
302             dprintf("kvm_exit_debug\n");
303             break;
304         default:
305             dprintf("kvm_arch_handle_exit\n");
306             ret = kvm_arch_handle_exit(env, run);
307             break;
308         }
309     } while (ret > 0);
310
311     if ((env->interrupt_request & CPU_INTERRUPT_EXIT)) {
312         env->interrupt_request &= ~CPU_INTERRUPT_EXIT;
313         env->exception_index = EXCP_INTERRUPT;
314     }
315
316     return ret;
317 }
318
319 static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
320 {
321     struct kvm_userspace_memory_region mem;
322
323     mem.slot = slot->slot;
324     mem.guest_phys_addr = slot->start_addr;
325     mem.memory_size = slot->memory_size;
326     mem.userspace_addr = (unsigned long)phys_ram_base + slot->phys_offset;
327     mem.flags = slot->flags;
328
329     return kvm_vm_ioctl(s, KVM_SET_USER_MEMORY_REGION, &mem);
330 }
331
332 void kvm_set_phys_mem(target_phys_addr_t start_addr,
333                       ram_addr_t size,
334                       ram_addr_t phys_offset)
335 {
336     KVMState *s = kvm_state;
337     ram_addr_t flags = phys_offset & ~TARGET_PAGE_MASK;
338     KVMSlot *mem;
339
340     /* KVM does not support read-only slots */
341     phys_offset &= ~IO_MEM_ROM;
342
343     mem = kvm_lookup_slot(s, start_addr);
344     if (mem) {
345         if ((flags == IO_MEM_UNASSIGNED) || (flags >= TLB_MMIO)) {
346             mem->memory_size = 0;
347             mem->start_addr = start_addr;
348             mem->phys_offset = 0;
349             mem->flags = 0;
350
351             kvm_set_user_memory_region(s, mem);
352         } else if (start_addr >= mem->start_addr &&
353                    (start_addr + size) <= (mem->start_addr +
354                                            mem->memory_size)) {
355             KVMSlot slot;
356             target_phys_addr_t mem_start;
357             ram_addr_t mem_size, mem_offset;
358
359             /* Not splitting */
360             if ((phys_offset - (start_addr - mem->start_addr)) == 
361                 mem->phys_offset)
362                 return;
363
364             /* unregister whole slot */
365             memcpy(&slot, mem, sizeof(slot));
366             mem->memory_size = 0;
367             kvm_set_user_memory_region(s, mem);
368
369             /* register prefix slot */
370             mem_start = slot.start_addr;
371             mem_size = start_addr - slot.start_addr;
372             mem_offset = slot.phys_offset;
373             if (mem_size)
374                 kvm_set_phys_mem(mem_start, mem_size, mem_offset);
375
376             /* register new slot */
377             kvm_set_phys_mem(start_addr, size, phys_offset);
378
379             /* register suffix slot */
380             mem_start = start_addr + size;
381             mem_offset += mem_size + size;
382             mem_size = slot.memory_size - mem_size - size;
383             if (mem_size)
384                 kvm_set_phys_mem(mem_start, mem_size, mem_offset);
385
386             return;
387         } else {
388             printf("Registering overlapping slot\n");
389             abort();
390         }
391     }
392     /* KVM does not need to know about this memory */
393     if (flags >= IO_MEM_UNASSIGNED)
394         return;
395
396     mem = kvm_alloc_slot(s);
397     mem->memory_size = size;
398     mem->start_addr = start_addr;
399     mem->phys_offset = phys_offset;
400     mem->flags = 0;
401
402     kvm_set_user_memory_region(s, mem);
403     /* FIXME deal with errors */
404 }
405
406 int kvm_ioctl(KVMState *s, int type, ...)
407 {
408     int ret;
409     void *arg;
410     va_list ap;
411
412     va_start(ap, type);
413     arg = va_arg(ap, void *);
414     va_end(ap);
415
416     ret = ioctl(s->fd, type, arg);
417     if (ret == -1)
418         ret = -errno;
419
420     return ret;
421 }
422
423 int kvm_vm_ioctl(KVMState *s, int type, ...)
424 {
425     int ret;
426     void *arg;
427     va_list ap;
428
429     va_start(ap, type);
430     arg = va_arg(ap, void *);
431     va_end(ap);
432
433     ret = ioctl(s->vmfd, type, arg);
434     if (ret == -1)
435         ret = -errno;
436
437     return ret;
438 }
439
440 int kvm_vcpu_ioctl(CPUState *env, int type, ...)
441 {
442     int ret;
443     void *arg;
444     va_list ap;
445
446     va_start(ap, type);
447     arg = va_arg(ap, void *);
448     va_end(ap);
449
450     ret = ioctl(env->kvm_fd, type, arg);
451     if (ret == -1)
452         ret = -errno;
453
454     return ret;
455 }