1967264cfSMark Johnston /*- 2967264cfSMark Johnston * SPDX-License-Identifier: BSD-2-Clause 3967264cfSMark Johnston * 4967264cfSMark Johnston * Copyright (c) 2011 NetApp, Inc. 5967264cfSMark Johnston * All rights reserved. 6967264cfSMark Johnston * 7967264cfSMark Johnston * Redistribution and use in source and binary forms, with or without 8967264cfSMark Johnston * modification, are permitted provided that the following conditions 9967264cfSMark Johnston * are met: 10967264cfSMark Johnston * 1. Redistributions of source code must retain the above copyright 11967264cfSMark Johnston * notice, this list of conditions and the following disclaimer. 12967264cfSMark Johnston * 2. Redistributions in binary form must reproduce the above copyright 13967264cfSMark Johnston * notice, this list of conditions and the following disclaimer in the 14967264cfSMark Johnston * documentation and/or other materials provided with the distribution. 15967264cfSMark Johnston * 16967264cfSMark Johnston * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 17967264cfSMark Johnston * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18967264cfSMark Johnston * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19967264cfSMark Johnston * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 20967264cfSMark Johnston * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21967264cfSMark Johnston * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22967264cfSMark Johnston * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23967264cfSMark Johnston * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24967264cfSMark Johnston * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25967264cfSMark Johnston * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26967264cfSMark Johnston * SUCH DAMAGE. 27967264cfSMark Johnston */ 28967264cfSMark Johnston 29e4656e10SMark Johnston #include <sys/types.h> 30e4656e10SMark Johnston #include <sys/ioctl.h> 31e4656e10SMark Johnston 32967264cfSMark Johnston #include <machine/specialreg.h> 33e4656e10SMark Johnston #include <machine/vmm.h> 34*7f00e46bSMark Johnston #include <machine/vmm_dev.h> 35*7f00e46bSMark Johnston #include <machine/vmm_snapshot.h> 36e4656e10SMark Johnston 37e4656e10SMark Johnston #include <string.h> 38967264cfSMark Johnston 39967264cfSMark Johnston #include "vmmapi.h" 40967264cfSMark Johnston #include "internal.h" 41967264cfSMark Johnston 4285efb31dSMark Johnston const char *vm_capstrmap[] = { 4385efb31dSMark Johnston [VM_CAP_HALT_EXIT] = "hlt_exit", 4485efb31dSMark Johnston [VM_CAP_MTRAP_EXIT] = "mtrap_exit", 4585efb31dSMark Johnston [VM_CAP_PAUSE_EXIT] = "pause_exit", 4685efb31dSMark Johnston [VM_CAP_UNRESTRICTED_GUEST] = "unrestricted_guest", 4785efb31dSMark Johnston [VM_CAP_ENABLE_INVPCID] = "enable_invpcid", 4885efb31dSMark Johnston [VM_CAP_BPT_EXIT] = "bpt_exit", 4985efb31dSMark Johnston [VM_CAP_RDPID] = "rdpid", 5085efb31dSMark Johnston [VM_CAP_RDTSCP] = "rdtscp", 5185efb31dSMark Johnston [VM_CAP_IPI_EXIT] = "ipi_exit", 5285efb31dSMark Johnston [VM_CAP_MASK_HWINTR] = "mask_hwintr", 5385efb31dSMark Johnston [VM_CAP_RFLAGS_TF] = "rflags_tf", 5485efb31dSMark Johnston [VM_CAP_MAX] = NULL, 5585efb31dSMark Johnston }; 5685efb31dSMark Johnston 57*7f00e46bSMark Johnston #define VM_MD_IOCTLS \ 58*7f00e46bSMark Johnston VM_SET_SEGMENT_DESCRIPTOR, \ 59*7f00e46bSMark Johnston VM_GET_SEGMENT_DESCRIPTOR, \ 60*7f00e46bSMark Johnston VM_SET_KERNEMU_DEV, \ 61*7f00e46bSMark Johnston VM_GET_KERNEMU_DEV, \ 62*7f00e46bSMark Johnston VM_LAPIC_IRQ, \ 63*7f00e46bSMark Johnston VM_LAPIC_LOCAL_IRQ, \ 64*7f00e46bSMark Johnston VM_LAPIC_MSI, \ 65*7f00e46bSMark Johnston VM_IOAPIC_ASSERT_IRQ, \ 66*7f00e46bSMark Johnston VM_IOAPIC_DEASSERT_IRQ, \ 67*7f00e46bSMark Johnston VM_IOAPIC_PULSE_IRQ, \ 68*7f00e46bSMark Johnston VM_IOAPIC_PINCOUNT, \ 69*7f00e46bSMark Johnston VM_ISA_ASSERT_IRQ, \ 70*7f00e46bSMark Johnston VM_ISA_DEASSERT_IRQ, \ 71*7f00e46bSMark Johnston VM_ISA_PULSE_IRQ, \ 72*7f00e46bSMark Johnston VM_ISA_SET_IRQ_TRIGGER, \ 73*7f00e46bSMark Johnston VM_INJECT_NMI, \ 74*7f00e46bSMark Johnston VM_SET_X2APIC_STATE, \ 75*7f00e46bSMark Johnston VM_GET_X2APIC_STATE, \ 76*7f00e46bSMark Johnston VM_GET_HPET_CAPABILITIES, \ 77*7f00e46bSMark Johnston VM_RTC_WRITE, \ 78*7f00e46bSMark Johnston VM_RTC_READ, \ 79*7f00e46bSMark Johnston VM_RTC_SETTIME, \ 80*7f00e46bSMark Johnston VM_RTC_GETTIME 81*7f00e46bSMark Johnston 82*7f00e46bSMark Johnston const cap_ioctl_t vm_ioctl_cmds[] = { 83*7f00e46bSMark Johnston VM_COMMON_IOCTLS, 84*7f00e46bSMark Johnston VM_PPT_IOCTLS, 85*7f00e46bSMark Johnston VM_MD_IOCTLS, 86*7f00e46bSMark Johnston }; 87*7f00e46bSMark Johnston size_t vm_ioctl_ncmds = nitems(vm_ioctl_cmds); 88*7f00e46bSMark Johnston 89e4656e10SMark Johnston int 90e4656e10SMark Johnston vm_set_desc(struct vcpu *vcpu, int reg, 91e4656e10SMark Johnston uint64_t base, uint32_t limit, uint32_t access) 92e4656e10SMark Johnston { 93e4656e10SMark Johnston int error; 94e4656e10SMark Johnston struct vm_seg_desc vmsegdesc; 95e4656e10SMark Johnston 96e4656e10SMark Johnston bzero(&vmsegdesc, sizeof(vmsegdesc)); 97e4656e10SMark Johnston vmsegdesc.regnum = reg; 98e4656e10SMark Johnston vmsegdesc.desc.base = base; 99e4656e10SMark Johnston vmsegdesc.desc.limit = limit; 100e4656e10SMark Johnston vmsegdesc.desc.access = access; 101e4656e10SMark Johnston 102e4656e10SMark Johnston error = vcpu_ioctl(vcpu, VM_SET_SEGMENT_DESCRIPTOR, &vmsegdesc); 103e4656e10SMark Johnston return (error); 104e4656e10SMark Johnston } 105e4656e10SMark Johnston 106e4656e10SMark Johnston int 107e4656e10SMark Johnston vm_get_desc(struct vcpu *vcpu, int reg, uint64_t *base, uint32_t *limit, 108e4656e10SMark Johnston uint32_t *access) 109e4656e10SMark Johnston { 110e4656e10SMark Johnston int error; 111e4656e10SMark Johnston struct vm_seg_desc vmsegdesc; 112e4656e10SMark Johnston 113e4656e10SMark Johnston bzero(&vmsegdesc, sizeof(vmsegdesc)); 114e4656e10SMark Johnston vmsegdesc.regnum = reg; 115e4656e10SMark Johnston 116e4656e10SMark Johnston error = vcpu_ioctl(vcpu, VM_GET_SEGMENT_DESCRIPTOR, &vmsegdesc); 117e4656e10SMark Johnston if (error == 0) { 118e4656e10SMark Johnston *base = vmsegdesc.desc.base; 119e4656e10SMark Johnston *limit = vmsegdesc.desc.limit; 120e4656e10SMark Johnston *access = vmsegdesc.desc.access; 121e4656e10SMark Johnston } 122e4656e10SMark Johnston return (error); 123e4656e10SMark Johnston } 124e4656e10SMark Johnston 125e4656e10SMark Johnston int 126e4656e10SMark Johnston vm_get_seg_desc(struct vcpu *vcpu, int reg, struct seg_desc *seg_desc) 127e4656e10SMark Johnston { 128e4656e10SMark Johnston int error; 129e4656e10SMark Johnston 130e4656e10SMark Johnston error = vm_get_desc(vcpu, reg, &seg_desc->base, &seg_desc->limit, 131e4656e10SMark Johnston &seg_desc->access); 132e4656e10SMark Johnston return (error); 133e4656e10SMark Johnston } 134e4656e10SMark Johnston 135e4656e10SMark Johnston int 136e4656e10SMark Johnston vm_lapic_irq(struct vcpu *vcpu, int vector) 137e4656e10SMark Johnston { 138e4656e10SMark Johnston struct vm_lapic_irq vmirq; 139e4656e10SMark Johnston 140e4656e10SMark Johnston bzero(&vmirq, sizeof(vmirq)); 141e4656e10SMark Johnston vmirq.vector = vector; 142e4656e10SMark Johnston 143e4656e10SMark Johnston return (vcpu_ioctl(vcpu, VM_LAPIC_IRQ, &vmirq)); 144e4656e10SMark Johnston } 145e4656e10SMark Johnston 146e4656e10SMark Johnston int 147e4656e10SMark Johnston vm_lapic_local_irq(struct vcpu *vcpu, int vector) 148e4656e10SMark Johnston { 149e4656e10SMark Johnston struct vm_lapic_irq vmirq; 150e4656e10SMark Johnston 151e4656e10SMark Johnston bzero(&vmirq, sizeof(vmirq)); 152e4656e10SMark Johnston vmirq.vector = vector; 153e4656e10SMark Johnston 154e4656e10SMark Johnston return (vcpu_ioctl(vcpu, VM_LAPIC_LOCAL_IRQ, &vmirq)); 155e4656e10SMark Johnston } 156e4656e10SMark Johnston 157e4656e10SMark Johnston int 158e4656e10SMark Johnston vm_lapic_msi(struct vmctx *ctx, uint64_t addr, uint64_t msg) 159e4656e10SMark Johnston { 160e4656e10SMark Johnston struct vm_lapic_msi vmmsi; 161e4656e10SMark Johnston 162e4656e10SMark Johnston bzero(&vmmsi, sizeof(vmmsi)); 163e4656e10SMark Johnston vmmsi.addr = addr; 164e4656e10SMark Johnston vmmsi.msg = msg; 165e4656e10SMark Johnston 166e4656e10SMark Johnston return (ioctl(ctx->fd, VM_LAPIC_MSI, &vmmsi)); 167e4656e10SMark Johnston } 168e4656e10SMark Johnston 169e4656e10SMark Johnston int 170e4656e10SMark Johnston vm_apicid2vcpu(struct vmctx *ctx __unused, int apicid) 171e4656e10SMark Johnston { 172e4656e10SMark Johnston /* 173e4656e10SMark Johnston * The apic id associated with the 'vcpu' has the same numerical value 174e4656e10SMark Johnston * as the 'vcpu' itself. 175e4656e10SMark Johnston */ 176e4656e10SMark Johnston return (apicid); 177e4656e10SMark Johnston } 178e4656e10SMark Johnston 179e4656e10SMark Johnston int 180e4656e10SMark Johnston vm_ioapic_assert_irq(struct vmctx *ctx, int irq) 181e4656e10SMark Johnston { 182e4656e10SMark Johnston struct vm_ioapic_irq ioapic_irq; 183e4656e10SMark Johnston 184e4656e10SMark Johnston bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); 185e4656e10SMark Johnston ioapic_irq.irq = irq; 186e4656e10SMark Johnston 187e4656e10SMark Johnston return (ioctl(ctx->fd, VM_IOAPIC_ASSERT_IRQ, &ioapic_irq)); 188e4656e10SMark Johnston } 189e4656e10SMark Johnston 190e4656e10SMark Johnston int 191e4656e10SMark Johnston vm_ioapic_deassert_irq(struct vmctx *ctx, int irq) 192e4656e10SMark Johnston { 193e4656e10SMark Johnston struct vm_ioapic_irq ioapic_irq; 194e4656e10SMark Johnston 195e4656e10SMark Johnston bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); 196e4656e10SMark Johnston ioapic_irq.irq = irq; 197e4656e10SMark Johnston 198e4656e10SMark Johnston return (ioctl(ctx->fd, VM_IOAPIC_DEASSERT_IRQ, &ioapic_irq)); 199e4656e10SMark Johnston } 200e4656e10SMark Johnston 201e4656e10SMark Johnston int 202e4656e10SMark Johnston vm_ioapic_pulse_irq(struct vmctx *ctx, int irq) 203e4656e10SMark Johnston { 204e4656e10SMark Johnston struct vm_ioapic_irq ioapic_irq; 205e4656e10SMark Johnston 206e4656e10SMark Johnston bzero(&ioapic_irq, sizeof(struct vm_ioapic_irq)); 207e4656e10SMark Johnston ioapic_irq.irq = irq; 208e4656e10SMark Johnston 209e4656e10SMark Johnston return (ioctl(ctx->fd, VM_IOAPIC_PULSE_IRQ, &ioapic_irq)); 210e4656e10SMark Johnston } 211e4656e10SMark Johnston 212e4656e10SMark Johnston int 213e4656e10SMark Johnston vm_ioapic_pincount(struct vmctx *ctx, int *pincount) 214e4656e10SMark Johnston { 215e4656e10SMark Johnston 216e4656e10SMark Johnston return (ioctl(ctx->fd, VM_IOAPIC_PINCOUNT, pincount)); 217e4656e10SMark Johnston } 218e4656e10SMark Johnston 219e4656e10SMark Johnston int 220e4656e10SMark Johnston vm_isa_assert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) 221e4656e10SMark Johnston { 222e4656e10SMark Johnston struct vm_isa_irq isa_irq; 223e4656e10SMark Johnston 224e4656e10SMark Johnston bzero(&isa_irq, sizeof(struct vm_isa_irq)); 225e4656e10SMark Johnston isa_irq.atpic_irq = atpic_irq; 226e4656e10SMark Johnston isa_irq.ioapic_irq = ioapic_irq; 227e4656e10SMark Johnston 228e4656e10SMark Johnston return (ioctl(ctx->fd, VM_ISA_ASSERT_IRQ, &isa_irq)); 229e4656e10SMark Johnston } 230e4656e10SMark Johnston 231e4656e10SMark Johnston int 232e4656e10SMark Johnston vm_isa_deassert_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) 233e4656e10SMark Johnston { 234e4656e10SMark Johnston struct vm_isa_irq isa_irq; 235e4656e10SMark Johnston 236e4656e10SMark Johnston bzero(&isa_irq, sizeof(struct vm_isa_irq)); 237e4656e10SMark Johnston isa_irq.atpic_irq = atpic_irq; 238e4656e10SMark Johnston isa_irq.ioapic_irq = ioapic_irq; 239e4656e10SMark Johnston 240e4656e10SMark Johnston return (ioctl(ctx->fd, VM_ISA_DEASSERT_IRQ, &isa_irq)); 241e4656e10SMark Johnston } 242e4656e10SMark Johnston 243e4656e10SMark Johnston int 244e4656e10SMark Johnston vm_isa_pulse_irq(struct vmctx *ctx, int atpic_irq, int ioapic_irq) 245e4656e10SMark Johnston { 246e4656e10SMark Johnston struct vm_isa_irq isa_irq; 247e4656e10SMark Johnston 248e4656e10SMark Johnston bzero(&isa_irq, sizeof(struct vm_isa_irq)); 249e4656e10SMark Johnston isa_irq.atpic_irq = atpic_irq; 250e4656e10SMark Johnston isa_irq.ioapic_irq = ioapic_irq; 251e4656e10SMark Johnston 252e4656e10SMark Johnston return (ioctl(ctx->fd, VM_ISA_PULSE_IRQ, &isa_irq)); 253e4656e10SMark Johnston } 254e4656e10SMark Johnston 255e4656e10SMark Johnston int 256e4656e10SMark Johnston vm_isa_set_irq_trigger(struct vmctx *ctx, int atpic_irq, 257e4656e10SMark Johnston enum vm_intr_trigger trigger) 258e4656e10SMark Johnston { 259e4656e10SMark Johnston struct vm_isa_irq_trigger isa_irq_trigger; 260e4656e10SMark Johnston 261e4656e10SMark Johnston bzero(&isa_irq_trigger, sizeof(struct vm_isa_irq_trigger)); 262e4656e10SMark Johnston isa_irq_trigger.atpic_irq = atpic_irq; 263e4656e10SMark Johnston isa_irq_trigger.trigger = trigger; 264e4656e10SMark Johnston 265e4656e10SMark Johnston return (ioctl(ctx->fd, VM_ISA_SET_IRQ_TRIGGER, &isa_irq_trigger)); 266e4656e10SMark Johnston } 267e4656e10SMark Johnston 268e4656e10SMark Johnston int 269e4656e10SMark Johnston vm_inject_nmi(struct vcpu *vcpu) 270e4656e10SMark Johnston { 271e4656e10SMark Johnston struct vm_nmi vmnmi; 272e4656e10SMark Johnston 273e4656e10SMark Johnston bzero(&vmnmi, sizeof(vmnmi)); 274e4656e10SMark Johnston 275e4656e10SMark Johnston return (vcpu_ioctl(vcpu, VM_INJECT_NMI, &vmnmi)); 276e4656e10SMark Johnston } 277e4656e10SMark Johnston 278967264cfSMark Johnston /* 279967264cfSMark Johnston * From Intel Vol 3a: 280967264cfSMark Johnston * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT 281967264cfSMark Johnston */ 282967264cfSMark Johnston int 283967264cfSMark Johnston vcpu_reset(struct vcpu *vcpu) 284967264cfSMark Johnston { 285967264cfSMark Johnston int error; 286967264cfSMark Johnston uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx; 287967264cfSMark Johnston uint32_t desc_access, desc_limit; 288967264cfSMark Johnston uint16_t sel; 289967264cfSMark Johnston 290967264cfSMark Johnston zero = 0; 291967264cfSMark Johnston 292967264cfSMark Johnston rflags = 0x2; 293967264cfSMark Johnston error = vm_set_register(vcpu, VM_REG_GUEST_RFLAGS, rflags); 294967264cfSMark Johnston if (error) 295967264cfSMark Johnston goto done; 296967264cfSMark Johnston 297967264cfSMark Johnston rip = 0xfff0; 298967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RIP, rip)) != 0) 299967264cfSMark Johnston goto done; 300967264cfSMark Johnston 301967264cfSMark Johnston /* 302967264cfSMark Johnston * According to Intels Software Developer Manual CR0 should be 303967264cfSMark Johnston * initialized with CR0_ET | CR0_NW | CR0_CD but that crashes some 304967264cfSMark Johnston * guests like Windows. 305967264cfSMark Johnston */ 306967264cfSMark Johnston cr0 = CR0_NE; 307967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR0, cr0)) != 0) 308967264cfSMark Johnston goto done; 309967264cfSMark Johnston 310967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR2, zero)) != 0) 311967264cfSMark Johnston goto done; 312967264cfSMark Johnston 313967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR3, zero)) != 0) 314967264cfSMark Johnston goto done; 315967264cfSMark Johnston 316967264cfSMark Johnston cr4 = 0; 317967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR4, cr4)) != 0) 318967264cfSMark Johnston goto done; 319967264cfSMark Johnston 320967264cfSMark Johnston /* 321967264cfSMark Johnston * CS: present, r/w, accessed, 16-bit, byte granularity, usable 322967264cfSMark Johnston */ 323967264cfSMark Johnston desc_base = 0xffff0000; 324967264cfSMark Johnston desc_limit = 0xffff; 325967264cfSMark Johnston desc_access = 0x0093; 326967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_CS, 327967264cfSMark Johnston desc_base, desc_limit, desc_access); 328967264cfSMark Johnston if (error) 329967264cfSMark Johnston goto done; 330967264cfSMark Johnston 331967264cfSMark Johnston sel = 0xf000; 332967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CS, sel)) != 0) 333967264cfSMark Johnston goto done; 334967264cfSMark Johnston 335967264cfSMark Johnston /* 336967264cfSMark Johnston * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity 337967264cfSMark Johnston */ 338967264cfSMark Johnston desc_base = 0; 339967264cfSMark Johnston desc_limit = 0xffff; 340967264cfSMark Johnston desc_access = 0x0093; 341967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_SS, 342967264cfSMark Johnston desc_base, desc_limit, desc_access); 343967264cfSMark Johnston if (error) 344967264cfSMark Johnston goto done; 345967264cfSMark Johnston 346967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_DS, 347967264cfSMark Johnston desc_base, desc_limit, desc_access); 348967264cfSMark Johnston if (error) 349967264cfSMark Johnston goto done; 350967264cfSMark Johnston 351967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_ES, 352967264cfSMark Johnston desc_base, desc_limit, desc_access); 353967264cfSMark Johnston if (error) 354967264cfSMark Johnston goto done; 355967264cfSMark Johnston 356967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_FS, 357967264cfSMark Johnston desc_base, desc_limit, desc_access); 358967264cfSMark Johnston if (error) 359967264cfSMark Johnston goto done; 360967264cfSMark Johnston 361967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_GS, 362967264cfSMark Johnston desc_base, desc_limit, desc_access); 363967264cfSMark Johnston if (error) 364967264cfSMark Johnston goto done; 365967264cfSMark Johnston 366967264cfSMark Johnston sel = 0; 367967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_SS, sel)) != 0) 368967264cfSMark Johnston goto done; 369967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_DS, sel)) != 0) 370967264cfSMark Johnston goto done; 371967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_ES, sel)) != 0) 372967264cfSMark Johnston goto done; 373967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_FS, sel)) != 0) 374967264cfSMark Johnston goto done; 375967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_GS, sel)) != 0) 376967264cfSMark Johnston goto done; 377967264cfSMark Johnston 378967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_EFER, zero)) != 0) 379967264cfSMark Johnston goto done; 380967264cfSMark Johnston 381967264cfSMark Johnston /* General purpose registers */ 382967264cfSMark Johnston rdx = 0xf00; 383967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RAX, zero)) != 0) 384967264cfSMark Johnston goto done; 385967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBX, zero)) != 0) 386967264cfSMark Johnston goto done; 387967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RCX, zero)) != 0) 388967264cfSMark Johnston goto done; 389967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDX, rdx)) != 0) 390967264cfSMark Johnston goto done; 391967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSI, zero)) != 0) 392967264cfSMark Johnston goto done; 393967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDI, zero)) != 0) 394967264cfSMark Johnston goto done; 395967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBP, zero)) != 0) 396967264cfSMark Johnston goto done; 397967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSP, zero)) != 0) 398967264cfSMark Johnston goto done; 399967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R8, zero)) != 0) 400967264cfSMark Johnston goto done; 401967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R9, zero)) != 0) 402967264cfSMark Johnston goto done; 403967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R10, zero)) != 0) 404967264cfSMark Johnston goto done; 405967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R11, zero)) != 0) 406967264cfSMark Johnston goto done; 407967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R12, zero)) != 0) 408967264cfSMark Johnston goto done; 409967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R13, zero)) != 0) 410967264cfSMark Johnston goto done; 411967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R14, zero)) != 0) 412967264cfSMark Johnston goto done; 413967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R15, zero)) != 0) 414967264cfSMark Johnston goto done; 415967264cfSMark Johnston 416967264cfSMark Johnston /* GDTR, IDTR */ 417967264cfSMark Johnston desc_base = 0; 418967264cfSMark Johnston desc_limit = 0xffff; 419967264cfSMark Johnston desc_access = 0; 420967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_GDTR, 421967264cfSMark Johnston desc_base, desc_limit, desc_access); 422967264cfSMark Johnston if (error != 0) 423967264cfSMark Johnston goto done; 424967264cfSMark Johnston 425967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_IDTR, 426967264cfSMark Johnston desc_base, desc_limit, desc_access); 427967264cfSMark Johnston if (error != 0) 428967264cfSMark Johnston goto done; 429967264cfSMark Johnston 430967264cfSMark Johnston /* TR */ 431967264cfSMark Johnston desc_base = 0; 432967264cfSMark Johnston desc_limit = 0xffff; 433967264cfSMark Johnston desc_access = 0x0000008b; 434967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); 435967264cfSMark Johnston if (error) 436967264cfSMark Johnston goto done; 437967264cfSMark Johnston 438967264cfSMark Johnston sel = 0; 439967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_TR, sel)) != 0) 440967264cfSMark Johnston goto done; 441967264cfSMark Johnston 442967264cfSMark Johnston /* LDTR */ 443967264cfSMark Johnston desc_base = 0; 444967264cfSMark Johnston desc_limit = 0xffff; 445967264cfSMark Johnston desc_access = 0x00000082; 446967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_LDTR, desc_base, 447967264cfSMark Johnston desc_limit, desc_access); 448967264cfSMark Johnston if (error) 449967264cfSMark Johnston goto done; 450967264cfSMark Johnston 451967264cfSMark Johnston sel = 0; 452967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_LDTR, 0)) != 0) 453967264cfSMark Johnston goto done; 454967264cfSMark Johnston 455967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR6, 456967264cfSMark Johnston 0xffff0ff0)) != 0) 457967264cfSMark Johnston goto done; 458967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR7, 0x400)) != 459967264cfSMark Johnston 0) 460967264cfSMark Johnston goto done; 461967264cfSMark Johnston 462967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_INTR_SHADOW, 463967264cfSMark Johnston zero)) != 0) 464967264cfSMark Johnston goto done; 465967264cfSMark Johnston 466967264cfSMark Johnston error = 0; 467967264cfSMark Johnston done: 468967264cfSMark Johnston return (error); 469967264cfSMark Johnston } 470