vmmapi.c revision 239026
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_apicid2vcpu(struct vmctx *ctx, int apicid) 31872339Sabial{ 31972339Sabial /* 32072339Sabial * The apic id associated with the 'vcpu' has the same numerical value 32172339Sabial * as the 'vcpu' itself. 32272339Sabial */ 32372339Sabial return (apicid); 32472339Sabial} 32572339Sabial 32672339Sabialint 32772339Sabialvm_lapic_irq(struct vmctx *ctx, int vcpu, int vector) 32872339Sabial{ 32972339Sabial struct vm_lapic_irq vmirq; 33072339Sabial 33172339Sabial bzero(&vmirq, sizeof(vmirq)); 33272339Sabial vmirq.cpuid = vcpu; 33372339Sabial vmirq.vector = vector; 33472339Sabial 33572339Sabial return (ioctl(ctx->fd, VM_LAPIC_IRQ, &vmirq)); 33672339Sabial} 33772339Sabial 33872339Sabialint 33972339Sabialvm_inject_nmi(struct vmctx *ctx, int vcpu) 34072339Sabial{ 34172339Sabial struct vm_nmi vmnmi; 34272339Sabial 34372339Sabial bzero(&vmnmi, sizeof(vmnmi)); 34472339Sabial vmnmi.cpuid = vcpu; 34572339Sabial 34672339Sabial return (ioctl(ctx->fd, VM_INJECT_NMI, &vmnmi)); 34772339Sabial} 34872339Sabial 34972339Sabialint 35072339Sabialvm_capability_name2type(const char *capname) 35172339Sabial{ 35272339Sabial int i; 35372339Sabial 35472339Sabial static struct { 35572339Sabial const char *name; 35672339Sabial int type; 35772339Sabial } capstrmap[] = { 35872339Sabial { "hlt_exit", VM_CAP_HALT_EXIT }, 35972339Sabial { "mtrap_exit", VM_CAP_MTRAP_EXIT }, 36072339Sabial { "pause_exit", VM_CAP_PAUSE_EXIT }, 36172339Sabial { "unrestricted_guest", VM_CAP_UNRESTRICTED_GUEST }, 36272339Sabial { 0 } 36372339Sabial }; 36472339Sabial 36572339Sabial for (i = 0; capstrmap[i].name != NULL && capname != NULL; i++) { 36672339Sabial if (strcmp(capstrmap[i].name, capname) == 0) 36772339Sabial return (capstrmap[i].type); 36872339Sabial } 36972339Sabial 37072339Sabial return (-1); 37172339Sabial} 37272339Sabial 37372339Sabialint 37472339Sabialvm_get_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, 37572339Sabial int *retval) 37672339Sabial{ 37772339Sabial int error; 37872339Sabial struct vm_capability vmcap; 37972339Sabial 38072339Sabial bzero(&vmcap, sizeof(vmcap)); 38172339Sabial vmcap.cpuid = vcpu; 38272339Sabial vmcap.captype = cap; 38372339Sabial 38472339Sabial error = ioctl(ctx->fd, VM_GET_CAPABILITY, &vmcap); 38572339Sabial *retval = vmcap.capval; 38672339Sabial return (error); 38772339Sabial} 38872339Sabial 38972339Sabialint 39072339Sabialvm_set_capability(struct vmctx *ctx, int vcpu, enum vm_cap_type cap, int val) 39172339Sabial{ 39272339Sabial struct vm_capability vmcap; 39372339Sabial 39472339Sabial bzero(&vmcap, sizeof(vmcap)); 39572339Sabial vmcap.cpuid = vcpu; 39672339Sabial vmcap.captype = cap; 39772339Sabial vmcap.capval = val; 39872339Sabial 39972339Sabial return (ioctl(ctx->fd, VM_SET_CAPABILITY, &vmcap)); 40072339Sabial} 40172339Sabial 40272339Sabialint 40372339Sabialvm_assign_pptdev(struct vmctx *ctx, int bus, int slot, int func) 40472339Sabial{ 40572339Sabial struct vm_pptdev pptdev; 40672339Sabial 40772339Sabial bzero(&pptdev, sizeof(pptdev)); 40872339Sabial pptdev.bus = bus; 40972339Sabial pptdev.slot = slot; 41072339Sabial pptdev.func = func; 41172339Sabial 41272339Sabial return (ioctl(ctx->fd, VM_BIND_PPTDEV, &pptdev)); 41372339Sabial} 41472339Sabial 41572339Sabialint 41672339Sabialvm_unassign_pptdev(struct vmctx *ctx, int bus, int slot, int func) 41772339Sabial{ 41872339Sabial struct vm_pptdev pptdev; 41972339Sabial 42072339Sabial bzero(&pptdev, sizeof(pptdev)); 42172339Sabial pptdev.bus = bus; 42272339Sabial pptdev.slot = slot; 42372339Sabial pptdev.func = func; 42472339Sabial 42572339Sabial return (ioctl(ctx->fd, VM_UNBIND_PPTDEV, &pptdev)); 42672339Sabial} 42772339Sabial 42872339Sabialint 42972339Sabialvm_map_pptdev_mmio(struct vmctx *ctx, int bus, int slot, int func, 43072339Sabial vm_paddr_t gpa, size_t len, vm_paddr_t hpa) 43172339Sabial{ 43272339Sabial struct vm_pptdev_mmio pptmmio; 43372339Sabial 43472339Sabial bzero(&pptmmio, sizeof(pptmmio)); 43572339Sabial pptmmio.bus = bus; 43672339Sabial pptmmio.slot = slot; 43772339Sabial pptmmio.func = func; 43872339Sabial pptmmio.gpa = gpa; 43972339Sabial pptmmio.len = len; 44072339Sabial pptmmio.hpa = hpa; 44172339Sabial 44272339Sabial return (ioctl(ctx->fd, VM_MAP_PPTDEV_MMIO, &pptmmio)); 44372339Sabial} 44472339Sabial 44572339Sabialint 44672339Sabialvm_setup_msi(struct vmctx *ctx, int vcpu, int bus, int slot, int func, 44772339Sabial int destcpu, int vector, int numvec) 44872339Sabial{ 44972339Sabial struct vm_pptdev_msi pptmsi; 45072339Sabial 45172339Sabial bzero(&pptmsi, sizeof(pptmsi)); 45272339Sabial pptmsi.vcpu = vcpu; 45372339Sabial pptmsi.bus = bus; 45472339Sabial pptmsi.slot = slot; 45572339Sabial pptmsi.func = func; 45672339Sabial pptmsi.destcpu = destcpu; 45772339Sabial pptmsi.vector = vector; 45872339Sabial pptmsi.numvec = numvec; 45972339Sabial 46072339Sabial return (ioctl(ctx->fd, VM_PPTDEV_MSI, &pptmsi)); 46172339Sabial} 46272339Sabial 46372339Sabialint 46472339Sabialvm_setup_msix(struct vmctx *ctx, int vcpu, int bus, int slot, int func, 46572339Sabial int idx, uint32_t msg, uint32_t vector_control, uint64_t addr) 46672339Sabial{ 46772339Sabial struct vm_pptdev_msix pptmsix; 46872339Sabial 46972339Sabial bzero(&pptmsix, sizeof(pptmsix)); 47072339Sabial pptmsix.vcpu = vcpu; 47172339Sabial pptmsix.bus = bus; 47272339Sabial pptmsix.slot = slot; 47372339Sabial pptmsix.func = func; 47472339Sabial pptmsix.idx = idx; 47572339Sabial pptmsix.msg = msg; 47672339Sabial pptmsix.addr = addr; 47772339Sabial pptmsix.vector_control = vector_control; 47872339Sabial 47972339Sabial return ioctl(ctx->fd, VM_PPTDEV_MSIX, &pptmsix); 48072339Sabial} 48172339Sabial 48272339Sabialuint64_t * 48372339Sabialvm_get_stats(struct vmctx *ctx, int vcpu, struct timeval *ret_tv, 48472339Sabial int *ret_entries) 48572339Sabial{ 48672339Sabial int error; 48772339Sabial 48872339Sabial static struct vm_stats vmstats; 48972339Sabial 49072339Sabial vmstats.cpuid = vcpu; 49172339Sabial 49272339Sabial error = ioctl(ctx->fd, VM_STATS, &vmstats); 49372339Sabial if (error == 0) { 49472339Sabial if (ret_entries) 49572339Sabial *ret_entries = vmstats.num_entries; 49672339Sabial if (ret_tv) 49772339Sabial *ret_tv = vmstats.tv; 49872339Sabial return (vmstats.statbuf); 49972339Sabial } else 50072339Sabial return (NULL); 50172339Sabial} 50272339Sabial 50372339Sabialconst char * 50472339Sabialvm_get_stat_desc(struct vmctx *ctx, int index) 50572339Sabial{ 50672339Sabial static struct vm_stat_desc statdesc; 50772339Sabial 50872339Sabial statdesc.index = index; 50972339Sabial if (ioctl(ctx->fd, VM_STAT_DESC, &statdesc) == 0) 51072339Sabial return (statdesc.desc); 51172339Sabial else 51272339Sabial return (NULL); 51372339Sabial} 51472339Sabial 51572339Sabial/* 51672339Sabial * From Intel Vol 3a: 51772339Sabial * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT 51872339Sabial */ 51972339Sabialint 52072339Sabialvcpu_reset(struct vmctx *vmctx, int vcpu) 52172339Sabial{ 52272339Sabial int error; 52372339Sabial uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx; 52472339Sabial uint32_t desc_access, desc_limit; 52572339Sabial uint16_t sel; 52672339Sabial 52772339Sabial zero = 0; 52872339Sabial 52972339Sabial rflags = 0x2; 53072339Sabial error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RFLAGS, rflags); 53172339Sabial if (error) 53272339Sabial goto done; 53372339Sabial 53472339Sabial rip = 0xfff0; 53572339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RIP, rip)) != 0) 53672339Sabial goto done; 53772339Sabial 53872339Sabial cr0 = CR0_NE; 53972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR0, cr0)) != 0) 54072339Sabial goto done; 54172339Sabial 54272339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR3, zero)) != 0) 54372339Sabial goto done; 54472339Sabial 54572339Sabial cr4 = 0; 54672339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CR4, cr4)) != 0) 54772339Sabial goto done; 54872339Sabial 54972339Sabial /* 55072339Sabial * CS: present, r/w, accessed, 16-bit, byte granularity, usable 55172339Sabial */ 55272339Sabial desc_base = 0xffff0000; 55372339Sabial desc_limit = 0xffff; 55472339Sabial desc_access = 0x0093; 55572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_CS, 55672339Sabial desc_base, desc_limit, desc_access); 55772339Sabial if (error) 55872339Sabial goto done; 55972339Sabial 56072339Sabial sel = 0xf000; 56172339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_CS, sel)) != 0) 56272339Sabial goto done; 56372339Sabial 56472339Sabial /* 56572339Sabial * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity 56672339Sabial */ 56772339Sabial desc_base = 0; 56872339Sabial desc_limit = 0xffff; 56972339Sabial desc_access = 0x0093; 57072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_SS, 57172339Sabial desc_base, desc_limit, desc_access); 57272339Sabial if (error) 57372339Sabial goto done; 57472339Sabial 57572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_DS, 57672339Sabial desc_base, desc_limit, desc_access); 57772339Sabial if (error) 57872339Sabial goto done; 57972339Sabial 58072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_ES, 58172339Sabial desc_base, desc_limit, desc_access); 58272339Sabial if (error) 58372339Sabial goto done; 58472339Sabial 58572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_FS, 58672339Sabial desc_base, desc_limit, desc_access); 58772339Sabial if (error) 58872339Sabial goto done; 58972339Sabial 59072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GS, 59172339Sabial desc_base, desc_limit, desc_access); 59272339Sabial if (error) 59372339Sabial goto done; 59472339Sabial 59572339Sabial sel = 0; 59672339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_SS, sel)) != 0) 59772339Sabial goto done; 59872339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_DS, sel)) != 0) 59972339Sabial goto done; 60072339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_ES, sel)) != 0) 60172339Sabial goto done; 60272339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_FS, sel)) != 0) 60372339Sabial goto done; 60472339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_GS, sel)) != 0) 60572339Sabial goto done; 60672339Sabial 60772339Sabial /* General purpose registers */ 60872339Sabial rdx = 0xf00; 60972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RAX, zero)) != 0) 61072339Sabial goto done; 61172339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBX, zero)) != 0) 61272339Sabial goto done; 61372339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RCX, zero)) != 0) 61472339Sabial goto done; 61572339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDX, rdx)) != 0) 61672339Sabial goto done; 61772339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSI, zero)) != 0) 61872339Sabial goto done; 61972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RDI, zero)) != 0) 62072339Sabial goto done; 62172339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RBP, zero)) != 0) 62272339Sabial goto done; 62372339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_RSP, zero)) != 0) 62472339Sabial goto done; 62572339Sabial 62672339Sabial /* GDTR, IDTR */ 62772339Sabial desc_base = 0; 62872339Sabial desc_limit = 0xffff; 62972339Sabial desc_access = 0; 63072339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_GDTR, 63172339Sabial desc_base, desc_limit, desc_access); 63272339Sabial if (error != 0) 63372339Sabial goto done; 63472339Sabial 63572339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_IDTR, 63672339Sabial desc_base, desc_limit, desc_access); 63772339Sabial if (error != 0) 63872339Sabial goto done; 63972339Sabial 64072339Sabial /* TR */ 64172339Sabial desc_base = 0; 64272339Sabial desc_limit = 0xffff; 64372339Sabial desc_access = 0x0000008b; 64472339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); 64572339Sabial if (error) 64672339Sabial goto done; 64772339Sabial 64872339Sabial sel = 0; 64972339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_TR, sel)) != 0) 65072339Sabial goto done; 65172339Sabial 65272339Sabial /* LDTR */ 65372339Sabial desc_base = 0; 65472339Sabial desc_limit = 0xffff; 65572339Sabial desc_access = 0x00000082; 65672339Sabial error = vm_set_desc(vmctx, vcpu, VM_REG_GUEST_LDTR, desc_base, 65772339Sabial desc_limit, desc_access); 65872339Sabial if (error) 65972339Sabial goto done; 66072339Sabial 66172339Sabial sel = 0; 66272339Sabial if ((error = vm_set_register(vmctx, vcpu, VM_REG_GUEST_LDTR, 0)) != 0) 66372339Sabial goto done; 66472339Sabial 66572339Sabial /* XXX cr2, debug registers */ 66672339Sabial 66772339Sabial error = 0; 66872339Sabialdone: 66972339Sabial return (error); 67072339Sabial} 67172339Sabial