^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef __KVM_X86_VMX_VMCS_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define __KVM_X86_VMX_VMCS_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/ktime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/nospec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/kvm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/vmx.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "capabilities.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) struct vmcs_hdr {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) u32 revision_id:31;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) u32 shadow_vmcs:1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct vmcs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct vmcs_hdr hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) u32 abort;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) char data[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) DECLARE_PER_CPU(struct vmcs *, current_vmcs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * vmcs_host_state tracks registers that are loaded from the VMCS on VMEXIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * and whose values change infrequently, but are not constant. I.e. this is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * used as a write-through cache of the corresponding VMCS fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) struct vmcs_host_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) unsigned long cr3; /* May not match real cr3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned long cr4; /* May not match real cr4 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) unsigned long gs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) unsigned long fs_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) unsigned long rsp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) u16 fs_sel, gs_sel, ldt_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) u16 ds_sel, es_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) struct vmcs_controls_shadow {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) u32 vm_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) u32 vm_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) u32 pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) u32 exec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) u32 secondary_exec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Track a VMCS that may be loaded on a certain CPU. If it is (cpu!=-1), also
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * remember whether it was VMLAUNCHed, and maintain a linked list of all VMCSs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * loaded on this CPU (so we can clear them if the CPU goes down).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) struct loaded_vmcs {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct vmcs *vmcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct vmcs *shadow_vmcs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) bool launched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) bool nmi_known_unmasked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bool hv_timer_soft_disabled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* Support for vnmi-less CPUs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int soft_vnmi_blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ktime_t entry_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) s64 vnmi_blocked_time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) unsigned long *msr_bitmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) struct list_head loaded_vmcss_on_cpu_link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct vmcs_host_state host_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct vmcs_controls_shadow controls_shadow;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static inline bool is_intr_type(u32 intr_info, u32 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) const u32 mask = INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return (intr_info & mask) == (INTR_INFO_VALID_MASK | type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) static inline bool is_intr_type_n(u32 intr_info, u32 type, u8 vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) const u32 mask = INTR_INFO_VALID_MASK | INTR_INFO_INTR_TYPE_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) INTR_INFO_VECTOR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) return (intr_info & mask) == (INTR_INFO_VALID_MASK | type | vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) static inline bool is_exception_n(u32 intr_info, u8 vector)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return is_intr_type_n(intr_info, INTR_TYPE_HARD_EXCEPTION, vector);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static inline bool is_debug(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return is_exception_n(intr_info, DB_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static inline bool is_breakpoint(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return is_exception_n(intr_info, BP_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) static inline bool is_page_fault(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return is_exception_n(intr_info, PF_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static inline bool is_invalid_opcode(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) return is_exception_n(intr_info, UD_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static inline bool is_gp_fault(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return is_exception_n(intr_info, GP_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static inline bool is_alignment_check(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) return is_exception_n(intr_info, AC_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) static inline bool is_machine_check(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) return is_exception_n(intr_info, MC_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /* Undocumented: icebp/int1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) static inline bool is_icebp(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return is_intr_type(intr_info, INTR_TYPE_PRIV_SW_EXCEPTION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static inline bool is_nmi(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return is_intr_type(intr_info, INTR_TYPE_NMI_INTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) static inline bool is_external_intr(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) return is_intr_type(intr_info, INTR_TYPE_EXT_INTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static inline bool is_exception_with_error_code(u32 intr_info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) const u32 mask = INTR_INFO_VALID_MASK | INTR_INFO_DELIVER_CODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return (intr_info & mask) == mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) enum vmcs_field_width {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) VMCS_FIELD_WIDTH_U16 = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) VMCS_FIELD_WIDTH_U64 = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) VMCS_FIELD_WIDTH_U32 = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) VMCS_FIELD_WIDTH_NATURAL_WIDTH = 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) static inline int vmcs_field_width(unsigned long field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (0x1 & field) /* the *_HIGH fields are all 32 bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return VMCS_FIELD_WIDTH_U32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) return (field >> 13) & 0x3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static inline int vmcs_field_readonly(unsigned long field)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return (((field >> 10) & 0x3) == 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #endif /* __KVM_X86_VMX_VMCS_H */