1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __KVM_X86_VMX_VMCS_H
3 #define __KVM_X86_VMX_VMCS_H
5 #include <linux/ktime.h>
6 #include <linux/list.h>
7 #include <linux/nospec.h>
12 #include "capabilities.h"
26 * vmcs_host_state tracks registers that are loaded from the VMCS on VMEXIT
27 * and whose values change infrequently, but are not constant. I.e. this is
28 * used as a write-through cache of the corresponding VMCS fields.
30 struct vmcs_host_state
{
31 unsigned long cr3
; /* May not match real cr3 */
32 unsigned long cr4
; /* May not match real cr4 */
33 unsigned long gs_base
;
34 unsigned long fs_base
;
36 u16 fs_sel
, gs_sel
, ldt_sel
;
43 * Track a VMCS that may be loaded on a certain CPU. If it is (cpu!=-1), also
44 * remember whether it was VMLAUNCHed, and maintain a linked list of all VMCSs
45 * loaded on this CPU (so we can clear them if the CPU goes down).
49 struct vmcs
*shadow_vmcs
;
52 bool nmi_known_unmasked
;
54 /* Support for vnmi-less CPUs */
55 int soft_vnmi_blocked
;
57 s64 vnmi_blocked_time
;
58 unsigned long *msr_bitmap
;
59 struct list_head loaded_vmcss_on_cpu_link
;
60 struct vmcs_host_state host_state
;
63 static inline bool is_exception_n(u32 intr_info
, u8 vector
)
65 return (intr_info
& (INTR_INFO_INTR_TYPE_MASK
| INTR_INFO_VECTOR_MASK
|
66 INTR_INFO_VALID_MASK
)) ==
67 (INTR_TYPE_HARD_EXCEPTION
| vector
| INTR_INFO_VALID_MASK
);
70 static inline bool is_debug(u32 intr_info
)
72 return is_exception_n(intr_info
, DB_VECTOR
);
75 static inline bool is_breakpoint(u32 intr_info
)
77 return is_exception_n(intr_info
, BP_VECTOR
);
80 static inline bool is_page_fault(u32 intr_info
)
82 return is_exception_n(intr_info
, PF_VECTOR
);
85 static inline bool is_invalid_opcode(u32 intr_info
)
87 return is_exception_n(intr_info
, UD_VECTOR
);
90 static inline bool is_gp_fault(u32 intr_info
)
92 return is_exception_n(intr_info
, GP_VECTOR
);
95 static inline bool is_machine_check(u32 intr_info
)
97 return (intr_info
& (INTR_INFO_INTR_TYPE_MASK
| INTR_INFO_VECTOR_MASK
|
98 INTR_INFO_VALID_MASK
)) ==
99 (INTR_TYPE_HARD_EXCEPTION
| MC_VECTOR
| INTR_INFO_VALID_MASK
);
102 /* Undocumented: icebp/int1 */
103 static inline bool is_icebp(u32 intr_info
)
105 return (intr_info
& (INTR_INFO_INTR_TYPE_MASK
| INTR_INFO_VALID_MASK
))
106 == (INTR_TYPE_PRIV_SW_EXCEPTION
| INTR_INFO_VALID_MASK
);
109 static inline bool is_nmi(u32 intr_info
)
111 return (intr_info
& (INTR_INFO_INTR_TYPE_MASK
| INTR_INFO_VALID_MASK
))
112 == (INTR_TYPE_NMI_INTR
| INTR_INFO_VALID_MASK
);
115 enum vmcs_field_width
{
116 VMCS_FIELD_WIDTH_U16
= 0,
117 VMCS_FIELD_WIDTH_U64
= 1,
118 VMCS_FIELD_WIDTH_U32
= 2,
119 VMCS_FIELD_WIDTH_NATURAL_WIDTH
= 3
122 static inline int vmcs_field_width(unsigned long field
)
124 if (0x1 & field
) /* the *_HIGH fields are all 32 bit */
125 return VMCS_FIELD_WIDTH_U32
;
126 return (field
>> 13) & 0x3;
129 static inline int vmcs_field_readonly(unsigned long field
)
131 return (((field
>> 10) & 0x3) == 1);
134 #endif /* __KVM_X86_VMX_VMCS_H */