Merge branch 'stable-0.10' of git://git.sv.gnu.org/qemu into stable-0.10
[qemu-kvm/fedora.git] / kvm / libkvm / libkvm-x86.c
blob54247133c6c576c6e049fd59230c1df50863835d
1 #include "libkvm.h"
2 #include "kvm-x86.h"
3 #include <errno.h>
4 #include <sys/ioctl.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <stropts.h>
8 #include <sys/mman.h>
9 #include <stdio.h>
10 #include <errno.h>
11 #include <sys/types.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <stdlib.h>
16 int kvm_set_tss_addr(kvm_context_t kvm, unsigned long addr)
18 #ifdef KVM_CAP_SET_TSS_ADDR
19 int r;
21 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
22 if (r > 0) {
23 r = ioctl(kvm->vm_fd, KVM_SET_TSS_ADDR, addr);
24 if (r == -1) {
25 fprintf(stderr, "kvm_set_tss_addr: %m\n");
26 return -errno;
28 return 0;
30 #endif
31 return -ENOSYS;
34 static int kvm_init_tss(kvm_context_t kvm)
36 #ifdef KVM_CAP_SET_TSS_ADDR
37 int r;
39 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_SET_TSS_ADDR);
40 if (r > 0) {
42 * this address is 3 pages before the bios, and the bios should present
43 * as unavaible memory
45 r = kvm_set_tss_addr(kvm, 0xfffbd000);
46 if (r < 0) {
47 fprintf(stderr, "kvm_init_tss: unable to set tss addr\n");
48 return r;
52 #endif
53 return 0;
56 int kvm_create_pit(kvm_context_t kvm)
58 #ifdef KVM_CAP_PIT
59 int r;
61 kvm->pit_in_kernel = 0;
62 if (!kvm->no_pit_creation) {
63 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_PIT);
64 if (r > 0) {
65 r = ioctl(kvm->vm_fd, KVM_CREATE_PIT);
66 if (r >= 0)
67 kvm->pit_in_kernel = 1;
68 else {
69 fprintf(stderr, "Create kernel PIC irqchip failed\n");
70 return r;
74 #endif
75 return 0;
78 int kvm_arch_create(kvm_context_t kvm, unsigned long phys_mem_bytes,
79 void **vm_mem)
81 int r = 0;
83 r = kvm_init_tss(kvm);
84 if (r < 0)
85 return r;
87 r = kvm_create_pit(kvm);
88 if (r < 0)
89 return r;
91 r = kvm_init_coalesced_mmio(kvm);
92 if (r < 0)
93 return r;
95 return 0;
98 #ifdef KVM_EXIT_TPR_ACCESS
100 static int handle_tpr_access(kvm_context_t kvm, struct kvm_run *run, int vcpu)
102 return kvm->callbacks->tpr_access(kvm->opaque, vcpu,
103 run->tpr_access.rip,
104 run->tpr_access.is_write);
108 int kvm_enable_vapic(kvm_context_t kvm, int vcpu, uint64_t vapic)
110 int r;
111 struct kvm_vapic_addr va = {
112 .vapic_addr = vapic,
115 r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_VAPIC_ADDR, &va);
116 if (r == -1) {
117 r = -errno;
118 perror("kvm_enable_vapic");
119 return r;
121 return 0;
124 #endif
126 int kvm_arch_run(struct kvm_run *run,kvm_context_t kvm, int vcpu)
128 int r = 0;
130 switch (run->exit_reason) {
131 #ifdef KVM_EXIT_SET_TPR
132 case KVM_EXIT_SET_TPR:
133 break;
134 #endif
135 #ifdef KVM_EXIT_TPR_ACCESS
136 case KVM_EXIT_TPR_ACCESS:
137 r = handle_tpr_access(kvm, run, vcpu);
138 break;
139 #endif
140 default:
141 r = 1;
142 break;
145 return r;
148 #define MAX_ALIAS_SLOTS 4
149 static struct {
150 uint64_t start;
151 uint64_t len;
152 } kvm_aliases[MAX_ALIAS_SLOTS];
154 static int get_alias_slot(uint64_t start)
156 int i;
158 for (i=0; i<MAX_ALIAS_SLOTS; i++)
159 if (kvm_aliases[i].start == start)
160 return i;
161 return -1;
163 static int get_free_alias_slot(void)
165 int i;
167 for (i=0; i<MAX_ALIAS_SLOTS; i++)
168 if (kvm_aliases[i].len == 0)
169 return i;
170 return -1;
173 static void register_alias(int slot, uint64_t start, uint64_t len)
175 kvm_aliases[slot].start = start;
176 kvm_aliases[slot].len = len;
179 int kvm_create_memory_alias(kvm_context_t kvm,
180 uint64_t phys_start,
181 uint64_t len,
182 uint64_t target_phys)
184 struct kvm_memory_alias alias = {
185 .flags = 0,
186 .guest_phys_addr = phys_start,
187 .memory_size = len,
188 .target_phys_addr = target_phys,
190 int fd = kvm->vm_fd;
191 int r;
192 int slot;
194 slot = get_alias_slot(phys_start);
195 if (slot < 0)
196 slot = get_free_alias_slot();
197 if (slot < 0)
198 return -EBUSY;
199 alias.slot = slot;
201 r = ioctl(fd, KVM_SET_MEMORY_ALIAS, &alias);
202 if (r == -1)
203 return -errno;
205 register_alias(slot, phys_start, len);
206 return 0;
209 int kvm_destroy_memory_alias(kvm_context_t kvm, uint64_t phys_start)
211 return kvm_create_memory_alias(kvm, phys_start, 0, 0);
214 #ifdef KVM_CAP_IRQCHIP
216 int kvm_get_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
218 int r;
219 if (!kvm->irqchip_in_kernel)
220 return 0;
221 r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_LAPIC, s);
222 if (r == -1) {
223 r = -errno;
224 perror("kvm_get_lapic");
226 return r;
229 int kvm_set_lapic(kvm_context_t kvm, int vcpu, struct kvm_lapic_state *s)
231 int r;
232 if (!kvm->irqchip_in_kernel)
233 return 0;
234 r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_LAPIC, s);
235 if (r == -1) {
236 r = -errno;
237 perror("kvm_set_lapic");
239 return r;
242 #endif
244 #ifdef KVM_CAP_PIT
246 int kvm_get_pit(kvm_context_t kvm, struct kvm_pit_state *s)
248 int r;
249 if (!kvm->pit_in_kernel)
250 return 0;
251 r = ioctl(kvm->vm_fd, KVM_GET_PIT, s);
252 if (r == -1) {
253 r = -errno;
254 perror("kvm_get_pit");
256 return r;
259 int kvm_set_pit(kvm_context_t kvm, struct kvm_pit_state *s)
261 int r;
262 if (!kvm->pit_in_kernel)
263 return 0;
264 r = ioctl(kvm->vm_fd, KVM_SET_PIT, s);
265 if (r == -1) {
266 r = -errno;
267 perror("kvm_set_pit");
269 return r;
272 #endif
274 void kvm_show_code(kvm_context_t kvm, int vcpu)
276 #define SHOW_CODE_LEN 50
277 int fd = kvm->vcpu_fd[vcpu];
278 struct kvm_regs regs;
279 struct kvm_sregs sregs;
280 int r, n;
281 int back_offset;
282 unsigned char code;
283 char code_str[SHOW_CODE_LEN * 3 + 1];
284 unsigned long rip;
286 r = ioctl(fd, KVM_GET_SREGS, &sregs);
287 if (r == -1) {
288 perror("KVM_GET_SREGS");
289 return;
291 r = ioctl(fd, KVM_GET_REGS, &regs);
292 if (r == -1) {
293 perror("KVM_GET_REGS");
294 return;
296 rip = sregs.cs.base + regs.rip;
297 back_offset = regs.rip;
298 if (back_offset > 20)
299 back_offset = 20;
300 *code_str = 0;
301 for (n = -back_offset; n < SHOW_CODE_LEN-back_offset; ++n) {
302 if (n == 0)
303 strcat(code_str, " -->");
304 r = kvm->callbacks->mmio_read(kvm->opaque, rip + n, &code, 1);
305 if (r < 0) {
306 strcat(code_str, " xx");
307 continue;
309 sprintf(code_str + strlen(code_str), " %02x", code);
311 fprintf(stderr, "code:%s\n", code_str);
316 * Returns available msr list. User must free.
318 struct kvm_msr_list *kvm_get_msr_list(kvm_context_t kvm)
320 struct kvm_msr_list sizer, *msrs;
321 int r, e;
323 sizer.nmsrs = 0;
324 r = ioctl(kvm->fd, KVM_GET_MSR_INDEX_LIST, &sizer);
325 if (r == -1 && errno != E2BIG)
326 return NULL;
327 msrs = malloc(sizeof *msrs + sizer.nmsrs * sizeof *msrs->indices);
328 if (!msrs) {
329 errno = ENOMEM;
330 return NULL;
332 msrs->nmsrs = sizer.nmsrs;
333 r = ioctl(kvm->fd, KVM_GET_MSR_INDEX_LIST, msrs);
334 if (r == -1) {
335 e = errno;
336 free(msrs);
337 errno = e;
338 return NULL;
340 return msrs;
343 int kvm_get_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
344 int n)
346 struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
347 int r, e;
349 if (!kmsrs) {
350 errno = ENOMEM;
351 return -1;
353 kmsrs->nmsrs = n;
354 memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
355 r = ioctl(kvm->vcpu_fd[vcpu], KVM_GET_MSRS, kmsrs);
356 e = errno;
357 memcpy(msrs, kmsrs->entries, n * sizeof *msrs);
358 free(kmsrs);
359 errno = e;
360 return r;
363 int kvm_set_msrs(kvm_context_t kvm, int vcpu, struct kvm_msr_entry *msrs,
364 int n)
366 struct kvm_msrs *kmsrs = malloc(sizeof *kmsrs + n * sizeof *msrs);
367 int r, e;
369 if (!kmsrs) {
370 errno = ENOMEM;
371 return -1;
373 kmsrs->nmsrs = n;
374 memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
375 r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_MSRS, kmsrs);
376 e = errno;
377 free(kmsrs);
378 errno = e;
379 return r;
382 static void print_seg(FILE *file, const char *name, struct kvm_segment *seg)
384 fprintf(stderr,
385 "%s %04x (%08llx/%08x p %d dpl %d db %d s %d type %x l %d"
386 " g %d avl %d)\n",
387 name, seg->selector, seg->base, seg->limit, seg->present,
388 seg->dpl, seg->db, seg->s, seg->type, seg->l, seg->g,
389 seg->avl);
392 static void print_dt(FILE *file, const char *name, struct kvm_dtable *dt)
394 fprintf(stderr, "%s %llx/%x\n", name, dt->base, dt->limit);
397 void kvm_show_regs(kvm_context_t kvm, int vcpu)
399 int fd = kvm->vcpu_fd[vcpu];
400 struct kvm_regs regs;
401 struct kvm_sregs sregs;
402 int r;
404 r = ioctl(fd, KVM_GET_REGS, &regs);
405 if (r == -1) {
406 perror("KVM_GET_REGS");
407 return;
409 fprintf(stderr,
410 "rax %016llx rbx %016llx rcx %016llx rdx %016llx\n"
411 "rsi %016llx rdi %016llx rsp %016llx rbp %016llx\n"
412 "r8 %016llx r9 %016llx r10 %016llx r11 %016llx\n"
413 "r12 %016llx r13 %016llx r14 %016llx r15 %016llx\n"
414 "rip %016llx rflags %08llx\n",
415 regs.rax, regs.rbx, regs.rcx, regs.rdx,
416 regs.rsi, regs.rdi, regs.rsp, regs.rbp,
417 regs.r8, regs.r9, regs.r10, regs.r11,
418 regs.r12, regs.r13, regs.r14, regs.r15,
419 regs.rip, regs.rflags);
420 r = ioctl(fd, KVM_GET_SREGS, &sregs);
421 if (r == -1) {
422 perror("KVM_GET_SREGS");
423 return;
425 print_seg(stderr, "cs", &sregs.cs);
426 print_seg(stderr, "ds", &sregs.ds);
427 print_seg(stderr, "es", &sregs.es);
428 print_seg(stderr, "ss", &sregs.ss);
429 print_seg(stderr, "fs", &sregs.fs);
430 print_seg(stderr, "gs", &sregs.gs);
431 print_seg(stderr, "tr", &sregs.tr);
432 print_seg(stderr, "ldt", &sregs.ldt);
433 print_dt(stderr, "gdt", &sregs.gdt);
434 print_dt(stderr, "idt", &sregs.idt);
435 fprintf(stderr, "cr0 %llx cr2 %llx cr3 %llx cr4 %llx cr8 %llx"
436 " efer %llx\n",
437 sregs.cr0, sregs.cr2, sregs.cr3, sregs.cr4, sregs.cr8,
438 sregs.efer);
441 uint64_t kvm_get_apic_base(kvm_context_t kvm, int vcpu)
443 struct kvm_run *run = kvm->run[vcpu];
445 return run->apic_base;
448 void kvm_set_cr8(kvm_context_t kvm, int vcpu, uint64_t cr8)
450 struct kvm_run *run = kvm->run[vcpu];
452 run->cr8 = cr8;
455 __u64 kvm_get_cr8(kvm_context_t kvm, int vcpu)
457 return kvm->run[vcpu]->cr8;
460 int kvm_setup_cpuid(kvm_context_t kvm, int vcpu, int nent,
461 struct kvm_cpuid_entry *entries)
463 struct kvm_cpuid *cpuid;
464 int r;
466 cpuid = malloc(sizeof(*cpuid) + nent * sizeof(*entries));
467 if (!cpuid)
468 return -ENOMEM;
470 cpuid->nent = nent;
471 memcpy(cpuid->entries, entries, nent * sizeof(*entries));
472 r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_CPUID, cpuid);
474 free(cpuid);
475 return r;
478 int kvm_setup_cpuid2(kvm_context_t kvm, int vcpu, int nent,
479 struct kvm_cpuid_entry2 *entries)
481 struct kvm_cpuid2 *cpuid;
482 int r;
484 cpuid = malloc(sizeof(*cpuid) + nent * sizeof(*entries));
485 if (!cpuid)
486 return -ENOMEM;
488 cpuid->nent = nent;
489 memcpy(cpuid->entries, entries, nent * sizeof(*entries));
490 r = ioctl(kvm->vcpu_fd[vcpu], KVM_SET_CPUID2, cpuid);
491 if (r == -1) {
492 fprintf(stderr, "kvm_setup_cpuid2: %m\n");
493 return -errno;
495 free(cpuid);
496 return r;
499 int kvm_set_shadow_pages(kvm_context_t kvm, unsigned int nrshadow_pages)
501 #ifdef KVM_CAP_MMU_SHADOW_CACHE_CONTROL
502 int r;
504 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION,
505 KVM_CAP_MMU_SHADOW_CACHE_CONTROL);
506 if (r > 0) {
507 r = ioctl(kvm->vm_fd, KVM_SET_NR_MMU_PAGES, nrshadow_pages);
508 if (r == -1) {
509 fprintf(stderr, "kvm_set_shadow_pages: %m\n");
510 return -errno;
512 return 0;
514 #endif
515 return -1;
518 int kvm_get_shadow_pages(kvm_context_t kvm, unsigned int *nrshadow_pages)
520 #ifdef KVM_CAP_MMU_SHADOW_CACHE_CONTROL
521 int r;
523 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION,
524 KVM_CAP_MMU_SHADOW_CACHE_CONTROL);
525 if (r > 0) {
526 *nrshadow_pages = ioctl(kvm->vm_fd, KVM_GET_NR_MMU_PAGES);
527 return 0;
529 #endif
530 return -1;
533 #ifdef KVM_CAP_VAPIC
535 static int tpr_access_reporting(kvm_context_t kvm, int vcpu, int enabled)
537 int r;
538 struct kvm_tpr_access_ctl tac = {
539 .enabled = enabled,
542 r = ioctl(kvm->fd, KVM_CHECK_EXTENSION, KVM_CAP_VAPIC);
543 if (r == -1 || r == 0)
544 return -ENOSYS;
545 r = ioctl(kvm->vcpu_fd[vcpu], KVM_TPR_ACCESS_REPORTING, &tac);
546 if (r == -1) {
547 r = -errno;
548 perror("KVM_TPR_ACCESS_REPORTING");
549 return r;
551 return 0;
554 int kvm_enable_tpr_access_reporting(kvm_context_t kvm, int vcpu)
556 return tpr_access_reporting(kvm, vcpu, 1);
559 int kvm_disable_tpr_access_reporting(kvm_context_t kvm, int vcpu)
561 return tpr_access_reporting(kvm, vcpu, 0);
564 #endif
566 #ifdef KVM_CAP_EXT_CPUID
568 static struct kvm_cpuid2 *try_get_cpuid(kvm_context_t kvm, int max)
570 struct kvm_cpuid2 *cpuid;
571 int r, size;
573 size = sizeof(*cpuid) + max * sizeof(*cpuid->entries);
574 cpuid = (struct kvm_cpuid2 *)malloc(size);
575 cpuid->nent = max;
576 r = ioctl(kvm->fd, KVM_GET_SUPPORTED_CPUID, cpuid);
577 if (r == -1)
578 r = -errno;
579 else if (r == 0 && cpuid->nent >= max)
580 r = -E2BIG;
581 if (r < 0) {
582 if (r == -E2BIG) {
583 free(cpuid);
584 return NULL;
585 } else {
586 fprintf(stderr, "KVM_GET_SUPPORTED_CPUID failed: %s\n",
587 strerror(-r));
588 exit(1);
591 return cpuid;
594 #define R_EAX 0
595 #define R_ECX 1
596 #define R_EDX 2
597 #define R_EBX 3
598 #define R_ESP 4
599 #define R_EBP 5
600 #define R_ESI 6
601 #define R_EDI 7
603 uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg)
605 struct kvm_cpuid2 *cpuid;
606 int i, max;
607 uint32_t ret = 0;
608 uint32_t cpuid_1_edx;
610 if (!kvm_check_extension(kvm, KVM_CAP_EXT_CPUID)) {
611 return -1U;
614 max = 1;
615 while ((cpuid = try_get_cpuid(kvm, max)) == NULL) {
616 max *= 2;
619 for (i = 0; i < cpuid->nent; ++i) {
620 if (cpuid->entries[i].function == function) {
621 switch (reg) {
622 case R_EAX:
623 ret = cpuid->entries[i].eax;
624 break;
625 case R_EBX:
626 ret = cpuid->entries[i].ebx;
627 break;
628 case R_ECX:
629 ret = cpuid->entries[i].ecx;
630 break;
631 case R_EDX:
632 ret = cpuid->entries[i].edx;
633 if (function == 1) {
634 /* kvm misreports the following features
636 ret |= 1 << 12; /* MTRR */
637 ret |= 1 << 16; /* PAT */
638 ret |= 1 << 7; /* MCE */
639 ret |= 1 << 14; /* MCA */
642 /* On Intel, kvm returns cpuid according to
643 * the Intel spec, so add missing bits
644 * according to the AMD spec:
646 if (function == 0x80000001) {
647 cpuid_1_edx = kvm_get_supported_cpuid(kvm, 1, R_EDX);
648 ret |= cpuid_1_edx & 0xdfeff7ff;
650 break;
655 free(cpuid);
657 return ret;
660 #else
662 uint32_t kvm_get_supported_cpuid(kvm_context_t kvm, uint32_t function, int reg)
664 return -1U;
667 #endif