| 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | #ifndef __SVM_H |
| 3 | #define __SVM_H |
| 4 | |
| 5 | #include <uapi/asm/svm.h> |
| 6 | #include <uapi/asm/kvm.h> |
| 7 | |
| 8 | #include <hyperv/hvhdk.h> |
| 9 | |
| 10 | /* |
| 11 | * 32-bit intercept words in the VMCB Control Area, starting |
| 12 | * at Byte offset 000h. |
| 13 | */ |
| 14 | |
| 15 | enum intercept_words { |
| 16 | INTERCEPT_CR = 0, |
| 17 | INTERCEPT_DR, |
| 18 | INTERCEPT_EXCEPTION, |
| 19 | INTERCEPT_WORD3, |
| 20 | INTERCEPT_WORD4, |
| 21 | INTERCEPT_WORD5, |
| 22 | MAX_INTERCEPT, |
| 23 | }; |
| 24 | |
| 25 | enum { |
| 26 | /* Byte offset 000h (word 0) */ |
| 27 | INTERCEPT_CR0_READ = 0, |
| 28 | INTERCEPT_CR3_READ = 3, |
| 29 | INTERCEPT_CR4_READ = 4, |
| 30 | INTERCEPT_CR8_READ = 8, |
| 31 | INTERCEPT_CR0_WRITE = 16, |
| 32 | INTERCEPT_CR3_WRITE = 16 + 3, |
| 33 | INTERCEPT_CR4_WRITE = 16 + 4, |
| 34 | INTERCEPT_CR8_WRITE = 16 + 8, |
| 35 | /* Byte offset 004h (word 1) */ |
| 36 | INTERCEPT_DR0_READ = 32, |
| 37 | INTERCEPT_DR1_READ, |
| 38 | INTERCEPT_DR2_READ, |
| 39 | INTERCEPT_DR3_READ, |
| 40 | INTERCEPT_DR4_READ, |
| 41 | INTERCEPT_DR5_READ, |
| 42 | INTERCEPT_DR6_READ, |
| 43 | INTERCEPT_DR7_READ, |
| 44 | INTERCEPT_DR0_WRITE = 48, |
| 45 | INTERCEPT_DR1_WRITE, |
| 46 | INTERCEPT_DR2_WRITE, |
| 47 | INTERCEPT_DR3_WRITE, |
| 48 | INTERCEPT_DR4_WRITE, |
| 49 | INTERCEPT_DR5_WRITE, |
| 50 | INTERCEPT_DR6_WRITE, |
| 51 | INTERCEPT_DR7_WRITE, |
| 52 | /* Byte offset 008h (word 2) */ |
| 53 | INTERCEPT_EXCEPTION_OFFSET = 64, |
| 54 | /* Byte offset 00Ch (word 3) */ |
| 55 | INTERCEPT_INTR = 96, |
| 56 | INTERCEPT_NMI, |
| 57 | INTERCEPT_SMI, |
| 58 | INTERCEPT_INIT, |
| 59 | INTERCEPT_VINTR, |
| 60 | INTERCEPT_SELECTIVE_CR0, |
| 61 | INTERCEPT_STORE_IDTR, |
| 62 | INTERCEPT_STORE_GDTR, |
| 63 | INTERCEPT_STORE_LDTR, |
| 64 | INTERCEPT_STORE_TR, |
| 65 | INTERCEPT_LOAD_IDTR, |
| 66 | INTERCEPT_LOAD_GDTR, |
| 67 | INTERCEPT_LOAD_LDTR, |
| 68 | INTERCEPT_LOAD_TR, |
| 69 | INTERCEPT_RDTSC, |
| 70 | INTERCEPT_RDPMC, |
| 71 | INTERCEPT_PUSHF, |
| 72 | INTERCEPT_POPF, |
| 73 | INTERCEPT_CPUID, |
| 74 | INTERCEPT_RSM, |
| 75 | INTERCEPT_IRET, |
| 76 | INTERCEPT_INTn, |
| 77 | INTERCEPT_INVD, |
| 78 | INTERCEPT_PAUSE, |
| 79 | INTERCEPT_HLT, |
| 80 | INTERCEPT_INVLPG, |
| 81 | INTERCEPT_INVLPGA, |
| 82 | INTERCEPT_IOIO_PROT, |
| 83 | INTERCEPT_MSR_PROT, |
| 84 | INTERCEPT_TASK_SWITCH, |
| 85 | INTERCEPT_FERR_FREEZE, |
| 86 | INTERCEPT_SHUTDOWN, |
| 87 | /* Byte offset 010h (word 4) */ |
| 88 | INTERCEPT_VMRUN = 128, |
| 89 | INTERCEPT_VMMCALL, |
| 90 | INTERCEPT_VMLOAD, |
| 91 | INTERCEPT_VMSAVE, |
| 92 | INTERCEPT_STGI, |
| 93 | INTERCEPT_CLGI, |
| 94 | INTERCEPT_SKINIT, |
| 95 | INTERCEPT_RDTSCP, |
| 96 | INTERCEPT_ICEBP, |
| 97 | INTERCEPT_WBINVD, |
| 98 | INTERCEPT_MONITOR, |
| 99 | INTERCEPT_MWAIT, |
| 100 | INTERCEPT_MWAIT_COND, |
| 101 | INTERCEPT_XSETBV, |
| 102 | INTERCEPT_RDPRU, |
| 103 | TRAP_EFER_WRITE, |
| 104 | TRAP_CR0_WRITE, |
| 105 | TRAP_CR1_WRITE, |
| 106 | TRAP_CR2_WRITE, |
| 107 | TRAP_CR3_WRITE, |
| 108 | TRAP_CR4_WRITE, |
| 109 | TRAP_CR5_WRITE, |
| 110 | TRAP_CR6_WRITE, |
| 111 | TRAP_CR7_WRITE, |
| 112 | TRAP_CR8_WRITE, |
| 113 | /* Byte offset 014h (word 5) */ |
| 114 | INTERCEPT_INVLPGB = 160, |
| 115 | INTERCEPT_INVLPGB_ILLEGAL, |
| 116 | INTERCEPT_INVPCID, |
| 117 | INTERCEPT_MCOMMIT, |
| 118 | INTERCEPT_TLBSYNC, |
| 119 | INTERCEPT_BUSLOCK, |
| 120 | INTERCEPT_IDLE_HLT = 166, |
| 121 | }; |
| 122 | |
| 123 | |
| 124 | struct __attribute__ ((__packed__)) vmcb_control_area { |
| 125 | u32 intercepts[MAX_INTERCEPT]; |
| 126 | u32 reserved_1[15 - MAX_INTERCEPT]; |
| 127 | u16 pause_filter_thresh; |
| 128 | u16 pause_filter_count; |
| 129 | u64 iopm_base_pa; |
| 130 | u64 msrpm_base_pa; |
| 131 | u64 tsc_offset; |
| 132 | u32 asid; |
| 133 | u8 tlb_ctl; |
| 134 | u8 reserved_2[3]; |
| 135 | u32 int_ctl; |
| 136 | u32 int_vector; |
| 137 | u32 int_state; |
| 138 | u8 reserved_3[4]; |
| 139 | u32 exit_code; |
| 140 | u32 exit_code_hi; |
| 141 | u64 exit_info_1; |
| 142 | u64 exit_info_2; |
| 143 | u32 exit_int_info; |
| 144 | u32 exit_int_info_err; |
| 145 | u64 nested_ctl; |
| 146 | u64 avic_vapic_bar; |
| 147 | u64 ghcb_gpa; |
| 148 | u32 event_inj; |
| 149 | u32 event_inj_err; |
| 150 | u64 nested_cr3; |
| 151 | u64 virt_ext; |
| 152 | u32 clean; |
| 153 | u32 reserved_5; |
| 154 | u64 next_rip; |
| 155 | u8 insn_len; |
| 156 | u8 insn_bytes[15]; |
| 157 | u64 avic_backing_page; /* Offset 0xe0 */ |
| 158 | u8 reserved_6[8]; /* Offset 0xe8 */ |
| 159 | u64 avic_logical_id; /* Offset 0xf0 */ |
| 160 | u64 avic_physical_id; /* Offset 0xf8 */ |
| 161 | u8 reserved_7[8]; |
| 162 | u64 vmsa_pa; /* Used for an SEV-ES guest */ |
| 163 | u8 reserved_8[16]; |
| 164 | u16 bus_lock_counter; /* Offset 0x120 */ |
| 165 | u8 reserved_9[22]; |
| 166 | u64 allowed_sev_features; /* Offset 0x138 */ |
| 167 | u64 guest_sev_features; /* Offset 0x140 */ |
| 168 | u8 reserved_10[664]; |
| 169 | /* |
| 170 | * Offset 0x3e0, 32 bytes reserved |
| 171 | * for use by hypervisor/software. |
| 172 | */ |
| 173 | union { |
| 174 | struct hv_vmcb_enlightenments hv_enlightenments; |
| 175 | u8 reserved_sw[32]; |
| 176 | }; |
| 177 | }; |
| 178 | |
| 179 | |
| 180 | #define TLB_CONTROL_DO_NOTHING 0 |
| 181 | #define TLB_CONTROL_FLUSH_ALL_ASID 1 |
| 182 | #define TLB_CONTROL_FLUSH_ASID 3 |
| 183 | #define TLB_CONTROL_FLUSH_ASID_LOCAL 7 |
| 184 | |
| 185 | #define V_TPR_MASK 0x0f |
| 186 | |
| 187 | #define V_IRQ_SHIFT 8 |
| 188 | #define V_IRQ_MASK (1 << V_IRQ_SHIFT) |
| 189 | |
| 190 | #define V_GIF_SHIFT 9 |
| 191 | #define V_GIF_MASK (1 << V_GIF_SHIFT) |
| 192 | |
| 193 | #define V_NMI_PENDING_SHIFT 11 |
| 194 | #define V_NMI_PENDING_MASK (1 << V_NMI_PENDING_SHIFT) |
| 195 | |
| 196 | #define V_NMI_BLOCKING_SHIFT 12 |
| 197 | #define V_NMI_BLOCKING_MASK (1 << V_NMI_BLOCKING_SHIFT) |
| 198 | |
| 199 | #define V_INTR_PRIO_SHIFT 16 |
| 200 | #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT) |
| 201 | |
| 202 | #define V_IGN_TPR_SHIFT 20 |
| 203 | #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT) |
| 204 | |
| 205 | #define V_IRQ_INJECTION_BITS_MASK (V_IRQ_MASK | V_INTR_PRIO_MASK | V_IGN_TPR_MASK) |
| 206 | |
| 207 | #define V_INTR_MASKING_SHIFT 24 |
| 208 | #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT) |
| 209 | |
| 210 | #define V_GIF_ENABLE_SHIFT 25 |
| 211 | #define V_GIF_ENABLE_MASK (1 << V_GIF_ENABLE_SHIFT) |
| 212 | |
| 213 | #define V_NMI_ENABLE_SHIFT 26 |
| 214 | #define V_NMI_ENABLE_MASK (1 << V_NMI_ENABLE_SHIFT) |
| 215 | |
| 216 | #define AVIC_ENABLE_SHIFT 31 |
| 217 | #define AVIC_ENABLE_MASK (1 << AVIC_ENABLE_SHIFT) |
| 218 | |
| 219 | #define X2APIC_MODE_SHIFT 30 |
| 220 | #define X2APIC_MODE_MASK (1 << X2APIC_MODE_SHIFT) |
| 221 | |
| 222 | #define LBR_CTL_ENABLE_MASK BIT_ULL(0) |
| 223 | #define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1) |
| 224 | |
| 225 | #define SVM_INTERRUPT_SHADOW_MASK BIT_ULL(0) |
| 226 | #define SVM_GUEST_INTERRUPT_MASK BIT_ULL(1) |
| 227 | |
| 228 | #define SVM_IOIO_STR_SHIFT 2 |
| 229 | #define SVM_IOIO_REP_SHIFT 3 |
| 230 | #define SVM_IOIO_SIZE_SHIFT 4 |
| 231 | #define SVM_IOIO_ASIZE_SHIFT 7 |
| 232 | |
| 233 | #define SVM_IOIO_TYPE_MASK 1 |
| 234 | #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT) |
| 235 | #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT) |
| 236 | #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT) |
| 237 | #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT) |
| 238 | |
| 239 | #define SVM_NESTED_CTL_NP_ENABLE BIT(0) |
| 240 | #define SVM_NESTED_CTL_SEV_ENABLE BIT(1) |
| 241 | #define SVM_NESTED_CTL_SEV_ES_ENABLE BIT(2) |
| 242 | |
| 243 | |
| 244 | #define SVM_TSC_RATIO_RSVD 0xffffff0000000000ULL |
| 245 | #define SVM_TSC_RATIO_MIN 0x0000000000000001ULL |
| 246 | #define SVM_TSC_RATIO_MAX 0x000000ffffffffffULL |
| 247 | #define SVM_TSC_RATIO_DEFAULT 0x0100000000ULL |
| 248 | |
| 249 | |
| 250 | /* AVIC */ |
| 251 | #define AVIC_LOGICAL_ID_ENTRY_GUEST_PHYSICAL_ID_MASK (0xFFULL) |
| 252 | #define AVIC_LOGICAL_ID_ENTRY_VALID_BIT 31 |
| 253 | #define AVIC_LOGICAL_ID_ENTRY_VALID_MASK (1 << 31) |
| 254 | |
| 255 | /* |
| 256 | * GA_LOG_INTR is a synthetic flag that's never propagated to hardware-visible |
| 257 | * tables. GA_LOG_INTR is set if the vCPU needs device posted IRQs to generate |
| 258 | * GA log interrupts to wake the vCPU (because it's blocking or about to block). |
| 259 | */ |
| 260 | #define AVIC_PHYSICAL_ID_ENTRY_GA_LOG_INTR BIT_ULL(61) |
| 261 | |
| 262 | #define AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK GENMASK_ULL(11, 0) |
| 263 | #define AVIC_PHYSICAL_ID_ENTRY_BACKING_PAGE_MASK GENMASK_ULL(51, 12) |
| 264 | #define AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK (1ULL << 62) |
| 265 | #define AVIC_PHYSICAL_ID_ENTRY_VALID_MASK (1ULL << 63) |
| 266 | #define AVIC_PHYSICAL_ID_TABLE_SIZE_MASK (0xFFULL) |
| 267 | |
| 268 | #define AVIC_DOORBELL_PHYSICAL_ID_MASK GENMASK_ULL(11, 0) |
| 269 | |
| 270 | #define AVIC_UNACCEL_ACCESS_WRITE_MASK 1 |
| 271 | #define AVIC_UNACCEL_ACCESS_OFFSET_MASK 0xFF0 |
| 272 | #define AVIC_UNACCEL_ACCESS_VECTOR_MASK 0xFFFFFFFF |
| 273 | |
| 274 | enum avic_ipi_failure_cause { |
| 275 | AVIC_IPI_FAILURE_INVALID_INT_TYPE, |
| 276 | AVIC_IPI_FAILURE_TARGET_NOT_RUNNING, |
| 277 | AVIC_IPI_FAILURE_INVALID_TARGET, |
| 278 | AVIC_IPI_FAILURE_INVALID_BACKING_PAGE, |
| 279 | AVIC_IPI_FAILURE_INVALID_IPI_VECTOR, |
| 280 | }; |
| 281 | |
| 282 | #define AVIC_PHYSICAL_MAX_INDEX_MASK GENMASK_ULL(11, 0) |
| 283 | |
| 284 | /* |
| 285 | * For AVIC, the max index allowed for physical APIC ID table is 0xfe (254), as |
| 286 | * 0xff is a broadcast to all CPUs, i.e. can't be targeted individually. |
| 287 | */ |
| 288 | #define AVIC_MAX_PHYSICAL_ID 0XFEULL |
| 289 | |
| 290 | /* |
| 291 | * For x2AVIC, the max index allowed for physical APIC ID table is 0x1ff (511). |
| 292 | * With X86_FEATURE_X2AVIC_EXT, the max index is increased to 0xfff (4095). |
| 293 | */ |
| 294 | #define X2AVIC_MAX_PHYSICAL_ID 0x1FFUL |
| 295 | #define X2AVIC_4K_MAX_PHYSICAL_ID 0xFFFUL |
| 296 | |
| 297 | static_assert((AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == AVIC_MAX_PHYSICAL_ID); |
| 298 | static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_MAX_PHYSICAL_ID); |
| 299 | static_assert((X2AVIC_4K_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_4K_MAX_PHYSICAL_ID); |
| 300 | |
| 301 | #define SVM_SEV_FEAT_SNP_ACTIVE BIT(0) |
| 302 | #define SVM_SEV_FEAT_RESTRICTED_INJECTION BIT(3) |
| 303 | #define SVM_SEV_FEAT_ALTERNATE_INJECTION BIT(4) |
| 304 | #define SVM_SEV_FEAT_DEBUG_SWAP BIT(5) |
| 305 | #define SVM_SEV_FEAT_SECURE_TSC BIT(9) |
| 306 | |
| 307 | #define VMCB_ALLOWED_SEV_FEATURES_VALID BIT_ULL(63) |
| 308 | |
| 309 | struct vmcb_seg { |
| 310 | u16 selector; |
| 311 | u16 attrib; |
| 312 | u32 limit; |
| 313 | u64 base; |
| 314 | } __packed; |
| 315 | |
| 316 | /* Save area definition for legacy and SEV-MEM guests */ |
| 317 | struct vmcb_save_area { |
| 318 | struct vmcb_seg es; |
| 319 | struct vmcb_seg cs; |
| 320 | struct vmcb_seg ss; |
| 321 | struct vmcb_seg ds; |
| 322 | struct vmcb_seg fs; |
| 323 | struct vmcb_seg gs; |
| 324 | struct vmcb_seg gdtr; |
| 325 | struct vmcb_seg ldtr; |
| 326 | struct vmcb_seg idtr; |
| 327 | struct vmcb_seg tr; |
| 328 | /* Reserved fields are named following their struct offset */ |
| 329 | u8 reserved_0xa0[42]; |
| 330 | u8 vmpl; |
| 331 | u8 cpl; |
| 332 | u8 reserved_0xcc[4]; |
| 333 | u64 efer; |
| 334 | u8 reserved_0xd8[112]; |
| 335 | u64 cr4; |
| 336 | u64 cr3; |
| 337 | u64 cr0; |
| 338 | u64 dr7; |
| 339 | u64 dr6; |
| 340 | u64 rflags; |
| 341 | u64 rip; |
| 342 | u8 reserved_0x180[88]; |
| 343 | u64 rsp; |
| 344 | u64 s_cet; |
| 345 | u64 ssp; |
| 346 | u64 isst_addr; |
| 347 | u64 rax; |
| 348 | u64 star; |
| 349 | u64 lstar; |
| 350 | u64 cstar; |
| 351 | u64 sfmask; |
| 352 | u64 kernel_gs_base; |
| 353 | u64 sysenter_cs; |
| 354 | u64 sysenter_esp; |
| 355 | u64 sysenter_eip; |
| 356 | u64 cr2; |
| 357 | u8 reserved_0x248[32]; |
| 358 | u64 g_pat; |
| 359 | u64 dbgctl; |
| 360 | u64 br_from; |
| 361 | u64 br_to; |
| 362 | u64 last_excp_from; |
| 363 | u64 last_excp_to; |
| 364 | u8 reserved_0x298[72]; |
| 365 | u64 spec_ctrl; /* Guest version of SPEC_CTRL at 0x2E0 */ |
| 366 | } __packed; |
| 367 | |
| 368 | /* Save area definition for SEV-ES and SEV-SNP guests */ |
| 369 | struct sev_es_save_area { |
| 370 | struct vmcb_seg es; |
| 371 | struct vmcb_seg cs; |
| 372 | struct vmcb_seg ss; |
| 373 | struct vmcb_seg ds; |
| 374 | struct vmcb_seg fs; |
| 375 | struct vmcb_seg gs; |
| 376 | struct vmcb_seg gdtr; |
| 377 | struct vmcb_seg ldtr; |
| 378 | struct vmcb_seg idtr; |
| 379 | struct vmcb_seg tr; |
| 380 | u64 pl0_ssp; |
| 381 | u64 pl1_ssp; |
| 382 | u64 pl2_ssp; |
| 383 | u64 pl3_ssp; |
| 384 | u64 u_cet; |
| 385 | u8 reserved_0xc8[2]; |
| 386 | u8 vmpl; |
| 387 | u8 cpl; |
| 388 | u8 reserved_0xcc[4]; |
| 389 | u64 efer; |
| 390 | u8 reserved_0xd8[104]; |
| 391 | u64 xss; |
| 392 | u64 cr4; |
| 393 | u64 cr3; |
| 394 | u64 cr0; |
| 395 | u64 dr7; |
| 396 | u64 dr6; |
| 397 | u64 rflags; |
| 398 | u64 rip; |
| 399 | u64 dr0; |
| 400 | u64 dr1; |
| 401 | u64 dr2; |
| 402 | u64 dr3; |
| 403 | u64 dr0_addr_mask; |
| 404 | u64 dr1_addr_mask; |
| 405 | u64 dr2_addr_mask; |
| 406 | u64 dr3_addr_mask; |
| 407 | u8 reserved_0x1c0[24]; |
| 408 | u64 rsp; |
| 409 | u64 s_cet; |
| 410 | u64 ssp; |
| 411 | u64 isst_addr; |
| 412 | u64 rax; |
| 413 | u64 star; |
| 414 | u64 lstar; |
| 415 | u64 cstar; |
| 416 | u64 sfmask; |
| 417 | u64 kernel_gs_base; |
| 418 | u64 sysenter_cs; |
| 419 | u64 sysenter_esp; |
| 420 | u64 sysenter_eip; |
| 421 | u64 cr2; |
| 422 | u8 reserved_0x248[32]; |
| 423 | u64 g_pat; |
| 424 | u64 dbgctl; |
| 425 | u64 br_from; |
| 426 | u64 br_to; |
| 427 | u64 last_excp_from; |
| 428 | u64 last_excp_to; |
| 429 | u8 reserved_0x298[80]; |
| 430 | u32 pkru; |
| 431 | u32 tsc_aux; |
| 432 | u64 tsc_scale; |
| 433 | u64 tsc_offset; |
| 434 | u8 reserved_0x300[8]; |
| 435 | u64 rcx; |
| 436 | u64 rdx; |
| 437 | u64 rbx; |
| 438 | u64 reserved_0x320; /* rsp already available at 0x01d8 */ |
| 439 | u64 rbp; |
| 440 | u64 rsi; |
| 441 | u64 rdi; |
| 442 | u64 r8; |
| 443 | u64 r9; |
| 444 | u64 r10; |
| 445 | u64 r11; |
| 446 | u64 r12; |
| 447 | u64 r13; |
| 448 | u64 r14; |
| 449 | u64 r15; |
| 450 | u8 reserved_0x380[16]; |
| 451 | u64 guest_exit_info_1; |
| 452 | u64 guest_exit_info_2; |
| 453 | u64 guest_exit_int_info; |
| 454 | u64 guest_nrip; |
| 455 | u64 sev_features; |
| 456 | u64 vintr_ctrl; |
| 457 | u64 guest_exit_code; |
| 458 | u64 virtual_tom; |
| 459 | u64 tlb_id; |
| 460 | u64 pcpu_id; |
| 461 | u64 event_inj; |
| 462 | u64 xcr0; |
| 463 | u8 reserved_0x3f0[16]; |
| 464 | |
| 465 | /* Floating point area */ |
| 466 | u64 x87_dp; |
| 467 | u32 mxcsr; |
| 468 | u16 x87_ftw; |
| 469 | u16 x87_fsw; |
| 470 | u16 x87_fcw; |
| 471 | u16 x87_fop; |
| 472 | u16 x87_ds; |
| 473 | u16 x87_cs; |
| 474 | u64 x87_rip; |
| 475 | u8 fpreg_x87[80]; |
| 476 | u8 fpreg_xmm[256]; |
| 477 | u8 fpreg_ymm[256]; |
| 478 | } __packed; |
| 479 | |
| 480 | struct ghcb_save_area { |
| 481 | u8 reserved_0x0[203]; |
| 482 | u8 cpl; |
| 483 | u8 reserved_0xcc[116]; |
| 484 | u64 xss; |
| 485 | u8 reserved_0x148[24]; |
| 486 | u64 dr7; |
| 487 | u8 reserved_0x168[16]; |
| 488 | u64 rip; |
| 489 | u8 reserved_0x180[88]; |
| 490 | u64 rsp; |
| 491 | u8 reserved_0x1e0[24]; |
| 492 | u64 rax; |
| 493 | u8 reserved_0x200[264]; |
| 494 | u64 rcx; |
| 495 | u64 rdx; |
| 496 | u64 rbx; |
| 497 | u8 reserved_0x320[8]; |
| 498 | u64 rbp; |
| 499 | u64 rsi; |
| 500 | u64 rdi; |
| 501 | u64 r8; |
| 502 | u64 r9; |
| 503 | u64 r10; |
| 504 | u64 r11; |
| 505 | u64 r12; |
| 506 | u64 r13; |
| 507 | u64 r14; |
| 508 | u64 r15; |
| 509 | u8 reserved_0x380[16]; |
| 510 | u64 sw_exit_code; |
| 511 | u64 sw_exit_info_1; |
| 512 | u64 sw_exit_info_2; |
| 513 | u64 sw_scratch; |
| 514 | u8 reserved_0x3b0[56]; |
| 515 | u64 xcr0; |
| 516 | u8 valid_bitmap[16]; |
| 517 | u64 x87_state_gpa; |
| 518 | } __packed; |
| 519 | |
| 520 | #define GHCB_SHARED_BUF_SIZE 2032 |
| 521 | |
| 522 | struct ghcb { |
| 523 | struct ghcb_save_area save; |
| 524 | u8 reserved_save[2048 - sizeof(struct ghcb_save_area)]; |
| 525 | |
| 526 | u8 shared_buffer[GHCB_SHARED_BUF_SIZE]; |
| 527 | |
| 528 | u8 reserved_0xff0[10]; |
| 529 | u16 protocol_version; /* negotiated SEV-ES/GHCB protocol version */ |
| 530 | u32 ghcb_usage; |
| 531 | } __packed; |
| 532 | |
| 533 | struct vmcb { |
| 534 | struct vmcb_control_area control; |
| 535 | union { |
| 536 | struct vmcb_save_area save; |
| 537 | |
| 538 | /* |
| 539 | * For SEV-ES VMs, the save area in the VMCB is used only to |
| 540 | * save/load host state. Guest state resides in a separate |
| 541 | * page, the aptly named VM Save Area (VMSA), that is encrypted |
| 542 | * with the guest's private key. |
| 543 | */ |
| 544 | struct sev_es_save_area host_sev_es_save; |
| 545 | }; |
| 546 | } __packed; |
| 547 | |
| 548 | #define EXPECTED_VMCB_SAVE_AREA_SIZE 744 |
| 549 | #define EXPECTED_GHCB_SAVE_AREA_SIZE 1032 |
| 550 | #define EXPECTED_SEV_ES_SAVE_AREA_SIZE 1648 |
| 551 | #define EXPECTED_VMCB_CONTROL_AREA_SIZE 1024 |
| 552 | #define EXPECTED_GHCB_SIZE PAGE_SIZE |
| 553 | |
| 554 | #define BUILD_BUG_RESERVED_OFFSET(x, y) \ |
| 555 | ASSERT_STRUCT_OFFSET(struct x, reserved ## _ ## y, y) |
| 556 | |
| 557 | static inline void __unused_size_checks(void) |
| 558 | { |
| 559 | BUILD_BUG_ON(sizeof(struct vmcb_save_area) != EXPECTED_VMCB_SAVE_AREA_SIZE); |
| 560 | BUILD_BUG_ON(sizeof(struct ghcb_save_area) != EXPECTED_GHCB_SAVE_AREA_SIZE); |
| 561 | BUILD_BUG_ON(sizeof(struct sev_es_save_area) != EXPECTED_SEV_ES_SAVE_AREA_SIZE); |
| 562 | BUILD_BUG_ON(sizeof(struct vmcb_control_area) != EXPECTED_VMCB_CONTROL_AREA_SIZE); |
| 563 | BUILD_BUG_ON(offsetof(struct vmcb, save) != EXPECTED_VMCB_CONTROL_AREA_SIZE); |
| 564 | BUILD_BUG_ON(sizeof(struct ghcb) != EXPECTED_GHCB_SIZE); |
| 565 | |
| 566 | /* Check offsets of reserved fields */ |
| 567 | |
| 568 | BUILD_BUG_RESERVED_OFFSET(vmcb_save_area, 0xa0); |
| 569 | BUILD_BUG_RESERVED_OFFSET(vmcb_save_area, 0xcc); |
| 570 | BUILD_BUG_RESERVED_OFFSET(vmcb_save_area, 0xd8); |
| 571 | BUILD_BUG_RESERVED_OFFSET(vmcb_save_area, 0x180); |
| 572 | BUILD_BUG_RESERVED_OFFSET(vmcb_save_area, 0x248); |
| 573 | BUILD_BUG_RESERVED_OFFSET(vmcb_save_area, 0x298); |
| 574 | |
| 575 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0xc8); |
| 576 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0xcc); |
| 577 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0xd8); |
| 578 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x1c0); |
| 579 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x248); |
| 580 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x298); |
| 581 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x300); |
| 582 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x320); |
| 583 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x380); |
| 584 | BUILD_BUG_RESERVED_OFFSET(sev_es_save_area, 0x3f0); |
| 585 | |
| 586 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x0); |
| 587 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0xcc); |
| 588 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x148); |
| 589 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x168); |
| 590 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x180); |
| 591 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x1e0); |
| 592 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x200); |
| 593 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x320); |
| 594 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x380); |
| 595 | BUILD_BUG_RESERVED_OFFSET(ghcb_save_area, 0x3b0); |
| 596 | |
| 597 | BUILD_BUG_RESERVED_OFFSET(ghcb, 0xff0); |
| 598 | } |
| 599 | |
| 600 | #define SVM_CPUID_FUNC 0x8000000a |
| 601 | |
| 602 | #define SVM_SELECTOR_S_SHIFT 4 |
| 603 | #define SVM_SELECTOR_DPL_SHIFT 5 |
| 604 | #define SVM_SELECTOR_P_SHIFT 7 |
| 605 | #define SVM_SELECTOR_AVL_SHIFT 8 |
| 606 | #define SVM_SELECTOR_L_SHIFT 9 |
| 607 | #define SVM_SELECTOR_DB_SHIFT 10 |
| 608 | #define SVM_SELECTOR_G_SHIFT 11 |
| 609 | |
| 610 | #define SVM_SELECTOR_TYPE_MASK (0xf) |
| 611 | #define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT) |
| 612 | #define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT) |
| 613 | #define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT) |
| 614 | #define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT) |
| 615 | #define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT) |
| 616 | #define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT) |
| 617 | #define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT) |
| 618 | |
| 619 | #define SVM_SELECTOR_WRITE_MASK (1 << 1) |
| 620 | #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK |
| 621 | #define SVM_SELECTOR_CODE_MASK (1 << 3) |
| 622 | |
| 623 | #define SVM_EVTINJ_VEC_MASK 0xff |
| 624 | |
| 625 | #define SVM_EVTINJ_TYPE_SHIFT 8 |
| 626 | #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT) |
| 627 | |
| 628 | #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT) |
| 629 | #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT) |
| 630 | #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT) |
| 631 | #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT) |
| 632 | |
| 633 | #define SVM_EVTINJ_VALID (1 << 31) |
| 634 | #define SVM_EVTINJ_VALID_ERR (1 << 11) |
| 635 | |
| 636 | #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK |
| 637 | #define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK |
| 638 | |
| 639 | #define SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR |
| 640 | #define SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI |
| 641 | #define SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT |
| 642 | #define SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT |
| 643 | |
| 644 | #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID |
| 645 | #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR |
| 646 | |
| 647 | #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36 |
| 648 | #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38 |
| 649 | #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44 |
| 650 | |
| 651 | #define SVM_EXITINFO_REG_MASK 0x0F |
| 652 | |
| 653 | #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) |
| 654 | |
| 655 | /* GHCB Accessor functions */ |
| 656 | |
| 657 | #define GHCB_BITMAP_IDX(field) \ |
| 658 | (offsetof(struct ghcb_save_area, field) / sizeof(u64)) |
| 659 | |
| 660 | #define DEFINE_GHCB_ACCESSORS(field) \ |
| 661 | static __always_inline bool ghcb_##field##_is_valid(const struct ghcb *ghcb) \ |
| 662 | { \ |
| 663 | return test_bit(GHCB_BITMAP_IDX(field), \ |
| 664 | (unsigned long *)&ghcb->save.valid_bitmap); \ |
| 665 | } \ |
| 666 | \ |
| 667 | static __always_inline u64 ghcb_get_##field(struct ghcb *ghcb) \ |
| 668 | { \ |
| 669 | return ghcb->save.field; \ |
| 670 | } \ |
| 671 | \ |
| 672 | static __always_inline u64 ghcb_get_##field##_if_valid(struct ghcb *ghcb) \ |
| 673 | { \ |
| 674 | return ghcb_##field##_is_valid(ghcb) ? ghcb->save.field : 0; \ |
| 675 | } \ |
| 676 | \ |
| 677 | static __always_inline void ghcb_set_##field(struct ghcb *ghcb, u64 value) \ |
| 678 | { \ |
| 679 | __set_bit(GHCB_BITMAP_IDX(field), \ |
| 680 | (unsigned long *)&ghcb->save.valid_bitmap); \ |
| 681 | ghcb->save.field = value; \ |
| 682 | } |
| 683 | |
| 684 | DEFINE_GHCB_ACCESSORS(cpl) |
| 685 | DEFINE_GHCB_ACCESSORS(rip) |
| 686 | DEFINE_GHCB_ACCESSORS(rsp) |
| 687 | DEFINE_GHCB_ACCESSORS(rax) |
| 688 | DEFINE_GHCB_ACCESSORS(rcx) |
| 689 | DEFINE_GHCB_ACCESSORS(rdx) |
| 690 | DEFINE_GHCB_ACCESSORS(rbx) |
| 691 | DEFINE_GHCB_ACCESSORS(rbp) |
| 692 | DEFINE_GHCB_ACCESSORS(rsi) |
| 693 | DEFINE_GHCB_ACCESSORS(rdi) |
| 694 | DEFINE_GHCB_ACCESSORS(r8) |
| 695 | DEFINE_GHCB_ACCESSORS(r9) |
| 696 | DEFINE_GHCB_ACCESSORS(r10) |
| 697 | DEFINE_GHCB_ACCESSORS(r11) |
| 698 | DEFINE_GHCB_ACCESSORS(r12) |
| 699 | DEFINE_GHCB_ACCESSORS(r13) |
| 700 | DEFINE_GHCB_ACCESSORS(r14) |
| 701 | DEFINE_GHCB_ACCESSORS(r15) |
| 702 | DEFINE_GHCB_ACCESSORS(sw_exit_code) |
| 703 | DEFINE_GHCB_ACCESSORS(sw_exit_info_1) |
| 704 | DEFINE_GHCB_ACCESSORS(sw_exit_info_2) |
| 705 | DEFINE_GHCB_ACCESSORS(sw_scratch) |
| 706 | DEFINE_GHCB_ACCESSORS(xcr0) |
| 707 | DEFINE_GHCB_ACCESSORS(xss) |
| 708 | |
| 709 | #endif |
| 710 | |