1*967264cfSMark Johnston /*- 2*967264cfSMark Johnston * SPDX-License-Identifier: BSD-2-Clause 3*967264cfSMark Johnston * 4*967264cfSMark Johnston * Copyright (c) 2011 NetApp, Inc. 5*967264cfSMark Johnston * All rights reserved. 6*967264cfSMark Johnston * 7*967264cfSMark Johnston * Redistribution and use in source and binary forms, with or without 8*967264cfSMark Johnston * modification, are permitted provided that the following conditions 9*967264cfSMark Johnston * are met: 10*967264cfSMark Johnston * 1. Redistributions of source code must retain the above copyright 11*967264cfSMark Johnston * notice, this list of conditions and the following disclaimer. 12*967264cfSMark Johnston * 2. Redistributions in binary form must reproduce the above copyright 13*967264cfSMark Johnston * notice, this list of conditions and the following disclaimer in the 14*967264cfSMark Johnston * documentation and/or other materials provided with the distribution. 15*967264cfSMark Johnston * 16*967264cfSMark Johnston * THIS SOFTWARE IS PROVIDED BY NETAPP, INC ``AS IS'' AND 17*967264cfSMark Johnston * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*967264cfSMark Johnston * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*967264cfSMark Johnston * ARE DISCLAIMED. IN NO EVENT SHALL NETAPP, INC OR CONTRIBUTORS BE LIABLE 20*967264cfSMark Johnston * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*967264cfSMark Johnston * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*967264cfSMark Johnston * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*967264cfSMark Johnston * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*967264cfSMark Johnston * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*967264cfSMark Johnston * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*967264cfSMark Johnston * SUCH DAMAGE. 27*967264cfSMark Johnston */ 28*967264cfSMark Johnston 29*967264cfSMark Johnston #include <machine/specialreg.h> 30*967264cfSMark Johnston 31*967264cfSMark Johnston #include "vmmapi.h" 32*967264cfSMark Johnston #include "internal.h" 33*967264cfSMark Johnston 34*967264cfSMark Johnston /* 35*967264cfSMark Johnston * From Intel Vol 3a: 36*967264cfSMark Johnston * Table 9-1. IA-32 Processor States Following Power-up, Reset or INIT 37*967264cfSMark Johnston */ 38*967264cfSMark Johnston int 39*967264cfSMark Johnston vcpu_reset(struct vcpu *vcpu) 40*967264cfSMark Johnston { 41*967264cfSMark Johnston int error; 42*967264cfSMark Johnston uint64_t rflags, rip, cr0, cr4, zero, desc_base, rdx; 43*967264cfSMark Johnston uint32_t desc_access, desc_limit; 44*967264cfSMark Johnston uint16_t sel; 45*967264cfSMark Johnston 46*967264cfSMark Johnston zero = 0; 47*967264cfSMark Johnston 48*967264cfSMark Johnston rflags = 0x2; 49*967264cfSMark Johnston error = vm_set_register(vcpu, VM_REG_GUEST_RFLAGS, rflags); 50*967264cfSMark Johnston if (error) 51*967264cfSMark Johnston goto done; 52*967264cfSMark Johnston 53*967264cfSMark Johnston rip = 0xfff0; 54*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RIP, rip)) != 0) 55*967264cfSMark Johnston goto done; 56*967264cfSMark Johnston 57*967264cfSMark Johnston /* 58*967264cfSMark Johnston * According to Intels Software Developer Manual CR0 should be 59*967264cfSMark Johnston * initialized with CR0_ET | CR0_NW | CR0_CD but that crashes some 60*967264cfSMark Johnston * guests like Windows. 61*967264cfSMark Johnston */ 62*967264cfSMark Johnston cr0 = CR0_NE; 63*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR0, cr0)) != 0) 64*967264cfSMark Johnston goto done; 65*967264cfSMark Johnston 66*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR2, zero)) != 0) 67*967264cfSMark Johnston goto done; 68*967264cfSMark Johnston 69*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR3, zero)) != 0) 70*967264cfSMark Johnston goto done; 71*967264cfSMark Johnston 72*967264cfSMark Johnston cr4 = 0; 73*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CR4, cr4)) != 0) 74*967264cfSMark Johnston goto done; 75*967264cfSMark Johnston 76*967264cfSMark Johnston /* 77*967264cfSMark Johnston * CS: present, r/w, accessed, 16-bit, byte granularity, usable 78*967264cfSMark Johnston */ 79*967264cfSMark Johnston desc_base = 0xffff0000; 80*967264cfSMark Johnston desc_limit = 0xffff; 81*967264cfSMark Johnston desc_access = 0x0093; 82*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_CS, 83*967264cfSMark Johnston desc_base, desc_limit, desc_access); 84*967264cfSMark Johnston if (error) 85*967264cfSMark Johnston goto done; 86*967264cfSMark Johnston 87*967264cfSMark Johnston sel = 0xf000; 88*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_CS, sel)) != 0) 89*967264cfSMark Johnston goto done; 90*967264cfSMark Johnston 91*967264cfSMark Johnston /* 92*967264cfSMark Johnston * SS,DS,ES,FS,GS: present, r/w, accessed, 16-bit, byte granularity 93*967264cfSMark Johnston */ 94*967264cfSMark Johnston desc_base = 0; 95*967264cfSMark Johnston desc_limit = 0xffff; 96*967264cfSMark Johnston desc_access = 0x0093; 97*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_SS, 98*967264cfSMark Johnston desc_base, desc_limit, desc_access); 99*967264cfSMark Johnston if (error) 100*967264cfSMark Johnston goto done; 101*967264cfSMark Johnston 102*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_DS, 103*967264cfSMark Johnston desc_base, desc_limit, desc_access); 104*967264cfSMark Johnston if (error) 105*967264cfSMark Johnston goto done; 106*967264cfSMark Johnston 107*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_ES, 108*967264cfSMark Johnston desc_base, desc_limit, desc_access); 109*967264cfSMark Johnston if (error) 110*967264cfSMark Johnston goto done; 111*967264cfSMark Johnston 112*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_FS, 113*967264cfSMark Johnston desc_base, desc_limit, desc_access); 114*967264cfSMark Johnston if (error) 115*967264cfSMark Johnston goto done; 116*967264cfSMark Johnston 117*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_GS, 118*967264cfSMark Johnston desc_base, desc_limit, desc_access); 119*967264cfSMark Johnston if (error) 120*967264cfSMark Johnston goto done; 121*967264cfSMark Johnston 122*967264cfSMark Johnston sel = 0; 123*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_SS, sel)) != 0) 124*967264cfSMark Johnston goto done; 125*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_DS, sel)) != 0) 126*967264cfSMark Johnston goto done; 127*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_ES, sel)) != 0) 128*967264cfSMark Johnston goto done; 129*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_FS, sel)) != 0) 130*967264cfSMark Johnston goto done; 131*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_GS, sel)) != 0) 132*967264cfSMark Johnston goto done; 133*967264cfSMark Johnston 134*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_EFER, zero)) != 0) 135*967264cfSMark Johnston goto done; 136*967264cfSMark Johnston 137*967264cfSMark Johnston /* General purpose registers */ 138*967264cfSMark Johnston rdx = 0xf00; 139*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RAX, zero)) != 0) 140*967264cfSMark Johnston goto done; 141*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBX, zero)) != 0) 142*967264cfSMark Johnston goto done; 143*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RCX, zero)) != 0) 144*967264cfSMark Johnston goto done; 145*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDX, rdx)) != 0) 146*967264cfSMark Johnston goto done; 147*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSI, zero)) != 0) 148*967264cfSMark Johnston goto done; 149*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RDI, zero)) != 0) 150*967264cfSMark Johnston goto done; 151*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RBP, zero)) != 0) 152*967264cfSMark Johnston goto done; 153*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_RSP, zero)) != 0) 154*967264cfSMark Johnston goto done; 155*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R8, zero)) != 0) 156*967264cfSMark Johnston goto done; 157*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R9, zero)) != 0) 158*967264cfSMark Johnston goto done; 159*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R10, zero)) != 0) 160*967264cfSMark Johnston goto done; 161*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R11, zero)) != 0) 162*967264cfSMark Johnston goto done; 163*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R12, zero)) != 0) 164*967264cfSMark Johnston goto done; 165*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R13, zero)) != 0) 166*967264cfSMark Johnston goto done; 167*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R14, zero)) != 0) 168*967264cfSMark Johnston goto done; 169*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_R15, zero)) != 0) 170*967264cfSMark Johnston goto done; 171*967264cfSMark Johnston 172*967264cfSMark Johnston /* GDTR, IDTR */ 173*967264cfSMark Johnston desc_base = 0; 174*967264cfSMark Johnston desc_limit = 0xffff; 175*967264cfSMark Johnston desc_access = 0; 176*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_GDTR, 177*967264cfSMark Johnston desc_base, desc_limit, desc_access); 178*967264cfSMark Johnston if (error != 0) 179*967264cfSMark Johnston goto done; 180*967264cfSMark Johnston 181*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_IDTR, 182*967264cfSMark Johnston desc_base, desc_limit, desc_access); 183*967264cfSMark Johnston if (error != 0) 184*967264cfSMark Johnston goto done; 185*967264cfSMark Johnston 186*967264cfSMark Johnston /* TR */ 187*967264cfSMark Johnston desc_base = 0; 188*967264cfSMark Johnston desc_limit = 0xffff; 189*967264cfSMark Johnston desc_access = 0x0000008b; 190*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_TR, 0, 0, desc_access); 191*967264cfSMark Johnston if (error) 192*967264cfSMark Johnston goto done; 193*967264cfSMark Johnston 194*967264cfSMark Johnston sel = 0; 195*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_TR, sel)) != 0) 196*967264cfSMark Johnston goto done; 197*967264cfSMark Johnston 198*967264cfSMark Johnston /* LDTR */ 199*967264cfSMark Johnston desc_base = 0; 200*967264cfSMark Johnston desc_limit = 0xffff; 201*967264cfSMark Johnston desc_access = 0x00000082; 202*967264cfSMark Johnston error = vm_set_desc(vcpu, VM_REG_GUEST_LDTR, desc_base, 203*967264cfSMark Johnston desc_limit, desc_access); 204*967264cfSMark Johnston if (error) 205*967264cfSMark Johnston goto done; 206*967264cfSMark Johnston 207*967264cfSMark Johnston sel = 0; 208*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_LDTR, 0)) != 0) 209*967264cfSMark Johnston goto done; 210*967264cfSMark Johnston 211*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR6, 212*967264cfSMark Johnston 0xffff0ff0)) != 0) 213*967264cfSMark Johnston goto done; 214*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_DR7, 0x400)) != 215*967264cfSMark Johnston 0) 216*967264cfSMark Johnston goto done; 217*967264cfSMark Johnston 218*967264cfSMark Johnston if ((error = vm_set_register(vcpu, VM_REG_GUEST_INTR_SHADOW, 219*967264cfSMark Johnston zero)) != 0) 220*967264cfSMark Johnston goto done; 221*967264cfSMark Johnston 222*967264cfSMark Johnston error = 0; 223*967264cfSMark Johnston done: 224*967264cfSMark Johnston return (error); 225*967264cfSMark Johnston } 226