1 /*- 2 * Copyright (c) 2011 NetApp, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/lib/libvmmapi/vmmapi.c 280929 2015-04-01 00:15:31Z tychon $ 27 */ 28 /* 29 * This file and its contents are supplied under the terms of the 30 * Common Development and Distribution License ("CDDL"), version 1.0. 31 * You may only use this file in accordance with the terms of version 32 * 1.0 of the CDDL. 33 * 34 * A full copy of the text of the CDDL should have accompanied this 35 * source. A copy of the CDDL is also available via the Internet at 36 * http://www.illumos.org/license/CDDL. 37 * 38 * Copyright 2015 Pluribus Networks Inc. 39 */ 40 41 #include <sys/cdefs.h> 42 __FBSDID("$FreeBSD: head/lib/libvmmapi/vmmapi.c 280929 2015-04-01 00:15:31Z tychon $"); 43 44 #include <sys/param.h> 45 #include <sys/sysctl.h> 46 #include <sys/ioctl.h> 47 #include <sys/mman.h> 48 #include <sys/_iovec.h> 49 #include <sys/cpuset.h> 50 51 #include <machine/specialreg.h> 52 53 #ifndef __FreeBSD__ 54 #include <errno.h> 55 #endif 56 #include <stdio.h> 57 #include <stdlib.h> 58 #include <assert.h> 59 #include <string.h> 60 #include <fcntl.h> 61 #include <unistd.h> 62 63 #include <libutil.h> 64 65 #include <machine/vmm.h> 66 #include <machine/vmm_dev.h> 67 #ifndef __FreeBSD__ 68 #include <sys/vmm_impl.h> 69 #endif 70 71 #include "vmmapi.h" 72 73 #define KB (1024UL) 74 #define MB (1024 * 1024UL) 75 #define GB (1024 * 1024 * 1024UL) 76 77 struct vmctx { 78 int fd; 79 uint32_t lowmem_limit; 80 enum vm_mmap_style vms; 81 char *lowermem_addr; 82 char *biosmem_addr; 83 size_t lowmem; 84 char *lowmem_addr; 85 size_t highmem; 86 char *highmem_addr; 87 uint64_t rombase; 88 uint64_t romlimit; 89 char *rom_addr; 90 char *name; 91 }; 92 93 #ifdef __FreeBSD__ 94 #define CREATE(x) sysctlbyname("hw.vmm.create", NULL, NULL, (x), strlen((x))) 95 #define DESTROY(x) sysctlbyname("hw.vmm.destroy", NULL, NULL, (x), strlen((x))) 96 #else 97 #define CREATE(x) vmm_vm_create(x) 98 #define DESTROY(x) vmm_vm_destroy(x) 99 #endif 100 101 static int 102 vm_device_open(const char *name) 103 { 104 int fd, len; 105 char *vmfile; 106 107 #ifdef __FreeBSD__ 108 len = strlen("/dev/vmm/") + strlen(name) + 1; 109 #else 110 len = strlen("/devices/pseudo/vmm@0:") + strlen(name) + 1; 111 #endif 112 vmfile = malloc(len); 113 assert(vmfile != NULL); 114 #ifdef __FreeBSD__ 115 snprintf(vmfile, len, "/dev/vmm/%s", name); 116 #else 117 snprintf(vmfile, len, "/devices/pseudo/vmm@0:%s", name); 118 #endif 119 120 /* Open the device file */ 121 fd = open(vmfile, O_RDWR, 0); 122 123 free(vmfile); 124 return (fd); 125 } 126 127 #ifndef __FreeBSD__ 128 static int 129 vmm_vm_create(const char *name) 130 { 131 const char vmm_ctl[] = "/devices/pseudo/vmm@0:ctl"; 132 struct vmm_ioctl vi; 133 int err = 0; 134 int ctl_fd; 135 136 (void) strlcpy(vi.vmm_name, name, sizeof (vi.vmm_name) - 1); 137 138 ctl_fd = open(vmm_ctl, O_EXCL | O_RDWR); 139 if (ctl_fd == -1) { 140 err = errno; 141 if ((errno == EPERM) || (errno == EACCES)) { 142 fprintf(stderr, "you do not have permission to " 143 "perform that operation.\n"); 144 } else { 145 fprintf(stderr, "open: %s: %s\n", vmm_ctl, 146 strerror(errno)); 147 } 148 return (err); 149 } 150 if (ioctl(ctl_fd, VMM_CREATE_VM, &vi) == -1) { 151 err = errno; 152 fprintf(stderr, "couldn't create vm \"%s\"", name); 153 } 154 close (ctl_fd); 155 156 return (err); 157 } 158 #endif 159 160 int 161 vm_create(const char *name) 162 { 163 164 return (CREATE((char *)name)); 165 } 166 167 struct vmctx * 168 vm_open(const char *name) 169 { 170 struct vmctx *vm; 171 172 vm = malloc(sizeof(struct vmctx) + strlen(name) + 1); 173 assert(vm != NULL); 174 175 vm->fd = -1; 176 vm->lowmem_limit = 3 * GB; 177 vm->name = (char *)(vm + 1); 178 strcpy(vm->name, name); 179 180 if ((vm->fd = vm_device_open(vm->name)) < 0) 181 goto err; 182 183 return (vm); 184 err: 185 (void) vm_destroy(vm); 186 return (NULL); 187 } 188 189 #ifndef __FreeBSD__ 190 static int 191 vmm_vm_destroy(const char *name) 192 { 193 const char vmm_ctl[] = "/devices/pseudo/vmm@0:ctl"; 194 struct vmm_ioctl vi; 195 int ctl_fd; 196 int err = 0; 197 198 (void) strlcpy(vi.vmm_name, name, sizeof (vi.vmm_name) - 1); 199 200 ctl_fd = open(vmm_ctl, O_EXCL | O_RDWR); 201 if (ctl_fd == -1) { 202 err = errno; 203 if ((errno == EPERM) || (errno == EACCES)) { 204 fprintf(stderr, "you do not have permission to " 205 "perform that operation.\n"); 206 } else { 207 fprintf(stderr, "open: %s: %s\n", vmm_ctl, 208 strerror(errno)); 209 } 210 return (err); 211 } 212 if (ioctl(ctl_fd, VMM_DESTROY_VM, &vi) == -1) { 213 err = errno; 214 fprintf(stderr, "couldn't destroy vm \"%s\"", name); 215 } 216 close (ctl_fd); 217 return (err); 218 } 219 #endif 220 221 int 222 vm_destroy(struct vmctx *vm) 223 { 224 int err; 225 assert(vm != NULL); 226 227 if (vm->fd >= 0) 228 close(vm->fd); 229 err = DESTROY(vm->name); 230 231 free(vm); 232 return (err); 233 } 234 235 int 236 vm_parse_memsize(const char *optarg, size_t *ret_memsize) 237 { 238 char *endptr; 239 size_t optval; 240 int error; 241 242 optval = strtoul(optarg, &endptr, 0); 243 if (*optarg != '\0' && *endptr == '\0') { 244 /* 245 * For the sake of backward compatibility if the memory size 246 * specified on the command line is less than a megabyte then 247 * it is interpreted as being in units of MB. 248 */ 249 if (optval < MB) 250 optval *= MB; 251 *ret_memsize = optval; 252 error = 0; 253 } else 254 error = expand_number(optarg, ret_memsize); 255 256 return (error); 257 } 258 259 #ifdef __FreeBSD__ 260 size_t 261 vmm_get_mem_total(void) 262 { 263 size_t mem_total = 0; 264 size_t oldlen = sizeof(mem_total); 265 int error; 266 error = sysctlbyname("hw.vmm.mem_total", &mem_total, &oldlen, NULL, 0); 267 if (error) 268 return -1; 269 return mem_total; 270 } 271 272 size_t 273 vmm_get_mem_free(void) 274 { 275 size_t mem_free = 0; 276 size_t oldlen = sizeof(mem_free); 277 int error; 278 error = sysctlbyname("hw.vmm.mem_free", &mem_free, &oldlen, NULL, 0); 279 if (error) 280 return -1; 281 return mem_free; 282 } 283 #endif 284 285 int 286 vm_get_memory_seg(struct vmctx *ctx, vm_paddr_t gpa, size_t *ret_len, 287 int *wired) 288 { 289 int error; 290 struct vm_memory_segment seg; 291 292 bzero(&seg, sizeof(seg)); 293 seg.gpa = gpa; 294 error = ioctl(ctx->fd, VM_GET_MEMORY_SEG, &seg); 295 *ret_len = seg.len; 296 if (wired != NULL) 297 *wired = seg.wired; 298 return (error); 299 } 300 301 uint32_t 302 vm_get_lowmem_limit(struct vmctx *ctx) 303 { 304 305 return (ctx->lowmem_limit); 306 } 307 308 void 309 vm_set_lowmem_limit(struct vmctx *ctx, uint32_t limit) 310 { 311 312 ctx->lowmem_limit = limit; 313 } 314 315 static int 316 setup_memory_segment(struct vmctx *ctx, vm_paddr_t gpa, size_t len, char **addr) 317 { 318 int error; 319 struct vm_memory_segment seg; 320 321 /* 322 * Create and optionally map 'len' bytes of memory at guest 323 * physical address 'gpa' 324 */ 325 bzero(&seg, sizeof(seg)); 326 seg.gpa = gpa; 327 seg.len = len; 328 error = ioctl(ctx->fd, VM_MAP_MEMORY, &seg); 329 if (error == 0 && addr != NULL) { 330 *addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, 331 ctx->fd, gpa); 332 } 333 return (error); 334 } 335 336 int 337 vm_setup_memory(struct vmctx *ctx, size_t memsize, enum vm_mmap_style vms) 338 { 339 char **addr; 340 int error; 341 342 /* XXX VM_MMAP_SPARSE not implemented yet */ 343 assert(vms == VM_MMAP_NONE || vms == VM_MMAP_ALL); 344 ctx->vms = vms; 345 346 /* 347 * If 'memsize' cannot fit entirely in the 'lowmem' segment then 348 * create another 'highmem' segment above 4GB for the remainder. 349 */ 350 if (memsize > ctx->lowmem_limit) { 351 ctx->lowmem = ctx->lowmem_limit; 352 ctx->highmem = memsize - ctx->lowmem; 353 } else { 354 ctx->lowmem = memsize; 355 ctx->highmem = 0; 356 } 357 358 if (ctx->lowmem > 0) { 359 addr = (vms == VM_MMAP_ALL) ? &ctx->lowermem_addr : NULL; 360 error = setup_memory_segment(ctx, 0, 640*KB, addr); 361 if (error) 362 return (error); 363 364 addr = (vms == VM_MMAP_ALL) ? &ctx->biosmem_addr : NULL; 365 error = setup_memory_segment(ctx, 768*KB, 256*KB, addr); 366 if (error) 367 return (error); 368 369 addr = (vms == VM_MMAP_ALL) ? &ctx->lowmem_addr : NULL; 370 error = setup_memory_segment(ctx, 1*MB, ctx->lowmem - 1*MB, addr); 371 if (error) 372 return (error); 373 } 374 375 if (ctx->highmem > 0) { 376 addr = (vms == VM_MMAP_ALL) ? &ctx->highmem_addr : NULL; 377 error = setup_memory_segment(ctx, 4*GB, ctx->highmem, addr); 378 if (error) 379 return (error); 380 } 381 382 return (0); 383 } 384 385 int 386 vm_setup_rom(struct vmctx *ctx, vm_paddr_t gpa, size_t len) 387 { 388 ctx->rombase = gpa; 389 ctx->romlimit = gpa + len; 390 391 return (setup_memory_segment(ctx, gpa, len, &ctx->rom_addr)); 392 } 393 394 void * 395 vm_map_gpa(struct vmctx *ctx, vm_paddr_t gaddr, size_t len) 396 { 397 398 /* XXX VM_MMAP_SPARSE not implemented yet */ 399 assert(ctx->vms == VM_MMAP_ALL); 400 401 if (gaddr + len <= 1*MB) { 402 if (gaddr + len <= 640*KB) 403 return ((void *)(ctx->lowermem_addr + gaddr)); 404 405 if (768*KB <= gaddr && gaddr + len <= 1*MB) { 406 gaddr -= 768*KB; 407 return ((void *)(ctx->biosmem_addr + gaddr)); 408 } 409 410 return (NULL); 411 } 412 413 if (gaddr < ctx->lowmem && gaddr + len <= ctx->lowmem) { 414 gaddr -= 1*MB; 415 return ((void *)(ctx->lowmem_addr + gaddr)); 416 } 417 418 if (ctx->rombase <= gaddr && gaddr + len <= ctx->romlimit) { 419 gaddr -= ctx->rombase; 420 return ((void *)(ctx->rom_addr + gaddr)); 421 } 422 423 if (gaddr >= 4*GB) { 424 gaddr -= 4*GB; 425 if (gaddr < ctx->highmem && gaddr + len <= ctx->highmem) 426 return ((void *)(ctx->highmem_addr + gaddr)); 427 } 428 429 return (NULL); 430 } 431 432 size_t 433 vm_get_lowmem_size(struct vmctx *ctx) 434 { 435 436 return (ctx->lowmem); 437 } 438 439 size_t 440 vm_get_highmem_size(struct vmctx *ctx) 441 { 442 443 return (ctx->highmem); 444 } 445 446 int 447 vm_set_desc(struct vmctx *ctx, int vcpu, int reg, 448 uint64_t base, uint32_t limit, uint32_t access) 449 { 450 int error; 451 struct vm_seg_desc vmsegdesc; 452 453 bzero(&vmsegdesc, sizeof(vmsegdesc)); 454 vmsegdesc.cpuid = vcpu; 455 vmsegdesc.regnum = reg; 456 vmsegdesc.desc.base = base; 457 vmsegdesc.desc.limit = limit; 458 vmsegdesc.desc.access = access; 459 460 error = ioctl(ctx->fd, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc); 461 return (error); 462 } 463 464 int 465 vm_get_desc(struct vmctx *ctx, int vcpu, int reg, 466 uint64_t *base, uint32_t *limit, uint32_t *access) 467 { 468 int error; 469 struct vm_seg_desc vmsegdesc; 470 471 bzero(&vmsegdesc, sizeof(vmsegdesc)); 472 vmsegdesc.cpuid = vcpu; 473 vmsegdesc.regnum = reg; 474 475 error = ioctl(ctx->fd, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc); 476 if (error == 0) { 477 *base = vmsegdesc.desc.base; 478 *limit = vmsegdesc.desc.limit; 479 *access = vmsegdesc.desc.access; 480 } 481 return (error); 482 } 483 484 int 485 vm_get_seg_desc(struct vmctx *ctx, int vcpu, int reg, struct seg_desc *seg_desc) 486 { 487 int error; 488 489 error = vm_get_desc(ctx, vcpu, reg, &seg_desc->base, &seg_desc->limit, 490 &seg_desc->access); 491 return (error); 492 } 493 494 int 495 vm_set_register(struct vmctx *ctx, int vcpu, int reg, uint64_t val) 496 { 497 int error; 498 struct vm_register vmreg; 499 500 bzero(&vmreg, sizeof(vmreg)); 501 vmreg.cpuid = vcpu; 502 vmreg.regnum = reg; 503 vmreg.regval = val; 504 505 error = ioctl(ctx->fd, VM_SET_REGISTER, &vmreg); 506 return (error); 507 } 508 509 int 510 vm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *ret_val) 511 { 512 int error; 513 struct vm_register vmreg; 514 515 bzero(&vmreg, sizeof(vmreg)); 516 vmreg.cpuid = vcpu; 517 vmreg.regnum = reg; 518 519 error = ioctl(ctx->fd, VM_GET_REGISTER, &vmreg); 520 *ret_val = vmreg.regval; 521 return (error); 522 } 523 524 int 525 vm_run(struct vmctx *ctx, int vcpu, struct vm_exit *vmexit) 526 { 527 int error; 528 struct vm_run vmrun; 529 530 bzero(&vmrun, sizeof(vmrun)); 531 vmrun.cpuid = vcpu; 532 533 error = ioctl(ctx->fd, VM_RUN, &vmrun); 534 bcopy(&vmrun.vm_exit, vmexit, sizeof(struct vm_exit)); 535 return (error); 536 } 537 538 static int 539 vm_inject_exception_real(struct vmctx *ctx, int vcpu, int vector, 540 int error_code, int error_code_valid) 541 { 542 struct vm_exception exc; 543 544 bzero(&exc, sizeof(exc)); 545 exc.cpuid = vcpu; 546 exc.vector = vector; 547 exc.error_code = error_code; 548 exc.error_code_valid = error_code_valid; 549 550 return (ioctl(ctx->fd, VM_INJECT_EXCEPTION, &exc)); 551 } 552 553 int 554 vm_inject_exception(struct vmctx *ctx, int vcpu, int vector, int errcode_valid, 555 uint32_t errcode, int restart_instruction) 556 { 557 struct vm_exception exc; 558 559 exc.cpuid = vcpu; 560 exc.vector = vector; 561 exc.error_code = errcode; 562 exc.error_code_valid = errcode_valid; 563 exc.restart_instruction = restart_instruction; 564 565 return (ioctl(ctx->fd, VM_INJECT_EXCEPTION, &exc)); 566 } 567 568 int 569 vm_apicid2vcpu(struct vmctx *ctx, int apicid) 570 { 571 /* 572 * The apic id associated with the 'vcpu' has the same numerical value 573 * as the 'vcpu' itself. 574 */ 575 return (apicid); 576 } 577 578 int 579 vm_lapic_irq(struct vmctx *ctx, int vcpu, int vector) 580 { 581 struct vm_lapic_irq vmirq; 582 583 bzero(&vmirq, sizeof(vmirq)); 584 vmirq.cpuid = vcpu; 585 vmirq.vector = vector; 586 587 return (ioctl(ctx->fd, VM_LAPIC_IRQ, &vmirq)); 588 } 589 590 int 591 vm_lapic_local_irq(struct vmctx *ctx, int vcpu, int vector) 592 { 593 struct vm_lapic_irq vmirq; 594 595 bzero(&vmirq, sizeof(vmirq)); 596 vmirq.cpuid = vcpu; 597 vmirq.vector = vector; 598 599 return (ioctl(ctx->fd, VM_LAPIC_LOCAL_IRQ, &vmirq)); 600 } 601 602 int 603 vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg) 604 { 605 struct vm_lapic_msi vmmsi; 606 607 bzero(&vmmsi, sizeof(vmmsi)); 608 vmmsi.addr = addr; 609 vmmsi.msg = msg; 610 611 return (ioctl(ctx->fd, VM_LAPIC_MSI, &vmmsi)); 612 } 613 614 int 615 vm_ioapic_assert_irq(struct vmctx *ctx, int irq) 616 { 617 struct vm_ioapic_irq ioapic_irq; 618 619 bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); 620 ioapic_irq.irq = irq; 621 622 return (ioctl(ctx->fd, VM_IOAPIC_ASSERT_IRQ, &ioapic_irq)); 623 } 624 625 int 626 vm_ioapic_deassert_irq(struct vmctx *ctx, int irq) 627 { 628 struct vm_ioapic_irq ioapic_irq; 629 630 bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); 631 ioapic_irq.irq = irq; 632 633 return (ioctl(ctx->fd, VM_IOAPIC_DEASSERT_IRQ, &ioapic_irq)); 634 } 635 636 int 637 vm_ioapic_pulse_irq(struct vmctx *ctx, int irq) 638 { 639 struct vm_ioapic_irq ioapic_irq; 640 641 bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); 642 ioapic_irq.irq = irq; 643 644 return (ioctl(ctx->fd, VM_IOAPIC_PULSE_IRQ, &ioapic_irq)); 645 } 646 647 int 648 vm_ioapic_pincount(struct vmctx *ctx, int *pincount) 649 { 650 651 return (ioctl(ctx->fd, VM_IOAPIC_PINCOUNT, pincount)); 652 } 653 654 int 655 vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) 656 { 657 struct vm_isa_irq isa_irq; 658 659 bzero(&isa_irq, sizeof(struct vm_isa_irq)); 660 isa_irq.atpic_irq = atpic_irq; 661 isa_irq.ioapic_irq = ioapic_irq; 662 663 return (ioctl(ctx->fd, VM_ISA_ASSERT_IRQ, &isa_irq)); 664 } 665 666 int 667 vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) 668 { 669 struct vm_isa_irq isa_irq; 670 671 bzero(&isa_irq, sizeof(struct vm_isa_irq)); 672 isa_irq.atpic_irq = atpic_irq; 673 isa_irq.ioapic_irq = ioapic_irq; 674 675 return (ioctl(ctx->fd, VM_ISA_DEASSERT_IRQ, &isa_irq)); 676 } 677 678 int 679 vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) 680 { 681 struct vm_isa_irq isa_irq; 682 683 bzero(&isa_irq, sizeof(struct vm_isa_irq)); 684 isa_irq.atpic_irq = atpic_irq; 685 isa_irq.ioapic_irq = ioapic_irq; 686 687 return (ioctl(ctx->fd, VM_ISA_PULSE_IRQ, &isa_irq)); 688 } 689 690 int 691 vm_isa_set_irq_trigger(struct vmctx *ctx, int atpic_irq, 692 enum vm_intr_trigger trigger) 693 { 694 struct vm_isa_irq_trigger isa_irq_trigger; 695 696 bzero(&isa_irq_trigger, sizeof(struct vm_isa_irq_trigger)); 697 isa_irq_trigger.atpic_irq = atpic_irq; 698 isa_irq_trigger.trigger = trigger; 699 700 return (ioctl(ctx->fd, VM_ISA_SET_IRQ_TRIGGER, &isa_irq_trigger)); 701 } 702 703 int 704 vm_inject_nmi(struct vmctx *ctx, int vcpu) 705 { 706 struct vm_nmi vmnmi; 707 708 bzero(&vmnmi, sizeof(vmnmi)); 709 vmnmi.cpuid = vcpu; 710 711 return (ioctl(ctx->fd, VM_INJECT_NMI, &vmnmi)); 712 } 713 714 static struct { 715 const char *name; 716 int type; 717 } capstrmap[] = { 718 { "hlt_exit", VM_CAP_HALT_EXIT }, 719 { "mtrap_exit", VM_CAP_MTRAP_EXIT }, 720 { "pause_exit", VM_CAP_PAUSE_EXIT }, 721 { "unrestricted_guest", VM_CAP_UNRESTRICTED_GUEST }, 722 { "enable_invpcid", VM_CAP_ENABLE_INVPCID }, 723 { 0 } 724 }; 725 726 int 727 vm_capability_name2type(const char *capname) 728 { 729 int i; 730 731 for (i = 0; capstrmap[i].name != NULL && capname != NULL; i++) { 732 if (strcmp(capstrmap[i].name, capname) == 0) 733 return (capstrmap[i].type); 734 } 735 736 return (-1); 737 } 738 739 const char * 740 vm_capability_type2name(int type) 741 { 742 int i; 743 744 for (i = 0; capstrmap[i].name != NULL; i++) { 745 if (capstrmap[i].type == type) 746 return (capstrmap[i].name); 747 } 748 749 return (NULL); 750 } 751 752 int 753 vm_get_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, 754 int *retval) 755 { 756 int error; 757 struct vm_capability vmcap; 758 759 bzero(&vmcap, sizeof(vmcap)); 760 vmcap.cpuid = vcpu; 761 vmcap.captype = cap; 762 763 error = ioctl(ctx->fd, VM_GET_CAPABILITY, &vmcap); 764 *retval = vmcap.capval; 765 return (error); 766 } 767 768 int 769 vm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int val) 770 { 771 struct vm_capability vmcap; 772 773 bzero(&vmcap, sizeof(vmcap)); 774 vmcap.cpuid = vcpu; 775 vmcap.captype = cap; 776 vmcap.capval = val; 777 778 return (ioctl(ctx->fd, VM_SET_CAPABILITY, &vmcap)); 779 } 780 781 int 782 vm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func) 783 { 784 struct vm_pptdev pptdev; 785 786 bzero(&pptdev, sizeof(pptdev)); 787 pptdev.bus = bus; 788 pptdev.slot = slot; 789 pptdev.func = func; 790 791 return (ioctl(ctx->fd, VM_BIND_PPTDEV, &pptdev)); 792 } 793 794 int 795 vm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func) 796 { 797 struct vm_pptdev pptdev; 798 799 bzero(&pptdev, sizeof(pptdev)); 800 pptdev.bus = bus; 801 pptdev.slot = slot; 802 pptdev.func = func; 803 804 return (ioctl(ctx->fd, VM_UNBIND_PPTDEV, &pptdev)); 805 } 806 807 int 808 vm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, 809 vm_paddr_t gpa, size_t len, vm_paddr_t hpa) 810 { 811 struct vm_pptdev_mmio pptmmio; 812 813 bzero(&pptmmio, sizeof(pptmmio)); 814 pptmmio.bus = bus; 815 pptmmio.slot = slot; 816 pptmmio.func = func; 817 pptmmio.gpa = gpa; 818 pptmmio.len = len; 819 pptmmio.hpa = hpa; 820 821 return (ioctl(ctx->fd, VM_MAP_PPTDEV_MMIO, &pptmmio)); 822 } 823 824 int 825 vm_setup_pptdev_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, 826 uint64_t addr, uint64_t msg, int numvec) 827 { 828 struct vm_pptdev_msi pptmsi; 829 830 bzero(&pptmsi, sizeof(pptmsi)); 831 pptmsi.vcpu = vcpu; 832 pptmsi.bus = bus; 833 pptmsi.slot = slot; 834 pptmsi.func = func; 835 pptmsi.msg = msg; 836 pptmsi.addr = addr; 837 pptmsi.numvec = numvec; 838 839 return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi)); 840 } 841 842 int 843 vm_setup_pptdev_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, 844 int idx, uint64_t addr, uint64_t msg, uint32_t vector_control) 845 { 846 struct vm_pptdev_msix pptmsix; 847 848 bzero(&pptmsix, sizeof(pptmsix)); 849 pptmsix.vcpu = vcpu; 850 pptmsix.bus = bus; 851 pptmsix.slot = slot; 852 pptmsix.func = func; 853 pptmsix.idx = idx; 854 pptmsix.msg = msg; 855 pptmsix.addr = addr; 856 pptmsix.vector_control = vector_control; 857 858 return ioctl(ctx->fd, VM_PPTDEV_MSIX, &pptmsix); 859 } 860 861 #ifdef __FreeBSD__ 862 uint64_t * 863 vm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, 864 int *ret_entries) 865 { 866 int error; 867 868 static struct vm_stats vmstats; 869 870 vmstats.cpuid = vcpu; 871 872 error = ioctl(ctx->fd, VM_STATS, &vmstats); 873 if (error == 0) { 874 if (ret_entries) 875 *ret_entries = vmstats.num_entries; 876 if (ret_tv) 877 *ret_tv = vmstats.tv; 878 return (vmstats.statbuf); 879 } else 880 return (NULL); 881 } 882 883 const char * 884 vm_get_stat_desc(struct vmctx *ctx, int index) 885 { 886 static struct vm_stat_desc statdesc; 887 888 statdesc.index = index; 889 if (ioctl(ctx->fd, VM_STAT_DESC, &statdesc) == 0) 890 return (statdesc.desc); 891 else 892 return (NULL); 893 } 894 #endif 895 896 int 897 vm_get_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state *state) 898 { 899 int error; 900 struct vm_x2apic x2apic; 901 902 bzero(&x2apic, sizeof(x2apic)); 903 x2apic.cpuid = vcpu; 904 905 error = ioctl(ctx->fd, VM_GET_X2APIC_STATE, &x2apic); 906 *state = x2apic.state; 907 return (error); 908 } 909 910 int 911 vm_set_x2apic_state(struct vmctx *ctx, int vcpu, enum x2apic_state state) 912 { 913 int error; 914 struct vm_x2apic x2apic; 915 916 bzero(&x2apic, sizeof(x2apic)); 917 x2apic.cpuid = vcpu; 918 x2apic.state = state; 919 920 error = ioctl(ctx->fd, VM_SET_X2APIC_STATE, &x2apic); 921 922 return (error); 923 } 924 925 /* 926 * From Intel Vol 3a: 927 * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT 928 */ 929 int 930 vcpu_reset(struct vmctx *vmctx, int vcpu) 931 { 932 int error; 933 uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx; 934 uint32_t desc_access, desc_limit; 935 uint16_t sel; 936 937 zero = 0; 938 939 rflags = 0x2; 940 error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); 941 if (error) 942 goto done; 943 944 rip = 0xfff0; 945 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RIP, rip)) != 0) 946 goto done; 947 948 cr0 = CR0_NE; 949 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR0, cr0)) != 0) 950 goto done; 951 952 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR3, zero)) != 0) 953 goto done; 954 955 cr4 = 0; 956 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR4, cr4)) != 0) 957 goto done; 958 959 /* 960 * CS: present, r/w, accessed, 16-bit, byte granularity, usable 961 */ 962 desc_base = 0xffff0000; 963 desc_limit = 0xffff; 964 desc_access = 0x0093; 965 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_CS, 966 desc_base, desc_limit, desc_access); 967 if (error) 968 goto done; 969 970 sel = 0xf000; 971 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CS, sel)) != 0) 972 goto done; 973 974 /* 975 * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity 976 */ 977 desc_base = 0; 978 desc_limit = 0xffff; 979 desc_access = 0x0093; 980 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_SS, 981 desc_base, desc_limit, desc_access); 982 if (error) 983 goto done; 984 985 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_DS, 986 desc_base, desc_limit, desc_access); 987 if (error) 988 goto done; 989 990 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_ES, 991 desc_base, desc_limit, desc_access); 992 if (error) 993 goto done; 994 995 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_FS, 996 desc_base, desc_limit, desc_access); 997 if (error) 998 goto done; 999 1000 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GS, 1001 desc_base, desc_limit, desc_access); 1002 if (error) 1003 goto done; 1004 1005 sel = 0; 1006 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_SS, sel)) != 0) 1007 goto done; 1008 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DS, sel)) != 0) 1009 goto done; 1010 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_ES, sel)) != 0) 1011 goto done; 1012 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_FS, sel)) != 0) 1013 goto done; 1014 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_GS, sel)) != 0) 1015 goto done; 1016 1017 /* General purpose registers */ 1018 rdx = 0xf00; 1019 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RAX, zero)) != 0) 1020 goto done; 1021 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBX, zero)) != 0) 1022 goto done; 1023 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RCX, zero)) != 0) 1024 goto done; 1025 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDX, rdx)) != 0) 1026 goto done; 1027 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSI, zero)) != 0) 1028 goto done; 1029 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDI, zero)) != 0) 1030 goto done; 1031 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBP, zero)) != 0) 1032 goto done; 1033 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSP, zero)) != 0) 1034 goto done; 1035 1036 /* GDTR, IDTR */ 1037 desc_base = 0; 1038 desc_limit = 0xffff; 1039 desc_access = 0; 1040 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GDTR, 1041 desc_base, desc_limit, desc_access); 1042 if (error != 0) 1043 goto done; 1044 1045 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_IDTR, 1046 desc_base, desc_limit, desc_access); 1047 if (error != 0) 1048 goto done; 1049 1050 /* TR */ 1051 desc_base = 0; 1052 desc_limit = 0xffff; 1053 desc_access = 0x0000008b; 1054 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); 1055 if (error) 1056 goto done; 1057 1058 sel = 0; 1059 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_TR, sel)) != 0) 1060 goto done; 1061 1062 /* LDTR */ 1063 desc_base = 0; 1064 desc_limit = 0xffff; 1065 desc_access = 0x00000082; 1066 error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, desc_base, 1067 desc_limit, desc_access); 1068 if (error) 1069 goto done; 1070 1071 sel = 0; 1072 if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0) 1073 goto done; 1074 1075 /* XXX cr2, debug registers */ 1076 1077 error = 0; 1078 done: 1079 return (error); 1080 } 1081 1082 int 1083 vm_get_gpa_pmap(struct vmctx *ctx, uint64_t gpa, uint64_t *pte, int *num) 1084 { 1085 int error, i; 1086 struct vm_gpa_pte gpapte; 1087 1088 bzero(&gpapte, sizeof(gpapte)); 1089 gpapte.gpa = gpa; 1090 1091 error = ioctl(ctx->fd, VM_GET_GPA_PMAP, &gpapte); 1092 1093 if (error == 0) { 1094 *num = gpapte.ptenum; 1095 for (i = 0; i < gpapte.ptenum; i++) 1096 pte[i] = gpapte.pte[i]; 1097 } 1098 1099 return (error); 1100 } 1101 1102 int 1103 vm_get_hpet_capabilities(struct vmctx *ctx, uint32_t *capabilities) 1104 { 1105 int error; 1106 struct vm_hpet_cap cap; 1107 1108 bzero(&cap, sizeof(struct vm_hpet_cap)); 1109 error = ioctl(ctx->fd, VM_GET_HPET_CAPABILITIES, &cap); 1110 if (capabilities != NULL) 1111 *capabilities = cap.capabilities; 1112 return (error); 1113 } 1114 1115 static int 1116 gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, 1117 uint64_t gla, int prot, int *fault, uint64_t *gpa) 1118 { 1119 struct vm_gla2gpa gg; 1120 int error; 1121 1122 bzero(&gg, sizeof(struct vm_gla2gpa)); 1123 gg.vcpuid = vcpu; 1124 gg.prot = prot; 1125 gg.gla = gla; 1126 gg.paging = *paging; 1127 1128 error = ioctl(ctx->fd, VM_GLA2GPA, &gg); 1129 if (error == 0) { 1130 *fault = gg.fault; 1131 *gpa = gg.gpa; 1132 } 1133 return (error); 1134 } 1135 1136 int 1137 vm_gla2gpa(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, 1138 uint64_t gla, int prot, uint64_t *gpa) 1139 { 1140 int error, fault; 1141 1142 error = gla2gpa(ctx, vcpu, paging, gla, prot, &fault, gpa); 1143 if (fault) 1144 error = fault; 1145 return (error); 1146 } 1147 1148 #ifndef min 1149 #define min(a,b) (((a) < (b)) ? (a) : (b)) 1150 #endif 1151 1152 int 1153 vm_copy_setup(struct vmctx *ctx, int vcpu, struct vm_guest_paging *paging, 1154 uint64_t gla, size_t len, int prot, struct iovec *iov, int iovcnt) 1155 { 1156 void *va; 1157 uint64_t gpa; 1158 int error, fault, i, n, off; 1159 1160 for (i = 0; i < iovcnt; i++) { 1161 iov[i].iov_base = 0; 1162 iov[i].iov_len = 0; 1163 } 1164 1165 while (len) { 1166 assert(iovcnt > 0); 1167 error = gla2gpa(ctx, vcpu, paging, gla, prot, &fault, &gpa); 1168 if (error) 1169 return (-1); 1170 if (fault) 1171 return (1); 1172 1173 off = gpa & PAGE_MASK; 1174 n = min(len, PAGE_SIZE - off); 1175 1176 va = vm_map_gpa(ctx, gpa, n); 1177 if (va == NULL) 1178 return (-1); 1179 1180 iov->iov_base = va; 1181 iov->iov_len = n; 1182 iov++; 1183 iovcnt--; 1184 1185 gla += n; 1186 len -= n; 1187 } 1188 return (0); 1189 } 1190 1191 void 1192 vm_copy_teardown(struct vmctx *ctx, int vcpu, struct iovec *iov, int iovcnt) 1193 { 1194 1195 return; 1196 } 1197 1198 void 1199 vm_copyin(struct vmctx *ctx, int vcpu, struct iovec *iov, void *vp, size_t len) 1200 { 1201 const char *src; 1202 char *dst; 1203 size_t n; 1204 1205 dst = vp; 1206 while (len) { 1207 assert(iov->iov_len); 1208 n = min(len, iov->iov_len); 1209 src = iov->iov_base; 1210 bcopy(src, dst, n); 1211 1212 iov++; 1213 dst += n; 1214 len -= n; 1215 } 1216 } 1217 1218 void 1219 vm_copyout(struct vmctx *ctx, int vcpu, const void *vp, struct iovec *iov, 1220 size_t len) 1221 { 1222 const char *src; 1223 char *dst; 1224 size_t n; 1225 1226 src = vp; 1227 while (len) { 1228 assert(iov->iov_len); 1229 n = min(len, iov->iov_len); 1230 dst = iov->iov_base; 1231 bcopy(src, dst, n); 1232 1233 iov++; 1234 src += n; 1235 len -= n; 1236 } 1237 } 1238 1239 int 1240 vm_activate_cpu(struct vmctx *ctx, int vcpu) 1241 { 1242 struct vm_activate_cpu ac; 1243 int error; 1244 1245 bzero(&ac, sizeof(struct vm_activate_cpu)); 1246 ac.vcpuid = vcpu; 1247 error = ioctl(ctx->fd, VM_ACTIVATE_CPU, &ac); 1248 return (error); 1249 } 1250 1251 int 1252 vm_restart_instruction(void *arg, int vcpu) 1253 { 1254 struct vmctx *ctx = arg; 1255 1256 return (ioctl(ctx->fd, VM_RESTART_INSTRUCTION, &vcpu)); 1257 } 1258