1*9d7eaa29SArthur Chunqi Li #ifndef __HYPERVISOR_H 2*9d7eaa29SArthur Chunqi Li #define __HYPERVISOR_H 3*9d7eaa29SArthur Chunqi Li 4*9d7eaa29SArthur Chunqi Li #include "libcflat.h" 5*9d7eaa29SArthur Chunqi Li 6*9d7eaa29SArthur Chunqi Li struct vmcs { 7*9d7eaa29SArthur Chunqi Li u32 revision_id; /* vmcs revision identifier */ 8*9d7eaa29SArthur Chunqi Li u32 abort; /* VMX-abort indicator */ 9*9d7eaa29SArthur Chunqi Li /* VMCS data */ 10*9d7eaa29SArthur Chunqi Li char data[0]; 11*9d7eaa29SArthur Chunqi Li }; 12*9d7eaa29SArthur Chunqi Li 13*9d7eaa29SArthur Chunqi Li struct regs { 14*9d7eaa29SArthur Chunqi Li u64 rax; 15*9d7eaa29SArthur Chunqi Li u64 rcx; 16*9d7eaa29SArthur Chunqi Li u64 rdx; 17*9d7eaa29SArthur Chunqi Li u64 rbx; 18*9d7eaa29SArthur Chunqi Li u64 cr2; 19*9d7eaa29SArthur Chunqi Li u64 rbp; 20*9d7eaa29SArthur Chunqi Li u64 rsi; 21*9d7eaa29SArthur Chunqi Li u64 rdi; 22*9d7eaa29SArthur Chunqi Li u64 r8; 23*9d7eaa29SArthur Chunqi Li u64 r9; 24*9d7eaa29SArthur Chunqi Li u64 r10; 25*9d7eaa29SArthur Chunqi Li u64 r11; 26*9d7eaa29SArthur Chunqi Li u64 r12; 27*9d7eaa29SArthur Chunqi Li u64 r13; 28*9d7eaa29SArthur Chunqi Li u64 r14; 29*9d7eaa29SArthur Chunqi Li u64 r15; 30*9d7eaa29SArthur Chunqi Li u64 rflags; 31*9d7eaa29SArthur Chunqi Li }; 32*9d7eaa29SArthur Chunqi Li 33*9d7eaa29SArthur Chunqi Li struct vmx_test { 34*9d7eaa29SArthur Chunqi Li const char *name; 35*9d7eaa29SArthur Chunqi Li void (*init)(struct vmcs *vmcs); 36*9d7eaa29SArthur Chunqi Li void (*guest_main)(); 37*9d7eaa29SArthur Chunqi Li int (*exit_handler)(); 38*9d7eaa29SArthur Chunqi Li void (*syscall_handler)(u64 syscall_no); 39*9d7eaa29SArthur Chunqi Li struct regs guest_regs; 40*9d7eaa29SArthur Chunqi Li struct vmcs *vmcs; 41*9d7eaa29SArthur Chunqi Li int exits; 42*9d7eaa29SArthur Chunqi Li }; 43*9d7eaa29SArthur Chunqi Li 44*9d7eaa29SArthur Chunqi Li static union vmx_basic { 45*9d7eaa29SArthur Chunqi Li u64 val; 46*9d7eaa29SArthur Chunqi Li struct { 47*9d7eaa29SArthur Chunqi Li u32 revision; 48*9d7eaa29SArthur Chunqi Li u32 size:13, 49*9d7eaa29SArthur Chunqi Li : 3, 50*9d7eaa29SArthur Chunqi Li width:1, 51*9d7eaa29SArthur Chunqi Li dual:1, 52*9d7eaa29SArthur Chunqi Li type:4, 53*9d7eaa29SArthur Chunqi Li insouts:1, 54*9d7eaa29SArthur Chunqi Li ctrl:1; 55*9d7eaa29SArthur Chunqi Li }; 56*9d7eaa29SArthur Chunqi Li } basic; 57*9d7eaa29SArthur Chunqi Li 58*9d7eaa29SArthur Chunqi Li static union vmx_ctrl_pin { 59*9d7eaa29SArthur Chunqi Li u64 val; 60*9d7eaa29SArthur Chunqi Li struct { 61*9d7eaa29SArthur Chunqi Li u32 set, clr; 62*9d7eaa29SArthur Chunqi Li }; 63*9d7eaa29SArthur Chunqi Li } ctrl_pin_rev; 64*9d7eaa29SArthur Chunqi Li 65*9d7eaa29SArthur Chunqi Li static union vmx_ctrl_cpu { 66*9d7eaa29SArthur Chunqi Li u64 val; 67*9d7eaa29SArthur Chunqi Li struct { 68*9d7eaa29SArthur Chunqi Li u32 set, clr; 69*9d7eaa29SArthur Chunqi Li }; 70*9d7eaa29SArthur Chunqi Li } ctrl_cpu_rev[2]; 71*9d7eaa29SArthur Chunqi Li 72*9d7eaa29SArthur Chunqi Li static union vmx_ctrl_exit { 73*9d7eaa29SArthur Chunqi Li u64 val; 74*9d7eaa29SArthur Chunqi Li struct { 75*9d7eaa29SArthur Chunqi Li u32 set, clr; 76*9d7eaa29SArthur Chunqi Li }; 77*9d7eaa29SArthur Chunqi Li } ctrl_exit_rev; 78*9d7eaa29SArthur Chunqi Li 79*9d7eaa29SArthur Chunqi Li static union vmx_ctrl_ent { 80*9d7eaa29SArthur Chunqi Li u64 val; 81*9d7eaa29SArthur Chunqi Li struct { 82*9d7eaa29SArthur Chunqi Li u32 set, clr; 83*9d7eaa29SArthur Chunqi Li }; 84*9d7eaa29SArthur Chunqi Li } ctrl_enter_rev; 85*9d7eaa29SArthur Chunqi Li 86*9d7eaa29SArthur Chunqi Li static union vmx_ept_vpid { 87*9d7eaa29SArthur Chunqi Li u64 val; 88*9d7eaa29SArthur Chunqi Li struct { 89*9d7eaa29SArthur Chunqi Li u32:16, 90*9d7eaa29SArthur Chunqi Li super:2, 91*9d7eaa29SArthur Chunqi Li : 2, 92*9d7eaa29SArthur Chunqi Li invept:1, 93*9d7eaa29SArthur Chunqi Li : 11; 94*9d7eaa29SArthur Chunqi Li u32 invvpid:1; 95*9d7eaa29SArthur Chunqi Li }; 96*9d7eaa29SArthur Chunqi Li } ept_vpid; 97*9d7eaa29SArthur Chunqi Li 98*9d7eaa29SArthur Chunqi Li struct descr { 99*9d7eaa29SArthur Chunqi Li u16 limit; 100*9d7eaa29SArthur Chunqi Li u64 addr; 101*9d7eaa29SArthur Chunqi Li }; 102*9d7eaa29SArthur Chunqi Li 103*9d7eaa29SArthur Chunqi Li enum Encoding { 104*9d7eaa29SArthur Chunqi Li /* 16-Bit Control Fields */ 105*9d7eaa29SArthur Chunqi Li VPID = 0x0000ul, 106*9d7eaa29SArthur Chunqi Li /* Posted-interrupt notification vector */ 107*9d7eaa29SArthur Chunqi Li PINV = 0x0002ul, 108*9d7eaa29SArthur Chunqi Li /* EPTP index */ 109*9d7eaa29SArthur Chunqi Li EPTP_IDX = 0x0004ul, 110*9d7eaa29SArthur Chunqi Li 111*9d7eaa29SArthur Chunqi Li /* 16-Bit Guest State Fields */ 112*9d7eaa29SArthur Chunqi Li GUEST_SEL_ES = 0x0800ul, 113*9d7eaa29SArthur Chunqi Li GUEST_SEL_CS = 0x0802ul, 114*9d7eaa29SArthur Chunqi Li GUEST_SEL_SS = 0x0804ul, 115*9d7eaa29SArthur Chunqi Li GUEST_SEL_DS = 0x0806ul, 116*9d7eaa29SArthur Chunqi Li GUEST_SEL_FS = 0x0808ul, 117*9d7eaa29SArthur Chunqi Li GUEST_SEL_GS = 0x080aul, 118*9d7eaa29SArthur Chunqi Li GUEST_SEL_LDTR = 0x080cul, 119*9d7eaa29SArthur Chunqi Li GUEST_SEL_TR = 0x080eul, 120*9d7eaa29SArthur Chunqi Li GUEST_INT_STATUS = 0x0810ul, 121*9d7eaa29SArthur Chunqi Li 122*9d7eaa29SArthur Chunqi Li /* 16-Bit Host State Fields */ 123*9d7eaa29SArthur Chunqi Li HOST_SEL_ES = 0x0c00ul, 124*9d7eaa29SArthur Chunqi Li HOST_SEL_CS = 0x0c02ul, 125*9d7eaa29SArthur Chunqi Li HOST_SEL_SS = 0x0c04ul, 126*9d7eaa29SArthur Chunqi Li HOST_SEL_DS = 0x0c06ul, 127*9d7eaa29SArthur Chunqi Li HOST_SEL_FS = 0x0c08ul, 128*9d7eaa29SArthur Chunqi Li HOST_SEL_GS = 0x0c0aul, 129*9d7eaa29SArthur Chunqi Li HOST_SEL_TR = 0x0c0cul, 130*9d7eaa29SArthur Chunqi Li 131*9d7eaa29SArthur Chunqi Li /* 64-Bit Control Fields */ 132*9d7eaa29SArthur Chunqi Li IO_BITMAP_A = 0x2000ul, 133*9d7eaa29SArthur Chunqi Li IO_BITMAP_B = 0x2002ul, 134*9d7eaa29SArthur Chunqi Li MSR_BITMAP = 0x2004ul, 135*9d7eaa29SArthur Chunqi Li EXIT_MSR_ST_ADDR = 0x2006ul, 136*9d7eaa29SArthur Chunqi Li EXIT_MSR_LD_ADDR = 0x2008ul, 137*9d7eaa29SArthur Chunqi Li ENTER_MSR_LD_ADDR = 0x200aul, 138*9d7eaa29SArthur Chunqi Li VMCS_EXEC_PTR = 0x200cul, 139*9d7eaa29SArthur Chunqi Li TSC_OFFSET = 0x2010ul, 140*9d7eaa29SArthur Chunqi Li TSC_OFFSET_HI = 0x2011ul, 141*9d7eaa29SArthur Chunqi Li APIC_VIRT_ADDR = 0x2012ul, 142*9d7eaa29SArthur Chunqi Li APIC_ACCS_ADDR = 0x2014ul, 143*9d7eaa29SArthur Chunqi Li EPTP = 0x201aul, 144*9d7eaa29SArthur Chunqi Li EPTP_HI = 0x201bul, 145*9d7eaa29SArthur Chunqi Li 146*9d7eaa29SArthur Chunqi Li /* 64-Bit Readonly Data Field */ 147*9d7eaa29SArthur Chunqi Li INFO_PHYS_ADDR = 0x2400ul, 148*9d7eaa29SArthur Chunqi Li 149*9d7eaa29SArthur Chunqi Li /* 64-Bit Guest State */ 150*9d7eaa29SArthur Chunqi Li VMCS_LINK_PTR = 0x2800ul, 151*9d7eaa29SArthur Chunqi Li VMCS_LINK_PTR_HI = 0x2801ul, 152*9d7eaa29SArthur Chunqi Li GUEST_DEBUGCTL = 0x2802ul, 153*9d7eaa29SArthur Chunqi Li GUEST_DEBUGCTL_HI = 0x2803ul, 154*9d7eaa29SArthur Chunqi Li GUEST_EFER = 0x2806ul, 155*9d7eaa29SArthur Chunqi Li GUEST_PERF_GLOBAL_CTRL = 0x2808ul, 156*9d7eaa29SArthur Chunqi Li GUEST_PDPTE = 0x280aul, 157*9d7eaa29SArthur Chunqi Li 158*9d7eaa29SArthur Chunqi Li /* 64-Bit Host State */ 159*9d7eaa29SArthur Chunqi Li HOST_EFER = 0x2c02ul, 160*9d7eaa29SArthur Chunqi Li HOST_PERF_GLOBAL_CTRL = 0x2c04ul, 161*9d7eaa29SArthur Chunqi Li 162*9d7eaa29SArthur Chunqi Li /* 32-Bit Control Fields */ 163*9d7eaa29SArthur Chunqi Li PIN_CONTROLS = 0x4000ul, 164*9d7eaa29SArthur Chunqi Li CPU_EXEC_CTRL0 = 0x4002ul, 165*9d7eaa29SArthur Chunqi Li EXC_BITMAP = 0x4004ul, 166*9d7eaa29SArthur Chunqi Li PF_ERROR_MASK = 0x4006ul, 167*9d7eaa29SArthur Chunqi Li PF_ERROR_MATCH = 0x4008ul, 168*9d7eaa29SArthur Chunqi Li CR3_TARGET_COUNT = 0x400aul, 169*9d7eaa29SArthur Chunqi Li EXI_CONTROLS = 0x400cul, 170*9d7eaa29SArthur Chunqi Li EXI_MSR_ST_CNT = 0x400eul, 171*9d7eaa29SArthur Chunqi Li EXI_MSR_LD_CNT = 0x4010ul, 172*9d7eaa29SArthur Chunqi Li ENT_CONTROLS = 0x4012ul, 173*9d7eaa29SArthur Chunqi Li ENT_MSR_LD_CNT = 0x4014ul, 174*9d7eaa29SArthur Chunqi Li ENT_INTR_INFO = 0x4016ul, 175*9d7eaa29SArthur Chunqi Li ENT_INTR_ERROR = 0x4018ul, 176*9d7eaa29SArthur Chunqi Li ENT_INST_LEN = 0x401aul, 177*9d7eaa29SArthur Chunqi Li TPR_THRESHOLD = 0x401cul, 178*9d7eaa29SArthur Chunqi Li CPU_EXEC_CTRL1 = 0x401eul, 179*9d7eaa29SArthur Chunqi Li 180*9d7eaa29SArthur Chunqi Li /* 32-Bit R/O Data Fields */ 181*9d7eaa29SArthur Chunqi Li VMX_INST_ERROR = 0x4400ul, 182*9d7eaa29SArthur Chunqi Li EXI_REASON = 0x4402ul, 183*9d7eaa29SArthur Chunqi Li EXI_INTR_INFO = 0x4404ul, 184*9d7eaa29SArthur Chunqi Li EXI_INTR_ERROR = 0x4406ul, 185*9d7eaa29SArthur Chunqi Li IDT_VECT_INFO = 0x4408ul, 186*9d7eaa29SArthur Chunqi Li IDT_VECT_ERROR = 0x440aul, 187*9d7eaa29SArthur Chunqi Li EXI_INST_LEN = 0x440cul, 188*9d7eaa29SArthur Chunqi Li EXI_INST_INFO = 0x440eul, 189*9d7eaa29SArthur Chunqi Li 190*9d7eaa29SArthur Chunqi Li /* 32-Bit Guest State Fields */ 191*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_ES = 0x4800ul, 192*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_CS = 0x4802ul, 193*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_SS = 0x4804ul, 194*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_DS = 0x4806ul, 195*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_FS = 0x4808ul, 196*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_GS = 0x480aul, 197*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_LDTR = 0x480cul, 198*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_TR = 0x480eul, 199*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_GDTR = 0x4810ul, 200*9d7eaa29SArthur Chunqi Li GUEST_LIMIT_IDTR = 0x4812ul, 201*9d7eaa29SArthur Chunqi Li GUEST_AR_ES = 0x4814ul, 202*9d7eaa29SArthur Chunqi Li GUEST_AR_CS = 0x4816ul, 203*9d7eaa29SArthur Chunqi Li GUEST_AR_SS = 0x4818ul, 204*9d7eaa29SArthur Chunqi Li GUEST_AR_DS = 0x481aul, 205*9d7eaa29SArthur Chunqi Li GUEST_AR_FS = 0x481cul, 206*9d7eaa29SArthur Chunqi Li GUEST_AR_GS = 0x481eul, 207*9d7eaa29SArthur Chunqi Li GUEST_AR_LDTR = 0x4820ul, 208*9d7eaa29SArthur Chunqi Li GUEST_AR_TR = 0x4822ul, 209*9d7eaa29SArthur Chunqi Li GUEST_INTR_STATE = 0x4824ul, 210*9d7eaa29SArthur Chunqi Li GUEST_ACTV_STATE = 0x4826ul, 211*9d7eaa29SArthur Chunqi Li GUEST_SMBASE = 0x4828ul, 212*9d7eaa29SArthur Chunqi Li GUEST_SYSENTER_CS = 0x482aul, 213*9d7eaa29SArthur Chunqi Li 214*9d7eaa29SArthur Chunqi Li /* 32-Bit Host State Fields */ 215*9d7eaa29SArthur Chunqi Li HOST_SYSENTER_CS = 0x4c00ul, 216*9d7eaa29SArthur Chunqi Li 217*9d7eaa29SArthur Chunqi Li /* Natural-Width Control Fields */ 218*9d7eaa29SArthur Chunqi Li CR0_MASK = 0x6000ul, 219*9d7eaa29SArthur Chunqi Li CR4_MASK = 0x6002ul, 220*9d7eaa29SArthur Chunqi Li CR0_READ_SHADOW = 0x6004ul, 221*9d7eaa29SArthur Chunqi Li CR4_READ_SHADOW = 0x6006ul, 222*9d7eaa29SArthur Chunqi Li CR3_TARGET_0 = 0x6008ul, 223*9d7eaa29SArthur Chunqi Li CR3_TARGET_1 = 0x600aul, 224*9d7eaa29SArthur Chunqi Li CR3_TARGET_2 = 0x600cul, 225*9d7eaa29SArthur Chunqi Li CR3_TARGET_3 = 0x600eul, 226*9d7eaa29SArthur Chunqi Li 227*9d7eaa29SArthur Chunqi Li /* Natural-Width R/O Data Fields */ 228*9d7eaa29SArthur Chunqi Li EXI_QUALIFICATION = 0x6400ul, 229*9d7eaa29SArthur Chunqi Li IO_RCX = 0x6402ul, 230*9d7eaa29SArthur Chunqi Li IO_RSI = 0x6404ul, 231*9d7eaa29SArthur Chunqi Li IO_RDI = 0x6406ul, 232*9d7eaa29SArthur Chunqi Li IO_RIP = 0x6408ul, 233*9d7eaa29SArthur Chunqi Li GUEST_LINEAR_ADDRESS = 0x640aul, 234*9d7eaa29SArthur Chunqi Li 235*9d7eaa29SArthur Chunqi Li /* Natural-Width Guest State Fields */ 236*9d7eaa29SArthur Chunqi Li GUEST_CR0 = 0x6800ul, 237*9d7eaa29SArthur Chunqi Li GUEST_CR3 = 0x6802ul, 238*9d7eaa29SArthur Chunqi Li GUEST_CR4 = 0x6804ul, 239*9d7eaa29SArthur Chunqi Li GUEST_BASE_ES = 0x6806ul, 240*9d7eaa29SArthur Chunqi Li GUEST_BASE_CS = 0x6808ul, 241*9d7eaa29SArthur Chunqi Li GUEST_BASE_SS = 0x680aul, 242*9d7eaa29SArthur Chunqi Li GUEST_BASE_DS = 0x680cul, 243*9d7eaa29SArthur Chunqi Li GUEST_BASE_FS = 0x680eul, 244*9d7eaa29SArthur Chunqi Li GUEST_BASE_GS = 0x6810ul, 245*9d7eaa29SArthur Chunqi Li GUEST_BASE_LDTR = 0x6812ul, 246*9d7eaa29SArthur Chunqi Li GUEST_BASE_TR = 0x6814ul, 247*9d7eaa29SArthur Chunqi Li GUEST_BASE_GDTR = 0x6816ul, 248*9d7eaa29SArthur Chunqi Li GUEST_BASE_IDTR = 0x6818ul, 249*9d7eaa29SArthur Chunqi Li GUEST_DR7 = 0x681aul, 250*9d7eaa29SArthur Chunqi Li GUEST_RSP = 0x681cul, 251*9d7eaa29SArthur Chunqi Li GUEST_RIP = 0x681eul, 252*9d7eaa29SArthur Chunqi Li GUEST_RFLAGS = 0x6820ul, 253*9d7eaa29SArthur Chunqi Li GUEST_PENDING_DEBUG = 0x6822ul, 254*9d7eaa29SArthur Chunqi Li GUEST_SYSENTER_ESP = 0x6824ul, 255*9d7eaa29SArthur Chunqi Li GUEST_SYSENTER_EIP = 0x6826ul, 256*9d7eaa29SArthur Chunqi Li 257*9d7eaa29SArthur Chunqi Li /* Natural-Width Host State Fields */ 258*9d7eaa29SArthur Chunqi Li HOST_CR0 = 0x6c00ul, 259*9d7eaa29SArthur Chunqi Li HOST_CR3 = 0x6c02ul, 260*9d7eaa29SArthur Chunqi Li HOST_CR4 = 0x6c04ul, 261*9d7eaa29SArthur Chunqi Li HOST_BASE_FS = 0x6c06ul, 262*9d7eaa29SArthur Chunqi Li HOST_BASE_GS = 0x6c08ul, 263*9d7eaa29SArthur Chunqi Li HOST_BASE_TR = 0x6c0aul, 264*9d7eaa29SArthur Chunqi Li HOST_BASE_GDTR = 0x6c0cul, 265*9d7eaa29SArthur Chunqi Li HOST_BASE_IDTR = 0x6c0eul, 266*9d7eaa29SArthur Chunqi Li HOST_SYSENTER_ESP = 0x6c10ul, 267*9d7eaa29SArthur Chunqi Li HOST_SYSENTER_EIP = 0x6c12ul, 268*9d7eaa29SArthur Chunqi Li HOST_RSP = 0x6c14ul, 269*9d7eaa29SArthur Chunqi Li HOST_RIP = 0x6c16ul 270*9d7eaa29SArthur Chunqi Li }; 271*9d7eaa29SArthur Chunqi Li 272*9d7eaa29SArthur Chunqi Li enum Reason { 273*9d7eaa29SArthur Chunqi Li VMX_EXC_NMI = 0, 274*9d7eaa29SArthur Chunqi Li VMX_EXTINT = 1, 275*9d7eaa29SArthur Chunqi Li VMX_TRIPLE_FAULT = 2, 276*9d7eaa29SArthur Chunqi Li VMX_INIT = 3, 277*9d7eaa29SArthur Chunqi Li VMX_SIPI = 4, 278*9d7eaa29SArthur Chunqi Li VMX_SMI_IO = 5, 279*9d7eaa29SArthur Chunqi Li VMX_SMI_OTHER = 6, 280*9d7eaa29SArthur Chunqi Li VMX_INTR_WINDOW = 7, 281*9d7eaa29SArthur Chunqi Li VMX_NMI_WINDOW = 8, 282*9d7eaa29SArthur Chunqi Li VMX_TASK_SWITCH = 9, 283*9d7eaa29SArthur Chunqi Li VMX_CPUID = 10, 284*9d7eaa29SArthur Chunqi Li VMX_GETSEC = 11, 285*9d7eaa29SArthur Chunqi Li VMX_HLT = 12, 286*9d7eaa29SArthur Chunqi Li VMX_INVD = 13, 287*9d7eaa29SArthur Chunqi Li VMX_INVLPG = 14, 288*9d7eaa29SArthur Chunqi Li VMX_RDPMC = 15, 289*9d7eaa29SArthur Chunqi Li VMX_RDTSC = 16, 290*9d7eaa29SArthur Chunqi Li VMX_RSM = 17, 291*9d7eaa29SArthur Chunqi Li VMX_VMCALL = 18, 292*9d7eaa29SArthur Chunqi Li VMX_VMCLEAR = 19, 293*9d7eaa29SArthur Chunqi Li VMX_VMLAUNCH = 20, 294*9d7eaa29SArthur Chunqi Li VMX_VMPTRLD = 21, 295*9d7eaa29SArthur Chunqi Li VMX_VMPTRST = 22, 296*9d7eaa29SArthur Chunqi Li VMX_VMREAD = 23, 297*9d7eaa29SArthur Chunqi Li VMX_VMRESUME = 24, 298*9d7eaa29SArthur Chunqi Li VMX_VMWRITE = 25, 299*9d7eaa29SArthur Chunqi Li VMX_VMXOFF = 26, 300*9d7eaa29SArthur Chunqi Li VMX_VMXON = 27, 301*9d7eaa29SArthur Chunqi Li VMX_CR = 28, 302*9d7eaa29SArthur Chunqi Li VMX_DR = 29, 303*9d7eaa29SArthur Chunqi Li VMX_IO = 30, 304*9d7eaa29SArthur Chunqi Li VMX_RDMSR = 31, 305*9d7eaa29SArthur Chunqi Li VMX_WRMSR = 32, 306*9d7eaa29SArthur Chunqi Li VMX_FAIL_STATE = 33, 307*9d7eaa29SArthur Chunqi Li VMX_FAIL_MSR = 34, 308*9d7eaa29SArthur Chunqi Li VMX_MWAIT = 36, 309*9d7eaa29SArthur Chunqi Li VMX_MTF = 37, 310*9d7eaa29SArthur Chunqi Li VMX_MONITOR = 39, 311*9d7eaa29SArthur Chunqi Li VMX_PAUSE = 40, 312*9d7eaa29SArthur Chunqi Li VMX_FAIL_MCHECK = 41, 313*9d7eaa29SArthur Chunqi Li VMX_TPR_THRESHOLD = 43, 314*9d7eaa29SArthur Chunqi Li VMX_APIC_ACCESS = 44, 315*9d7eaa29SArthur Chunqi Li VMX_GDTR_IDTR = 46, 316*9d7eaa29SArthur Chunqi Li VMX_LDTR_TR = 47, 317*9d7eaa29SArthur Chunqi Li VMX_EPT_VIOLATION = 48, 318*9d7eaa29SArthur Chunqi Li VMX_EPT_MISCONFIG = 49, 319*9d7eaa29SArthur Chunqi Li VMX_INVEPT = 50, 320*9d7eaa29SArthur Chunqi Li VMX_PREEMPT = 52, 321*9d7eaa29SArthur Chunqi Li VMX_INVVPID = 53, 322*9d7eaa29SArthur Chunqi Li VMX_WBINVD = 54, 323*9d7eaa29SArthur Chunqi Li VMX_XSETBV = 55 324*9d7eaa29SArthur Chunqi Li }; 325*9d7eaa29SArthur Chunqi Li 326*9d7eaa29SArthur Chunqi Li #define X86_EFLAGS_CF 0x00000001 /* Carry Flag */ 327*9d7eaa29SArthur Chunqi Li #define X86_EFLAGS_ZF 0x00000040 /* Zero Flag */ 328*9d7eaa29SArthur Chunqi Li 329*9d7eaa29SArthur Chunqi Li enum Ctrl_exi { 330*9d7eaa29SArthur Chunqi Li EXI_HOST_64 = 1UL << 9, 331*9d7eaa29SArthur Chunqi Li EXI_LOAD_PERF = 1UL << 12, 332*9d7eaa29SArthur Chunqi Li EXI_INTA = 1UL << 15, 333*9d7eaa29SArthur Chunqi Li EXI_LOAD_EFER = 1UL << 21, 334*9d7eaa29SArthur Chunqi Li }; 335*9d7eaa29SArthur Chunqi Li 336*9d7eaa29SArthur Chunqi Li enum Ctrl_ent { 337*9d7eaa29SArthur Chunqi Li ENT_GUEST_64 = 1UL << 9, 338*9d7eaa29SArthur Chunqi Li ENT_LOAD_EFER = 1UL << 15, 339*9d7eaa29SArthur Chunqi Li }; 340*9d7eaa29SArthur Chunqi Li 341*9d7eaa29SArthur Chunqi Li enum Ctrl_pin { 342*9d7eaa29SArthur Chunqi Li PIN_EXTINT = 1ul << 0, 343*9d7eaa29SArthur Chunqi Li PIN_NMI = 1ul << 3, 344*9d7eaa29SArthur Chunqi Li PIN_VIRT_NMI = 1ul << 5, 345*9d7eaa29SArthur Chunqi Li }; 346*9d7eaa29SArthur Chunqi Li 347*9d7eaa29SArthur Chunqi Li enum Ctrl0 { 348*9d7eaa29SArthur Chunqi Li CPU_INTR_WINDOW = 1ul << 2, 349*9d7eaa29SArthur Chunqi Li CPU_HLT = 1ul << 7, 350*9d7eaa29SArthur Chunqi Li CPU_INVLPG = 1ul << 9, 351*9d7eaa29SArthur Chunqi Li CPU_CR3_LOAD = 1ul << 15, 352*9d7eaa29SArthur Chunqi Li CPU_CR3_STORE = 1ul << 16, 353*9d7eaa29SArthur Chunqi Li CPU_TPR_SHADOW = 1ul << 21, 354*9d7eaa29SArthur Chunqi Li CPU_NMI_WINDOW = 1ul << 22, 355*9d7eaa29SArthur Chunqi Li CPU_IO = 1ul << 24, 356*9d7eaa29SArthur Chunqi Li CPU_IO_BITMAP = 1ul << 25, 357*9d7eaa29SArthur Chunqi Li CPU_SECONDARY = 1ul << 31, 358*9d7eaa29SArthur Chunqi Li }; 359*9d7eaa29SArthur Chunqi Li 360*9d7eaa29SArthur Chunqi Li enum Ctrl1 { 361*9d7eaa29SArthur Chunqi Li CPU_EPT = 1ul << 1, 362*9d7eaa29SArthur Chunqi Li CPU_VPID = 1ul << 5, 363*9d7eaa29SArthur Chunqi Li CPU_URG = 1ul << 7, 364*9d7eaa29SArthur Chunqi Li }; 365*9d7eaa29SArthur Chunqi Li 366*9d7eaa29SArthur Chunqi Li #define SAVE_GPR \ 367*9d7eaa29SArthur Chunqi Li "xchg %rax, regs\n\t" \ 368*9d7eaa29SArthur Chunqi Li "xchg %rbx, regs+0x8\n\t" \ 369*9d7eaa29SArthur Chunqi Li "xchg %rcx, regs+0x10\n\t" \ 370*9d7eaa29SArthur Chunqi Li "xchg %rdx, regs+0x18\n\t" \ 371*9d7eaa29SArthur Chunqi Li "xchg %rbp, regs+0x28\n\t" \ 372*9d7eaa29SArthur Chunqi Li "xchg %rsi, regs+0x30\n\t" \ 373*9d7eaa29SArthur Chunqi Li "xchg %rdi, regs+0x38\n\t" \ 374*9d7eaa29SArthur Chunqi Li "xchg %r8, regs+0x40\n\t" \ 375*9d7eaa29SArthur Chunqi Li "xchg %r9, regs+0x48\n\t" \ 376*9d7eaa29SArthur Chunqi Li "xchg %r10, regs+0x50\n\t" \ 377*9d7eaa29SArthur Chunqi Li "xchg %r11, regs+0x58\n\t" \ 378*9d7eaa29SArthur Chunqi Li "xchg %r12, regs+0x60\n\t" \ 379*9d7eaa29SArthur Chunqi Li "xchg %r13, regs+0x68\n\t" \ 380*9d7eaa29SArthur Chunqi Li "xchg %r14, regs+0x70\n\t" \ 381*9d7eaa29SArthur Chunqi Li "xchg %r15, regs+0x78\n\t" 382*9d7eaa29SArthur Chunqi Li 383*9d7eaa29SArthur Chunqi Li #define LOAD_GPR SAVE_GPR 384*9d7eaa29SArthur Chunqi Li 385*9d7eaa29SArthur Chunqi Li #define SAVE_GPR_C \ 386*9d7eaa29SArthur Chunqi Li "xchg %%rax, regs\n\t" \ 387*9d7eaa29SArthur Chunqi Li "xchg %%rbx, regs+0x8\n\t" \ 388*9d7eaa29SArthur Chunqi Li "xchg %%rcx, regs+0x10\n\t" \ 389*9d7eaa29SArthur Chunqi Li "xchg %%rdx, regs+0x18\n\t" \ 390*9d7eaa29SArthur Chunqi Li "xchg %%rbp, regs+0x28\n\t" \ 391*9d7eaa29SArthur Chunqi Li "xchg %%rsi, regs+0x30\n\t" \ 392*9d7eaa29SArthur Chunqi Li "xchg %%rdi, regs+0x38\n\t" \ 393*9d7eaa29SArthur Chunqi Li "xchg %%r8, regs+0x40\n\t" \ 394*9d7eaa29SArthur Chunqi Li "xchg %%r9, regs+0x48\n\t" \ 395*9d7eaa29SArthur Chunqi Li "xchg %%r10, regs+0x50\n\t" \ 396*9d7eaa29SArthur Chunqi Li "xchg %%r11, regs+0x58\n\t" \ 397*9d7eaa29SArthur Chunqi Li "xchg %%r12, regs+0x60\n\t" \ 398*9d7eaa29SArthur Chunqi Li "xchg %%r13, regs+0x68\n\t" \ 399*9d7eaa29SArthur Chunqi Li "xchg %%r14, regs+0x70\n\t" \ 400*9d7eaa29SArthur Chunqi Li "xchg %%r15, regs+0x78\n\t" 401*9d7eaa29SArthur Chunqi Li 402*9d7eaa29SArthur Chunqi Li #define LOAD_GPR_C SAVE_GPR_C 403*9d7eaa29SArthur Chunqi Li 404*9d7eaa29SArthur Chunqi Li #define SAVE_RFLAGS \ 405*9d7eaa29SArthur Chunqi Li "pushf\n\t" \ 406*9d7eaa29SArthur Chunqi Li "pop regs+0x80\n\t" 407*9d7eaa29SArthur Chunqi Li 408*9d7eaa29SArthur Chunqi Li #define LOAD_RFLAGS \ 409*9d7eaa29SArthur Chunqi Li "push regs+0x80\n\t" \ 410*9d7eaa29SArthur Chunqi Li "popf\n\t" 411*9d7eaa29SArthur Chunqi Li 412*9d7eaa29SArthur Chunqi Li #define VMX_IO_SIZE_MASK 0x7 413*9d7eaa29SArthur Chunqi Li #define _VMX_IO_BYTE 1 414*9d7eaa29SArthur Chunqi Li #define _VMX_IO_WORD 2 415*9d7eaa29SArthur Chunqi Li #define _VMX_IO_LONG 3 416*9d7eaa29SArthur Chunqi Li #define VMX_IO_DIRECTION_MASK (1ul << 3) 417*9d7eaa29SArthur Chunqi Li #define VMX_IO_IN (1ul << 3) 418*9d7eaa29SArthur Chunqi Li #define VMX_IO_OUT 0 419*9d7eaa29SArthur Chunqi Li #define VMX_IO_STRING (1ul << 4) 420*9d7eaa29SArthur Chunqi Li #define VMX_IO_REP (1ul << 5) 421*9d7eaa29SArthur Chunqi Li #define VMX_IO_OPRAND_DX (1ul << 6) 422*9d7eaa29SArthur Chunqi Li #define VMX_IO_PORT_MASK 0xFFFF0000 423*9d7eaa29SArthur Chunqi Li #define VMX_IO_PORT_SHIFT 16 424*9d7eaa29SArthur Chunqi Li 425*9d7eaa29SArthur Chunqi Li #define VMX_TEST_VMEXIT 1 426*9d7eaa29SArthur Chunqi Li #define VMX_TEST_EXIT 2 427*9d7eaa29SArthur Chunqi Li #define VMX_TEST_RESUME 3 428*9d7eaa29SArthur Chunqi Li #define VMX_TEST_LAUNCH_ERR 4 429*9d7eaa29SArthur Chunqi Li #define VMX_TEST_RESUME_ERR 5 430*9d7eaa29SArthur Chunqi Li 431*9d7eaa29SArthur Chunqi Li #define HYPERCALL_BIT (1ul << 12) 432*9d7eaa29SArthur Chunqi Li #define HYPERCALL_MASK 0xFFF 433*9d7eaa29SArthur Chunqi Li #define HYPERCALL_VMEXIT 0x1 434*9d7eaa29SArthur Chunqi Li 435*9d7eaa29SArthur Chunqi Li static inline int vmcs_clear(struct vmcs *vmcs) 436*9d7eaa29SArthur Chunqi Li { 437*9d7eaa29SArthur Chunqi Li bool ret; 438*9d7eaa29SArthur Chunqi Li asm volatile ("vmclear %1; setbe %0" : "=q" (ret) : "m" (vmcs) : "cc"); 439*9d7eaa29SArthur Chunqi Li return ret; 440*9d7eaa29SArthur Chunqi Li } 441*9d7eaa29SArthur Chunqi Li 442*9d7eaa29SArthur Chunqi Li static inline u64 vmcs_read(enum Encoding enc) 443*9d7eaa29SArthur Chunqi Li { 444*9d7eaa29SArthur Chunqi Li u64 val; 445*9d7eaa29SArthur Chunqi Li asm volatile ("vmread %1, %0" : "=rm" (val) : "r" ((u64)enc) : "cc"); 446*9d7eaa29SArthur Chunqi Li return val; 447*9d7eaa29SArthur Chunqi Li } 448*9d7eaa29SArthur Chunqi Li 449*9d7eaa29SArthur Chunqi Li static inline int vmcs_write(enum Encoding enc, u64 val) 450*9d7eaa29SArthur Chunqi Li { 451*9d7eaa29SArthur Chunqi Li bool ret; 452*9d7eaa29SArthur Chunqi Li asm volatile ("vmwrite %1, %2; setbe %0" 453*9d7eaa29SArthur Chunqi Li : "=q"(ret) : "rm" (val), "r" ((u64)enc) : "cc"); 454*9d7eaa29SArthur Chunqi Li return ret; 455*9d7eaa29SArthur Chunqi Li } 456*9d7eaa29SArthur Chunqi Li 457*9d7eaa29SArthur Chunqi Li static inline int vmcs_save(struct vmcs **vmcs) 458*9d7eaa29SArthur Chunqi Li { 459*9d7eaa29SArthur Chunqi Li bool ret; 460*9d7eaa29SArthur Chunqi Li 461*9d7eaa29SArthur Chunqi Li asm volatile ("vmptrst %1; setbe %0" : "=q" (ret) : "m" (*vmcs) : "cc"); 462*9d7eaa29SArthur Chunqi Li return ret; 463*9d7eaa29SArthur Chunqi Li } 464*9d7eaa29SArthur Chunqi Li 465*9d7eaa29SArthur Chunqi Li #endif 466*9d7eaa29SArthur Chunqi Li 467