xen-vtx-unstable
annotate xen/include/asm-x86/vmx.h @ 3290:b9ab4345fd1b
bitkeeper revision 1.1159.1.483 (41c0c417XYObowWqbfqU0cdLx30C9w)
Initial Intel VMX changes to support unmodified Linux guests on Intel's VT p
latform.
Initial Intel VMX changes to support unmodified Linux guests on Intel's VT p
latform.
author | iap10@labyrinth.cl.cam.ac.uk |
---|---|
date | Wed Dec 15 23:09:11 2004 +0000 (2004-12-15) |
parents | |
children | 0a4b76b6b5a0 |
rev | line source |
---|---|
iap10@3290 | 1 /* |
iap10@3290 | 2 * vmx.h: VMX Architecture related definitions |
iap10@3290 | 3 * Copyright (c) 2004, Intel Corporation. |
iap10@3290 | 4 * |
iap10@3290 | 5 * This program is free software; you can redistribute it and/or modify it |
iap10@3290 | 6 * under the terms and conditions of the GNU General Public License, |
iap10@3290 | 7 * version 2, as published by the Free Software Foundation. |
iap10@3290 | 8 * |
iap10@3290 | 9 * This program is distributed in the hope it will be useful, but WITHOUT |
iap10@3290 | 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
iap10@3290 | 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
iap10@3290 | 12 * more details. |
iap10@3290 | 13 * |
iap10@3290 | 14 * You should have received a copy of the GNU General Public License along with |
iap10@3290 | 15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple |
iap10@3290 | 16 * Place - Suite 330, Boston, MA 02111-1307 USA. |
iap10@3290 | 17 * |
iap10@3290 | 18 */ |
iap10@3290 | 19 #ifndef __ASM_X86_VMX_H__ |
iap10@3290 | 20 #define __ASM_X86_VMX_H__ |
iap10@3290 | 21 |
iap10@3290 | 22 #include <xen/sched.h> |
iap10@3290 | 23 #include <asm/types.h> |
iap10@3290 | 24 #include <asm/regs.h> |
iap10@3290 | 25 #include <asm/processor.h> |
iap10@3290 | 26 #include <asm/vmx_vmcs.h> |
iap10@3290 | 27 |
iap10@3290 | 28 extern void vmx_asm_vmexit_handler(struct xen_regs); |
iap10@3290 | 29 extern void vmx_asm_do_resume(void); |
iap10@3290 | 30 extern void vmx_asm_do_launch(void); |
iap10@3290 | 31 extern void vmx_intr_assist(struct exec_domain *d); |
iap10@3290 | 32 |
iap10@3290 | 33 extern void arch_vmx_do_launch(struct exec_domain *); |
iap10@3290 | 34 extern void arch_vmx_do_resume(struct exec_domain *); |
iap10@3290 | 35 |
iap10@3290 | 36 extern int vmcs_size; |
iap10@3290 | 37 extern unsigned int cpu_rev; |
iap10@3290 | 38 |
iap10@3290 | 39 /* |
iap10@3290 | 40 * Need fill bits for SENTER |
iap10@3290 | 41 */ |
iap10@3290 | 42 |
iap10@3290 | 43 #define MONITOR_PIN_BASED_EXEC_CONTROLS 0x0000001f |
iap10@3290 | 44 #define MONITOR_CPU_BASED_EXEC_CONTROLS 0x0581e7f2 |
iap10@3290 | 45 #define MONITOR_VM_EXIT_CONTROLS 0x0003edff |
iap10@3290 | 46 #define MONITOR_VM_ENTRY_CONTROLS 0x000011ff |
iap10@3290 | 47 |
iap10@3290 | 48 /* |
iap10@3290 | 49 * Exit Reasons |
iap10@3290 | 50 */ |
iap10@3290 | 51 #define VMX_EXIT_REASONS_FAILED_VMENTRY 0x80000000 |
iap10@3290 | 52 |
iap10@3290 | 53 #define EXIT_REASON_EXCEPTION_NMI 0 |
iap10@3290 | 54 #define EXIT_REASON_EXTERNAL_INTERRUPT 1 |
iap10@3290 | 55 |
iap10@3290 | 56 #define EXIT_REASON_PENDING_INTERRUPT 7 |
iap10@3290 | 57 |
iap10@3290 | 58 #define EXIT_REASON_TASK_SWITCH 9 |
iap10@3290 | 59 #define EXIT_REASON_CPUID 10 |
iap10@3290 | 60 #define EXIT_REASON_HLT 12 |
iap10@3290 | 61 #define EXIT_REASON_INVLPG 14 |
iap10@3290 | 62 #define EXIT_REASON_RDPMC 15 |
iap10@3290 | 63 #define EXIT_REASON_RDTSC 16 |
iap10@3290 | 64 #define EXIT_REASON_VMCALL 18 |
iap10@3290 | 65 |
iap10@3290 | 66 #define EXIT_REASON_CR_ACCESS 28 |
iap10@3290 | 67 #define EXIT_REASON_DR_ACCESS 29 |
iap10@3290 | 68 #define EXIT_REASON_IO_INSTRUCTION 30 |
iap10@3290 | 69 #define EXIT_REASON_MSR_READ 31 |
iap10@3290 | 70 #define EXIT_REASON_MSR_WRITE 32 |
iap10@3290 | 71 #define EXIT_REASON_MWAIT_INSTRUCTION 36 |
iap10@3290 | 72 |
iap10@3290 | 73 /* |
iap10@3290 | 74 * Interruption-information format |
iap10@3290 | 75 */ |
iap10@3290 | 76 #define INTR_INFO_VECTOR_MASK 0xff /* 7:0 */ |
iap10@3290 | 77 #define INTR_INFO_INTR_TYPE_MASK 0x700 /* 10:8 */ |
iap10@3290 | 78 #define INTR_INFO_DELIEVER_CODE_MASK 0x800 /* 11 */ |
iap10@3290 | 79 #define INTR_INFO_VALID_MASK 0x80000000 /* 31 */ |
iap10@3290 | 80 |
iap10@3290 | 81 #define INTR_TYPE_EXT_INTR (0 << 8) /* external interrupt */ |
iap10@3290 | 82 #define INTR_TYPE_EXCEPTION (3 << 8) /* processor exception */ |
iap10@3290 | 83 |
iap10@3290 | 84 /* |
iap10@3290 | 85 * Exit Qualifications for MOV for Control Register Access |
iap10@3290 | 86 */ |
iap10@3290 | 87 #define CONTROL_REG_ACCESS_NUM 0x7 /* 2:0, number of control register */ |
iap10@3290 | 88 #define CONTROL_REG_ACCESS_TYPE 0x30 /* 5:4, access type */ |
iap10@3290 | 89 #define TYPE_MOV_TO_CR (0 << 4) |
iap10@3290 | 90 #define TYPE_MOV_FROM_CR (1 << 4) |
iap10@3290 | 91 #define TYPE_CLTS (2 << 4) |
iap10@3290 | 92 #define CONTROL_REG_ACCESS_REG 0x700 /* 10:8, general purpose register */ |
iap10@3290 | 93 #define REG_EAX (0 << 8) |
iap10@3290 | 94 #define REG_ECX (1 << 8) |
iap10@3290 | 95 #define REG_EDX (2 << 8) |
iap10@3290 | 96 #define REG_EBX (3 << 8) |
iap10@3290 | 97 #define REG_ESP (4 << 8) |
iap10@3290 | 98 #define REG_EBP (5 << 8) |
iap10@3290 | 99 #define REG_ESI (6 << 8) |
iap10@3290 | 100 #define REG_EDI (7 << 8) |
iap10@3290 | 101 |
iap10@3290 | 102 /* |
iap10@3290 | 103 * Exit Qualifications for MOV for Debug Register Access |
iap10@3290 | 104 */ |
iap10@3290 | 105 #define DEBUG_REG_ACCESS_NUM 0x7 /* 2:0, number of debug register */ |
iap10@3290 | 106 #define DEBUG_REG_ACCESS_TYPE 0x10 /* 4, direction of access */ |
iap10@3290 | 107 #define TYPE_MOV_TO_DR (0 << 4) |
iap10@3290 | 108 #define TYPE_MOV_FROM_DR (1 << 4) |
iap10@3290 | 109 #define DEBUG_REG_ACCESS_REG 0x700 /* 11:8, general purpose register */ |
iap10@3290 | 110 |
iap10@3290 | 111 #define EXCEPTION_BITMAP_DE (1 << 0) /* Divide Error */ |
iap10@3290 | 112 #define EXCEPTION_BITMAP_DB (1 << 1) /* Debug */ |
iap10@3290 | 113 #define EXCEPTION_BITMAP_NMI (1 << 2) /* NMI */ |
iap10@3290 | 114 #define EXCEPTION_BITMAP_BP (1 << 3) /* Breakpoint */ |
iap10@3290 | 115 #define EXCEPTION_BITMAP_OF (1 << 4) /* Overflow */ |
iap10@3290 | 116 #define EXCEPTION_BITMAP_BR (1 << 5) /* BOUND Range Exceeded */ |
iap10@3290 | 117 #define EXCEPTION_BITMAP_UD (1 << 6) /* Invalid Opcode */ |
iap10@3290 | 118 #define EXCEPTION_BITMAP_NM (1 << 7) /* Device Not Available */ |
iap10@3290 | 119 #define EXCEPTION_BITMAP_DF (1 << 8) /* Double Fault */ |
iap10@3290 | 120 /* reserved */ |
iap10@3290 | 121 #define EXCEPTION_BITMAP_TS (1 << 10) /* Invalid TSS */ |
iap10@3290 | 122 #define EXCEPTION_BITMAP_NP (1 << 11) /* Segment Not Present */ |
iap10@3290 | 123 #define EXCEPTION_BITMAP_SS (1 << 12) /* Stack-Segment Fault */ |
iap10@3290 | 124 #define EXCEPTION_BITMAP_GP (1 << 13) /* General Protection */ |
iap10@3290 | 125 #define EXCEPTION_BITMAP_PG (1 << 14) /* Page Fault */ |
iap10@3290 | 126 #define EXCEPTION_BITMAP_MF (1 << 16) /* x87 FPU Floating-Point Error (Math Fault) */ |
iap10@3290 | 127 #define EXCEPTION_BITMAP_AC (1 << 17) /* Alignment Check */ |
iap10@3290 | 128 #define EXCEPTION_BITMAP_MC (1 << 18) /* Machine Check */ |
iap10@3290 | 129 #define EXCEPTION_BITMAP_XF (1 << 19) /* SIMD Floating-Point Exception */ |
iap10@3290 | 130 |
iap10@3290 | 131 #ifdef XEN_DEBUGGER |
iap10@3290 | 132 #define MONITOR_DEFAULT_EXCEPTION_BITMAP \ |
iap10@3290 | 133 ( EXCEPTION_BITMAP_PG | \ |
iap10@3290 | 134 EXCEPTION_BITMAP_DB | \ |
iap10@3290 | 135 EXCEPTION_BITMAP_BP | \ |
iap10@3290 | 136 EXCEPTION_BITMAP_GP ) |
iap10@3290 | 137 #else |
iap10@3290 | 138 #define MONITOR_DEFAULT_EXCEPTION_BITMAP \ |
iap10@3290 | 139 ( EXCEPTION_BITMAP_PG | \ |
iap10@3290 | 140 EXCEPTION_BITMAP_GP ) |
iap10@3290 | 141 #endif |
iap10@3290 | 142 |
iap10@3290 | 143 #define VMCALL_OPCODE ".byte 0x0f,0x01,0xc1\n" |
iap10@3290 | 144 #define VMCLEAR_OPCODE ".byte 0x66,0x0f,0xc7\n" /* reg/opcode: /6 */ |
iap10@3290 | 145 #define VMLAUNCH_OPCODE ".byte 0x0f,0x01,0xc2\n" |
iap10@3290 | 146 #define VMPTRLD_OPCODE ".byte 0x0f,0xc7\n" /* reg/opcode: /6 */ |
iap10@3290 | 147 #define VMPTRST_OPCODE ".byte 0x0f,0xc7\n" /* reg/opcode: /7 */ |
iap10@3290 | 148 #define VMREAD_OPCODE ".byte 0x0f,0x78\n" |
iap10@3290 | 149 #define VMRESUME_OPCODE ".byte 0x0f,0x01,0xc3\n" |
iap10@3290 | 150 #define VMWRITE_OPCODE ".byte 0x0f,0x79\n" |
iap10@3290 | 151 #define VMXOFF_OPCODE ".byte 0x0f,0x01,0xc4\n" |
iap10@3290 | 152 #define VMXON_OPCODE ".byte 0xf3,0x0f,0xc7\n" |
iap10@3290 | 153 |
iap10@3290 | 154 #define MODRM_EAX_06 ".byte 0x30\n" /* [EAX], with reg/opcode: /6 */ |
iap10@3290 | 155 #define MODRM_EAX_07 ".byte 0x38\n" /* [EAX], with reg/opcode: /7 */ |
iap10@3290 | 156 #define MODRM_EAX_ECX ".byte 0xc1\n" /* [EAX], [ECX] */ |
iap10@3290 | 157 |
iap10@3290 | 158 static inline int __vmptrld (u64 addr) |
iap10@3290 | 159 { |
iap10@3290 | 160 unsigned long eflags; |
iap10@3290 | 161 __asm__ __volatile__ ( VMPTRLD_OPCODE |
iap10@3290 | 162 MODRM_EAX_06 |
iap10@3290 | 163 : |
iap10@3290 | 164 : "a" (&addr) |
iap10@3290 | 165 : "memory"); |
iap10@3290 | 166 |
iap10@3290 | 167 __save_flags(eflags); |
iap10@3290 | 168 if (eflags & X86_EFLAGS_ZF || eflags & X86_EFLAGS_CF) |
iap10@3290 | 169 return -1; |
iap10@3290 | 170 return 0; |
iap10@3290 | 171 } |
iap10@3290 | 172 |
iap10@3290 | 173 static inline void __vmptrst (u64 addr) |
iap10@3290 | 174 { |
iap10@3290 | 175 __asm__ __volatile__ ( VMPTRST_OPCODE |
iap10@3290 | 176 MODRM_EAX_07 |
iap10@3290 | 177 : |
iap10@3290 | 178 : "a" (&addr) |
iap10@3290 | 179 : "memory"); |
iap10@3290 | 180 } |
iap10@3290 | 181 |
iap10@3290 | 182 static inline int __vmpclear (u64 addr) |
iap10@3290 | 183 { |
iap10@3290 | 184 unsigned long eflags; |
iap10@3290 | 185 |
iap10@3290 | 186 __asm__ __volatile__ ( VMCLEAR_OPCODE |
iap10@3290 | 187 MODRM_EAX_06 |
iap10@3290 | 188 : |
iap10@3290 | 189 : "a" (&addr) |
iap10@3290 | 190 : "memory"); |
iap10@3290 | 191 __save_flags(eflags); |
iap10@3290 | 192 if (eflags & X86_EFLAGS_ZF || eflags & X86_EFLAGS_CF) |
iap10@3290 | 193 return -1; |
iap10@3290 | 194 return 0; |
iap10@3290 | 195 } |
iap10@3290 | 196 |
iap10@3290 | 197 static inline int __vmread (unsigned int field, void *value) |
iap10@3290 | 198 { |
iap10@3290 | 199 unsigned long eflags; |
iap10@3290 | 200 unsigned long ecx = 0; |
iap10@3290 | 201 |
iap10@3290 | 202 __asm__ __volatile__ ( VMREAD_OPCODE |
iap10@3290 | 203 MODRM_EAX_ECX |
iap10@3290 | 204 : "=c" (ecx) |
iap10@3290 | 205 : "a" (field) |
iap10@3290 | 206 : "memory"); |
iap10@3290 | 207 |
iap10@3290 | 208 *((long *) value) = ecx; |
iap10@3290 | 209 |
iap10@3290 | 210 __save_flags(eflags); |
iap10@3290 | 211 if (eflags & X86_EFLAGS_ZF || eflags & X86_EFLAGS_CF) |
iap10@3290 | 212 return -1; |
iap10@3290 | 213 return 0; |
iap10@3290 | 214 } |
iap10@3290 | 215 |
iap10@3290 | 216 static inline int __vmwrite (unsigned int field, unsigned int value) |
iap10@3290 | 217 { |
iap10@3290 | 218 unsigned long eflags; |
iap10@3290 | 219 |
iap10@3290 | 220 __asm__ __volatile__ ( VMWRITE_OPCODE |
iap10@3290 | 221 MODRM_EAX_ECX |
iap10@3290 | 222 : |
iap10@3290 | 223 : "a" (field) , "c" (value) |
iap10@3290 | 224 : "memory"); |
iap10@3290 | 225 __save_flags(eflags); |
iap10@3290 | 226 if (eflags & X86_EFLAGS_ZF || eflags & X86_EFLAGS_CF) |
iap10@3290 | 227 return -1; |
iap10@3290 | 228 return 0; |
iap10@3290 | 229 } |
iap10@3290 | 230 |
iap10@3290 | 231 static inline void __vmxoff (void) |
iap10@3290 | 232 { |
iap10@3290 | 233 __asm__ __volatile__ ( VMXOFF_OPCODE |
iap10@3290 | 234 ::: "memory"); |
iap10@3290 | 235 } |
iap10@3290 | 236 |
iap10@3290 | 237 static inline int __vmxon (u64 addr) |
iap10@3290 | 238 { |
iap10@3290 | 239 unsigned long eflags; |
iap10@3290 | 240 |
iap10@3290 | 241 __asm__ __volatile__ ( VMXON_OPCODE |
iap10@3290 | 242 MODRM_EAX_06 |
iap10@3290 | 243 : |
iap10@3290 | 244 : "a" (&addr) |
iap10@3290 | 245 : "memory"); |
iap10@3290 | 246 __save_flags(eflags); |
iap10@3290 | 247 if (eflags & X86_EFLAGS_ZF || eflags & X86_EFLAGS_CF) |
iap10@3290 | 248 return -1; |
iap10@3290 | 249 return 0; |
iap10@3290 | 250 } |
iap10@3290 | 251 #endif /* __ASM_X86_VMX_H__ */ |