1 /* 2 * tools/testing/selftests/kvm/lib/x86_64/processor.c 3 * 4 * Copyright (C) 2018, Google LLC. 5 * 6 * This work is licensed under the terms of the GNU GPL, version 2. 7 */ 8 9 #define _GNU_SOURCE /* for program_invocation_name */ 10 11 #include "test_util.h" 12 #include "kvm_util.h" 13 #include "../kvm_util_internal.h" 14 #include "processor.h" 15 16 /* Minimum physical address used for virtual translation tables. */ 17 #define KVM_GUEST_PAGE_TABLE_MIN_PADDR 0x180000 18 19 /* Virtual translation table structure declarations */ 20 struct pageMapL4Entry { 21 uint64_t present:1; 22 uint64_t writable:1; 23 uint64_t user:1; 24 uint64_t write_through:1; 25 uint64_t cache_disable:1; 26 uint64_t accessed:1; 27 uint64_t ignored_06:1; 28 uint64_t page_size:1; 29 uint64_t ignored_11_08:4; 30 uint64_t address:40; 31 uint64_t ignored_62_52:11; 32 uint64_t execute_disable:1; 33 }; 34 35 struct pageDirectoryPointerEntry { 36 uint64_t present:1; 37 uint64_t writable:1; 38 uint64_t user:1; 39 uint64_t write_through:1; 40 uint64_t cache_disable:1; 41 uint64_t accessed:1; 42 uint64_t ignored_06:1; 43 uint64_t page_size:1; 44 uint64_t ignored_11_08:4; 45 uint64_t address:40; 46 uint64_t ignored_62_52:11; 47 uint64_t execute_disable:1; 48 }; 49 50 struct pageDirectoryEntry { 51 uint64_t present:1; 52 uint64_t writable:1; 53 uint64_t user:1; 54 uint64_t write_through:1; 55 uint64_t cache_disable:1; 56 uint64_t accessed:1; 57 uint64_t ignored_06:1; 58 uint64_t page_size:1; 59 uint64_t ignored_11_08:4; 60 uint64_t address:40; 61 uint64_t ignored_62_52:11; 62 uint64_t execute_disable:1; 63 }; 64 65 struct pageTableEntry { 66 uint64_t present:1; 67 uint64_t writable:1; 68 uint64_t user:1; 69 uint64_t write_through:1; 70 uint64_t cache_disable:1; 71 uint64_t accessed:1; 72 uint64_t dirty:1; 73 uint64_t reserved_07:1; 74 uint64_t global:1; 75 uint64_t ignored_11_09:3; 76 uint64_t address:40; 77 uint64_t ignored_62_52:11; 78 uint64_t execute_disable:1; 79 }; 80 81 /* Register Dump 82 * 83 * Input Args: 84 * indent - Left margin indent amount 85 * regs - register 86 * 87 * Output Args: 88 * stream - Output FILE stream 89 * 90 * Return: None 91 * 92 * Dumps the state of the registers given by regs, to the FILE stream 93 * given by steam. 94 */ 95 void regs_dump(FILE *stream, struct kvm_regs *regs, 96 uint8_t indent) 97 { 98 fprintf(stream, "%*srax: 0x%.16llx rbx: 0x%.16llx " 99 "rcx: 0x%.16llx rdx: 0x%.16llx\n", 100 indent, "", 101 regs->rax, regs->rbx, regs->rcx, regs->rdx); 102 fprintf(stream, "%*srsi: 0x%.16llx rdi: 0x%.16llx " 103 "rsp: 0x%.16llx rbp: 0x%.16llx\n", 104 indent, "", 105 regs->rsi, regs->rdi, regs->rsp, regs->rbp); 106 fprintf(stream, "%*sr8: 0x%.16llx r9: 0x%.16llx " 107 "r10: 0x%.16llx r11: 0x%.16llx\n", 108 indent, "", 109 regs->r8, regs->r9, regs->r10, regs->r11); 110 fprintf(stream, "%*sr12: 0x%.16llx r13: 0x%.16llx " 111 "r14: 0x%.16llx r15: 0x%.16llx\n", 112 indent, "", 113 regs->r12, regs->r13, regs->r14, regs->r15); 114 fprintf(stream, "%*srip: 0x%.16llx rfl: 0x%.16llx\n", 115 indent, "", 116 regs->rip, regs->rflags); 117 } 118 119 /* Segment Dump 120 * 121 * Input Args: 122 * indent - Left margin indent amount 123 * segment - KVM segment 124 * 125 * Output Args: 126 * stream - Output FILE stream 127 * 128 * Return: None 129 * 130 * Dumps the state of the KVM segment given by segment, to the FILE stream 131 * given by steam. 132 */ 133 static void segment_dump(FILE *stream, struct kvm_segment *segment, 134 uint8_t indent) 135 { 136 fprintf(stream, "%*sbase: 0x%.16llx limit: 0x%.8x " 137 "selector: 0x%.4x type: 0x%.2x\n", 138 indent, "", segment->base, segment->limit, 139 segment->selector, segment->type); 140 fprintf(stream, "%*spresent: 0x%.2x dpl: 0x%.2x " 141 "db: 0x%.2x s: 0x%.2x l: 0x%.2x\n", 142 indent, "", segment->present, segment->dpl, 143 segment->db, segment->s, segment->l); 144 fprintf(stream, "%*sg: 0x%.2x avl: 0x%.2x " 145 "unusable: 0x%.2x padding: 0x%.2x\n", 146 indent, "", segment->g, segment->avl, 147 segment->unusable, segment->padding); 148 } 149 150 /* dtable Dump 151 * 152 * Input Args: 153 * indent - Left margin indent amount 154 * dtable - KVM dtable 155 * 156 * Output Args: 157 * stream - Output FILE stream 158 * 159 * Return: None 160 * 161 * Dumps the state of the KVM dtable given by dtable, to the FILE stream 162 * given by steam. 163 */ 164 static void dtable_dump(FILE *stream, struct kvm_dtable *dtable, 165 uint8_t indent) 166 { 167 fprintf(stream, "%*sbase: 0x%.16llx limit: 0x%.4x " 168 "padding: 0x%.4x 0x%.4x 0x%.4x\n", 169 indent, "", dtable->base, dtable->limit, 170 dtable->padding[0], dtable->padding[1], dtable->padding[2]); 171 } 172 173 /* System Register Dump 174 * 175 * Input Args: 176 * indent - Left margin indent amount 177 * sregs - System registers 178 * 179 * Output Args: 180 * stream - Output FILE stream 181 * 182 * Return: None 183 * 184 * Dumps the state of the system registers given by sregs, to the FILE stream 185 * given by steam. 186 */ 187 void sregs_dump(FILE *stream, struct kvm_sregs *sregs, 188 uint8_t indent) 189 { 190 unsigned int i; 191 192 fprintf(stream, "%*scs:\n", indent, ""); 193 segment_dump(stream, &sregs->cs, indent + 2); 194 fprintf(stream, "%*sds:\n", indent, ""); 195 segment_dump(stream, &sregs->ds, indent + 2); 196 fprintf(stream, "%*ses:\n", indent, ""); 197 segment_dump(stream, &sregs->es, indent + 2); 198 fprintf(stream, "%*sfs:\n", indent, ""); 199 segment_dump(stream, &sregs->fs, indent + 2); 200 fprintf(stream, "%*sgs:\n", indent, ""); 201 segment_dump(stream, &sregs->gs, indent + 2); 202 fprintf(stream, "%*sss:\n", indent, ""); 203 segment_dump(stream, &sregs->ss, indent + 2); 204 fprintf(stream, "%*str:\n", indent, ""); 205 segment_dump(stream, &sregs->tr, indent + 2); 206 fprintf(stream, "%*sldt:\n", indent, ""); 207 segment_dump(stream, &sregs->ldt, indent + 2); 208 209 fprintf(stream, "%*sgdt:\n", indent, ""); 210 dtable_dump(stream, &sregs->gdt, indent + 2); 211 fprintf(stream, "%*sidt:\n", indent, ""); 212 dtable_dump(stream, &sregs->idt, indent + 2); 213 214 fprintf(stream, "%*scr0: 0x%.16llx cr2: 0x%.16llx " 215 "cr3: 0x%.16llx cr4: 0x%.16llx\n", 216 indent, "", 217 sregs->cr0, sregs->cr2, sregs->cr3, sregs->cr4); 218 fprintf(stream, "%*scr8: 0x%.16llx efer: 0x%.16llx " 219 "apic_base: 0x%.16llx\n", 220 indent, "", 221 sregs->cr8, sregs->efer, sregs->apic_base); 222 223 fprintf(stream, "%*sinterrupt_bitmap:\n", indent, ""); 224 for (i = 0; i < (KVM_NR_INTERRUPTS + 63) / 64; i++) { 225 fprintf(stream, "%*s%.16llx\n", indent + 2, "", 226 sregs->interrupt_bitmap[i]); 227 } 228 } 229 230 void virt_pgd_alloc(struct kvm_vm *vm, uint32_t pgd_memslot) 231 { 232 TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use " 233 "unknown or unsupported guest mode, mode: 0x%x", vm->mode); 234 235 /* If needed, create page map l4 table. */ 236 if (!vm->pgd_created) { 237 vm_paddr_t paddr = vm_phy_page_alloc(vm, 238 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot); 239 vm->pgd = paddr; 240 vm->pgd_created = true; 241 } 242 } 243 244 /* VM Virtual Page Map 245 * 246 * Input Args: 247 * vm - Virtual Machine 248 * vaddr - VM Virtual Address 249 * paddr - VM Physical Address 250 * pgd_memslot - Memory region slot for new virtual translation tables 251 * 252 * Output Args: None 253 * 254 * Return: None 255 * 256 * Within the VM given by vm, creates a virtual translation for the page 257 * starting at vaddr to the page starting at paddr. 258 */ 259 void virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, 260 uint32_t pgd_memslot) 261 { 262 uint16_t index[4]; 263 struct pageMapL4Entry *pml4e; 264 265 TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use " 266 "unknown or unsupported guest mode, mode: 0x%x", vm->mode); 267 268 TEST_ASSERT((vaddr % vm->page_size) == 0, 269 "Virtual address not on page boundary,\n" 270 " vaddr: 0x%lx vm->page_size: 0x%x", 271 vaddr, vm->page_size); 272 TEST_ASSERT(sparsebit_is_set(vm->vpages_valid, 273 (vaddr >> vm->page_shift)), 274 "Invalid virtual address, vaddr: 0x%lx", 275 vaddr); 276 TEST_ASSERT((paddr % vm->page_size) == 0, 277 "Physical address not on page boundary,\n" 278 " paddr: 0x%lx vm->page_size: 0x%x", 279 paddr, vm->page_size); 280 TEST_ASSERT((paddr >> vm->page_shift) <= vm->max_gfn, 281 "Physical address beyond beyond maximum supported,\n" 282 " paddr: 0x%lx vm->max_gfn: 0x%lx vm->page_size: 0x%x", 283 paddr, vm->max_gfn, vm->page_size); 284 285 index[0] = (vaddr >> 12) & 0x1ffu; 286 index[1] = (vaddr >> 21) & 0x1ffu; 287 index[2] = (vaddr >> 30) & 0x1ffu; 288 index[3] = (vaddr >> 39) & 0x1ffu; 289 290 /* Allocate page directory pointer table if not present. */ 291 pml4e = addr_gpa2hva(vm, vm->pgd); 292 if (!pml4e[index[3]].present) { 293 pml4e[index[3]].address = vm_phy_page_alloc(vm, 294 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot) 295 >> vm->page_shift; 296 pml4e[index[3]].writable = true; 297 pml4e[index[3]].present = true; 298 } 299 300 /* Allocate page directory table if not present. */ 301 struct pageDirectoryPointerEntry *pdpe; 302 pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size); 303 if (!pdpe[index[2]].present) { 304 pdpe[index[2]].address = vm_phy_page_alloc(vm, 305 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot) 306 >> vm->page_shift; 307 pdpe[index[2]].writable = true; 308 pdpe[index[2]].present = true; 309 } 310 311 /* Allocate page table if not present. */ 312 struct pageDirectoryEntry *pde; 313 pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size); 314 if (!pde[index[1]].present) { 315 pde[index[1]].address = vm_phy_page_alloc(vm, 316 KVM_GUEST_PAGE_TABLE_MIN_PADDR, pgd_memslot) 317 >> vm->page_shift; 318 pde[index[1]].writable = true; 319 pde[index[1]].present = true; 320 } 321 322 /* Fill in page table entry. */ 323 struct pageTableEntry *pte; 324 pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size); 325 pte[index[0]].address = paddr >> vm->page_shift; 326 pte[index[0]].writable = true; 327 pte[index[0]].present = 1; 328 } 329 330 /* Virtual Translation Tables Dump 331 * 332 * Input Args: 333 * vm - Virtual Machine 334 * indent - Left margin indent amount 335 * 336 * Output Args: 337 * stream - Output FILE stream 338 * 339 * Return: None 340 * 341 * Dumps to the FILE stream given by stream, the contents of all the 342 * virtual translation tables for the VM given by vm. 343 */ 344 void virt_dump(FILE *stream, struct kvm_vm *vm, uint8_t indent) 345 { 346 struct pageMapL4Entry *pml4e, *pml4e_start; 347 struct pageDirectoryPointerEntry *pdpe, *pdpe_start; 348 struct pageDirectoryEntry *pde, *pde_start; 349 struct pageTableEntry *pte, *pte_start; 350 351 if (!vm->pgd_created) 352 return; 353 354 fprintf(stream, "%*s " 355 " no\n", indent, ""); 356 fprintf(stream, "%*s index hvaddr gpaddr " 357 "addr w exec dirty\n", 358 indent, ""); 359 pml4e_start = (struct pageMapL4Entry *) addr_gpa2hva(vm, 360 vm->pgd); 361 for (uint16_t n1 = 0; n1 <= 0x1ffu; n1++) { 362 pml4e = &pml4e_start[n1]; 363 if (!pml4e->present) 364 continue; 365 fprintf(stream, "%*spml4e 0x%-3zx %p 0x%-12lx 0x%-10lx %u " 366 " %u\n", 367 indent, "", 368 pml4e - pml4e_start, pml4e, 369 addr_hva2gpa(vm, pml4e), (uint64_t) pml4e->address, 370 pml4e->writable, pml4e->execute_disable); 371 372 pdpe_start = addr_gpa2hva(vm, pml4e->address 373 * vm->page_size); 374 for (uint16_t n2 = 0; n2 <= 0x1ffu; n2++) { 375 pdpe = &pdpe_start[n2]; 376 if (!pdpe->present) 377 continue; 378 fprintf(stream, "%*spdpe 0x%-3zx %p 0x%-12lx 0x%-10lx " 379 "%u %u\n", 380 indent, "", 381 pdpe - pdpe_start, pdpe, 382 addr_hva2gpa(vm, pdpe), 383 (uint64_t) pdpe->address, pdpe->writable, 384 pdpe->execute_disable); 385 386 pde_start = addr_gpa2hva(vm, 387 pdpe->address * vm->page_size); 388 for (uint16_t n3 = 0; n3 <= 0x1ffu; n3++) { 389 pde = &pde_start[n3]; 390 if (!pde->present) 391 continue; 392 fprintf(stream, "%*spde 0x%-3zx %p " 393 "0x%-12lx 0x%-10lx %u %u\n", 394 indent, "", pde - pde_start, pde, 395 addr_hva2gpa(vm, pde), 396 (uint64_t) pde->address, pde->writable, 397 pde->execute_disable); 398 399 pte_start = addr_gpa2hva(vm, 400 pde->address * vm->page_size); 401 for (uint16_t n4 = 0; n4 <= 0x1ffu; n4++) { 402 pte = &pte_start[n4]; 403 if (!pte->present) 404 continue; 405 fprintf(stream, "%*spte 0x%-3zx %p " 406 "0x%-12lx 0x%-10lx %u %u " 407 " %u 0x%-10lx\n", 408 indent, "", 409 pte - pte_start, pte, 410 addr_hva2gpa(vm, pte), 411 (uint64_t) pte->address, 412 pte->writable, 413 pte->execute_disable, 414 pte->dirty, 415 ((uint64_t) n1 << 27) 416 | ((uint64_t) n2 << 18) 417 | ((uint64_t) n3 << 9) 418 | ((uint64_t) n4)); 419 } 420 } 421 } 422 } 423 } 424 425 /* Set Unusable Segment 426 * 427 * Input Args: None 428 * 429 * Output Args: 430 * segp - Pointer to segment register 431 * 432 * Return: None 433 * 434 * Sets the segment register pointed to by segp to an unusable state. 435 */ 436 static void kvm_seg_set_unusable(struct kvm_segment *segp) 437 { 438 memset(segp, 0, sizeof(*segp)); 439 segp->unusable = true; 440 } 441 442 static void kvm_seg_fill_gdt_64bit(struct kvm_vm *vm, struct kvm_segment *segp) 443 { 444 void *gdt = addr_gva2hva(vm, vm->gdt); 445 struct desc64 *desc = gdt + (segp->selector >> 3) * 8; 446 447 desc->limit0 = segp->limit & 0xFFFF; 448 desc->base0 = segp->base & 0xFFFF; 449 desc->base1 = segp->base >> 16; 450 desc->s = segp->s; 451 desc->type = segp->type; 452 desc->dpl = segp->dpl; 453 desc->p = segp->present; 454 desc->limit1 = segp->limit >> 16; 455 desc->l = segp->l; 456 desc->db = segp->db; 457 desc->g = segp->g; 458 desc->base2 = segp->base >> 24; 459 if (!segp->s) 460 desc->base3 = segp->base >> 32; 461 } 462 463 464 /* Set Long Mode Flat Kernel Code Segment 465 * 466 * Input Args: 467 * vm - VM whose GDT is being filled, or NULL to only write segp 468 * selector - selector value 469 * 470 * Output Args: 471 * segp - Pointer to KVM segment 472 * 473 * Return: None 474 * 475 * Sets up the KVM segment pointed to by segp, to be a code segment 476 * with the selector value given by selector. 477 */ 478 static void kvm_seg_set_kernel_code_64bit(struct kvm_vm *vm, uint16_t selector, 479 struct kvm_segment *segp) 480 { 481 memset(segp, 0, sizeof(*segp)); 482 segp->selector = selector; 483 segp->limit = 0xFFFFFFFFu; 484 segp->s = 0x1; /* kTypeCodeData */ 485 segp->type = 0x08 | 0x01 | 0x02; /* kFlagCode | kFlagCodeAccessed 486 * | kFlagCodeReadable 487 */ 488 segp->g = true; 489 segp->l = true; 490 segp->present = 1; 491 if (vm) 492 kvm_seg_fill_gdt_64bit(vm, segp); 493 } 494 495 /* Set Long Mode Flat Kernel Data Segment 496 * 497 * Input Args: 498 * vm - VM whose GDT is being filled, or NULL to only write segp 499 * selector - selector value 500 * 501 * Output Args: 502 * segp - Pointer to KVM segment 503 * 504 * Return: None 505 * 506 * Sets up the KVM segment pointed to by segp, to be a data segment 507 * with the selector value given by selector. 508 */ 509 static void kvm_seg_set_kernel_data_64bit(struct kvm_vm *vm, uint16_t selector, 510 struct kvm_segment *segp) 511 { 512 memset(segp, 0, sizeof(*segp)); 513 segp->selector = selector; 514 segp->limit = 0xFFFFFFFFu; 515 segp->s = 0x1; /* kTypeCodeData */ 516 segp->type = 0x00 | 0x01 | 0x02; /* kFlagData | kFlagDataAccessed 517 * | kFlagDataWritable 518 */ 519 segp->g = true; 520 segp->present = true; 521 if (vm) 522 kvm_seg_fill_gdt_64bit(vm, segp); 523 } 524 525 /* Address Guest Virtual to Guest Physical 526 * 527 * Input Args: 528 * vm - Virtual Machine 529 * gpa - VM virtual address 530 * 531 * Output Args: None 532 * 533 * Return: 534 * Equivalent VM physical address 535 * 536 * Translates the VM virtual address given by gva to a VM physical 537 * address and then locates the memory region containing the VM 538 * physical address, within the VM given by vm. When found, the host 539 * virtual address providing the memory to the vm physical address is returned. 540 * A TEST_ASSERT failure occurs if no region containing translated 541 * VM virtual address exists. 542 */ 543 vm_paddr_t addr_gva2gpa(struct kvm_vm *vm, vm_vaddr_t gva) 544 { 545 uint16_t index[4]; 546 struct pageMapL4Entry *pml4e; 547 struct pageDirectoryPointerEntry *pdpe; 548 struct pageDirectoryEntry *pde; 549 struct pageTableEntry *pte; 550 551 TEST_ASSERT(vm->mode == VM_MODE_P52V48_4K, "Attempt to use " 552 "unknown or unsupported guest mode, mode: 0x%x", vm->mode); 553 554 index[0] = (gva >> 12) & 0x1ffu; 555 index[1] = (gva >> 21) & 0x1ffu; 556 index[2] = (gva >> 30) & 0x1ffu; 557 index[3] = (gva >> 39) & 0x1ffu; 558 559 if (!vm->pgd_created) 560 goto unmapped_gva; 561 pml4e = addr_gpa2hva(vm, vm->pgd); 562 if (!pml4e[index[3]].present) 563 goto unmapped_gva; 564 565 pdpe = addr_gpa2hva(vm, pml4e[index[3]].address * vm->page_size); 566 if (!pdpe[index[2]].present) 567 goto unmapped_gva; 568 569 pde = addr_gpa2hva(vm, pdpe[index[2]].address * vm->page_size); 570 if (!pde[index[1]].present) 571 goto unmapped_gva; 572 573 pte = addr_gpa2hva(vm, pde[index[1]].address * vm->page_size); 574 if (!pte[index[0]].present) 575 goto unmapped_gva; 576 577 return (pte[index[0]].address * vm->page_size) + (gva & 0xfffu); 578 579 unmapped_gva: 580 TEST_ASSERT(false, "No mapping for vm virtual address, " 581 "gva: 0x%lx", gva); 582 exit(EXIT_FAILURE); 583 } 584 585 static void kvm_setup_gdt(struct kvm_vm *vm, struct kvm_dtable *dt, int gdt_memslot, 586 int pgd_memslot) 587 { 588 if (!vm->gdt) 589 vm->gdt = vm_vaddr_alloc(vm, getpagesize(), 590 KVM_UTIL_MIN_VADDR, gdt_memslot, pgd_memslot); 591 592 dt->base = vm->gdt; 593 dt->limit = getpagesize(); 594 } 595 596 static void kvm_setup_tss_64bit(struct kvm_vm *vm, struct kvm_segment *segp, 597 int selector, int gdt_memslot, 598 int pgd_memslot) 599 { 600 if (!vm->tss) 601 vm->tss = vm_vaddr_alloc(vm, getpagesize(), 602 KVM_UTIL_MIN_VADDR, gdt_memslot, pgd_memslot); 603 604 memset(segp, 0, sizeof(*segp)); 605 segp->base = vm->tss; 606 segp->limit = 0x67; 607 segp->selector = selector; 608 segp->type = 0xb; 609 segp->present = 1; 610 kvm_seg_fill_gdt_64bit(vm, segp); 611 } 612 613 void vcpu_setup(struct kvm_vm *vm, int vcpuid, int pgd_memslot, int gdt_memslot) 614 { 615 struct kvm_sregs sregs; 616 617 /* Set mode specific system register values. */ 618 vcpu_sregs_get(vm, vcpuid, &sregs); 619 620 sregs.idt.limit = 0; 621 622 kvm_setup_gdt(vm, &sregs.gdt, gdt_memslot, pgd_memslot); 623 624 switch (vm->mode) { 625 case VM_MODE_P52V48_4K: 626 sregs.cr0 = X86_CR0_PE | X86_CR0_NE | X86_CR0_PG; 627 sregs.cr4 |= X86_CR4_PAE | X86_CR4_OSFXSR; 628 sregs.efer |= (EFER_LME | EFER_LMA | EFER_NX); 629 630 kvm_seg_set_unusable(&sregs.ldt); 631 kvm_seg_set_kernel_code_64bit(vm, 0x8, &sregs.cs); 632 kvm_seg_set_kernel_data_64bit(vm, 0x10, &sregs.ds); 633 kvm_seg_set_kernel_data_64bit(vm, 0x10, &sregs.es); 634 kvm_setup_tss_64bit(vm, &sregs.tr, 0x18, gdt_memslot, pgd_memslot); 635 break; 636 637 default: 638 TEST_ASSERT(false, "Unknown guest mode, mode: 0x%x", vm->mode); 639 } 640 641 sregs.cr3 = vm->pgd; 642 vcpu_sregs_set(vm, vcpuid, &sregs); 643 } 644 /* Adds a vCPU with reasonable defaults (i.e., a stack) 645 * 646 * Input Args: 647 * vcpuid - The id of the VCPU to add to the VM. 648 * guest_code - The vCPU's entry point 649 */ 650 void vm_vcpu_add_default(struct kvm_vm *vm, uint32_t vcpuid, void *guest_code) 651 { 652 struct kvm_mp_state mp_state; 653 struct kvm_regs regs; 654 vm_vaddr_t stack_vaddr; 655 stack_vaddr = vm_vaddr_alloc(vm, DEFAULT_STACK_PGS * getpagesize(), 656 DEFAULT_GUEST_STACK_VADDR_MIN, 0, 0); 657 658 /* Create VCPU */ 659 vm_vcpu_add(vm, vcpuid, 0, 0); 660 661 /* Setup guest general purpose registers */ 662 vcpu_regs_get(vm, vcpuid, ®s); 663 regs.rflags = regs.rflags | 0x2; 664 regs.rsp = stack_vaddr + (DEFAULT_STACK_PGS * getpagesize()); 665 regs.rip = (unsigned long) guest_code; 666 vcpu_regs_set(vm, vcpuid, ®s); 667 668 /* Setup the MP state */ 669 mp_state.mp_state = 0; 670 vcpu_set_mp_state(vm, vcpuid, &mp_state); 671 } 672 673 /* Allocate an instance of struct kvm_cpuid2 674 * 675 * Input Args: None 676 * 677 * Output Args: None 678 * 679 * Return: A pointer to the allocated struct. The caller is responsible 680 * for freeing this struct. 681 * 682 * Since kvm_cpuid2 uses a 0-length array to allow a the size of the 683 * array to be decided at allocation time, allocation is slightly 684 * complicated. This function uses a reasonable default length for 685 * the array and performs the appropriate allocation. 686 */ 687 static struct kvm_cpuid2 *allocate_kvm_cpuid2(void) 688 { 689 struct kvm_cpuid2 *cpuid; 690 int nent = 100; 691 size_t size; 692 693 size = sizeof(*cpuid); 694 size += nent * sizeof(struct kvm_cpuid_entry2); 695 cpuid = malloc(size); 696 if (!cpuid) { 697 perror("malloc"); 698 abort(); 699 } 700 701 cpuid->nent = nent; 702 703 return cpuid; 704 } 705 706 /* KVM Supported CPUID Get 707 * 708 * Input Args: None 709 * 710 * Output Args: 711 * 712 * Return: The supported KVM CPUID 713 * 714 * Get the guest CPUID supported by KVM. 715 */ 716 struct kvm_cpuid2 *kvm_get_supported_cpuid(void) 717 { 718 static struct kvm_cpuid2 *cpuid; 719 int ret; 720 int kvm_fd; 721 722 if (cpuid) 723 return cpuid; 724 725 cpuid = allocate_kvm_cpuid2(); 726 kvm_fd = open(KVM_DEV_PATH, O_RDONLY); 727 if (kvm_fd < 0) 728 exit(KSFT_SKIP); 729 730 ret = ioctl(kvm_fd, KVM_GET_SUPPORTED_CPUID, cpuid); 731 TEST_ASSERT(ret == 0, "KVM_GET_SUPPORTED_CPUID failed %d %d\n", 732 ret, errno); 733 734 close(kvm_fd); 735 return cpuid; 736 } 737 738 /* Locate a cpuid entry. 739 * 740 * Input Args: 741 * cpuid: The cpuid. 742 * function: The function of the cpuid entry to find. 743 * 744 * Output Args: None 745 * 746 * Return: A pointer to the cpuid entry. Never returns NULL. 747 */ 748 struct kvm_cpuid_entry2 * 749 kvm_get_supported_cpuid_index(uint32_t function, uint32_t index) 750 { 751 struct kvm_cpuid2 *cpuid; 752 struct kvm_cpuid_entry2 *entry = NULL; 753 int i; 754 755 cpuid = kvm_get_supported_cpuid(); 756 for (i = 0; i < cpuid->nent; i++) { 757 if (cpuid->entries[i].function == function && 758 cpuid->entries[i].index == index) { 759 entry = &cpuid->entries[i]; 760 break; 761 } 762 } 763 764 TEST_ASSERT(entry, "Guest CPUID entry not found: (EAX=%x, ECX=%x).", 765 function, index); 766 return entry; 767 } 768 769 /* VM VCPU CPUID Set 770 * 771 * Input Args: 772 * vm - Virtual Machine 773 * vcpuid - VCPU id 774 * cpuid - The CPUID values to set. 775 * 776 * Output Args: None 777 * 778 * Return: void 779 * 780 * Set the VCPU's CPUID. 781 */ 782 void vcpu_set_cpuid(struct kvm_vm *vm, 783 uint32_t vcpuid, struct kvm_cpuid2 *cpuid) 784 { 785 struct vcpu *vcpu = vcpu_find(vm, vcpuid); 786 int rc; 787 788 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid); 789 790 rc = ioctl(vcpu->fd, KVM_SET_CPUID2, cpuid); 791 TEST_ASSERT(rc == 0, "KVM_SET_CPUID2 failed, rc: %i errno: %i", 792 rc, errno); 793 794 } 795 796 /* Create a VM with reasonable defaults 797 * 798 * Input Args: 799 * vcpuid - The id of the single VCPU to add to the VM. 800 * extra_mem_pages - The size of extra memories to add (this will 801 * decide how much extra space we will need to 802 * setup the page tables using mem slot 0) 803 * guest_code - The vCPU's entry point 804 * 805 * Output Args: None 806 * 807 * Return: 808 * Pointer to opaque structure that describes the created VM. 809 */ 810 struct kvm_vm *vm_create_default(uint32_t vcpuid, uint64_t extra_mem_pages, 811 void *guest_code) 812 { 813 struct kvm_vm *vm; 814 /* 815 * For x86 the maximum page table size for a memory region 816 * will be when only 4K pages are used. In that case the 817 * total extra size for page tables (for extra N pages) will 818 * be: N/512+N/512^2+N/512^3+... which is definitely smaller 819 * than N/512*2. 820 */ 821 uint64_t extra_pg_pages = extra_mem_pages / 512 * 2; 822 823 /* Create VM */ 824 vm = vm_create(VM_MODE_P52V48_4K, 825 DEFAULT_GUEST_PHY_PAGES + extra_pg_pages, 826 O_RDWR); 827 828 /* Setup guest code */ 829 kvm_vm_elf_load(vm, program_invocation_name, 0, 0); 830 831 /* Setup IRQ Chip */ 832 vm_create_irqchip(vm); 833 834 /* Add the first vCPU. */ 835 vm_vcpu_add_default(vm, vcpuid, guest_code); 836 837 return vm; 838 } 839 840 /* VCPU Get MSR 841 * 842 * Input Args: 843 * vm - Virtual Machine 844 * vcpuid - VCPU ID 845 * msr_index - Index of MSR 846 * 847 * Output Args: None 848 * 849 * Return: On success, value of the MSR. On failure a TEST_ASSERT is produced. 850 * 851 * Get value of MSR for VCPU. 852 */ 853 uint64_t vcpu_get_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index) 854 { 855 struct vcpu *vcpu = vcpu_find(vm, vcpuid); 856 struct { 857 struct kvm_msrs header; 858 struct kvm_msr_entry entry; 859 } buffer = {}; 860 int r; 861 862 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid); 863 buffer.header.nmsrs = 1; 864 buffer.entry.index = msr_index; 865 r = ioctl(vcpu->fd, KVM_GET_MSRS, &buffer.header); 866 TEST_ASSERT(r == 1, "KVM_GET_MSRS IOCTL failed,\n" 867 " rc: %i errno: %i", r, errno); 868 869 return buffer.entry.data; 870 } 871 872 /* VCPU Set MSR 873 * 874 * Input Args: 875 * vm - Virtual Machine 876 * vcpuid - VCPU ID 877 * msr_index - Index of MSR 878 * msr_value - New value of MSR 879 * 880 * Output Args: None 881 * 882 * Return: On success, nothing. On failure a TEST_ASSERT is produced. 883 * 884 * Set value of MSR for VCPU. 885 */ 886 void vcpu_set_msr(struct kvm_vm *vm, uint32_t vcpuid, uint64_t msr_index, 887 uint64_t msr_value) 888 { 889 struct vcpu *vcpu = vcpu_find(vm, vcpuid); 890 struct { 891 struct kvm_msrs header; 892 struct kvm_msr_entry entry; 893 } buffer = {}; 894 int r; 895 896 TEST_ASSERT(vcpu != NULL, "vcpu not found, vcpuid: %u", vcpuid); 897 memset(&buffer, 0, sizeof(buffer)); 898 buffer.header.nmsrs = 1; 899 buffer.entry.index = msr_index; 900 buffer.entry.data = msr_value; 901 r = ioctl(vcpu->fd, KVM_SET_MSRS, &buffer.header); 902 TEST_ASSERT(r == 1, "KVM_SET_MSRS IOCTL failed,\n" 903 " rc: %i errno: %i", r, errno); 904 } 905 906 /* VM VCPU Args Set 907 * 908 * Input Args: 909 * vm - Virtual Machine 910 * vcpuid - VCPU ID 911 * num - number of arguments 912 * ... - arguments, each of type uint64_t 913 * 914 * Output Args: None 915 * 916 * Return: None 917 * 918 * Sets the first num function input arguments to the values 919 * given as variable args. Each of the variable args is expected to 920 * be of type uint64_t. 921 */ 922 void vcpu_args_set(struct kvm_vm *vm, uint32_t vcpuid, unsigned int num, ...) 923 { 924 va_list ap; 925 struct kvm_regs regs; 926 927 TEST_ASSERT(num >= 1 && num <= 6, "Unsupported number of args,\n" 928 " num: %u\n", 929 num); 930 931 va_start(ap, num); 932 vcpu_regs_get(vm, vcpuid, ®s); 933 934 if (num >= 1) 935 regs.rdi = va_arg(ap, uint64_t); 936 937 if (num >= 2) 938 regs.rsi = va_arg(ap, uint64_t); 939 940 if (num >= 3) 941 regs.rdx = va_arg(ap, uint64_t); 942 943 if (num >= 4) 944 regs.rcx = va_arg(ap, uint64_t); 945 946 if (num >= 5) 947 regs.r8 = va_arg(ap, uint64_t); 948 949 if (num >= 6) 950 regs.r9 = va_arg(ap, uint64_t); 951 952 vcpu_regs_set(vm, vcpuid, ®s); 953 va_end(ap); 954 } 955 956 /* 957 * VM VCPU Dump 958 * 959 * Input Args: 960 * vm - Virtual Machine 961 * vcpuid - VCPU ID 962 * indent - Left margin indent amount 963 * 964 * Output Args: 965 * stream - Output FILE stream 966 * 967 * Return: None 968 * 969 * Dumps the current state of the VCPU specified by vcpuid, within the VM 970 * given by vm, to the FILE stream given by stream. 971 */ 972 void vcpu_dump(FILE *stream, struct kvm_vm *vm, uint32_t vcpuid, uint8_t indent) 973 { 974 struct kvm_regs regs; 975 struct kvm_sregs sregs; 976 977 fprintf(stream, "%*scpuid: %u\n", indent, "", vcpuid); 978 979 fprintf(stream, "%*sregs:\n", indent + 2, ""); 980 vcpu_regs_get(vm, vcpuid, ®s); 981 regs_dump(stream, ®s, indent + 4); 982 983 fprintf(stream, "%*ssregs:\n", indent + 2, ""); 984 vcpu_sregs_get(vm, vcpuid, &sregs); 985 sregs_dump(stream, &sregs, indent + 4); 986 } 987 988 struct kvm_x86_state { 989 struct kvm_vcpu_events events; 990 struct kvm_mp_state mp_state; 991 struct kvm_regs regs; 992 struct kvm_xsave xsave; 993 struct kvm_xcrs xcrs; 994 struct kvm_sregs sregs; 995 struct kvm_debugregs debugregs; 996 union { 997 struct kvm_nested_state nested; 998 char nested_[16384]; 999 }; 1000 struct kvm_msrs msrs; 1001 }; 1002 1003 static int kvm_get_num_msrs(struct kvm_vm *vm) 1004 { 1005 struct kvm_msr_list nmsrs; 1006 int r; 1007 1008 nmsrs.nmsrs = 0; 1009 r = ioctl(vm->kvm_fd, KVM_GET_MSR_INDEX_LIST, &nmsrs); 1010 TEST_ASSERT(r == -1 && errno == E2BIG, "Unexpected result from KVM_GET_MSR_INDEX_LIST probe, r: %i", 1011 r); 1012 1013 return nmsrs.nmsrs; 1014 } 1015 1016 struct kvm_x86_state *vcpu_save_state(struct kvm_vm *vm, uint32_t vcpuid) 1017 { 1018 struct vcpu *vcpu = vcpu_find(vm, vcpuid); 1019 struct kvm_msr_list *list; 1020 struct kvm_x86_state *state; 1021 int nmsrs, r, i; 1022 static int nested_size = -1; 1023 1024 if (nested_size == -1) { 1025 nested_size = kvm_check_cap(KVM_CAP_NESTED_STATE); 1026 TEST_ASSERT(nested_size <= sizeof(state->nested_), 1027 "Nested state size too big, %i > %zi", 1028 nested_size, sizeof(state->nested_)); 1029 } 1030 1031 /* 1032 * When KVM exits to userspace with KVM_EXIT_IO, KVM guarantees 1033 * guest state is consistent only after userspace re-enters the 1034 * kernel with KVM_RUN. Complete IO prior to migrating state 1035 * to a new VM. 1036 */ 1037 vcpu_run_complete_io(vm, vcpuid); 1038 1039 nmsrs = kvm_get_num_msrs(vm); 1040 list = malloc(sizeof(*list) + nmsrs * sizeof(list->indices[0])); 1041 list->nmsrs = nmsrs; 1042 r = ioctl(vm->kvm_fd, KVM_GET_MSR_INDEX_LIST, list); 1043 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_MSR_INDEX_LIST, r: %i", 1044 r); 1045 1046 state = malloc(sizeof(*state) + nmsrs * sizeof(state->msrs.entries[0])); 1047 r = ioctl(vcpu->fd, KVM_GET_VCPU_EVENTS, &state->events); 1048 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_VCPU_EVENTS, r: %i", 1049 r); 1050 1051 r = ioctl(vcpu->fd, KVM_GET_MP_STATE, &state->mp_state); 1052 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_MP_STATE, r: %i", 1053 r); 1054 1055 r = ioctl(vcpu->fd, KVM_GET_REGS, &state->regs); 1056 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_REGS, r: %i", 1057 r); 1058 1059 r = ioctl(vcpu->fd, KVM_GET_XSAVE, &state->xsave); 1060 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_XSAVE, r: %i", 1061 r); 1062 1063 r = ioctl(vcpu->fd, KVM_GET_XCRS, &state->xcrs); 1064 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_XCRS, r: %i", 1065 r); 1066 1067 r = ioctl(vcpu->fd, KVM_GET_SREGS, &state->sregs); 1068 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_SREGS, r: %i", 1069 r); 1070 1071 if (nested_size) { 1072 state->nested.size = sizeof(state->nested_); 1073 r = ioctl(vcpu->fd, KVM_GET_NESTED_STATE, &state->nested); 1074 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_NESTED_STATE, r: %i", 1075 r); 1076 TEST_ASSERT(state->nested.size <= nested_size, 1077 "Nested state size too big, %i (KVM_CHECK_CAP gave %i)", 1078 state->nested.size, nested_size); 1079 } else 1080 state->nested.size = 0; 1081 1082 state->msrs.nmsrs = nmsrs; 1083 for (i = 0; i < nmsrs; i++) 1084 state->msrs.entries[i].index = list->indices[i]; 1085 r = ioctl(vcpu->fd, KVM_GET_MSRS, &state->msrs); 1086 TEST_ASSERT(r == nmsrs, "Unexpected result from KVM_GET_MSRS, r: %i (failed at %x)", 1087 r, r == nmsrs ? -1 : list->indices[r]); 1088 1089 r = ioctl(vcpu->fd, KVM_GET_DEBUGREGS, &state->debugregs); 1090 TEST_ASSERT(r == 0, "Unexpected result from KVM_GET_DEBUGREGS, r: %i", 1091 r); 1092 1093 free(list); 1094 return state; 1095 } 1096 1097 void vcpu_load_state(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_x86_state *state) 1098 { 1099 struct vcpu *vcpu = vcpu_find(vm, vcpuid); 1100 int r; 1101 1102 r = ioctl(vcpu->fd, KVM_SET_XSAVE, &state->xsave); 1103 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XSAVE, r: %i", 1104 r); 1105 1106 r = ioctl(vcpu->fd, KVM_SET_XCRS, &state->xcrs); 1107 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_XCRS, r: %i", 1108 r); 1109 1110 r = ioctl(vcpu->fd, KVM_SET_SREGS, &state->sregs); 1111 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_SREGS, r: %i", 1112 r); 1113 1114 r = ioctl(vcpu->fd, KVM_SET_MSRS, &state->msrs); 1115 TEST_ASSERT(r == state->msrs.nmsrs, "Unexpected result from KVM_SET_MSRS, r: %i (failed at %x)", 1116 r, r == state->msrs.nmsrs ? -1 : state->msrs.entries[r].index); 1117 1118 r = ioctl(vcpu->fd, KVM_SET_VCPU_EVENTS, &state->events); 1119 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_VCPU_EVENTS, r: %i", 1120 r); 1121 1122 r = ioctl(vcpu->fd, KVM_SET_MP_STATE, &state->mp_state); 1123 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_MP_STATE, r: %i", 1124 r); 1125 1126 r = ioctl(vcpu->fd, KVM_SET_DEBUGREGS, &state->debugregs); 1127 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_DEBUGREGS, r: %i", 1128 r); 1129 1130 r = ioctl(vcpu->fd, KVM_SET_REGS, &state->regs); 1131 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_REGS, r: %i", 1132 r); 1133 1134 if (state->nested.size) { 1135 r = ioctl(vcpu->fd, KVM_SET_NESTED_STATE, &state->nested); 1136 TEST_ASSERT(r == 0, "Unexpected result from KVM_SET_NESTED_STATE, r: %i", 1137 r); 1138 } 1139 } 1140