xref: /linux/tools/testing/selftests/kvm/include/x86_64/svm.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
120ba262fSEric Auger /* SPDX-License-Identifier: GPL-2.0 */
220ba262fSEric Auger /*
320ba262fSEric Auger  * tools/testing/selftests/kvm/include/x86_64/svm.h
420ba262fSEric Auger  * This is a copy of arch/x86/include/asm/svm.h
520ba262fSEric Auger  *
620ba262fSEric Auger  */
720ba262fSEric Auger 
820ba262fSEric Auger #ifndef SELFTEST_KVM_SVM_H
920ba262fSEric Auger #define SELFTEST_KVM_SVM_H
1020ba262fSEric Auger 
1120ba262fSEric Auger enum {
1220ba262fSEric Auger 	INTERCEPT_INTR,
1320ba262fSEric Auger 	INTERCEPT_NMI,
1420ba262fSEric Auger 	INTERCEPT_SMI,
1520ba262fSEric Auger 	INTERCEPT_INIT,
1620ba262fSEric Auger 	INTERCEPT_VINTR,
1720ba262fSEric Auger 	INTERCEPT_SELECTIVE_CR0,
1820ba262fSEric Auger 	INTERCEPT_STORE_IDTR,
1920ba262fSEric Auger 	INTERCEPT_STORE_GDTR,
2020ba262fSEric Auger 	INTERCEPT_STORE_LDTR,
2120ba262fSEric Auger 	INTERCEPT_STORE_TR,
2220ba262fSEric Auger 	INTERCEPT_LOAD_IDTR,
2320ba262fSEric Auger 	INTERCEPT_LOAD_GDTR,
2420ba262fSEric Auger 	INTERCEPT_LOAD_LDTR,
2520ba262fSEric Auger 	INTERCEPT_LOAD_TR,
2620ba262fSEric Auger 	INTERCEPT_RDTSC,
2720ba262fSEric Auger 	INTERCEPT_RDPMC,
2820ba262fSEric Auger 	INTERCEPT_PUSHF,
2920ba262fSEric Auger 	INTERCEPT_POPF,
3020ba262fSEric Auger 	INTERCEPT_CPUID,
3120ba262fSEric Auger 	INTERCEPT_RSM,
3220ba262fSEric Auger 	INTERCEPT_IRET,
3320ba262fSEric Auger 	INTERCEPT_INTn,
3420ba262fSEric Auger 	INTERCEPT_INVD,
3520ba262fSEric Auger 	INTERCEPT_PAUSE,
3620ba262fSEric Auger 	INTERCEPT_HLT,
3720ba262fSEric Auger 	INTERCEPT_INVLPG,
3820ba262fSEric Auger 	INTERCEPT_INVLPGA,
3920ba262fSEric Auger 	INTERCEPT_IOIO_PROT,
4020ba262fSEric Auger 	INTERCEPT_MSR_PROT,
4120ba262fSEric Auger 	INTERCEPT_TASK_SWITCH,
4220ba262fSEric Auger 	INTERCEPT_FERR_FREEZE,
4320ba262fSEric Auger 	INTERCEPT_SHUTDOWN,
4420ba262fSEric Auger 	INTERCEPT_VMRUN,
4520ba262fSEric Auger 	INTERCEPT_VMMCALL,
4620ba262fSEric Auger 	INTERCEPT_VMLOAD,
4720ba262fSEric Auger 	INTERCEPT_VMSAVE,
4820ba262fSEric Auger 	INTERCEPT_STGI,
4920ba262fSEric Auger 	INTERCEPT_CLGI,
5020ba262fSEric Auger 	INTERCEPT_SKINIT,
5120ba262fSEric Auger 	INTERCEPT_RDTSCP,
5220ba262fSEric Auger 	INTERCEPT_ICEBP,
5320ba262fSEric Auger 	INTERCEPT_WBINVD,
5420ba262fSEric Auger 	INTERCEPT_MONITOR,
5520ba262fSEric Auger 	INTERCEPT_MWAIT,
5620ba262fSEric Auger 	INTERCEPT_MWAIT_COND,
5720ba262fSEric Auger 	INTERCEPT_XSETBV,
5820ba262fSEric Auger 	INTERCEPT_RDPRU,
5920ba262fSEric Auger };
6020ba262fSEric Auger 
6126b516bbSSean Christopherson struct hv_vmcb_enlightenments {
62381fc63aSSean Christopherson 	struct __packed hv_enlightenments_control {
63381fc63aSSean Christopherson 		u32 nested_flush_hypercall:1;
64381fc63aSSean Christopherson 		u32 msr_bitmap:1;
65381fc63aSSean Christopherson 		u32 enlightened_npt_tlb: 1;
66381fc63aSSean Christopherson 		u32 reserved:29;
67381fc63aSSean Christopherson 	} __packed hv_enlightenments_control;
68381fc63aSSean Christopherson 	u32 hv_vp_id;
69381fc63aSSean Christopherson 	u64 hv_vm_id;
70381fc63aSSean Christopherson 	u64 partition_assist_page;
71381fc63aSSean Christopherson 	u64 reserved;
72381fc63aSSean Christopherson } __packed;
73381fc63aSSean Christopherson 
74381fc63aSSean Christopherson /*
75381fc63aSSean Christopherson  * Hyper-V uses the software reserved clean bit in VMCB
76381fc63aSSean Christopherson  */
77381fc63aSSean Christopherson #define HV_VMCB_NESTED_ENLIGHTENMENTS (1U << 31)
7820ba262fSEric Auger 
79*9c2e8819SVitaly Kuznetsov /* Synthetic VM-Exit */
80*9c2e8819SVitaly Kuznetsov #define HV_SVM_EXITCODE_ENL			0xf0000000
81*9c2e8819SVitaly Kuznetsov #define HV_SVM_ENL_EXITCODE_TRAP_AFTER_FLUSH	(1)
82*9c2e8819SVitaly Kuznetsov 
8320ba262fSEric Auger struct __attribute__ ((__packed__)) vmcb_control_area {
8420ba262fSEric Auger 	u32 intercept_cr;
8520ba262fSEric Auger 	u32 intercept_dr;
8620ba262fSEric Auger 	u32 intercept_exceptions;
8720ba262fSEric Auger 	u64 intercept;
8820ba262fSEric Auger 	u8 reserved_1[40];
8920ba262fSEric Auger 	u16 pause_filter_thresh;
9020ba262fSEric Auger 	u16 pause_filter_count;
9120ba262fSEric Auger 	u64 iopm_base_pa;
9220ba262fSEric Auger 	u64 msrpm_base_pa;
9320ba262fSEric Auger 	u64 tsc_offset;
9420ba262fSEric Auger 	u32 asid;
9520ba262fSEric Auger 	u8 tlb_ctl;
9620ba262fSEric Auger 	u8 reserved_2[3];
9720ba262fSEric Auger 	u32 int_ctl;
9820ba262fSEric Auger 	u32 int_vector;
9920ba262fSEric Auger 	u32 int_state;
10020ba262fSEric Auger 	u8 reserved_3[4];
10120ba262fSEric Auger 	u32 exit_code;
10220ba262fSEric Auger 	u32 exit_code_hi;
10320ba262fSEric Auger 	u64 exit_info_1;
10420ba262fSEric Auger 	u64 exit_info_2;
10520ba262fSEric Auger 	u32 exit_int_info;
10620ba262fSEric Auger 	u32 exit_int_info_err;
10720ba262fSEric Auger 	u64 nested_ctl;
10820ba262fSEric Auger 	u64 avic_vapic_bar;
10920ba262fSEric Auger 	u8 reserved_4[8];
11020ba262fSEric Auger 	u32 event_inj;
11120ba262fSEric Auger 	u32 event_inj_err;
11220ba262fSEric Auger 	u64 nested_cr3;
11320ba262fSEric Auger 	u64 virt_ext;
11420ba262fSEric Auger 	u32 clean;
11520ba262fSEric Auger 	u32 reserved_5;
11620ba262fSEric Auger 	u64 next_rip;
11720ba262fSEric Auger 	u8 insn_len;
11820ba262fSEric Auger 	u8 insn_bytes[15];
11920ba262fSEric Auger 	u64 avic_backing_page;	/* Offset 0xe0 */
12020ba262fSEric Auger 	u8 reserved_6[8];	/* Offset 0xe8 */
12120ba262fSEric Auger 	u64 avic_logical_id;	/* Offset 0xf0 */
12220ba262fSEric Auger 	u64 avic_physical_id;	/* Offset 0xf8 */
12329f557d5SVitaly Kuznetsov 	u8 reserved_7[8];
12429f557d5SVitaly Kuznetsov 	u64 vmsa_pa;		/* Used for an SEV-ES guest */
12529f557d5SVitaly Kuznetsov 	u8 reserved_8[720];
12629f557d5SVitaly Kuznetsov 	/*
12729f557d5SVitaly Kuznetsov 	 * Offset 0x3e0, 32 bytes reserved
12829f557d5SVitaly Kuznetsov 	 * for use by hypervisor/software.
12929f557d5SVitaly Kuznetsov 	 */
13068ae7c7bSSean Christopherson 	union {
13126b516bbSSean Christopherson 		struct hv_vmcb_enlightenments hv_enlightenments;
13229f557d5SVitaly Kuznetsov 		u8 reserved_sw[32];
13320ba262fSEric Auger 	};
13468ae7c7bSSean Christopherson };
13520ba262fSEric Auger 
13620ba262fSEric Auger 
13720ba262fSEric Auger #define TLB_CONTROL_DO_NOTHING 0
13820ba262fSEric Auger #define TLB_CONTROL_FLUSH_ALL_ASID 1
13920ba262fSEric Auger #define TLB_CONTROL_FLUSH_ASID 3
14020ba262fSEric Auger #define TLB_CONTROL_FLUSH_ASID_LOCAL 7
14120ba262fSEric Auger 
14220ba262fSEric Auger #define V_TPR_MASK 0x0f
14320ba262fSEric Auger 
14420ba262fSEric Auger #define V_IRQ_SHIFT 8
14520ba262fSEric Auger #define V_IRQ_MASK (1 << V_IRQ_SHIFT)
14620ba262fSEric Auger 
14720ba262fSEric Auger #define V_GIF_SHIFT 9
14820ba262fSEric Auger #define V_GIF_MASK (1 << V_GIF_SHIFT)
14920ba262fSEric Auger 
15020ba262fSEric Auger #define V_INTR_PRIO_SHIFT 16
15120ba262fSEric Auger #define V_INTR_PRIO_MASK (0x0f << V_INTR_PRIO_SHIFT)
15220ba262fSEric Auger 
15320ba262fSEric Auger #define V_IGN_TPR_SHIFT 20
15420ba262fSEric Auger #define V_IGN_TPR_MASK (1 << V_IGN_TPR_SHIFT)
15520ba262fSEric Auger 
15620ba262fSEric Auger #define V_INTR_MASKING_SHIFT 24
15720ba262fSEric Auger #define V_INTR_MASKING_MASK (1 << V_INTR_MASKING_SHIFT)
15820ba262fSEric Auger 
15920ba262fSEric Auger #define V_GIF_ENABLE_SHIFT 25
16020ba262fSEric Auger #define V_GIF_ENABLE_MASK (1 << V_GIF_ENABLE_SHIFT)
16120ba262fSEric Auger 
16220ba262fSEric Auger #define AVIC_ENABLE_SHIFT 31
16320ba262fSEric Auger #define AVIC_ENABLE_MASK (1 << AVIC_ENABLE_SHIFT)
16420ba262fSEric Auger 
16520ba262fSEric Auger #define LBR_CTL_ENABLE_MASK BIT_ULL(0)
16620ba262fSEric Auger #define VIRTUAL_VMLOAD_VMSAVE_ENABLE_MASK BIT_ULL(1)
16720ba262fSEric Auger 
16820ba262fSEric Auger #define SVM_INTERRUPT_SHADOW_MASK 1
16920ba262fSEric Auger 
17020ba262fSEric Auger #define SVM_IOIO_STR_SHIFT 2
17120ba262fSEric Auger #define SVM_IOIO_REP_SHIFT 3
17220ba262fSEric Auger #define SVM_IOIO_SIZE_SHIFT 4
17320ba262fSEric Auger #define SVM_IOIO_ASIZE_SHIFT 7
17420ba262fSEric Auger 
17520ba262fSEric Auger #define SVM_IOIO_TYPE_MASK 1
17620ba262fSEric Auger #define SVM_IOIO_STR_MASK (1 << SVM_IOIO_STR_SHIFT)
17720ba262fSEric Auger #define SVM_IOIO_REP_MASK (1 << SVM_IOIO_REP_SHIFT)
17820ba262fSEric Auger #define SVM_IOIO_SIZE_MASK (7 << SVM_IOIO_SIZE_SHIFT)
17920ba262fSEric Auger #define SVM_IOIO_ASIZE_MASK (7 << SVM_IOIO_ASIZE_SHIFT)
18020ba262fSEric Auger 
18120ba262fSEric Auger #define SVM_VM_CR_VALID_MASK	0x001fULL
18220ba262fSEric Auger #define SVM_VM_CR_SVM_LOCK_MASK 0x0008ULL
18320ba262fSEric Auger #define SVM_VM_CR_SVM_DIS_MASK  0x0010ULL
18420ba262fSEric Auger 
18520ba262fSEric Auger #define SVM_NESTED_CTL_NP_ENABLE	BIT(0)
18620ba262fSEric Auger #define SVM_NESTED_CTL_SEV_ENABLE	BIT(1)
18720ba262fSEric Auger 
18820ba262fSEric Auger struct __attribute__ ((__packed__)) vmcb_seg {
18920ba262fSEric Auger 	u16 selector;
19020ba262fSEric Auger 	u16 attrib;
19120ba262fSEric Auger 	u32 limit;
19220ba262fSEric Auger 	u64 base;
19320ba262fSEric Auger };
19420ba262fSEric Auger 
19520ba262fSEric Auger struct __attribute__ ((__packed__)) vmcb_save_area {
19620ba262fSEric Auger 	struct vmcb_seg es;
19720ba262fSEric Auger 	struct vmcb_seg cs;
19820ba262fSEric Auger 	struct vmcb_seg ss;
19920ba262fSEric Auger 	struct vmcb_seg ds;
20020ba262fSEric Auger 	struct vmcb_seg fs;
20120ba262fSEric Auger 	struct vmcb_seg gs;
20220ba262fSEric Auger 	struct vmcb_seg gdtr;
20320ba262fSEric Auger 	struct vmcb_seg ldtr;
20420ba262fSEric Auger 	struct vmcb_seg idtr;
20520ba262fSEric Auger 	struct vmcb_seg tr;
20620ba262fSEric Auger 	u8 reserved_1[43];
20720ba262fSEric Auger 	u8 cpl;
20820ba262fSEric Auger 	u8 reserved_2[4];
20920ba262fSEric Auger 	u64 efer;
21020ba262fSEric Auger 	u8 reserved_3[112];
21120ba262fSEric Auger 	u64 cr4;
21220ba262fSEric Auger 	u64 cr3;
21320ba262fSEric Auger 	u64 cr0;
21420ba262fSEric Auger 	u64 dr7;
21520ba262fSEric Auger 	u64 dr6;
21620ba262fSEric Auger 	u64 rflags;
21720ba262fSEric Auger 	u64 rip;
21820ba262fSEric Auger 	u8 reserved_4[88];
21920ba262fSEric Auger 	u64 rsp;
22020ba262fSEric Auger 	u8 reserved_5[24];
22120ba262fSEric Auger 	u64 rax;
22220ba262fSEric Auger 	u64 star;
22320ba262fSEric Auger 	u64 lstar;
22420ba262fSEric Auger 	u64 cstar;
22520ba262fSEric Auger 	u64 sfmask;
22620ba262fSEric Auger 	u64 kernel_gs_base;
22720ba262fSEric Auger 	u64 sysenter_cs;
22820ba262fSEric Auger 	u64 sysenter_esp;
22920ba262fSEric Auger 	u64 sysenter_eip;
23020ba262fSEric Auger 	u64 cr2;
23120ba262fSEric Auger 	u8 reserved_6[32];
23220ba262fSEric Auger 	u64 g_pat;
23320ba262fSEric Auger 	u64 dbgctl;
23420ba262fSEric Auger 	u64 br_from;
23520ba262fSEric Auger 	u64 br_to;
23620ba262fSEric Auger 	u64 last_excp_from;
23720ba262fSEric Auger 	u64 last_excp_to;
23820ba262fSEric Auger };
23920ba262fSEric Auger 
24020ba262fSEric Auger struct __attribute__ ((__packed__)) vmcb {
24120ba262fSEric Auger 	struct vmcb_control_area control;
24220ba262fSEric Auger 	struct vmcb_save_area save;
24320ba262fSEric Auger };
24420ba262fSEric Auger 
24520ba262fSEric Auger #define SVM_VM_CR_SVM_DISABLE 4
24620ba262fSEric Auger 
24720ba262fSEric Auger #define SVM_SELECTOR_S_SHIFT 4
24820ba262fSEric Auger #define SVM_SELECTOR_DPL_SHIFT 5
24920ba262fSEric Auger #define SVM_SELECTOR_P_SHIFT 7
25020ba262fSEric Auger #define SVM_SELECTOR_AVL_SHIFT 8
25120ba262fSEric Auger #define SVM_SELECTOR_L_SHIFT 9
25220ba262fSEric Auger #define SVM_SELECTOR_DB_SHIFT 10
25320ba262fSEric Auger #define SVM_SELECTOR_G_SHIFT 11
25420ba262fSEric Auger 
25520ba262fSEric Auger #define SVM_SELECTOR_TYPE_MASK (0xf)
25620ba262fSEric Auger #define SVM_SELECTOR_S_MASK (1 << SVM_SELECTOR_S_SHIFT)
25720ba262fSEric Auger #define SVM_SELECTOR_DPL_MASK (3 << SVM_SELECTOR_DPL_SHIFT)
25820ba262fSEric Auger #define SVM_SELECTOR_P_MASK (1 << SVM_SELECTOR_P_SHIFT)
25920ba262fSEric Auger #define SVM_SELECTOR_AVL_MASK (1 << SVM_SELECTOR_AVL_SHIFT)
26020ba262fSEric Auger #define SVM_SELECTOR_L_MASK (1 << SVM_SELECTOR_L_SHIFT)
26120ba262fSEric Auger #define SVM_SELECTOR_DB_MASK (1 << SVM_SELECTOR_DB_SHIFT)
26220ba262fSEric Auger #define SVM_SELECTOR_G_MASK (1 << SVM_SELECTOR_G_SHIFT)
26320ba262fSEric Auger 
26420ba262fSEric Auger #define SVM_SELECTOR_WRITE_MASK (1 << 1)
26520ba262fSEric Auger #define SVM_SELECTOR_READ_MASK SVM_SELECTOR_WRITE_MASK
26620ba262fSEric Auger #define SVM_SELECTOR_CODE_MASK (1 << 3)
26720ba262fSEric Auger 
26820ba262fSEric Auger #define INTERCEPT_CR0_READ	0
26920ba262fSEric Auger #define INTERCEPT_CR3_READ	3
27020ba262fSEric Auger #define INTERCEPT_CR4_READ	4
27120ba262fSEric Auger #define INTERCEPT_CR8_READ	8
27220ba262fSEric Auger #define INTERCEPT_CR0_WRITE	(16 + 0)
27320ba262fSEric Auger #define INTERCEPT_CR3_WRITE	(16 + 3)
27420ba262fSEric Auger #define INTERCEPT_CR4_WRITE	(16 + 4)
27520ba262fSEric Auger #define INTERCEPT_CR8_WRITE	(16 + 8)
27620ba262fSEric Auger 
27720ba262fSEric Auger #define INTERCEPT_DR0_READ	0
27820ba262fSEric Auger #define INTERCEPT_DR1_READ	1
27920ba262fSEric Auger #define INTERCEPT_DR2_READ	2
28020ba262fSEric Auger #define INTERCEPT_DR3_READ	3
28120ba262fSEric Auger #define INTERCEPT_DR4_READ	4
28220ba262fSEric Auger #define INTERCEPT_DR5_READ	5
28320ba262fSEric Auger #define INTERCEPT_DR6_READ	6
28420ba262fSEric Auger #define INTERCEPT_DR7_READ	7
28520ba262fSEric Auger #define INTERCEPT_DR0_WRITE	(16 + 0)
28620ba262fSEric Auger #define INTERCEPT_DR1_WRITE	(16 + 1)
28720ba262fSEric Auger #define INTERCEPT_DR2_WRITE	(16 + 2)
28820ba262fSEric Auger #define INTERCEPT_DR3_WRITE	(16 + 3)
28920ba262fSEric Auger #define INTERCEPT_DR4_WRITE	(16 + 4)
29020ba262fSEric Auger #define INTERCEPT_DR5_WRITE	(16 + 5)
29120ba262fSEric Auger #define INTERCEPT_DR6_WRITE	(16 + 6)
29220ba262fSEric Auger #define INTERCEPT_DR7_WRITE	(16 + 7)
29320ba262fSEric Auger 
29420ba262fSEric Auger #define SVM_EVTINJ_VEC_MASK 0xff
29520ba262fSEric Auger 
29620ba262fSEric Auger #define SVM_EVTINJ_TYPE_SHIFT 8
29720ba262fSEric Auger #define SVM_EVTINJ_TYPE_MASK (7 << SVM_EVTINJ_TYPE_SHIFT)
29820ba262fSEric Auger 
29920ba262fSEric Auger #define SVM_EVTINJ_TYPE_INTR (0 << SVM_EVTINJ_TYPE_SHIFT)
30020ba262fSEric Auger #define SVM_EVTINJ_TYPE_NMI (2 << SVM_EVTINJ_TYPE_SHIFT)
30120ba262fSEric Auger #define SVM_EVTINJ_TYPE_EXEPT (3 << SVM_EVTINJ_TYPE_SHIFT)
30220ba262fSEric Auger #define SVM_EVTINJ_TYPE_SOFT (4 << SVM_EVTINJ_TYPE_SHIFT)
30320ba262fSEric Auger 
30420ba262fSEric Auger #define SVM_EVTINJ_VALID (1 << 31)
30520ba262fSEric Auger #define SVM_EVTINJ_VALID_ERR (1 << 11)
30620ba262fSEric Auger 
30720ba262fSEric Auger #define SVM_EXITINTINFO_VEC_MASK SVM_EVTINJ_VEC_MASK
30820ba262fSEric Auger #define SVM_EXITINTINFO_TYPE_MASK SVM_EVTINJ_TYPE_MASK
30920ba262fSEric Auger 
31020ba262fSEric Auger #define	SVM_EXITINTINFO_TYPE_INTR SVM_EVTINJ_TYPE_INTR
31120ba262fSEric Auger #define	SVM_EXITINTINFO_TYPE_NMI SVM_EVTINJ_TYPE_NMI
31220ba262fSEric Auger #define	SVM_EXITINTINFO_TYPE_EXEPT SVM_EVTINJ_TYPE_EXEPT
31320ba262fSEric Auger #define	SVM_EXITINTINFO_TYPE_SOFT SVM_EVTINJ_TYPE_SOFT
31420ba262fSEric Auger 
31520ba262fSEric Auger #define SVM_EXITINTINFO_VALID SVM_EVTINJ_VALID
31620ba262fSEric Auger #define SVM_EXITINTINFO_VALID_ERR SVM_EVTINJ_VALID_ERR
31720ba262fSEric Auger 
31820ba262fSEric Auger #define SVM_EXITINFOSHIFT_TS_REASON_IRET 36
31920ba262fSEric Auger #define SVM_EXITINFOSHIFT_TS_REASON_JMP 38
32020ba262fSEric Auger #define SVM_EXITINFOSHIFT_TS_HAS_ERROR_CODE 44
32120ba262fSEric Auger 
32220ba262fSEric Auger #define SVM_EXITINFO_REG_MASK 0x0F
32320ba262fSEric Auger 
32420ba262fSEric Auger #define SVM_CR0_SELECTIVE_MASK (X86_CR0_TS | X86_CR0_MP)
32520ba262fSEric Auger 
32620ba262fSEric Auger #endif /* SELFTEST_KVM_SVM_H */
327