| .. | .. |
|---|
| 3 | 3 | #define __SVM_H |
|---|
| 4 | 4 | |
|---|
| 5 | 5 | #include <uapi/asm/svm.h> |
|---|
| 6 | +#include <uapi/asm/kvm.h> |
|---|
| 6 | 7 | |
|---|
| 8 | +/* |
|---|
| 9 | + * 32-bit intercept words in the VMCB Control Area, starting |
|---|
| 10 | + * at Byte offset 000h. |
|---|
| 11 | + */ |
|---|
| 12 | + |
|---|
| 13 | +enum intercept_words { |
|---|
| 14 | + INTERCEPT_CR = 0, |
|---|
| 15 | + INTERCEPT_DR, |
|---|
| 16 | + INTERCEPT_EXCEPTION, |
|---|
| 17 | + INTERCEPT_WORD3, |
|---|
| 18 | + INTERCEPT_WORD4, |
|---|
| 19 | + INTERCEPT_WORD5, |
|---|
| 20 | + MAX_INTERCEPT, |
|---|
| 21 | +}; |
|---|
| 7 | 22 | |
|---|
| 8 | 23 | enum { |
|---|
| 9 | | - INTERCEPT_INTR, |
|---|
| 24 | + /* Byte offset 000h (word 0) */ |
|---|
| 25 | + INTERCEPT_CR0_READ = 0, |
|---|
| 26 | + INTERCEPT_CR3_READ = 3, |
|---|
| 27 | + INTERCEPT_CR4_READ = 4, |
|---|
| 28 | + INTERCEPT_CR8_READ = 8, |
|---|
| 29 | + INTERCEPT_CR0_WRITE = 16, |
|---|
| 30 | + INTERCEPT_CR3_WRITE = 16 + 3, |
|---|
| 31 | + INTERCEPT_CR4_WRITE = 16 + 4, |
|---|
| 32 | + INTERCEPT_CR8_WRITE = 16 + 8, |
|---|
| 33 | + /* Byte offset 004h (word 1) */ |
|---|
| 34 | + INTERCEPT_DR0_READ = 32, |
|---|
| 35 | + INTERCEPT_DR1_READ, |
|---|
| 36 | + INTERCEPT_DR2_READ, |
|---|
| 37 | + INTERCEPT_DR3_READ, |
|---|
| 38 | + INTERCEPT_DR4_READ, |
|---|
| 39 | + INTERCEPT_DR5_READ, |
|---|
| 40 | + INTERCEPT_DR6_READ, |
|---|
| 41 | + INTERCEPT_DR7_READ, |
|---|
| 42 | + INTERCEPT_DR0_WRITE = 48, |
|---|
| 43 | + INTERCEPT_DR1_WRITE, |
|---|
| 44 | + INTERCEPT_DR2_WRITE, |
|---|
| 45 | + INTERCEPT_DR3_WRITE, |
|---|
| 46 | + INTERCEPT_DR4_WRITE, |
|---|
| 47 | + INTERCEPT_DR5_WRITE, |
|---|
| 48 | + INTERCEPT_DR6_WRITE, |
|---|
| 49 | + INTERCEPT_DR7_WRITE, |
|---|
| 50 | + /* Byte offset 008h (word 2) */ |
|---|
| 51 | + INTERCEPT_EXCEPTION_OFFSET = 64, |
|---|
| 52 | + /* Byte offset 00Ch (word 3) */ |
|---|
| 53 | + INTERCEPT_INTR = 96, |
|---|
| 10 | 54 | INTERCEPT_NMI, |
|---|
| 11 | 55 | INTERCEPT_SMI, |
|---|
| 12 | 56 | INTERCEPT_INIT, |
|---|
| .. | .. |
|---|
| 38 | 82 | INTERCEPT_TASK_SWITCH, |
|---|
| 39 | 83 | INTERCEPT_FERR_FREEZE, |
|---|
| 40 | 84 | INTERCEPT_SHUTDOWN, |
|---|
| 41 | | - INTERCEPT_VMRUN, |
|---|
| 85 | + /* Byte offset 010h (word 4) */ |
|---|
| 86 | + INTERCEPT_VMRUN = 128, |
|---|
| 42 | 87 | INTERCEPT_VMMCALL, |
|---|
| 43 | 88 | INTERCEPT_VMLOAD, |
|---|
| 44 | 89 | INTERCEPT_VMSAVE, |
|---|
| .. | .. |
|---|
| 52 | 97 | INTERCEPT_MWAIT, |
|---|
| 53 | 98 | INTERCEPT_MWAIT_COND, |
|---|
| 54 | 99 | INTERCEPT_XSETBV, |
|---|
| 100 | + INTERCEPT_RDPRU, |
|---|
| 101 | + /* Byte offset 014h (word 5) */ |
|---|
| 102 | + INTERCEPT_INVLPGB = 160, |
|---|
| 103 | + INTERCEPT_INVLPGB_ILLEGAL, |
|---|
| 104 | + INTERCEPT_INVPCID, |
|---|
| 105 | + INTERCEPT_MCOMMIT, |
|---|
| 106 | + INTERCEPT_TLBSYNC, |
|---|
| 55 | 107 | }; |
|---|
| 56 | 108 | |
|---|
| 57 | 109 | |
|---|
| 58 | 110 | struct __attribute__ ((__packed__)) vmcb_control_area { |
|---|
| 59 | | - u32 intercept_cr; |
|---|
| 60 | | - u32 intercept_dr; |
|---|
| 61 | | - u32 intercept_exceptions; |
|---|
| 62 | | - u64 intercept; |
|---|
| 63 | | - u8 reserved_1[40]; |
|---|
| 111 | + u32 intercepts[MAX_INTERCEPT]; |
|---|
| 112 | + u32 reserved_1[15 - MAX_INTERCEPT]; |
|---|
| 64 | 113 | u16 pause_filter_thresh; |
|---|
| 65 | 114 | u16 pause_filter_count; |
|---|
| 66 | 115 | u64 iopm_base_pa; |
|---|
| .. | .. |
|---|
| 95 | 144 | u8 reserved_6[8]; /* Offset 0xe8 */ |
|---|
| 96 | 145 | u64 avic_logical_id; /* Offset 0xf0 */ |
|---|
| 97 | 146 | u64 avic_physical_id; /* Offset 0xf8 */ |
|---|
| 98 | | - u8 reserved_7[768]; |
|---|
| 99 | 147 | }; |
|---|
| 100 | 148 | |
|---|
| 101 | 149 | |
|---|
| .. | .. |
|---|
| 152 | 200 | #define SVM_NESTED_CTL_NP_ENABLE BIT(0) |
|---|
| 153 | 201 | #define SVM_NESTED_CTL_SEV_ENABLE BIT(1) |
|---|
| 154 | 202 | |
|---|
| 155 | | -struct __attribute__ ((__packed__)) vmcb_seg { |
|---|
| 203 | +struct vmcb_seg { |
|---|
| 156 | 204 | u16 selector; |
|---|
| 157 | 205 | u16 attrib; |
|---|
| 158 | 206 | u32 limit; |
|---|
| 159 | 207 | u64 base; |
|---|
| 160 | | -}; |
|---|
| 208 | +} __packed; |
|---|
| 161 | 209 | |
|---|
| 162 | | -struct __attribute__ ((__packed__)) vmcb_save_area { |
|---|
| 210 | +struct vmcb_save_area { |
|---|
| 163 | 211 | struct vmcb_seg es; |
|---|
| 164 | 212 | struct vmcb_seg cs; |
|---|
| 165 | 213 | struct vmcb_seg ss; |
|---|
| .. | .. |
|---|
| 202 | 250 | u64 br_to; |
|---|
| 203 | 251 | u64 last_excp_from; |
|---|
| 204 | 252 | u64 last_excp_to; |
|---|
| 205 | | -}; |
|---|
| 206 | 253 | |
|---|
| 207 | | -struct __attribute__ ((__packed__)) vmcb { |
|---|
| 208 | | - struct vmcb_control_area control; |
|---|
| 254 | + /* |
|---|
| 255 | + * The following part of the save area is valid only for |
|---|
| 256 | + * SEV-ES guests when referenced through the GHCB. |
|---|
| 257 | + */ |
|---|
| 258 | + u8 reserved_7[104]; |
|---|
| 259 | + u64 reserved_8; /* rax already available at 0x01f8 */ |
|---|
| 260 | + u64 rcx; |
|---|
| 261 | + u64 rdx; |
|---|
| 262 | + u64 rbx; |
|---|
| 263 | + u64 reserved_9; /* rsp already available at 0x01d8 */ |
|---|
| 264 | + u64 rbp; |
|---|
| 265 | + u64 rsi; |
|---|
| 266 | + u64 rdi; |
|---|
| 267 | + u64 r8; |
|---|
| 268 | + u64 r9; |
|---|
| 269 | + u64 r10; |
|---|
| 270 | + u64 r11; |
|---|
| 271 | + u64 r12; |
|---|
| 272 | + u64 r13; |
|---|
| 273 | + u64 r14; |
|---|
| 274 | + u64 r15; |
|---|
| 275 | + u8 reserved_10[16]; |
|---|
| 276 | + u64 sw_exit_code; |
|---|
| 277 | + u64 sw_exit_info_1; |
|---|
| 278 | + u64 sw_exit_info_2; |
|---|
| 279 | + u64 sw_scratch; |
|---|
| 280 | + u8 reserved_11[56]; |
|---|
| 281 | + u64 xcr0; |
|---|
| 282 | + u8 valid_bitmap[16]; |
|---|
| 283 | + u64 x87_state_gpa; |
|---|
| 284 | +} __packed; |
|---|
| 285 | + |
|---|
| 286 | +struct ghcb { |
|---|
| 209 | 287 | struct vmcb_save_area save; |
|---|
| 210 | | -}; |
|---|
| 288 | + u8 reserved_save[2048 - sizeof(struct vmcb_save_area)]; |
|---|
| 289 | + |
|---|
| 290 | + u8 shared_buffer[2032]; |
|---|
| 291 | + |
|---|
| 292 | + u8 reserved_1[10]; |
|---|
| 293 | + u16 protocol_version; /* negotiated SEV-ES/GHCB protocol version */ |
|---|
| 294 | + u32 ghcb_usage; |
|---|
| 295 | +} __packed; |
|---|
| 296 | + |
|---|
| 297 | + |
|---|
| 298 | +#define EXPECTED_VMCB_SAVE_AREA_SIZE 1032 |
|---|
| 299 | +#define EXPECTED_VMCB_CONTROL_AREA_SIZE 256 |
|---|
| 300 | +#define EXPECTED_GHCB_SIZE PAGE_SIZE |
|---|
| 301 | + |
|---|
| 302 | +static inline void __unused_size_checks(void) |
|---|
| 303 | +{ |
|---|
| 304 | + BUILD_BUG_ON(sizeof(struct vmcb_save_area) != EXPECTED_VMCB_SAVE_AREA_SIZE); |
|---|
| 305 | + BUILD_BUG_ON(sizeof(struct vmcb_control_area) != EXPECTED_VMCB_CONTROL_AREA_SIZE); |
|---|
| 306 | + BUILD_BUG_ON(sizeof(struct ghcb) != EXPECTED_GHCB_SIZE); |
|---|
| 307 | +} |
|---|
| 308 | + |
|---|
| 309 | +struct vmcb { |
|---|
| 310 | + struct vmcb_control_area control; |
|---|
| 311 | + u8 reserved_control[1024 - sizeof(struct vmcb_control_area)]; |
|---|
| 312 | + struct vmcb_save_area save; |
|---|
| 313 | +} __packed; |
|---|
| 211 | 314 | |
|---|
| 212 | 315 | #define SVM_CPUID_FUNC 0x8000000a |
|---|
| 213 | 316 | |
|---|
| .. | .. |
|---|
| 233 | 336 | #define SVM_SELECTOR_WRITE_MASK (1 << 1) |
|---|
| 234 | 337 | #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK |
|---|
| 235 | 338 | #define SVM_SELECTOR_CODE_MASK (1 << 3) |
|---|
| 236 | | - |
|---|
| 237 | | -#define INTERCEPT_CR0_READ 0 |
|---|
| 238 | | -#define INTERCEPT_CR3_READ 3 |
|---|
| 239 | | -#define INTERCEPT_CR4_READ 4 |
|---|
| 240 | | -#define INTERCEPT_CR8_READ 8 |
|---|
| 241 | | -#define INTERCEPT_CR0_WRITE (16 + 0) |
|---|
| 242 | | -#define INTERCEPT_CR3_WRITE (16 + 3) |
|---|
| 243 | | -#define INTERCEPT_CR4_WRITE (16 + 4) |
|---|
| 244 | | -#define INTERCEPT_CR8_WRITE (16 + 8) |
|---|
| 245 | | - |
|---|
| 246 | | -#define INTERCEPT_DR0_READ 0 |
|---|
| 247 | | -#define INTERCEPT_DR1_READ 1 |
|---|
| 248 | | -#define INTERCEPT_DR2_READ 2 |
|---|
| 249 | | -#define INTERCEPT_DR3_READ 3 |
|---|
| 250 | | -#define INTERCEPT_DR4_READ 4 |
|---|
| 251 | | -#define INTERCEPT_DR5_READ 5 |
|---|
| 252 | | -#define INTERCEPT_DR6_READ 6 |
|---|
| 253 | | -#define INTERCEPT_DR7_READ 7 |
|---|
| 254 | | -#define INTERCEPT_DR0_WRITE (16 + 0) |
|---|
| 255 | | -#define INTERCEPT_DR1_WRITE (16 + 1) |
|---|
| 256 | | -#define INTERCEPT_DR2_WRITE (16 + 2) |
|---|
| 257 | | -#define INTERCEPT_DR3_WRITE (16 + 3) |
|---|
| 258 | | -#define INTERCEPT_DR4_WRITE (16 + 4) |
|---|
| 259 | | -#define INTERCEPT_DR5_WRITE (16 + 5) |
|---|
| 260 | | -#define INTERCEPT_DR6_WRITE (16 + 6) |
|---|
| 261 | | -#define INTERCEPT_DR7_WRITE (16 + 7) |
|---|
| 262 | 339 | |
|---|
| 263 | 340 | #define SVM_EVTINJ_VEC_MASK 0xff |
|---|
| 264 | 341 | |
|---|
| .. | .. |
|---|
| 292 | 369 | |
|---|
| 293 | 370 | #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP) |
|---|
| 294 | 371 | |
|---|
| 295 | | -#define SVM_VMLOAD ".byte 0x0f, 0x01, 0xda" |
|---|
| 296 | | -#define SVM_VMRUN ".byte 0x0f, 0x01, 0xd8" |
|---|
| 297 | | -#define SVM_VMSAVE ".byte 0x0f, 0x01, 0xdb" |
|---|
| 298 | | -#define SVM_CLGI ".byte 0x0f, 0x01, 0xdd" |
|---|
| 299 | | -#define SVM_STGI ".byte 0x0f, 0x01, 0xdc" |
|---|
| 300 | | -#define SVM_INVLPGA ".byte 0x0f, 0x01, 0xdf" |
|---|
| 372 | +/* GHCB Accessor functions */ |
|---|
| 373 | + |
|---|
| 374 | +#define GHCB_BITMAP_IDX(field) \ |
|---|
| 375 | + (offsetof(struct vmcb_save_area, field) / sizeof(u64)) |
|---|
| 376 | + |
|---|
| 377 | +#define DEFINE_GHCB_ACCESSORS(field) \ |
|---|
| 378 | + static inline bool ghcb_##field##_is_valid(const struct ghcb *ghcb) \ |
|---|
| 379 | + { \ |
|---|
| 380 | + return test_bit(GHCB_BITMAP_IDX(field), \ |
|---|
| 381 | + (unsigned long *)&ghcb->save.valid_bitmap); \ |
|---|
| 382 | + } \ |
|---|
| 383 | + \ |
|---|
| 384 | + static inline void ghcb_set_##field(struct ghcb *ghcb, u64 value) \ |
|---|
| 385 | + { \ |
|---|
| 386 | + __set_bit(GHCB_BITMAP_IDX(field), \ |
|---|
| 387 | + (unsigned long *)&ghcb->save.valid_bitmap); \ |
|---|
| 388 | + ghcb->save.field = value; \ |
|---|
| 389 | + } |
|---|
| 390 | + |
|---|
| 391 | +DEFINE_GHCB_ACCESSORS(cpl) |
|---|
| 392 | +DEFINE_GHCB_ACCESSORS(rip) |
|---|
| 393 | +DEFINE_GHCB_ACCESSORS(rsp) |
|---|
| 394 | +DEFINE_GHCB_ACCESSORS(rax) |
|---|
| 395 | +DEFINE_GHCB_ACCESSORS(rcx) |
|---|
| 396 | +DEFINE_GHCB_ACCESSORS(rdx) |
|---|
| 397 | +DEFINE_GHCB_ACCESSORS(rbx) |
|---|
| 398 | +DEFINE_GHCB_ACCESSORS(rbp) |
|---|
| 399 | +DEFINE_GHCB_ACCESSORS(rsi) |
|---|
| 400 | +DEFINE_GHCB_ACCESSORS(rdi) |
|---|
| 401 | +DEFINE_GHCB_ACCESSORS(r8) |
|---|
| 402 | +DEFINE_GHCB_ACCESSORS(r9) |
|---|
| 403 | +DEFINE_GHCB_ACCESSORS(r10) |
|---|
| 404 | +DEFINE_GHCB_ACCESSORS(r11) |
|---|
| 405 | +DEFINE_GHCB_ACCESSORS(r12) |
|---|
| 406 | +DEFINE_GHCB_ACCESSORS(r13) |
|---|
| 407 | +DEFINE_GHCB_ACCESSORS(r14) |
|---|
| 408 | +DEFINE_GHCB_ACCESSORS(r15) |
|---|
| 409 | +DEFINE_GHCB_ACCESSORS(sw_exit_code) |
|---|
| 410 | +DEFINE_GHCB_ACCESSORS(sw_exit_info_1) |
|---|
| 411 | +DEFINE_GHCB_ACCESSORS(sw_exit_info_2) |
|---|
| 412 | +DEFINE_GHCB_ACCESSORS(sw_scratch) |
|---|
| 413 | +DEFINE_GHCB_ACCESSORS(xcr0) |
|---|
| 301 | 414 | |
|---|
| 302 | 415 | #endif |
|---|