1 /* 2 * vmcb.h: VMCB related definitions 3 * Copyright (c) 2005-2007, Advanced Micro Devices, Inc 4 * Copyright (c) 2004, Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify it 7 * under the terms and conditions of the GNU General Public License, 8 * version 2, as published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 * more details. 14 * 15 * You should have received a copy of the GNU General Public License along with 16 * this program; If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 #ifndef __ASM_X86_HVM_SVM_VMCB_H__ 20 #define __ASM_X86_HVM_SVM_VMCB_H__ 21 22 #include <xen/types.h> 23 24 /* general 1 intercepts */ 25 enum GenericIntercept1bits 26 { 27 GENERAL1_INTERCEPT_INTR = 1 << 0, 28 GENERAL1_INTERCEPT_NMI = 1 << 1, 29 GENERAL1_INTERCEPT_SMI = 1 << 2, 30 GENERAL1_INTERCEPT_INIT = 1 << 3, 31 GENERAL1_INTERCEPT_VINTR = 1 << 4, 32 GENERAL1_INTERCEPT_CR0_SEL_WRITE = 1 << 5, 33 GENERAL1_INTERCEPT_IDTR_READ = 1 << 6, 34 GENERAL1_INTERCEPT_GDTR_READ = 1 << 7, 35 GENERAL1_INTERCEPT_LDTR_READ = 1 << 8, 36 GENERAL1_INTERCEPT_TR_READ = 1 << 9, 37 GENERAL1_INTERCEPT_IDTR_WRITE = 1 << 10, 38 GENERAL1_INTERCEPT_GDTR_WRITE = 1 << 11, 39 GENERAL1_INTERCEPT_LDTR_WRITE = 1 << 12, 40 GENERAL1_INTERCEPT_TR_WRITE = 1 << 13, 41 GENERAL1_INTERCEPT_RDTSC = 1 << 14, 42 GENERAL1_INTERCEPT_RDPMC = 1 << 15, 43 GENERAL1_INTERCEPT_PUSHF = 1 << 16, 44 GENERAL1_INTERCEPT_POPF = 1 << 17, 45 GENERAL1_INTERCEPT_CPUID = 1 << 18, 46 GENERAL1_INTERCEPT_RSM = 1 << 19, 47 GENERAL1_INTERCEPT_IRET = 1 << 20, 48 GENERAL1_INTERCEPT_SWINT = 1 << 21, 49 GENERAL1_INTERCEPT_INVD = 1 << 22, 50 GENERAL1_INTERCEPT_PAUSE = 1 << 23, 51 GENERAL1_INTERCEPT_HLT = 1 << 24, 52 GENERAL1_INTERCEPT_INVLPG = 1 << 25, 53 GENERAL1_INTERCEPT_INVLPGA = 1 << 26, 54 GENERAL1_INTERCEPT_IOIO_PROT = 1 << 27, 55 GENERAL1_INTERCEPT_MSR_PROT = 1 << 28, 56 GENERAL1_INTERCEPT_TASK_SWITCH = 1 << 29, 57 GENERAL1_INTERCEPT_FERR_FREEZE = 1 << 30, 58 GENERAL1_INTERCEPT_SHUTDOWN_EVT = 1 << 31 59 }; 60 61 /* general 2 intercepts */ 62 enum GenericIntercept2bits 63 { 64 GENERAL2_INTERCEPT_VMRUN = 1 << 0, 65 GENERAL2_INTERCEPT_VMMCALL = 1 << 1, 66 GENERAL2_INTERCEPT_VMLOAD = 1 << 2, 67 GENERAL2_INTERCEPT_VMSAVE = 1 << 3, 68 GENERAL2_INTERCEPT_STGI = 1 << 4, 69 GENERAL2_INTERCEPT_CLGI = 1 << 5, 70 GENERAL2_INTERCEPT_SKINIT = 1 << 6, 71 GENERAL2_INTERCEPT_RDTSCP = 1 << 7, 72 GENERAL2_INTERCEPT_ICEBP = 1 << 8, 73 GENERAL2_INTERCEPT_WBINVD = 1 << 9, 74 GENERAL2_INTERCEPT_MONITOR = 1 << 10, 75 GENERAL2_INTERCEPT_MWAIT = 1 << 11, 76 GENERAL2_INTERCEPT_MWAIT_CONDITIONAL = 1 << 12, 77 GENERAL2_INTERCEPT_XSETBV = 1 << 13 78 }; 79 80 81 /* control register intercepts */ 82 enum CRInterceptBits 83 { 84 CR_INTERCEPT_CR0_READ = 1 << 0, 85 CR_INTERCEPT_CR1_READ = 1 << 1, 86 CR_INTERCEPT_CR2_READ = 1 << 2, 87 CR_INTERCEPT_CR3_READ = 1 << 3, 88 CR_INTERCEPT_CR4_READ = 1 << 4, 89 CR_INTERCEPT_CR5_READ = 1 << 5, 90 CR_INTERCEPT_CR6_READ = 1 << 6, 91 CR_INTERCEPT_CR7_READ = 1 << 7, 92 CR_INTERCEPT_CR8_READ = 1 << 8, 93 CR_INTERCEPT_CR9_READ = 1 << 9, 94 CR_INTERCEPT_CR10_READ = 1 << 10, 95 CR_INTERCEPT_CR11_READ = 1 << 11, 96 CR_INTERCEPT_CR12_READ = 1 << 12, 97 CR_INTERCEPT_CR13_READ = 1 << 13, 98 CR_INTERCEPT_CR14_READ = 1 << 14, 99 CR_INTERCEPT_CR15_READ = 1 << 15, 100 CR_INTERCEPT_CR0_WRITE = 1 << 16, 101 CR_INTERCEPT_CR1_WRITE = 1 << 17, 102 CR_INTERCEPT_CR2_WRITE = 1 << 18, 103 CR_INTERCEPT_CR3_WRITE = 1 << 19, 104 CR_INTERCEPT_CR4_WRITE = 1 << 20, 105 CR_INTERCEPT_CR5_WRITE = 1 << 21, 106 CR_INTERCEPT_CR6_WRITE = 1 << 22, 107 CR_INTERCEPT_CR7_WRITE = 1 << 23, 108 CR_INTERCEPT_CR8_WRITE = 1 << 24, 109 CR_INTERCEPT_CR9_WRITE = 1 << 25, 110 CR_INTERCEPT_CR10_WRITE = 1 << 26, 111 CR_INTERCEPT_CR11_WRITE = 1 << 27, 112 CR_INTERCEPT_CR12_WRITE = 1 << 28, 113 CR_INTERCEPT_CR13_WRITE = 1 << 29, 114 CR_INTERCEPT_CR14_WRITE = 1 << 30, 115 CR_INTERCEPT_CR15_WRITE = 1 << 31, 116 }; 117 118 119 /* debug register intercepts */ 120 enum DRInterceptBits 121 { 122 DR_INTERCEPT_DR0_READ = 1 << 0, 123 DR_INTERCEPT_DR1_READ = 1 << 1, 124 DR_INTERCEPT_DR2_READ = 1 << 2, 125 DR_INTERCEPT_DR3_READ = 1 << 3, 126 DR_INTERCEPT_DR4_READ = 1 << 4, 127 DR_INTERCEPT_DR5_READ = 1 << 5, 128 DR_INTERCEPT_DR6_READ = 1 << 6, 129 DR_INTERCEPT_DR7_READ = 1 << 7, 130 DR_INTERCEPT_DR8_READ = 1 << 8, 131 DR_INTERCEPT_DR9_READ = 1 << 9, 132 DR_INTERCEPT_DR10_READ = 1 << 10, 133 DR_INTERCEPT_DR11_READ = 1 << 11, 134 DR_INTERCEPT_DR12_READ = 1 << 12, 135 DR_INTERCEPT_DR13_READ = 1 << 13, 136 DR_INTERCEPT_DR14_READ = 1 << 14, 137 DR_INTERCEPT_DR15_READ = 1 << 15, 138 DR_INTERCEPT_DR0_WRITE = 1 << 16, 139 DR_INTERCEPT_DR1_WRITE = 1 << 17, 140 DR_INTERCEPT_DR2_WRITE = 1 << 18, 141 DR_INTERCEPT_DR3_WRITE = 1 << 19, 142 DR_INTERCEPT_DR4_WRITE = 1 << 20, 143 DR_INTERCEPT_DR5_WRITE = 1 << 21, 144 DR_INTERCEPT_DR6_WRITE = 1 << 22, 145 DR_INTERCEPT_DR7_WRITE = 1 << 23, 146 DR_INTERCEPT_DR8_WRITE = 1 << 24, 147 DR_INTERCEPT_DR9_WRITE = 1 << 25, 148 DR_INTERCEPT_DR10_WRITE = 1 << 26, 149 DR_INTERCEPT_DR11_WRITE = 1 << 27, 150 DR_INTERCEPT_DR12_WRITE = 1 << 28, 151 DR_INTERCEPT_DR13_WRITE = 1 << 29, 152 DR_INTERCEPT_DR14_WRITE = 1 << 30, 153 DR_INTERCEPT_DR15_WRITE = 1 << 31, 154 }; 155 156 enum VMEXIT_EXITCODE 157 { 158 /* control register read exitcodes */ 159 VMEXIT_CR0_READ = 0, /* 0x0 */ 160 VMEXIT_CR1_READ = 1, /* 0x1 */ 161 VMEXIT_CR2_READ = 2, /* 0x2 */ 162 VMEXIT_CR3_READ = 3, /* 0x3 */ 163 VMEXIT_CR4_READ = 4, /* 0x4 */ 164 VMEXIT_CR5_READ = 5, /* 0x5 */ 165 VMEXIT_CR6_READ = 6, /* 0x6 */ 166 VMEXIT_CR7_READ = 7, /* 0x7 */ 167 VMEXIT_CR8_READ = 8, /* 0x8 */ 168 VMEXIT_CR9_READ = 9, /* 0x9 */ 169 VMEXIT_CR10_READ = 10, /* 0xa */ 170 VMEXIT_CR11_READ = 11, /* 0xb */ 171 VMEXIT_CR12_READ = 12, /* 0xc */ 172 VMEXIT_CR13_READ = 13, /* 0xd */ 173 VMEXIT_CR14_READ = 14, /* 0xe */ 174 VMEXIT_CR15_READ = 15, /* 0xf */ 175 176 /* control register write exitcodes */ 177 VMEXIT_CR0_WRITE = 16, /* 0x10 */ 178 VMEXIT_CR1_WRITE = 17, /* 0x11 */ 179 VMEXIT_CR2_WRITE = 18, /* 0x12 */ 180 VMEXIT_CR3_WRITE = 19, /* 0x13 */ 181 VMEXIT_CR4_WRITE = 20, /* 0x14 */ 182 VMEXIT_CR5_WRITE = 21, /* 0x15 */ 183 VMEXIT_CR6_WRITE = 22, /* 0x16 */ 184 VMEXIT_CR7_WRITE = 23, /* 0x17 */ 185 VMEXIT_CR8_WRITE = 24, /* 0x18 */ 186 VMEXIT_CR9_WRITE = 25, /* 0x19 */ 187 VMEXIT_CR10_WRITE = 26, /* 0x1a */ 188 VMEXIT_CR11_WRITE = 27, /* 0x1b */ 189 VMEXIT_CR12_WRITE = 28, /* 0x1c */ 190 VMEXIT_CR13_WRITE = 29, /* 0x1d */ 191 VMEXIT_CR14_WRITE = 30, /* 0x1e */ 192 VMEXIT_CR15_WRITE = 31, /* 0x1f */ 193 194 /* debug register read exitcodes */ 195 VMEXIT_DR0_READ = 32, /* 0x20 */ 196 VMEXIT_DR1_READ = 33, /* 0x21 */ 197 VMEXIT_DR2_READ = 34, /* 0x22 */ 198 VMEXIT_DR3_READ = 35, /* 0x23 */ 199 VMEXIT_DR4_READ = 36, /* 0x24 */ 200 VMEXIT_DR5_READ = 37, /* 0x25 */ 201 VMEXIT_DR6_READ = 38, /* 0x26 */ 202 VMEXIT_DR7_READ = 39, /* 0x27 */ 203 VMEXIT_DR8_READ = 40, /* 0x28 */ 204 VMEXIT_DR9_READ = 41, /* 0x29 */ 205 VMEXIT_DR10_READ = 42, /* 0x2a */ 206 VMEXIT_DR11_READ = 43, /* 0x2b */ 207 VMEXIT_DR12_READ = 44, /* 0x2c */ 208 VMEXIT_DR13_READ = 45, /* 0x2d */ 209 VMEXIT_DR14_READ = 46, /* 0x2e */ 210 VMEXIT_DR15_READ = 47, /* 0x2f */ 211 212 /* debug register write exitcodes */ 213 VMEXIT_DR0_WRITE = 48, /* 0x30 */ 214 VMEXIT_DR1_WRITE = 49, /* 0x31 */ 215 VMEXIT_DR2_WRITE = 50, /* 0x32 */ 216 VMEXIT_DR3_WRITE = 51, /* 0x33 */ 217 VMEXIT_DR4_WRITE = 52, /* 0x34 */ 218 VMEXIT_DR5_WRITE = 53, /* 0x35 */ 219 VMEXIT_DR6_WRITE = 54, /* 0x36 */ 220 VMEXIT_DR7_WRITE = 55, /* 0x37 */ 221 VMEXIT_DR8_WRITE = 56, /* 0x38 */ 222 VMEXIT_DR9_WRITE = 57, /* 0x39 */ 223 VMEXIT_DR10_WRITE = 58, /* 0x3a */ 224 VMEXIT_DR11_WRITE = 59, /* 0x3b */ 225 VMEXIT_DR12_WRITE = 60, /* 0x3c */ 226 VMEXIT_DR13_WRITE = 61, /* 0x3d */ 227 VMEXIT_DR14_WRITE = 62, /* 0x3e */ 228 VMEXIT_DR15_WRITE = 63, /* 0x3f */ 229 230 /* processor exception exitcodes (VMEXIT_EXCP[0-31]) */ 231 VMEXIT_EXCEPTION_DE = 64, /* 0x40, divide-by-zero-error */ 232 VMEXIT_EXCEPTION_DB = 65, /* 0x41, debug */ 233 VMEXIT_EXCEPTION_NMI = 66, /* 0x42, non-maskable-interrupt */ 234 VMEXIT_EXCEPTION_BP = 67, /* 0x43, breakpoint */ 235 VMEXIT_EXCEPTION_OF = 68, /* 0x44, overflow */ 236 VMEXIT_EXCEPTION_BR = 69, /* 0x45, bound-range */ 237 VMEXIT_EXCEPTION_UD = 70, /* 0x46, invalid-opcode*/ 238 VMEXIT_EXCEPTION_NM = 71, /* 0x47, device-not-available */ 239 VMEXIT_EXCEPTION_DF = 72, /* 0x48, double-fault */ 240 VMEXIT_EXCEPTION_09 = 73, /* 0x49, unsupported (reserved) */ 241 VMEXIT_EXCEPTION_TS = 74, /* 0x4a, invalid-tss */ 242 VMEXIT_EXCEPTION_NP = 75, /* 0x4b, segment-not-present */ 243 VMEXIT_EXCEPTION_SS = 76, /* 0x4c, stack */ 244 VMEXIT_EXCEPTION_GP = 77, /* 0x4d, general-protection */ 245 VMEXIT_EXCEPTION_PF = 78, /* 0x4e, page-fault */ 246 VMEXIT_EXCEPTION_15 = 79, /* 0x4f, reserved */ 247 VMEXIT_EXCEPTION_MF = 80, /* 0x50, x87 floating-point exception-pending */ 248 VMEXIT_EXCEPTION_AC = 81, /* 0x51, alignment-check */ 249 VMEXIT_EXCEPTION_MC = 82, /* 0x52, machine-check */ 250 VMEXIT_EXCEPTION_XF = 83, /* 0x53, simd floating-point */ 251 252 /* exceptions 20-31 (exitcodes 84-95) are reserved */ 253 254 /* ...and the rest of the #VMEXITs */ 255 VMEXIT_INTR = 96, /* 0x60 */ 256 VMEXIT_NMI = 97, /* 0x61 */ 257 VMEXIT_SMI = 98, /* 0x62 */ 258 VMEXIT_INIT = 99, /* 0x63 */ 259 VMEXIT_VINTR = 100, /* 0x64 */ 260 VMEXIT_CR0_SEL_WRITE = 101, /* 0x65 */ 261 VMEXIT_IDTR_READ = 102, /* 0x66 */ 262 VMEXIT_GDTR_READ = 103, /* 0x67 */ 263 VMEXIT_LDTR_READ = 104, /* 0x68 */ 264 VMEXIT_TR_READ = 105, /* 0x69 */ 265 VMEXIT_IDTR_WRITE = 106, /* 0x6a */ 266 VMEXIT_GDTR_WRITE = 107, /* 0x6b */ 267 VMEXIT_LDTR_WRITE = 108, /* 0x6c */ 268 VMEXIT_TR_WRITE = 109, /* 0x6d */ 269 VMEXIT_RDTSC = 110, /* 0x6e */ 270 VMEXIT_RDPMC = 111, /* 0x6f */ 271 VMEXIT_PUSHF = 112, /* 0x70 */ 272 VMEXIT_POPF = 113, /* 0x71 */ 273 VMEXIT_CPUID = 114, /* 0x72 */ 274 VMEXIT_RSM = 115, /* 0x73 */ 275 VMEXIT_IRET = 116, /* 0x74 */ 276 VMEXIT_SWINT = 117, /* 0x75 */ 277 VMEXIT_INVD = 118, /* 0x76 */ 278 VMEXIT_PAUSE = 119, /* 0x77 */ 279 VMEXIT_HLT = 120, /* 0x78 */ 280 VMEXIT_INVLPG = 121, /* 0x79 */ 281 VMEXIT_INVLPGA = 122, /* 0x7a */ 282 VMEXIT_IOIO = 123, /* 0x7b */ 283 VMEXIT_MSR = 124, /* 0x7c */ 284 VMEXIT_TASK_SWITCH = 125, /* 0x7d */ 285 VMEXIT_FERR_FREEZE = 126, /* 0x7e */ 286 VMEXIT_SHUTDOWN = 127, /* 0x7f */ 287 VMEXIT_VMRUN = 128, /* 0x80 */ 288 VMEXIT_VMMCALL = 129, /* 0x81 */ 289 VMEXIT_VMLOAD = 130, /* 0x82 */ 290 VMEXIT_VMSAVE = 131, /* 0x83 */ 291 VMEXIT_STGI = 132, /* 0x84 */ 292 VMEXIT_CLGI = 133, /* 0x85 */ 293 VMEXIT_SKINIT = 134, /* 0x86 */ 294 VMEXIT_RDTSCP = 135, /* 0x87 */ 295 VMEXIT_ICEBP = 136, /* 0x88 */ 296 VMEXIT_WBINVD = 137, /* 0x89 */ 297 VMEXIT_MONITOR = 138, /* 0x8a */ 298 VMEXIT_MWAIT = 139, /* 0x8b */ 299 VMEXIT_MWAIT_CONDITIONAL= 140, /* 0x8c */ 300 VMEXIT_XSETBV = 141, /* 0x8d */ 301 VMEXIT_NPF = 1024, /* 0x400, nested paging fault */ 302 VMEXIT_INVALID = -1 303 }; 304 305 enum 306 { 307 /* Available on all SVM-capable hardware. */ 308 TLB_CTRL_NO_FLUSH = 0, 309 TLB_CTRL_FLUSH_ALL = 1, 310 311 /* Available with the FlushByASID feature. */ 312 TLB_CTRL_FLUSH_ASID = 3, 313 TLB_CTRL_FLUSH_ASID_NONGLOBAL = 7, 314 }; 315 316 typedef union 317 { 318 struct 319 { 320 uint8_t vector; 321 uint8_t type:3; 322 bool ev:1; 323 uint32_t resvd1:19; 324 bool v:1; 325 uint32_t ec; 326 }; 327 uint64_t raw; 328 } intinfo_t; 329 330 typedef union { 331 struct { 332 bool intr_shadow: 1; 333 bool guest_intr_mask:1; 334 }; 335 uint64_t raw; 336 } intstat_t; 337 338 typedef union 339 { 340 u64 bytes; 341 struct 342 { 343 u64 tpr: 8; 344 u64 irq: 1; 345 u64 vgif: 1; 346 u64 rsvd0: 6; 347 u64 prio: 4; 348 u64 ign_tpr: 1; 349 u64 rsvd1: 3; 350 u64 intr_masking: 1; 351 u64 vgif_enable: 1; 352 u64 rsvd2: 6; 353 u64 vector: 8; 354 u64 rsvd3: 24; 355 } fields; 356 } vintr_t; 357 358 typedef union 359 { 360 u64 bytes; 361 struct 362 { 363 u64 type: 1; 364 u64 rsv0: 1; 365 u64 str: 1; 366 u64 rep: 1; 367 u64 sz8: 1; 368 u64 sz16: 1; 369 u64 sz32: 1; 370 u64 rsv1: 9; 371 u64 port: 16; 372 } fields; 373 } ioio_info_t; 374 375 typedef union 376 { 377 u64 bytes; 378 struct 379 { 380 u64 lbr_enable:1; 381 u64 vloadsave_enable:1; 382 } fields; 383 } virt_ext_t; 384 385 typedef union 386 { 387 struct { 388 bool intercepts:1; /* 0: cr/dr/exception/general intercepts, 389 * pause_filter_count, tsc_offset */ 390 bool iopm:1; /* 1: iopm_base_pa, msrpm_base_pa */ 391 bool asid:1; /* 2: guest_asid */ 392 bool tpr:1; /* 3: vintr */ 393 bool np:1; /* 4: np_enable, h_cr3, g_pat */ 394 bool cr:1; /* 5: cr0, cr3, cr4, efer */ 395 bool dr:1; /* 6: dr6, dr7 */ 396 bool dt:1; /* 7: gdtr, idtr */ 397 bool seg:1; /* 8: cs, ds, es, ss, cpl */ 398 bool cr2:1; /* 9: cr2 */ 399 bool lbr:1; /* 10: debugctlmsr, last{branch,int}{to,from}ip */ 400 }; 401 uint32_t raw; 402 } vmcbcleanbits_t; 403 404 #define IOPM_SIZE (12 * 1024) 405 #define MSRPM_SIZE (8 * 1024) 406 407 struct vmcb_struct { 408 u32 _cr_intercepts; /* offset 0x00 - cleanbit 0 */ 409 u32 _dr_intercepts; /* offset 0x04 - cleanbit 0 */ 410 u32 _exception_intercepts; /* offset 0x08 - cleanbit 0 */ 411 u32 _general1_intercepts; /* offset 0x0C - cleanbit 0 */ 412 u32 _general2_intercepts; /* offset 0x10 - cleanbit 0 */ 413 u32 res01[10]; 414 u16 _pause_filter_thresh; /* offset 0x3C - cleanbit 0 */ 415 u16 _pause_filter_count; /* offset 0x3E - cleanbit 0 */ 416 u64 _iopm_base_pa; /* offset 0x40 - cleanbit 1 */ 417 u64 _msrpm_base_pa; /* offset 0x48 - cleanbit 1 */ 418 u64 _tsc_offset; /* offset 0x50 - cleanbit 0 */ 419 u32 _guest_asid; /* offset 0x58 - cleanbit 2 */ 420 u8 tlb_control; /* offset 0x5C - TLB_CTRL_* */ 421 u8 res07[3]; 422 vintr_t _vintr; /* offset 0x60 - cleanbit 3 */ 423 intstat_t int_stat; /* offset 0x68 */ 424 u64 exitcode; /* offset 0x70 */ 425 union { 426 struct { 427 uint64_t exitinfo1; /* offset 0x78 */ 428 uint64_t exitinfo2; /* offset 0x80 */ 429 }; 430 union { 431 struct { 432 uint16_t sel; 433 uint64_t :48; 434 435 uint32_t ec; 436 uint32_t :4; 437 bool iret:1; 438 uint32_t :1; 439 bool jmp:1; 440 uint32_t :5; 441 bool ev:1; 442 uint32_t :3; 443 bool rf:1; 444 } task_switch; 445 } ei; 446 }; 447 intinfo_t exit_int_info; /* offset 0x88 */ 448 union { /* offset 0x90 - cleanbit 4 */ 449 struct { 450 bool _np_enable :1; 451 bool _sev_enable :1; 452 bool _sev_es_enable :1; 453 bool _gmet :1; 454 bool :1; 455 bool _vte :1; 456 }; 457 uint64_t _np_ctrl; 458 }; 459 u64 res08[2]; 460 intinfo_t event_inj; /* offset 0xA8 */ 461 u64 _h_cr3; /* offset 0xB0 - cleanbit 4 */ 462 virt_ext_t virt_ext; /* offset 0xB8 */ 463 vmcbcleanbits_t cleanbits; /* offset 0xC0 */ 464 u32 res09; /* offset 0xC4 */ 465 u64 nextrip; /* offset 0xC8 */ 466 u8 guest_ins_len; /* offset 0xD0 */ 467 u8 guest_ins[15]; /* offset 0xD1 */ 468 u64 res10a[100]; /* offset 0xE0 pad to save area */ 469 470 union { 471 struct segment_register sreg[6]; 472 struct { 473 struct segment_register es; /* offset 0x400 - cleanbit 8 */ 474 struct segment_register cs; /* cleanbit 8 */ 475 struct segment_register ss; /* cleanbit 8 */ 476 struct segment_register ds; /* cleanbit 8 */ 477 struct segment_register fs; 478 struct segment_register gs; 479 }; 480 }; 481 struct segment_register gdtr; /* cleanbit 7 */ 482 struct segment_register ldtr; 483 struct segment_register idtr; /* cleanbit 7 */ 484 struct segment_register tr; 485 u64 res10[5]; 486 u8 res11[3]; 487 u8 _cpl; /* cleanbit 8 */ 488 u32 res12; 489 u64 _efer; /* offset 0x400 + 0xD0 - cleanbit 5 */ 490 u64 res13[14]; 491 u64 _cr4; /* offset 0x400 + 0x148 - cleanbit 5 */ 492 u64 _cr3; /* cleanbit 5 */ 493 u64 _cr0; /* cleanbit 5 */ 494 u64 _dr7; /* cleanbit 6 */ 495 u64 _dr6; /* cleanbit 6 */ 496 u64 rflags; 497 u64 rip; 498 u64 res14[11]; 499 u64 rsp; 500 u64 res15[3]; 501 u64 rax; 502 u64 star; 503 u64 lstar; 504 u64 cstar; 505 u64 sfmask; 506 u64 kerngsbase; 507 u64 sysenter_cs; 508 u64 sysenter_esp; 509 u64 sysenter_eip; 510 u64 _cr2; /* cleanbit 9 */ 511 u64 res16[4]; 512 u64 _g_pat; /* cleanbit 4 */ 513 u64 _debugctlmsr; /* cleanbit 10 */ 514 u64 _lastbranchfromip; /* cleanbit 10 */ 515 u64 _lastbranchtoip; /* cleanbit 10 */ 516 u64 _lastintfromip; /* cleanbit 10 */ 517 u64 _lastinttoip; /* cleanbit 10 */ 518 u64 res17[301]; 519 }; 520 521 struct svm_domain { 522 /* OSVW MSRs */ 523 union { 524 uint64_t raw[2]; 525 struct { 526 uint64_t length; 527 uint64_t status; 528 }; 529 } osvw; 530 }; 531 532 /* 533 * VMRUN doesn't switch fs/gs/tr/ldtr and SHADOWGS/SYSCALL/SYSENTER state. 534 * Therefore, guest state is in the hardware registers when servicing a 535 * VMExit. 536 * 537 * Immediately after a VMExit, the vmcb is stale, and needs to be brought 538 * into sync by VMSAVE. If state in the vmcb is modified, a VMLOAD is 539 * needed before the following VMRUN. 540 */ 541 enum vmcb_sync_state { 542 vmcb_in_sync, 543 vmcb_needs_vmsave, /* VMCB out of sync (VMSAVE needed)? */ 544 vmcb_needs_vmload /* VMCB dirty (VMLOAD needed)? */ 545 }; 546 547 struct svm_vcpu { 548 struct vmcb_struct *vmcb; 549 u64 vmcb_pa; 550 unsigned long *msrpm; 551 int launch_core; 552 553 uint8_t vmcb_sync_state; /* enum vmcb_sync_state */ 554 555 /* VMCB has a cached instruction from #PF/#NPF Decode Assist? */ 556 uint8_t cached_insn_len; /* Zero if no cached instruction. */ 557 558 /* Upper four bytes are undefined in the VMCB, therefore we can't 559 * use the fields in the VMCB. Write a 64bit value and then read a 64bit 560 * value is fine unless there's a VMRUN/VMEXIT in between which clears 561 * the upper four bytes. 562 */ 563 uint64_t guest_sysenter_cs; 564 uint64_t guest_sysenter_esp; 565 uint64_t guest_sysenter_eip; 566 }; 567 568 struct vmcb_struct *alloc_vmcb(void); 569 void free_vmcb(struct vmcb_struct *vmcb); 570 571 int svm_create_vmcb(struct vcpu *v); 572 void svm_destroy_vmcb(struct vcpu *v); 573 574 void setup_vmcb_dump(void); 575 576 #define MSR_INTERCEPT_NONE 0 577 #define MSR_INTERCEPT_READ 1 578 #define MSR_INTERCEPT_WRITE 2 579 #define MSR_INTERCEPT_RW (MSR_INTERCEPT_WRITE | MSR_INTERCEPT_READ) 580 void svm_intercept_msr(struct vcpu *v, uint32_t msr, int enable); 581 #define svm_disable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), MSR_INTERCEPT_NONE) 582 #define svm_enable_intercept_for_msr(v, msr) svm_intercept_msr((v), (msr), MSR_INTERCEPT_RW) 583 584 /* 585 * VMCB accessor functions. 586 */ 587 588 #define VMCB_ACCESSORS_(name, type, cleanbit) \ 589 static inline void \ 590 vmcb_set_ ## name(struct vmcb_struct *vmcb, \ 591 type value) \ 592 { \ 593 vmcb->_ ## name = value; \ 594 vmcb->cleanbits.cleanbit = false; \ 595 } \ 596 static inline type \ 597 vmcb_get_ ## name(const struct vmcb_struct *vmcb) \ 598 { \ 599 return vmcb->_ ## name; \ 600 } 601 602 #define VMCB_ACCESSORS(name, cleanbit) \ 603 VMCB_ACCESSORS_(name, typeof(alloc_vmcb()->_ ## name), cleanbit) 604 605 VMCB_ACCESSORS(cr_intercepts, intercepts) 606 VMCB_ACCESSORS(dr_intercepts, intercepts) 607 VMCB_ACCESSORS(exception_intercepts, intercepts) 608 VMCB_ACCESSORS(general1_intercepts, intercepts) 609 VMCB_ACCESSORS(general2_intercepts, intercepts) 610 VMCB_ACCESSORS(pause_filter_count, intercepts) 611 VMCB_ACCESSORS(pause_filter_thresh, intercepts) 612 VMCB_ACCESSORS(tsc_offset, intercepts) 613 VMCB_ACCESSORS(iopm_base_pa, iopm) 614 VMCB_ACCESSORS(msrpm_base_pa, iopm) 615 VMCB_ACCESSORS(guest_asid, asid) 616 VMCB_ACCESSORS(vintr, tpr) 617 VMCB_ACCESSORS(np_ctrl, np) 618 VMCB_ACCESSORS_(np_enable, bool, np) 619 VMCB_ACCESSORS_(sev_enable, bool, np) 620 VMCB_ACCESSORS_(sev_es_enable, bool, np) 621 VMCB_ACCESSORS_(gmet, bool, np) 622 VMCB_ACCESSORS_(vte, bool, np) 623 VMCB_ACCESSORS(h_cr3, np) 624 VMCB_ACCESSORS(g_pat, np) 625 VMCB_ACCESSORS(cr0, cr) 626 VMCB_ACCESSORS(cr3, cr) 627 VMCB_ACCESSORS(cr4, cr) 628 VMCB_ACCESSORS(efer, cr) 629 VMCB_ACCESSORS(dr6, dr) 630 VMCB_ACCESSORS(dr7, dr) 631 VMCB_ACCESSORS(cpl, seg) 632 VMCB_ACCESSORS(cr2, cr2) 633 VMCB_ACCESSORS(debugctlmsr, lbr) 634 VMCB_ACCESSORS(lastbranchfromip, lbr) 635 VMCB_ACCESSORS(lastbranchtoip, lbr) 636 VMCB_ACCESSORS(lastintfromip, lbr) 637 VMCB_ACCESSORS(lastinttoip, lbr) 638 639 #undef VMCB_ACCESSORS 640 641 #endif /* ASM_X86_HVM_SVM_VMCS_H__ */ 642 643 /* 644 * Local variables: 645 * mode: C 646 * c-file-style: "BSD" 647 * c-basic-offset: 4 648 * tab-width: 4 649 * indent-tabs-mode: nil 650 * End: 651 */ 652