| .. | .. | 
|---|
| 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 | 
|---|