kvm: libkvm: move msr functions to libkvm-x86.c
[qemu-kvm/amd-iommu.git] / kvm / libkvm / libkvm-x86.c
blobb9ff47d867fc8bc93bab133147e4ed3a084e5d47
1 #include "libkvm.h"
2 #include "kvm-x86.h"
3 #include "kvm-abi-10.h"
4 #include <errno.h>
5 #include <sys/ioctl.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <stropts.h>
9 #include <sys/mman.h>
10 #include <stdio.h>
11 #include <errno.h>
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include <stdlib.h>
17 int kvm_alloc_kernel_memory(kvm_context_t kvm, unsigned long memory,
18 void **vm_mem)
20 unsigned long dosmem = 0xa0000;
21 unsigned long exmem = 0xc0000;
22 unsigned long pcimem = 0xe0000000;
23 int r;
24 int tss_ext;
25 struct kvm_memory_region low_memory = {
26 .memory_size = memory < dosmem ? memory : dosmem,
27 .guest_phys_addr = 0,
29 struct kvm_memory_region extended_memory = {
30 .memory_size = memory < exmem ? 0 : memory - exmem,
31 .guest_phys_addr = exmem,
33 struct kvm_memory_region above_4g_memory = {
34 .memory_size = memory < pcimem ? 0 : memory - pcimem,
35 .guest_phys_addr = 0x100000000ULL,
38 #ifdef KVM_CAP_SET_TSS_ADDR
39 tss_ext = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
40 #else
41 tss_ext = 0;
42 #endif
44 if (memory >= pcimem)
45 extended_memory.memory_size = pcimem - exmem;
47 /* 640K should be enough. */
48 low_memory.slot = get_free_slot(kvm);
49 r = ioctl(kvm->vm_fd, KVM_SET_MEMORY_REGION, &low_memory);
50 if (r == -1) {
51 fprintf(stderr, "kvm_create_memory_region: %m\n");
52 return -1;
54 register_slot(low_memory.slot, low_memory.guest_phys_addr);
56 if (extended_memory.memory_size) {
57 if (tss_ext > 0)
58 extended_memory.slot = get_free_slot(kvm);
59 else
60 extended_memory.slot = 0;
61 r = ioctl(kvm->vm_fd, KVM_SET_MEMORY_REGION, &extended_memory);
62 if (r == -1) {
63 fprintf(stderr, "kvm_create_memory_region: %m\n");
64 return -1;
66 register_slot(extended_memory.slot,
67 extended_memory.guest_phys_addr);
70 if (above_4g_memory.memory_size) {
71 above_4g_memory.slot = get_free_slot(kvm);
72 r = ioctl(kvm->vm_fd, KVM_SET_MEMORY_REGION, &above_4g_memory);
73 if (r == -1) {
74 fprintf(stderr, "kvm_create_memory_region: %m\n");
75 return -1;
77 register_slot(above_4g_memory.slot,
78 above_4g_memory.guest_phys_addr);
81 kvm_memory_region_save_params(kvm, &low_memory);
82 kvm_memory_region_save_params(kvm, &extended_memory);
83 kvm_memory_region_save_params(kvm, &above_4g_memory);
84 if (above_4g_memory.memory_size)
85 kvm_memory_region_save_params(kvm, &above_4g_memory);
87 *vm_mem = mmap(NULL, memory, PROT_READ|PROT_WRITE, MAP_SHARED, kvm->vm_fd, 0);
89 return 0;
93 #ifdef KVM_CAP_USER_MEMORY
95 int kvm_alloc_userspace_memory(kvm_context_t kvm, unsigned long memory,
96 void **vm_mem)
98 unsigned long dosmem = 0xa0000;
99 unsigned long exmem = 0xc0000;
100 unsigned long pcimem = 0xe0000000;
101 int r;
102 int tss_ext;
103 struct kvm_userspace_memory_region low_memory = {
104 .memory_size = memory < dosmem ? memory : dosmem,
105 .guest_phys_addr = 0,
107 struct kvm_userspace_memory_region extended_memory = {
108 .memory_size = memory < exmem ? 0 : memory - exmem,
109 .guest_phys_addr = exmem,
111 struct kvm_userspace_memory_region above_4g_memory = {
112 .memory_size = memory < pcimem ? 0 : memory - pcimem,
113 .guest_phys_addr = 0x100000000ULL,
116 #ifdef KVM_CAP_SET_TSS_ADDR
117 tss_ext = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
118 #else
119 tss_ext = 0;
120 #endif
122 if (memory >= pcimem) {
123 extended_memory.memory_size = pcimem - exmem;
124 *vm_mem = mmap(NULL, memory + 0x100000000ULL - pcimem,
125 PROT_READ|PROT_WRITE, MAP_ANONYMOUS |
126 MAP_SHARED, -1, 0);
128 else
129 *vm_mem = mmap(NULL, memory, PROT_READ|PROT_WRITE, MAP_ANONYMOUS
130 | MAP_SHARED, -1, 0);
131 if (*vm_mem == MAP_FAILED) {
132 fprintf(stderr, "kvm_alloc_userspace_memory: %s", strerror(errno));
133 return -1;
136 low_memory.userspace_addr = (unsigned long)*vm_mem;
137 low_memory.slot = get_free_slot(kvm);
138 /* 640K should be enough. */
139 r = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, &low_memory);
140 if (r == -1) {
141 fprintf(stderr, "kvm_create_memory_region: %m\n");
142 return -1;
144 register_slot(low_memory.slot, low_memory.guest_phys_addr);
146 if (extended_memory.memory_size) {
147 r = munmap(*vm_mem + dosmem, exmem - dosmem);
148 if (r == -1) {
149 fprintf(stderr, "kvm_alloc_userspace_memory: %s",
150 strerror(errno));
151 return -1;
153 extended_memory.userspace_addr = (unsigned long)(*vm_mem + exmem);
154 if (tss_ext > 0)
155 extended_memory.slot = get_free_slot(kvm);
156 else
157 extended_memory.slot = 0;
158 r = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, &extended_memory);
159 if (r == -1) {
160 fprintf(stderr, "kvm_create_memory_region: %m\n");
161 return -1;
163 register_slot(extended_memory.slot,
164 extended_memory.guest_phys_addr);
167 if (above_4g_memory.memory_size) {
168 r = munmap(*vm_mem + pcimem, 0x100000000ULL - pcimem);
169 if (r == -1) {
170 fprintf(stderr, "kvm_alloc_userspace_memory: %s",
171 strerror(errno));
172 return -1;
174 above_4g_memory.userspace_addr = (unsigned long)(*vm_mem + 0x100000000ULL);
175 above_4g_memory.slot = get_free_slot(kvm);
176 r = ioctl(kvm->vm_fd, KVM_SET_USER_MEMORY_REGION, &above_4g_memory);
177 if (r == -1) {
178 fprintf(stderr, "kvm_create_memory_region: %m\n");
179 return -1;
181 register_slot(above_4g_memory.slot,
182 above_4g_memory.guest_phys_addr);
185 kvm_userspace_memory_region_save_params(kvm, &low_memory);
186 kvm_userspace_memory_region_save_params(kvm, &extended_memory);
187 if (above_4g_memory.memory_size)
188 kvm_userspace_memory_region_save_params(kvm, &above_4g_memory);
190 return 0;
193 #endif
195 int kvm_set_tss_addr(kvm_context_t kvm, unsigned long addr)
197 #ifdef KVM_CAP_SET_TSS_ADDR
198 int r;
200 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
201 if (r > 0) {
202 r = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, addr);
203 if (r == -1) {
204 fprintf(stderr, "kvm_set_tss_addr: %m\n");
205 return -errno;
207 return 0;
209 #endif
210 return -ENOSYS;
213 static int kvm_init_tss(kvm_context_t kvm)
215 #ifdef KVM_CAP_SET_TSS_ADDR
216 int r;
218 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
219 if (r > 0) {
221 * this address is 3 pages before the bios, and the bios should present
222 * as unavaible memory
224 r = kvm_set_tss_addr(kvm, 0xfffbd000);
225 if (r < 0) {
226 printf("kvm_init_tss: unable to set tss addr\n");
227 return r;
231 #endif
232 return 0;
235 int kvm_arch_create_default_phys_mem(kvm_context_t kvm,
236 unsigned long phys_mem_bytes,
237 void **vm_mem)
239 int zfd;
241 zfd = open("/dev/zero", O_RDONLY);
242 if (zfd == -1) {
243 perror("open /dev/zero");
244 return -1;
246 mmap(*vm_mem + 0xa8000, 0x8000, PROT_READ|PROT_WRITE,
247 MAP_PRIVATE|MAP_FIXED, zfd, 0);
248 close(zfd);
250 return 0;
254 int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
255 void **vm_mem)
257 int r = 0;
259 r = kvm_init_tss(kvm);
260 if (r < 0)
261 return r;
263 return 0;
266 void *kvm_create_kernel_phys_mem(kvm_context_t kvm, unsigned long phys_start,
267 unsigned long len, int log, int writable)
269 int r;
270 int prot = PROT_READ;
271 void *ptr;
272 struct kvm_memory_region memory = {
273 .memory_size = len,
274 .guest_phys_addr = phys_start,
275 .flags = log ? KVM_MEM_LOG_DIRTY_PAGES : 0,
278 memory.slot = get_free_slot(kvm);
279 r = ioctl(kvm->vm_fd, KVM_SET_MEMORY_REGION, &memory);
280 if (r == -1) {
281 fprintf(stderr, "create_kernel_phys_mem: %s", strerror(errno));
282 return 0;
284 register_slot(memory.slot, memory.guest_phys_addr);
285 kvm_memory_region_save_params(kvm, &memory);
287 if (writable)
288 prot |= PROT_WRITE;
290 ptr = mmap(NULL, len, prot, MAP_SHARED, kvm->vm_fd, phys_start);
291 if (ptr == MAP_FAILED) {
292 fprintf(stderr, "create_kernel_phys_mem: %s", strerror(errno));
293 return 0;
296 return ptr;
299 int kvm_create_memory_alias(kvm_context_t kvm,
300 uint64_t phys_addr,
301 uint64_t phys_start,
302 uint64_t len,
303 uint64_t target_phys)
305 struct kvm_memory_alias alias = {
306 .flags = 0,
307 .guest_phys_addr = phys_start,
308 .memory_size = len,
309 .target_phys_addr = target_phys,
311 int fd = kvm->vm_fd;
312 int r;
314 alias.slot = get_slot(phys_addr);
316 r = ioctl(fd, KVM_SET_MEMORY_ALIAS, &alias);
317 if (r == -1)
318 return -errno;
320 return 0;
323 int kvm_destroy_memory_alias(kvm_context_t kvm, uint64_t phys_addr)
325 return kvm_create_memory_alias(kvm, phys_addr, 0, 0, 0);
328 #ifdef KVM_CAP_IRQCHIP
330 int kvm_get_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
332 int r;
333 if (!kvm->irqchip_in_kernel)
334 return 0;
335 r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_LAPIC, s);
336 if (r == -1) {
337 r = -errno;
338 perror("kvm_get_lapic");
340 return r;
343 int kvm_set_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
345 int r;
346 if (!kvm->irqchip_in_kernel)
347 return 0;
348 r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_LAPIC, s);
349 if (r == -1) {
350 r = -errno;
351 perror("kvm_set_lapic");
353 return r;
356 #endif
358 static int handle_io_abi10(kvm_context_t kvm, struct kvm_run_abi10 *run,
359 int vcpu)
361 uint16_t addr = run->io.port;
362 int r;
363 int i;
364 void *p = (void *)run + run->io.data_offset;
366 for (i = 0; i < run->io.count; ++i) {
367 switch (run->io.direction) {
368 case KVM_EXIT_IO_IN:
369 switch (run->io.size) {
370 case 1:
371 r = kvm->callbacks->inb(kvm->opaque, addr, p);
372 break;
373 case 2:
374 r = kvm->callbacks->inw(kvm->opaque, addr, p);
375 break;
376 case 4:
377 r = kvm->callbacks->inl(kvm->opaque, addr, p);
378 break;
379 default:
380 fprintf(stderr, "bad I/O size %d\n", run->io.size);
381 return -EMSGSIZE;
383 break;
384 case KVM_EXIT_IO_OUT:
385 switch (run->io.size) {
386 case 1:
387 r = kvm->callbacks->outb(kvm->opaque, addr,
388 *(uint8_t *)p);
389 break;
390 case 2:
391 r = kvm->callbacks->outw(kvm->opaque, addr,
392 *(uint16_t *)p);
393 break;
394 case 4:
395 r = kvm->callbacks->outl(kvm->opaque, addr,
396 *(uint32_t *)p);
397 break;
398 default:
399 fprintf(stderr, "bad I/O size %d\n", run->io.size);
400 return -EMSGSIZE;
402 break;
403 default:
404 fprintf(stderr, "bad I/O direction %d\n", run->io.direction);
405 return -EPROTO;
408 p += run->io.size;
410 run->io_completed = 1;
412 return 0;
415 static int handle_mmio_abi10(kvm_context_t kvm, struct kvm_run_abi10 *kvm_run)
417 unsigned long addr = kvm_run->mmio.phys_addr;
418 void *data = kvm_run->mmio.data;
419 int r = -1;
421 if (kvm_run->mmio.is_write) {
422 switch (kvm_run->mmio.len) {
423 case 1:
424 r = kvm->callbacks->writeb(kvm->opaque, addr,
425 *(uint8_t *)data);
426 break;
427 case 2:
428 r = kvm->callbacks->writew(kvm->opaque, addr,
429 *(uint16_t *)data);
430 break;
431 case 4:
432 r = kvm->callbacks->writel(kvm->opaque, addr,
433 *(uint32_t *)data);
434 break;
435 case 8:
436 r = kvm->callbacks->writeq(kvm->opaque, addr,
437 *(uint64_t *)data);
438 break;
440 } else {
441 switch (kvm_run->mmio.len) {
442 case 1:
443 r = kvm->callbacks->readb(kvm->opaque, addr,
444 (uint8_t *)data);
445 break;
446 case 2:
447 r = kvm->callbacks->readw(kvm->opaque, addr,
448 (uint16_t *)data);
449 break;
450 case 4:
451 r = kvm->callbacks->readl(kvm->opaque, addr,
452 (uint32_t *)data);
453 break;
454 case 8:
455 r = kvm->callbacks->readq(kvm->opaque, addr,
456 (uint64_t *)data);
457 break;
459 kvm_run->io_completed = 1;
461 return r;
464 int kvm_run_abi10(kvm_context_t kvm, int vcpu)
466 int r;
467 int fd = kvm->vcpu_fd[vcpu];
468 struct kvm_run_abi10 *run = (struct kvm_run_abi10 *)kvm->run[vcpu];
470 again:
471 run->request_interrupt_window = try_push_interrupts(kvm);
472 r = pre_kvm_run(kvm, vcpu);
473 if (r)
474 return r;
475 r = ioctl(fd, KVM_RUN, 0);
476 post_kvm_run(kvm, vcpu);
478 run->io_completed = 0;
479 if (r == -1 && errno != EINTR) {
480 r = -errno;
481 printf("kvm_run: %m\n");
482 return r;
484 if (r == -1) {
485 r = handle_io_window(kvm);
486 goto more;
488 if (1) {
489 switch (run->exit_reason) {
490 case KVM_EXIT_UNKNOWN:
491 fprintf(stderr, "unhandled vm exit: 0x%x vcpu_id %d\n",
492 (unsigned)run->hw.hardware_exit_reason, vcpu);
493 kvm_show_regs(kvm, vcpu);
494 abort();
495 break;
496 case KVM_EXIT_FAIL_ENTRY:
497 fprintf(stderr, "kvm_run: failed entry, reason %u\n",
498 (unsigned)run->fail_entry.hardware_entry_failure_reason & 0xffff);
499 return -ENOEXEC;
500 break;
501 case KVM_EXIT_EXCEPTION:
502 fprintf(stderr, "exception %d (%x)\n",
503 run->ex.exception,
504 run->ex.error_code);
505 kvm_show_regs(kvm, vcpu);
506 kvm_show_code(kvm, vcpu);
507 abort();
508 break;
509 case KVM_EXIT_IO:
510 r = handle_io_abi10(kvm, run, vcpu);
511 break;
512 case KVM_EXIT_DEBUG:
513 r = handle_debug(kvm, vcpu);
514 break;
515 case KVM_EXIT_MMIO:
516 r = handle_mmio_abi10(kvm, run);
517 break;
518 case KVM_EXIT_HLT:
519 r = handle_halt(kvm, vcpu);
520 break;
521 case KVM_EXIT_IRQ_WINDOW_OPEN:
522 break;
523 case KVM_EXIT_SHUTDOWN:
524 r = handle_shutdown(kvm, vcpu);
525 break;
526 default:
527 fprintf(stderr, "unhandled vm exit: 0x%x\n", run->exit_reason);
528 kvm_show_regs(kvm, vcpu);
529 abort();
530 break;
533 more:
534 if (!r)
535 goto again;
536 return r;
540 void kvm_show_code(kvm_context_t kvm, int vcpu)
542 #define CR0_PE_MASK (1ULL<<0)
543 int fd = kvm->vcpu_fd[vcpu];
544 struct kvm_regs regs;
545 struct kvm_sregs sregs;
546 int r;
547 unsigned char code[50];
548 int back_offset;
549 char code_str[sizeof(code) * 3 + 1];
550 unsigned long rip;
552 r = ioctl(fd, KVM_GET_SREGS, &sregs);
553 if (r == -1) {
554 perror("KVM_GET_SREGS");
555 return;
557 if (sregs.cr0 & CR0_PE_MASK)
558 return;
560 r = ioctl(fd, KVM_GET_REGS, &regs);
561 if (r == -1) {
562 perror("KVM_GET_REGS");
563 return;
565 rip = sregs.cs.base + regs.rip;
566 back_offset = regs.rip;
567 if (back_offset > 20)
568 back_offset = 20;
569 memcpy(code, kvm->physical_memory + rip - back_offset, sizeof code);
570 *code_str = 0;
571 for (r = 0; r < sizeof code; ++r) {
572 if (r == back_offset)
573 strcat(code_str, " -->");
574 sprintf(code_str + strlen(code_str), " %02x", code[r]);
576 fprintf(stderr, "code:%s\n", code_str);
581 * Returns available msr list. User must free.
583 struct kvm_msr_list *kvm_get_msr_list(kvm_context_t kvm)
585 struct kvm_msr_list sizer, *msrs;
586 int r, e;
588 sizer.nmsrs = 0;
589 r = ioctl(kvm->fd, KVM_GET_MSR_INDEX_LIST, &sizer);
590 if (r == -1 && errno != E2BIG)
591 return NULL;
592 msrs = malloc(sizeof *msrs + sizer.nmsrs * sizeof *msrs->indices);
593 if (!msrs) {
594 errno = ENOMEM;
595 return NULL;
597 msrs->nmsrs = sizer.nmsrs;
598 r = ioctl(kvm->fd, KVM_GET_MSR_INDEX_LIST, msrs);
599 if (r == -1) {
600 e = errno;
601 free(msrs);
602 errno = e;
603 return NULL;
605 return msrs;
608 int kvm_get_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
609 int n)
611 struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
612 int r, e;
614 if (!kmsrs) {
615 errno = ENOMEM;
616 return -1;
618 kmsrs->nmsrs = n;
619 memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
620 r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_MSRS, kmsrs);
621 e = errno;
622 memcpy(msrs, kmsrs->entries, n * sizeof *msrs);
623 free(kmsrs);
624 errno = e;
625 return r;
628 int kvm_set_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
629 int n)
631 struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
632 int r, e;
634 if (!kmsrs) {
635 errno = ENOMEM;
636 return -1;
638 kmsrs->nmsrs = n;
639 memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
640 r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_MSRS, kmsrs);
641 e = errno;
642 free(kmsrs);
643 errno = e;
644 return r;