vmmapi.c revision 239025
172339Sabial/*- 272339Sabial * Copyright (c) 2011 NetApp, Inc. 372339Sabial * All rights reserved. 472339Sabial * 572339Sabial * Redistribution and use in source and binary forms, with or without 672339Sabial * modification, are permitted provided that the following conditions 772339Sabial * are met: 872339Sabial * 1. Redistributions of source code must retain the above copyright 972339Sabial * notice, this list of conditions and the following disclaimer. 1072339Sabial * 2. Redistributions in binary form must reproduce the above copyright 1172339Sabial * notice, this list of conditions and the following disclaimer in the 1272339Sabial * documentation and/or other materials provided with the distribution. 1372339Sabial * 1472339Sabial * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 1572339Sabial * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1672339Sabial * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1772339Sabial * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 1872339Sabial * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 1972339Sabial * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2072339Sabial * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2172339Sabial * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2272339Sabial * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2372339Sabial * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2472339Sabial * SUCH DAMAGE. 2572339Sabial * 2672339Sabial * $FreeBSD$ 2772339Sabial */ 2872339Sabial 2972339Sabial#include <sys/cdefs.h> 3072339Sabial__FBSDID("$FreeBSD$"); 3172339Sabial 3272339Sabial#include <sys/types.h> 3372339Sabial#include <sys/sysctl.h> 3472339Sabial#include <sys/ioctl.h> 3572339Sabial#include <sys/mman.h> 3672339Sabial 3772339Sabial#include <machine/specialreg.h> 3872339Sabial 3972339Sabial#include <stdio.h> 4072339Sabial#include <stdlib.h> 4172339Sabial#include <assert.h> 4272339Sabial#include <string.h> 4372339Sabial#include <fcntl.h> 4472339Sabial#include <unistd.h> 4572339Sabial 4672339Sabial#include <machine/vmm.h> 4772339Sabial#include <machine/vmm_dev.h> 4872339Sabial 4972339Sabial#include "vmmapi.h" 5072339Sabial#include "mptable.h" 5172339Sabial 5272339Sabial#define BIOS_ROM_BASE (0xf0000) 5372339Sabial#define BIOS_ROM_SIZE (0x10000) 5472339Sabial 5572339Sabialstruct vmctx { 5672339Sabial int fd; 5772339Sabial char *name; 5872339Sabial}; 5972339Sabial 6072339Sabial#define CREATE(x) sysctlbyname("hw.vmm.create", NULL, NULL, (x), strlen((x))) 6172339Sabial#define DESTROY(x) sysctlbyname("hw.vmm.destroy", NULL, NULL, (x), strlen((x))) 6272339Sabial 6372339Sabialstatic int 6472339Sabialvm_device_open(const char *name) 6572339Sabial{ 6672339Sabial int fd, len; 6772339Sabial char *vmfile; 6872339Sabial 6972339Sabial len = strlen("/dev/vmm/") + strlen(name) + 1; 7072339Sabial vmfile = malloc(len); 7172339Sabial assert(vmfile != NULL); 7272339Sabial snprintf(vmfile, len, "/dev/vmm/%s", name); 7372339Sabial 7472339Sabial /* Open the device file */ 7572339Sabial fd = open(vmfile, O_RDWR, 0); 7672339Sabial 7772339Sabial free(vmfile); 7872339Sabial return (fd); 7972339Sabial} 8072339Sabial 8172339Sabialint 8272339Sabialvm_create(const char *name) 8372339Sabial{ 8472339Sabial 8572339Sabial return (CREATE((char *)name)); 8672339Sabial} 8772339Sabial 8872339Sabialstruct vmctx * 8972339Sabialvm_open(const char *name) 9072339Sabial{ 9172339Sabial struct vmctx *vm; 9272339Sabial 9372339Sabial vm = malloc(sizeof(struct vmctx) + strlen(name) + 1); 9472339Sabial assert(vm != NULL); 9572339Sabial 9672339Sabial vm->fd = -1; 9772339Sabial vm->name = (char *)(vm + 1); 9872339Sabial strcpy(vm->name, name); 9972339Sabial 10072339Sabial if ((vm->fd = vm_device_open(vm->name)) < 0) 10172339Sabial goto err; 10272339Sabial 10372339Sabial return (vm); 10472339Sabialerr: 10572339Sabial vm_destroy(vm); 10672339Sabial return (NULL); 10772339Sabial} 10872339Sabial 10972339Sabialvoid 11072339Sabialvm_destroy(struct vmctx *vm) 11172339Sabial{ 11272339Sabial assert(vm != NULL); 11372339Sabial 11472339Sabial DESTROY(vm->name); 11572339Sabial if (vm->fd >= 0) 11672339Sabial close(vm->fd); 11772339Sabial free(vm); 11872339Sabial} 11972339Sabial 12072339Sabialint 12172339Sabialvm_get_memory_seg(struct vmctx *ctx, vm_paddr_t gpa, 12272339Sabial vm_paddr_t *ret_hpa, size_t *ret_len) 12372339Sabial{ 12472339Sabial int error; 12572339Sabial struct vm_memory_segment seg; 12672339Sabial 12772339Sabial bzero(&seg, sizeof(seg)); 12872339Sabial seg.gpa = gpa; 12972339Sabial error = ioctl(ctx->fd, VM_GET_MEMORY_SEG, &seg); 13072339Sabial *ret_hpa = seg.hpa; 13172339Sabial *ret_len = seg.len; 13272339Sabial return (error); 13372339Sabial} 13472339Sabial 13572339Sabialint 13672339Sabialvm_setup_memory(struct vmctx *ctx, vm_paddr_t gpa, size_t len, char **mapaddr) 13772339Sabial{ 13872339Sabial int error; 13972339Sabial struct vm_memory_segment seg; 14072339Sabial 14172339Sabial /* 14272339Sabial * Create and optionally map 'len' bytes of memory at guest 14372339Sabial * physical address 'gpa' 14472339Sabial */ 14572339Sabial bzero(&seg, sizeof(seg)); 14672339Sabial seg.gpa = gpa; 14772339Sabial seg.len = len; 14872339Sabial error = ioctl(ctx->fd, VM_MAP_MEMORY, &seg); 14972339Sabial if (error == 0 && mapaddr != NULL) { 15072339Sabial *mapaddr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, 15172339Sabial ctx->fd, gpa); 15272339Sabial } 15372339Sabial return (error); 15472339Sabial} 15572339Sabial 15672339Sabialchar * 15772339Sabialvm_map_memory(struct vmctx *ctx, vm_paddr_t gpa, size_t len) 15872339Sabial{ 15972339Sabial 16072339Sabial /* Map 'len' bytes of memory at guest physical address 'gpa' */ 16172339Sabial return ((char *)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, 16272339Sabial ctx->fd, gpa)); 16372339Sabial} 16472339Sabial 16572339Sabialint 16672339Sabialvm_set_desc(struct vmctx *ctx, int vcpu, int reg, 16772339Sabial uint64_t base, uint32_t limit, uint32_t access) 16872339Sabial{ 16972339Sabial int error; 17072339Sabial struct vm_seg_desc vmsegdesc; 17172339Sabial 17272339Sabial bzero(&vmsegdesc, sizeof(vmsegdesc)); 17372339Sabial vmsegdesc.cpuid = vcpu; 17472339Sabial vmsegdesc.regnum = reg; 17572339Sabial vmsegdesc.desc.base = base; 17672339Sabial vmsegdesc.desc.limit = limit; 17772339Sabial vmsegdesc.desc.access = access; 17872339Sabial 17972339Sabial error = ioctl(ctx->fd, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc); 18072339Sabial return (error); 18172339Sabial} 18272339Sabial 18372339Sabialint 18472339Sabialvm_get_desc(struct vmctx *ctx, int vcpu, int reg, 18572339Sabial uint64_t *base, uint32_t *limit, uint32_t *access) 18672339Sabial{ 18772339Sabial int error; 18872339Sabial struct vm_seg_desc vmsegdesc; 18972339Sabial 19072339Sabial bzero(&vmsegdesc, sizeof(vmsegdesc)); 19172339Sabial vmsegdesc.cpuid = vcpu; 19272339Sabial vmsegdesc.regnum = reg; 19372339Sabial 19472339Sabial error = ioctl(ctx->fd, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc); 19572339Sabial if (error == 0) { 19672339Sabial *base = vmsegdesc.desc.base; 19772339Sabial *limit = vmsegdesc.desc.limit; 19872339Sabial *access = vmsegdesc.desc.access; 19972339Sabial } 20072339Sabial return (error); 20172339Sabial} 20272339Sabial 20372339Sabialint 20472339Sabialvm_set_register(struct vmctx *ctx, int vcpu, int reg, uint64_t val) 20572339Sabial{ 20672339Sabial int error; 20772339Sabial struct vm_register vmreg; 20872339Sabial 20972339Sabial bzero(&vmreg, sizeof(vmreg)); 21072339Sabial vmreg.cpuid = vcpu; 21172339Sabial vmreg.regnum = reg; 21272339Sabial vmreg.regval = val; 21372339Sabial 21472339Sabial error = ioctl(ctx->fd, VM_SET_REGISTER, &vmreg); 21572339Sabial return (error); 21672339Sabial} 21772339Sabial 21872339Sabialint 21972339Sabialvm_get_register(struct vmctx *ctx, int vcpu, int reg, uint64_t *ret_val) 22072339Sabial{ 22172339Sabial int error; 22272339Sabial struct vm_register vmreg; 22372339Sabial 22472339Sabial bzero(&vmreg, sizeof(vmreg)); 22572339Sabial vmreg.cpuid = vcpu; 22672339Sabial vmreg.regnum = reg; 22772339Sabial 22872339Sabial error = ioctl(ctx->fd, VM_GET_REGISTER, &vmreg); 22972339Sabial *ret_val = vmreg.regval; 23072339Sabial return (error); 23172339Sabial} 23272339Sabial 23372339Sabialint 23472339Sabialvm_get_pinning(struct vmctx *ctx, int vcpu, int *host_cpuid) 23572339Sabial{ 23672339Sabial int error; 23772339Sabial struct vm_pin vmpin; 23872339Sabial 23972339Sabial bzero(&vmpin, sizeof(vmpin)); 24072339Sabial vmpin.vm_cpuid = vcpu; 24172339Sabial 24272339Sabial error = ioctl(ctx->fd, VM_GET_PINNING, &vmpin); 24372339Sabial *host_cpuid = vmpin.host_cpuid; 24472339Sabial return (error); 24572339Sabial} 24672339Sabial 24772339Sabialint 24872339Sabialvm_set_pinning(struct vmctx *ctx, int vcpu, int host_cpuid) 24972339Sabial{ 25072339Sabial int error; 25172339Sabial struct vm_pin vmpin; 25272339Sabial 25372339Sabial bzero(&vmpin, sizeof(vmpin)); 25472339Sabial vmpin.vm_cpuid = vcpu; 25572339Sabial vmpin.host_cpuid = host_cpuid; 25672339Sabial 25772339Sabial error = ioctl(ctx->fd, VM_SET_PINNING, &vmpin); 25872339Sabial return (error); 25972339Sabial} 26072339Sabial 26172339Sabialint 26272339Sabialvm_run(struct vmctx *ctx, int vcpu, uint64_t rip, struct vm_exit *vmexit) 26372339Sabial{ 26472339Sabial int error; 26572339Sabial struct vm_run vmrun; 26672339Sabial 26772339Sabial bzero(&vmrun, sizeof(vmrun)); 26872339Sabial vmrun.cpuid = vcpu; 26972339Sabial vmrun.rip = rip; 27072339Sabial 27172339Sabial error = ioctl(ctx->fd, VM_RUN, &vmrun); 27272339Sabial bcopy(&vmrun.vm_exit, vmexit, sizeof(struct vm_exit)); 27372339Sabial return (error); 27472339Sabial} 27572339Sabial 27672339Sabialstatic int 27772339Sabialvm_inject_event_real(struct vmctx *ctx, int vcpu, enum vm_event_type type, 27872339Sabial int vector, int error_code, int error_code_valid) 27972339Sabial{ 28072339Sabial struct vm_event ev; 28172339Sabial 28272339Sabial bzero(&ev, sizeof(ev)); 28372339Sabial ev.cpuid = vcpu; 28472339Sabial ev.type = type; 28572339Sabial ev.vector = vector; 28672339Sabial ev.error_code = error_code; 28772339Sabial ev.error_code_valid = error_code_valid; 28872339Sabial 28972339Sabial return (ioctl(ctx->fd, VM_INJECT_EVENT, &ev)); 29072339Sabial} 29172339Sabial 29272339Sabialint 29372339Sabialvm_inject_event(struct vmctx *ctx, int vcpu, enum vm_event_type type, 29472339Sabial int vector) 29572339Sabial{ 29672339Sabial 29772339Sabial return (vm_inject_event_real(ctx, vcpu, type, vector, 0, 0)); 29872339Sabial} 29972339Sabial 30072339Sabialint 30172339Sabialvm_inject_event2(struct vmctx *ctx, int vcpu, enum vm_event_type type, 30272339Sabial int vector, int error_code) 30372339Sabial{ 30472339Sabial 30572339Sabial return (vm_inject_event_real(ctx, vcpu, type, vector, error_code, 1)); 30672339Sabial} 30772339Sabial 30872339Sabialint 30972339Sabialvm_build_tables(struct vmctx *ctxt, int ncpu, void *oemtbl, int oemtblsz) 31072339Sabial{ 31172339Sabial 31272339Sabial return (vm_build_mptable(ctxt, BIOS_ROM_BASE, BIOS_ROM_SIZE, ncpu, 31372339Sabial oemtbl, oemtblsz)); 31472339Sabial} 31572339Sabial 31672339Sabialint 31772339Sabialvm_lapic_irq(struct vmctx *ctx, int vcpu, int vector) 31872339Sabial{ 31972339Sabial struct vm_lapic_irq vmirq; 32072339Sabial 32172339Sabial bzero(&vmirq, sizeof(vmirq)); 32272339Sabial vmirq.cpuid = vcpu; 32372339Sabial vmirq.vector = vector; 32472339Sabial 32572339Sabial return (ioctl(ctx->fd, VM_LAPIC_IRQ, &vmirq)); 32672339Sabial} 32772339Sabial 32872339Sabialint 32972339Sabialvm_inject_nmi(struct vmctx *ctx, int vcpu) 33072339Sabial{ 33172339Sabial struct vm_nmi vmnmi; 33272339Sabial 33372339Sabial bzero(&vmnmi, sizeof(vmnmi)); 33472339Sabial vmnmi.cpuid = vcpu; 33572339Sabial 33672339Sabial return (ioctl(ctx->fd, VM_INJECT_NMI, &vmnmi)); 33772339Sabial} 33872339Sabial 33972339Sabialint 34072339Sabialvm_capability_name2type(const char *capname) 34172339Sabial{ 34272339Sabial int i; 34372339Sabial 34472339Sabial static struct { 34572339Sabial const char *name; 34672339Sabial int type; 34772339Sabial } capstrmap[] = { 34872339Sabial { "hlt_exit", VM_CAP_HALT_EXIT }, 34972339Sabial { "mtrap_exit", VM_CAP_MTRAP_EXIT }, 35072339Sabial { "pause_exit", VM_CAP_PAUSE_EXIT }, 35172339Sabial { "unrestricted_guest", VM_CAP_UNRESTRICTED_GUEST }, 35272339Sabial { 0 } 35372339Sabial }; 35472339Sabial 35572339Sabial for (i = 0; capstrmap[i].name != NULL && capname != NULL; i++) { 35672339Sabial if (strcmp(capstrmap[i].name, capname) == 0) 35772339Sabial return (capstrmap[i].type); 35872339Sabial } 35972339Sabial 36072339Sabial return (-1); 36172339Sabial} 36272339Sabial 36372339Sabialint 36472339Sabialvm_get_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, 36572339Sabial int *retval) 36672339Sabial{ 36772339Sabial int error; 36872339Sabial struct vm_capability vmcap; 36972339Sabial 37072339Sabial bzero(&vmcap, sizeof(vmcap)); 37172339Sabial vmcap.cpuid = vcpu; 37272339Sabial vmcap.captype = cap; 37372339Sabial 37472339Sabial error = ioctl(ctx->fd, VM_GET_CAPABILITY, &vmcap); 37572339Sabial *retval = vmcap.capval; 37672339Sabial return (error); 37772339Sabial} 37872339Sabial 37972339Sabialint 38072339Sabialvm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int val) 38172339Sabial{ 38272339Sabial struct vm_capability vmcap; 38372339Sabial 38472339Sabial bzero(&vmcap, sizeof(vmcap)); 38572339Sabial vmcap.cpuid = vcpu; 38672339Sabial vmcap.captype = cap; 38772339Sabial vmcap.capval = val; 38872339Sabial 38972339Sabial return (ioctl(ctx->fd, VM_SET_CAPABILITY, &vmcap)); 39072339Sabial} 39172339Sabial 39272339Sabialint 39372339Sabialvm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func) 39472339Sabial{ 39572339Sabial struct vm_pptdev pptdev; 39672339Sabial 39772339Sabial bzero(&pptdev, sizeof(pptdev)); 39872339Sabial pptdev.bus = bus; 39972339Sabial pptdev.slot = slot; 40072339Sabial pptdev.func = func; 40172339Sabial 40272339Sabial return (ioctl(ctx->fd, VM_BIND_PPTDEV, &pptdev)); 40372339Sabial} 40472339Sabial 40572339Sabialint 40672339Sabialvm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func) 40772339Sabial{ 40872339Sabial struct vm_pptdev pptdev; 40972339Sabial 41072339Sabial bzero(&pptdev, sizeof(pptdev)); 41172339Sabial pptdev.bus = bus; 41272339Sabial pptdev.slot = slot; 41372339Sabial pptdev.func = func; 41472339Sabial 41572339Sabial return (ioctl(ctx->fd, VM_UNBIND_PPTDEV, &pptdev)); 41672339Sabial} 41772339Sabial 41872339Sabialint 41972339Sabialvm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, 42072339Sabial vm_paddr_t gpa, size_t len, vm_paddr_t hpa) 42172339Sabial{ 42272339Sabial struct vm_pptdev_mmio pptmmio; 42372339Sabial 42472339Sabial bzero(&pptmmio, sizeof(pptmmio)); 42572339Sabial pptmmio.bus = bus; 42672339Sabial pptmmio.slot = slot; 42772339Sabial pptmmio.func = func; 42872339Sabial pptmmio.gpa = gpa; 42972339Sabial pptmmio.len = len; 43072339Sabial pptmmio.hpa = hpa; 43172339Sabial 43272339Sabial return (ioctl(ctx->fd, VM_MAP_PPTDEV_MMIO, &pptmmio)); 43372339Sabial} 43472339Sabial 43572339Sabialint 43672339Sabialvm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, 43772339Sabial int destcpu, int vector, int numvec) 43872339Sabial{ 43972339Sabial struct vm_pptdev_msi pptmsi; 44072339Sabial 44172339Sabial bzero(&pptmsi, sizeof(pptmsi)); 44272339Sabial pptmsi.vcpu = vcpu; 44372339Sabial pptmsi.bus = bus; 44472339Sabial pptmsi.slot = slot; 44572339Sabial pptmsi.func = func; 44672339Sabial pptmsi.destcpu = destcpu; 44772339Sabial pptmsi.vector = vector; 44872339Sabial pptmsi.numvec = numvec; 44972339Sabial 45072339Sabial return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi)); 45172339Sabial} 45272339Sabial 45372339Sabialint 45472339Sabialvm_setup_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, 45572339Sabial int idx, uint32_t msg, uint32_t vector_control, uint64_t addr) 45672339Sabial{ 45772339Sabial struct vm_pptdev_msix pptmsix; 45872339Sabial 45972339Sabial bzero(&pptmsix, sizeof(pptmsix)); 46072339Sabial pptmsix.vcpu = vcpu; 46172339Sabial pptmsix.bus = bus; 46272339Sabial pptmsix.slot = slot; 46372339Sabial pptmsix.func = func; 46472339Sabial pptmsix.idx = idx; 46572339Sabial pptmsix.msg = msg; 46672339Sabial pptmsix.addr = addr; 46772339Sabial pptmsix.vector_control = vector_control; 46872339Sabial 46972339Sabial return ioctl(ctx->fd, VM_PPTDEV_MSIX, &pptmsix); 47072339Sabial} 47172339Sabial 47272339Sabialuint64_t * 47372339Sabialvm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, 47472339Sabial int *ret_entries) 47572339Sabial{ 47672339Sabial int error; 47772339Sabial 47872339Sabial static struct vm_stats vmstats; 47972339Sabial 48072339Sabial vmstats.cpuid = vcpu; 48172339Sabial 48272339Sabial error = ioctl(ctx->fd, VM_STATS, &vmstats); 48372339Sabial if (error == 0) { 48472339Sabial if (ret_entries) 48572339Sabial *ret_entries = vmstats.num_entries; 48672339Sabial if (ret_tv) 48772339Sabial *ret_tv = vmstats.tv; 48872339Sabial return (vmstats.statbuf); 48972339Sabial } else 49072339Sabial return (NULL); 49172339Sabial} 49272339Sabial 49372339Sabialconst char * 49472339Sabialvm_get_stat_desc(struct vmctx *ctx, int index) 49572339Sabial{ 49672339Sabial static struct vm_stat_desc statdesc; 49772339Sabial 49872339Sabial statdesc.index = index; 49972339Sabial if (ioctl(ctx->fd, VM_STAT_DESC, &statdesc) == 0) 50072339Sabial return (statdesc.desc); 50172339Sabial else 50272339Sabial return (NULL); 50372339Sabial} 50472339Sabial 50572339Sabial/* 50672339Sabial * From Intel Vol 3a: 50772339Sabial * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT 50872339Sabial */ 50972339Sabialint 51072339Sabialvcpu_reset(struct vmctx *vmctx, int vcpu) 51172339Sabial{ 51272339Sabial int error; 51372339Sabial uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx; 51472339Sabial uint32_t desc_access, desc_limit; 51572339Sabial uint16_t sel; 51672339Sabial 51772339Sabial zero = 0; 51872339Sabial 51972339Sabial rflags = 0x2; 52072339Sabial error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); 52172339Sabial if (error) 52272339Sabial goto done; 52372339Sabial 52472339Sabial rip = 0xfff0; 52572339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RIP, rip)) != 0) 52672339Sabial goto done; 52772339Sabial 52872339Sabial cr0 = CR0_NE; 52972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR0, cr0)) != 0) 53072339Sabial goto done; 53172339Sabial 53272339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR3, zero)) != 0) 53372339Sabial goto done; 53472339Sabial 53572339Sabial cr4 = 0; 53672339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR4, cr4)) != 0) 53772339Sabial goto done; 53872339Sabial 53972339Sabial /* 54072339Sabial * CS: present, r/w, accessed, 16-bit, byte granularity, usable 54172339Sabial */ 54272339Sabial desc_base = 0xffff0000; 54372339Sabial desc_limit = 0xffff; 54472339Sabial desc_access = 0x0093; 54572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_CS, 54672339Sabial desc_base, desc_limit, desc_access); 54772339Sabial if (error) 54872339Sabial goto done; 54972339Sabial 55072339Sabial sel = 0xf000; 55172339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CS, sel)) != 0) 55272339Sabial goto done; 55372339Sabial 55472339Sabial /* 55572339Sabial * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity 55672339Sabial */ 55772339Sabial desc_base = 0; 55872339Sabial desc_limit = 0xffff; 55972339Sabial desc_access = 0x0093; 56072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_SS, 56172339Sabial desc_base, desc_limit, desc_access); 56272339Sabial if (error) 56372339Sabial goto done; 56472339Sabial 56572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_DS, 56672339Sabial desc_base, desc_limit, desc_access); 56772339Sabial if (error) 56872339Sabial goto done; 56972339Sabial 57072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_ES, 57172339Sabial desc_base, desc_limit, desc_access); 57272339Sabial if (error) 57372339Sabial goto done; 57472339Sabial 57572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_FS, 57672339Sabial desc_base, desc_limit, desc_access); 57772339Sabial if (error) 57872339Sabial goto done; 57972339Sabial 58072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GS, 58172339Sabial desc_base, desc_limit, desc_access); 58272339Sabial if (error) 58372339Sabial goto done; 58472339Sabial 58572339Sabial sel = 0; 58672339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_SS, sel)) != 0) 58772339Sabial goto done; 58872339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DS, sel)) != 0) 58972339Sabial goto done; 59072339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_ES, sel)) != 0) 59172339Sabial goto done; 59272339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_FS, sel)) != 0) 59372339Sabial goto done; 59472339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_GS, sel)) != 0) 59572339Sabial goto done; 59672339Sabial 59772339Sabial /* General purpose registers */ 59872339Sabial rdx = 0xf00; 59972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RAX, zero)) != 0) 60072339Sabial goto done; 60172339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBX, zero)) != 0) 60272339Sabial goto done; 60372339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RCX, zero)) != 0) 60472339Sabial goto done; 60572339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDX, rdx)) != 0) 60672339Sabial goto done; 60772339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSI, zero)) != 0) 60872339Sabial goto done; 60972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDI, zero)) != 0) 61072339Sabial goto done; 61172339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBP, zero)) != 0) 61272339Sabial goto done; 61372339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSP, zero)) != 0) 61472339Sabial goto done; 61572339Sabial 61672339Sabial /* GDTR, IDTR */ 61772339Sabial desc_base = 0; 61872339Sabial desc_limit = 0xffff; 61972339Sabial desc_access = 0; 62072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GDTR, 62172339Sabial desc_base, desc_limit, desc_access); 62272339Sabial if (error != 0) 62372339Sabial goto done; 62472339Sabial 62572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_IDTR, 62672339Sabial desc_base, desc_limit, desc_access); 62772339Sabial if (error != 0) 62872339Sabial goto done; 62972339Sabial 63072339Sabial /* TR */ 63172339Sabial desc_base = 0; 63272339Sabial desc_limit = 0xffff; 63372339Sabial desc_access = 0x0000008b; 63472339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); 63572339Sabial if (error) 63672339Sabial goto done; 63772339Sabial 63872339Sabial sel = 0; 63972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_TR, sel)) != 0) 64072339Sabial goto done; 64172339Sabial 64272339Sabial /* LDTR */ 64372339Sabial desc_base = 0; 64472339Sabial desc_limit = 0xffff; 64572339Sabial desc_access = 0x00000082; 64672339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, desc_base, 64772339Sabial desc_limit, desc_access); 64872339Sabial if (error) 64972339Sabial goto done; 65072339Sabial 65172339Sabial sel = 0; 65272339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0) 65372339Sabial goto done; 65472339Sabial 65572339Sabial /* XXX cr2, debug registers */ 65672339Sabial 65772339Sabial error = 0; 65872339Sabialdone: 65972339Sabial return (error); 66072339Sabial} 66172339Sabial