| 1 |
|
| 2 | |
| 3 | * Copyright (C) 2018, Google LLC.
|
| 4 |
|
| 5 |
|
| 6 | #ifndef SELFTEST_KVM_PROCESSOR_H
|
| 7 | #define SELFTEST_KVM_PROCESSOR_H
|
| 8 |
|
| 9 | #include <assert.h>
|
| 10 | #include <stdint.h>
|
| 11 | #include <syscall.h>
|
| 12 |
|
| 13 | #include <asm/msr-index.h>
|
| 14 | #include <asm/prctl.h>
|
| 15 |
|
| 16 | #include <linux/kvm_para.h>
|
| 17 | #include <linux/stringify.h>
|
| 18 |
|
| 19 | #include "kvm_util.h"
|
| 20 | #include "ucall_common.h"
|
| 21 |
|
| 22 | extern bool host_cpu_is_intel;
|
| 23 | extern bool host_cpu_is_amd;
|
| 24 | extern bool host_cpu_is_hygon;
|
| 25 | extern bool host_cpu_is_amd_compatible;
|
| 26 | extern u64 guest_tsc_khz;
|
| 27 | extern struct kvm_mmu guest_mmu;
|
| 28 |
|
| 29 | #ifndef MAX_NR_CPUID_ENTRIES
|
| 30 | #define MAX_NR_CPUID_ENTRIES 100
|
| 31 | #endif
|
| 32 |
|
| 33 | #define NONCANONICAL 0xaaaaaaaaaaaaaaaaull
|
| 34 |
|
| 35 |
|
| 36 | #define KVM_FEP "ud2; .byte 'k', 'v', 'm';"
|
| 37 |
|
| 38 | #define NMI_VECTOR 0x02
|
| 39 |
|
| 40 | const char *ex_str(int vector);
|
| 41 |
|
| 42 | #define X86_EFLAGS_CF BIT(0)
|
| 43 | #define X86_EFLAGS_FIXED BIT(1)
|
| 44 | #define X86_EFLAGS_PF BIT(2)
|
| 45 | #define X86_EFLAGS_AF BIT(4)
|
| 46 | #define X86_EFLAGS_ZF BIT(6)
|
| 47 | #define X86_EFLAGS_SF BIT(7)
|
| 48 | #define X86_EFLAGS_TF BIT(8)
|
| 49 | #define X86_EFLAGS_IF BIT(9)
|
| 50 | #define X86_EFLAGS_DF BIT(10)
|
| 51 | #define X86_EFLAGS_OF BIT(11)
|
| 52 | #define X86_EFLAGS_IOPL BIT(12)
|
| 53 | #define X86_EFLAGS_NT BIT(14)
|
| 54 | #define X86_EFLAGS_RF BIT(16)
|
| 55 | #define X86_EFLAGS_VM BIT(17)
|
| 56 | #define X86_EFLAGS_AC BIT(18)
|
| 57 | #define X86_EFLAGS_VIF BIT(19)
|
| 58 | #define X86_EFLAGS_VIP BIT(20)
|
| 59 | #define X86_EFLAGS_ID BIT(21)
|
| 60 |
|
| 61 | #define X86_CR4_VME (1ul << 0)
|
| 62 | #define X86_CR4_PVI (1ul << 1)
|
| 63 | #define X86_CR4_TSD (1ul << 2)
|
| 64 | #define X86_CR4_DE (1ul << 3)
|
| 65 | #define X86_CR4_PSE (1ul << 4)
|
| 66 | #define X86_CR4_PAE (1ul << 5)
|
| 67 | #define X86_CR4_MCE (1ul << 6)
|
| 68 | #define X86_CR4_PGE (1ul << 7)
|
| 69 | #define X86_CR4_PCE (1ul << 8)
|
| 70 | #define X86_CR4_OSFXSR (1ul << 9)
|
| 71 | #define X86_CR4_OSXMMEXCPT (1ul << 10)
|
| 72 | #define X86_CR4_UMIP (1ul << 11)
|
| 73 | #define X86_CR4_LA57 (1ul << 12)
|
| 74 | #define X86_CR4_VMXE (1ul << 13)
|
| 75 | #define X86_CR4_SMXE (1ul << 14)
|
| 76 | #define X86_CR4_FSGSBASE (1ul << 16)
|
| 77 | #define X86_CR4_PCIDE (1ul << 17)
|
| 78 | #define X86_CR4_OSXSAVE (1ul << 18)
|
| 79 | #define X86_CR4_SMEP (1ul << 20)
|
| 80 | #define X86_CR4_SMAP (1ul << 21)
|
| 81 | #define X86_CR4_PKE (1ul << 22)
|
| 82 |
|
| 83 | struct xstate_header {
|
| 84 | u64 xstate_bv;
|
| 85 | u64 xcomp_bv;
|
| 86 | u64 reserved[6];
|
| 87 | } __attribute__((packed));
|
| 88 |
|
| 89 | struct xstate {
|
| 90 | u8 i387[512];
|
| 91 | struct xstate_header header;
|
| 92 | u8 extended_state_area[0];
|
| 93 | } __attribute__ ((packed, aligned (64)));
|
| 94 |
|
| 95 | #define XFEATURE_MASK_FP BIT_ULL(0)
|
| 96 | #define XFEATURE_MASK_SSE BIT_ULL(1)
|
| 97 | #define XFEATURE_MASK_YMM BIT_ULL(2)
|
| 98 | #define XFEATURE_MASK_BNDREGS BIT_ULL(3)
|
| 99 | #define XFEATURE_MASK_BNDCSR BIT_ULL(4)
|
| 100 | #define XFEATURE_MASK_OPMASK BIT_ULL(5)
|
| 101 | #define XFEATURE_MASK_ZMM_Hi256 BIT_ULL(6)
|
| 102 | #define XFEATURE_MASK_Hi16_ZMM BIT_ULL(7)
|
| 103 | #define XFEATURE_MASK_PT BIT_ULL(8)
|
| 104 | #define XFEATURE_MASK_PKRU BIT_ULL(9)
|
| 105 | #define XFEATURE_MASK_PASID BIT_ULL(10)
|
| 106 | #define XFEATURE_MASK_CET_USER BIT_ULL(11)
|
| 107 | #define XFEATURE_MASK_CET_KERNEL BIT_ULL(12)
|
| 108 | #define XFEATURE_MASK_LBR BIT_ULL(15)
|
| 109 | #define XFEATURE_MASK_XTILE_CFG BIT_ULL(17)
|
| 110 | #define XFEATURE_MASK_XTILE_DATA BIT_ULL(18)
|
| 111 |
|
| 112 | #define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK | \
|
| 113 | XFEATURE_MASK_ZMM_Hi256 | \
|
| 114 | XFEATURE_MASK_Hi16_ZMM)
|
| 115 | #define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILE_DATA | \
|
| 116 | XFEATURE_MASK_XTILE_CFG)
|
| 117 |
|
| 118 |
|
| 119 | enum cpuid_output_regs {
|
| 120 | KVM_CPUID_EAX,
|
| 121 | KVM_CPUID_EBX,
|
| 122 | KVM_CPUID_ECX,
|
| 123 | KVM_CPUID_EDX
|
| 124 | };
|
| 125 |
|
| 126 | |
| 127 | * Pack the information into a 64-bit value so that each X86_FEATURE_XXX can be
|
| 128 | * passed by value with no overhead.
|
| 129 |
|
| 130 | struct kvm_x86_cpu_feature {
|
| 131 | u32 function;
|
| 132 | u16 index;
|
| 133 | u8 reg;
|
| 134 | u8 bit;
|
| 135 | };
|
| 136 | #define KVM_X86_CPU_FEATURE(fn, idx, gpr, __bit) \
|
| 137 | ({ \
|
| 138 | struct kvm_x86_cpu_feature feature = { \
|
| 139 | .function = fn, \
|
| 140 | .index = idx, \
|
| 141 | .reg = KVM_CPUID_##gpr, \
|
| 142 | .bit = __bit, \
|
| 143 | }; \
|
| 144 | \
|
| 145 | kvm_static_assert((fn & 0xc0000000) == 0 || \
|
| 146 | (fn & 0xc0000000) == 0x40000000 || \
|
| 147 | (fn & 0xc0000000) == 0x80000000 || \
|
| 148 | (fn & 0xc0000000) == 0xc0000000); \
|
| 149 | kvm_static_assert(idx < BIT(sizeof(feature.index) * BITS_PER_BYTE)); \
|
| 150 | feature; \
|
| 151 | })
|
| 152 |
|
| 153 | |
| 154 | * Basic Leafs, a.k.a. Intel defined
|
| 155 |
|
| 156 | #define X86_FEATURE_MWAIT KVM_X86_CPU_FEATURE(0x1, 0, ECX, 3)
|
| 157 | #define X86_FEATURE_VMX KVM_X86_CPU_FEATURE(0x1, 0, ECX, 5)
|
| 158 | #define X86_FEATURE_SMX KVM_X86_CPU_FEATURE(0x1, 0, ECX, 6)
|
| 159 | #define X86_FEATURE_PDCM KVM_X86_CPU_FEATURE(0x1, 0, ECX, 15)
|
| 160 | #define X86_FEATURE_PCID KVM_X86_CPU_FEATURE(0x1, 0, ECX, 17)
|
| 161 | #define X86_FEATURE_X2APIC KVM_X86_CPU_FEATURE(0x1, 0, ECX, 21)
|
| 162 | #define X86_FEATURE_MOVBE KVM_X86_CPU_FEATURE(0x1, 0, ECX, 22)
|
| 163 | #define X86_FEATURE_TSC_DEADLINE_TIMER KVM_X86_CPU_FEATURE(0x1, 0, ECX, 24)
|
| 164 | #define X86_FEATURE_XSAVE KVM_X86_CPU_FEATURE(0x1, 0, ECX, 26)
|
| 165 | #define X86_FEATURE_OSXSAVE KVM_X86_CPU_FEATURE(0x1, 0, ECX, 27)
|
| 166 | #define X86_FEATURE_RDRAND KVM_X86_CPU_FEATURE(0x1, 0, ECX, 30)
|
| 167 | #define X86_FEATURE_HYPERVISOR KVM_X86_CPU_FEATURE(0x1, 0, ECX, 31)
|
| 168 | #define X86_FEATURE_PAE KVM_X86_CPU_FEATURE(0x1, 0, EDX, 6)
|
| 169 | #define X86_FEATURE_MCE KVM_X86_CPU_FEATURE(0x1, 0, EDX, 7)
|
| 170 | #define X86_FEATURE_APIC KVM_X86_CPU_FEATURE(0x1, 0, EDX, 9)
|
| 171 | #define X86_FEATURE_CLFLUSH KVM_X86_CPU_FEATURE(0x1, 0, EDX, 19)
|
| 172 | #define X86_FEATURE_XMM KVM_X86_CPU_FEATURE(0x1, 0, EDX, 25)
|
| 173 | #define X86_FEATURE_XMM2 KVM_X86_CPU_FEATURE(0x1, 0, EDX, 26)
|
| 174 | #define X86_FEATURE_FSGSBASE KVM_X86_CPU_FEATURE(0x7, 0, EBX, 0)
|
| 175 | #define X86_FEATURE_TSC_ADJUST KVM_X86_CPU_FEATURE(0x7, 0, EBX, 1)
|
| 176 | #define X86_FEATURE_SGX KVM_X86_CPU_FEATURE(0x7, 0, EBX, 2)
|
| 177 | #define X86_FEATURE_HLE KVM_X86_CPU_FEATURE(0x7, 0, EBX, 4)
|
| 178 | #define X86_FEATURE_SMEP KVM_X86_CPU_FEATURE(0x7, 0, EBX, 7)
|
| 179 | #define X86_FEATURE_INVPCID KVM_X86_CPU_FEATURE(0x7, 0, EBX, 10)
|
| 180 | #define X86_FEATURE_RTM KVM_X86_CPU_FEATURE(0x7, 0, EBX, 11)
|
| 181 | #define X86_FEATURE_MPX KVM_X86_CPU_FEATURE(0x7, 0, EBX, 14)
|
| 182 | #define X86_FEATURE_SMAP KVM_X86_CPU_FEATURE(0x7, 0, EBX, 20)
|
| 183 | #define X86_FEATURE_PCOMMIT KVM_X86_CPU_FEATURE(0x7, 0, EBX, 22)
|
| 184 | #define X86_FEATURE_CLFLUSHOPT KVM_X86_CPU_FEATURE(0x7, 0, EBX, 23)
|
| 185 | #define X86_FEATURE_CLWB KVM_X86_CPU_FEATURE(0x7, 0, EBX, 24)
|
| 186 | #define X86_FEATURE_UMIP KVM_X86_CPU_FEATURE(0x7, 0, ECX, 2)
|
| 187 | #define X86_FEATURE_PKU KVM_X86_CPU_FEATURE(0x7, 0, ECX, 3)
|
| 188 | #define X86_FEATURE_OSPKE KVM_X86_CPU_FEATURE(0x7, 0, ECX, 4)
|
| 189 | #define X86_FEATURE_LA57 KVM_X86_CPU_FEATURE(0x7, 0, ECX, 16)
|
| 190 | #define X86_FEATURE_RDPID KVM_X86_CPU_FEATURE(0x7, 0, ECX, 22)
|
| 191 | #define X86_FEATURE_SGX_LC KVM_X86_CPU_FEATURE(0x7, 0, ECX, 30)
|
| 192 | #define X86_FEATURE_SHSTK KVM_X86_CPU_FEATURE(0x7, 0, ECX, 7)
|
| 193 | #define X86_FEATURE_IBT KVM_X86_CPU_FEATURE(0x7, 0, EDX, 20)
|
| 194 | #define X86_FEATURE_AMX_TILE KVM_X86_CPU_FEATURE(0x7, 0, EDX, 24)
|
| 195 | #define X86_FEATURE_SPEC_CTRL KVM_X86_CPU_FEATURE(0x7, 0, EDX, 26)
|
| 196 | #define X86_FEATURE_ARCH_CAPABILITIES KVM_X86_CPU_FEATURE(0x7, 0, EDX, 29)
|
| 197 | #define X86_FEATURE_PKS KVM_X86_CPU_FEATURE(0x7, 0, ECX, 31)
|
| 198 | #define X86_FEATURE_XTILECFG KVM_X86_CPU_FEATURE(0xD, 0, EAX, 17)
|
| 199 | #define X86_FEATURE_XTILEDATA KVM_X86_CPU_FEATURE(0xD, 0, EAX, 18)
|
| 200 | #define X86_FEATURE_XSAVES KVM_X86_CPU_FEATURE(0xD, 1, EAX, 3)
|
| 201 | #define X86_FEATURE_XFD KVM_X86_CPU_FEATURE(0xD, 1, EAX, 4)
|
| 202 | #define X86_FEATURE_XTILEDATA_XFD KVM_X86_CPU_FEATURE(0xD, 18, ECX, 2)
|
| 203 |
|
| 204 | |
| 205 | * Extended Leafs, a.k.a. AMD defined
|
| 206 |
|
| 207 | #define X86_FEATURE_SVM KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 2)
|
| 208 | #define X86_FEATURE_PERFCTR_CORE KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 23)
|
| 209 | #define X86_FEATURE_PERFCTR_NB KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 24)
|
| 210 | #define X86_FEATURE_PERFCTR_LLC KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 28)
|
| 211 | #define X86_FEATURE_NX KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 20)
|
| 212 | #define X86_FEATURE_FXSR_OPT KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 25)
|
| 213 | #define X86_FEATURE_GBPAGES KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 26)
|
| 214 | #define X86_FEATURE_RDTSCP KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 27)
|
| 215 | #define X86_FEATURE_LM KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 29)
|
| 216 | #define X86_FEATURE_INVTSC KVM_X86_CPU_FEATURE(0x80000007, 0, EDX, 8)
|
| 217 | #define X86_FEATURE_RDPRU KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 4)
|
| 218 | #define X86_FEATURE_AMD_IBPB KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 12)
|
| 219 | #define X86_FEATURE_NPT KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 0)
|
| 220 | #define X86_FEATURE_LBRV KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 1)
|
| 221 | #define X86_FEATURE_NRIPS KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 3)
|
| 222 | #define X86_FEATURE_TSCRATEMSR KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 4)
|
| 223 | #define X86_FEATURE_PAUSEFILTER KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 10)
|
| 224 | #define X86_FEATURE_PFTHRESHOLD KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 12)
|
| 225 | #define X86_FEATURE_V_VMSAVE_VMLOAD KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 15)
|
| 226 | #define X86_FEATURE_VGIF KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 16)
|
| 227 | #define X86_FEATURE_IDLE_HLT KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 30)
|
| 228 | #define X86_FEATURE_SEV KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 1)
|
| 229 | #define X86_FEATURE_SEV_ES KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 3)
|
| 230 | #define X86_FEATURE_SEV_SNP KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 4)
|
| 231 | #define X86_FEATURE_AUTOIBRS KVM_X86_CPU_FEATURE(0x80000021, 0, EAX, 8)
|
| 232 | #define X86_FEATURE_GP_ON_USER_CPUID KVM_X86_CPU_FEATURE(0x80000021, 0, EAX, 17)
|
| 233 | #define X86_FEATURE_PERFMON_V2 KVM_X86_CPU_FEATURE(0x80000022, 0, EAX, 0)
|
| 234 | #define X86_FEATURE_LBR_PMC_FREEZE KVM_X86_CPU_FEATURE(0x80000022, 0, EAX, 2)
|
| 235 |
|
| 236 | |
| 237 | * KVM defined paravirt features.
|
| 238 |
|
| 239 | #define X86_FEATURE_KVM_CLOCKSOURCE KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 0)
|
| 240 | #define X86_FEATURE_KVM_NOP_IO_DELAY KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 1)
|
| 241 | #define X86_FEATURE_KVM_MMU_OP KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 2)
|
| 242 | #define X86_FEATURE_KVM_CLOCKSOURCE2 KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 3)
|
| 243 | #define X86_FEATURE_KVM_ASYNC_PF KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 4)
|
| 244 | #define X86_FEATURE_KVM_STEAL_TIME KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 5)
|
| 245 | #define X86_FEATURE_KVM_PV_EOI KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 6)
|
| 246 | #define X86_FEATURE_KVM_PV_UNHALT KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 7)
|
| 247 |
|
| 248 | #define X86_FEATURE_KVM_PV_TLB_FLUSH KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 9)
|
| 249 | #define X86_FEATURE_KVM_ASYNC_PF_VMEXIT KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 10)
|
| 250 | #define X86_FEATURE_KVM_PV_SEND_IPI KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 11)
|
| 251 | #define X86_FEATURE_KVM_POLL_CONTROL KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 12)
|
| 252 | #define X86_FEATURE_KVM_PV_SCHED_YIELD KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 13)
|
| 253 | #define X86_FEATURE_KVM_ASYNC_PF_INT KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 14)
|
| 254 | #define X86_FEATURE_KVM_MSI_EXT_DEST_ID KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 15)
|
| 255 | #define X86_FEATURE_KVM_HC_MAP_GPA_RANGE KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 16)
|
| 256 | #define X86_FEATURE_KVM_MIGRATION_CONTROL KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 17)
|
| 257 |
|
| 258 | |
| 259 | * Same idea as X86_FEATURE_XXX, but X86_PROPERTY_XXX retrieves a multi-bit
|
| 260 | * value/property as opposed to a single-bit feature. Again, pack the info
|
| 261 | * into a 64-bit value to pass by value with no overhead.
|
| 262 |
|
| 263 | struct kvm_x86_cpu_property {
|
| 264 | u32 function;
|
| 265 | u8 index;
|
| 266 | u8 reg;
|
| 267 | u8 lo_bit;
|
| 268 | u8 hi_bit;
|
| 269 | };
|
| 270 | #define KVM_X86_CPU_PROPERTY(fn, idx, gpr, low_bit, high_bit) \
|
| 271 | ({ \
|
| 272 | struct kvm_x86_cpu_property property = { \
|
| 273 | .function = fn, \
|
| 274 | .index = idx, \
|
| 275 | .reg = KVM_CPUID_##gpr, \
|
| 276 | .lo_bit = low_bit, \
|
| 277 | .hi_bit = high_bit, \
|
| 278 | }; \
|
| 279 | \
|
| 280 | kvm_static_assert(low_bit < high_bit); \
|
| 281 | kvm_static_assert((fn & 0xc0000000) == 0 || \
|
| 282 | (fn & 0xc0000000) == 0x40000000 || \
|
| 283 | (fn & 0xc0000000) == 0x80000000 || \
|
| 284 | (fn & 0xc0000000) == 0xc0000000); \
|
| 285 | kvm_static_assert(idx < BIT(sizeof(property.index) * BITS_PER_BYTE)); \
|
| 286 | property; \
|
| 287 | })
|
| 288 |
|
| 289 | #define X86_PROPERTY_MAX_BASIC_LEAF KVM_X86_CPU_PROPERTY(0, 0, EAX, 0, 31)
|
| 290 | #define X86_PROPERTY_PMU_VERSION KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 0, 7)
|
| 291 | #define X86_PROPERTY_PMU_NR_GP_COUNTERS KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 8, 15)
|
| 292 | #define X86_PROPERTY_PMU_GP_COUNTERS_BIT_WIDTH KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 16, 23)
|
| 293 | #define X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 24, 31)
|
| 294 | #define X86_PROPERTY_PMU_EVENTS_MASK KVM_X86_CPU_PROPERTY(0xa, 0, EBX, 0, 12)
|
| 295 | #define X86_PROPERTY_PMU_FIXED_COUNTERS_BITMASK KVM_X86_CPU_PROPERTY(0xa, 0, ECX, 0, 31)
|
| 296 | #define X86_PROPERTY_PMU_NR_FIXED_COUNTERS KVM_X86_CPU_PROPERTY(0xa, 0, EDX, 0, 4)
|
| 297 | #define X86_PROPERTY_PMU_FIXED_COUNTERS_BIT_WIDTH KVM_X86_CPU_PROPERTY(0xa, 0, EDX, 5, 12)
|
| 298 |
|
| 299 | #define X86_PROPERTY_SUPPORTED_XCR0_LO KVM_X86_CPU_PROPERTY(0xd, 0, EAX, 0, 31)
|
| 300 | #define X86_PROPERTY_XSTATE_MAX_SIZE_XCR0 KVM_X86_CPU_PROPERTY(0xd, 0, EBX, 0, 31)
|
| 301 | #define X86_PROPERTY_XSTATE_MAX_SIZE KVM_X86_CPU_PROPERTY(0xd, 0, ECX, 0, 31)
|
| 302 | #define X86_PROPERTY_SUPPORTED_XCR0_HI KVM_X86_CPU_PROPERTY(0xd, 0, EDX, 0, 31)
|
| 303 |
|
| 304 | #define X86_PROPERTY_XSTATE_TILE_SIZE KVM_X86_CPU_PROPERTY(0xd, 18, EAX, 0, 31)
|
| 305 | #define X86_PROPERTY_XSTATE_TILE_OFFSET KVM_X86_CPU_PROPERTY(0xd, 18, EBX, 0, 31)
|
| 306 | #define X86_PROPERTY_AMX_MAX_PALETTE_TABLES KVM_X86_CPU_PROPERTY(0x1d, 0, EAX, 0, 31)
|
| 307 | #define X86_PROPERTY_AMX_TOTAL_TILE_BYTES KVM_X86_CPU_PROPERTY(0x1d, 1, EAX, 0, 15)
|
| 308 | #define X86_PROPERTY_AMX_BYTES_PER_TILE KVM_X86_CPU_PROPERTY(0x1d, 1, EAX, 16, 31)
|
| 309 | #define X86_PROPERTY_AMX_BYTES_PER_ROW KVM_X86_CPU_PROPERTY(0x1d, 1, EBX, 0, 15)
|
| 310 | #define X86_PROPERTY_AMX_NR_TILE_REGS KVM_X86_CPU_PROPERTY(0x1d, 1, EBX, 16, 31)
|
| 311 | #define X86_PROPERTY_AMX_MAX_ROWS KVM_X86_CPU_PROPERTY(0x1d, 1, ECX, 0, 15)
|
| 312 |
|
| 313 | #define X86_PROPERTY_MAX_KVM_LEAF KVM_X86_CPU_PROPERTY(0x40000000, 0, EAX, 0, 31)
|
| 314 |
|
| 315 | #define X86_PROPERTY_MAX_EXT_LEAF KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31)
|
| 316 | #define X86_PROPERTY_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7)
|
| 317 | #define X86_PROPERTY_MAX_VIRT_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15)
|
| 318 | #define X86_PROPERTY_GUEST_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 16, 23)
|
| 319 | #define X86_PROPERTY_SEV_C_BIT KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5)
|
| 320 | #define X86_PROPERTY_PHYS_ADDR_REDUCTION KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11)
|
| 321 | #define X86_PROPERTY_NR_PERFCTR_CORE KVM_X86_CPU_PROPERTY(0x80000022, 0, EBX, 0, 3)
|
| 322 | #define X86_PROPERTY_NR_PERFCTR_NB KVM_X86_CPU_PROPERTY(0x80000022, 0, EBX, 10, 15)
|
| 323 |
|
| 324 | #define X86_PROPERTY_MAX_CENTAUR_LEAF KVM_X86_CPU_PROPERTY(0xC0000000, 0, EAX, 0, 31)
|
| 325 |
|
| 326 | |
| 327 | * Intel's architectural PMU events are bizarre. They have a "feature" bit
|
| 328 | * that indicates the feature is _not_ supported, and a property that states
|
| 329 | * the length of the bit mask of unsupported features. A feature is supported
|
| 330 | * if the size of the bit mask is larger than the "unavailable" bit, and said
|
| 331 | * bit is not set. Fixed counters also bizarre enumeration, but inverted from
|
| 332 | * arch events for general purpose counters. Fixed counters are supported if a
|
| 333 | * feature flag is set **OR** the total number of fixed counters is greater
|
| 334 | * than index of the counter.
|
| 335 | *
|
| 336 | * Wrap the events for general purpose and fixed counters to simplify checking
|
| 337 | * whether or not a given architectural event is supported.
|
| 338 |
|
| 339 | struct kvm_x86_pmu_feature {
|
| 340 | struct kvm_x86_cpu_feature f;
|
| 341 | };
|
| 342 | #define KVM_X86_PMU_FEATURE(__reg, __bit) \
|
| 343 | ({ \
|
| 344 | struct kvm_x86_pmu_feature feature = { \
|
| 345 | .f = KVM_X86_CPU_FEATURE(0xa, 0, __reg, __bit), \
|
| 346 | }; \
|
| 347 | \
|
| 348 | kvm_static_assert(KVM_CPUID_##__reg == KVM_CPUID_EBX || \
|
| 349 | KVM_CPUID_##__reg == KVM_CPUID_ECX); \
|
| 350 | feature; \
|
| 351 | })
|
| 352 |
|
| 353 | #define X86_PMU_FEATURE_CPU_CYCLES KVM_X86_PMU_FEATURE(EBX, 0)
|
| 354 | #define X86_PMU_FEATURE_INSNS_RETIRED KVM_X86_PMU_FEATURE(EBX, 1)
|
| 355 | #define X86_PMU_FEATURE_REFERENCE_CYCLES KVM_X86_PMU_FEATURE(EBX, 2)
|
| 356 | #define X86_PMU_FEATURE_LLC_REFERENCES KVM_X86_PMU_FEATURE(EBX, 3)
|
| 357 | #define X86_PMU_FEATURE_LLC_MISSES KVM_X86_PMU_FEATURE(EBX, 4)
|
| 358 | #define X86_PMU_FEATURE_BRANCH_INSNS_RETIRED KVM_X86_PMU_FEATURE(EBX, 5)
|
| 359 | #define X86_PMU_FEATURE_BRANCHES_MISPREDICTED KVM_X86_PMU_FEATURE(EBX, 6)
|
| 360 | #define X86_PMU_FEATURE_TOPDOWN_SLOTS KVM_X86_PMU_FEATURE(EBX, 7)
|
| 361 | #define X86_PMU_FEATURE_TOPDOWN_BE_BOUND KVM_X86_PMU_FEATURE(EBX, 8)
|
| 362 | #define X86_PMU_FEATURE_TOPDOWN_BAD_SPEC KVM_X86_PMU_FEATURE(EBX, 9)
|
| 363 | #define X86_PMU_FEATURE_TOPDOWN_FE_BOUND KVM_X86_PMU_FEATURE(EBX, 10)
|
| 364 | #define X86_PMU_FEATURE_TOPDOWN_RETIRING KVM_X86_PMU_FEATURE(EBX, 11)
|
| 365 | #define X86_PMU_FEATURE_LBR_INSERTS KVM_X86_PMU_FEATURE(EBX, 12)
|
| 366 |
|
| 367 | #define X86_PMU_FEATURE_INSNS_RETIRED_FIXED KVM_X86_PMU_FEATURE(ECX, 0)
|
| 368 | #define X86_PMU_FEATURE_CPU_CYCLES_FIXED KVM_X86_PMU_FEATURE(ECX, 1)
|
| 369 | #define X86_PMU_FEATURE_REFERENCE_TSC_CYCLES_FIXED KVM_X86_PMU_FEATURE(ECX, 2)
|
| 370 | #define X86_PMU_FEATURE_TOPDOWN_SLOTS_FIXED KVM_X86_PMU_FEATURE(ECX, 3)
|
| 371 |
|
| 372 | static inline unsigned int x86_family(unsigned int eax)
|
| 373 | {
|
| 374 | unsigned int x86;
|
| 375 |
|
| 376 | x86 = (eax >> 8) & 0xf;
|
| 377 |
|
| 378 | if (x86 == 0xf)
|
| 379 | x86 += (eax >> 20) & 0xff;
|
| 380 |
|
| 381 | return x86;
|
| 382 | }
|
| 383 |
|
| 384 | static inline unsigned int x86_model(unsigned int eax)
|
| 385 | {
|
| 386 | return ((eax >> 12) & 0xf0) | ((eax >> 4) & 0x0f);
|
| 387 | }
|
| 388 |
|
| 389 | #define PHYSICAL_PAGE_MASK GENMASK_ULL(51, 12)
|
| 390 |
|
| 391 | #define PAGE_SHIFT 12
|
| 392 | #define PAGE_SIZE (1ULL << PAGE_SHIFT)
|
| 393 | #define PAGE_MASK (~(PAGE_SIZE-1) & PHYSICAL_PAGE_MASK)
|
| 394 |
|
| 395 | #define HUGEPAGE_SHIFT(x) (PAGE_SHIFT + (((x) - 1) * 9))
|
| 396 | #define HUGEPAGE_SIZE(x) (1UL << HUGEPAGE_SHIFT(x))
|
| 397 | #define HUGEPAGE_MASK(x) (~(HUGEPAGE_SIZE(x) - 1) & PHYSICAL_PAGE_MASK)
|
| 398 |
|
| 399 | #define PTE_GET_PA(pte) ((pte) & PHYSICAL_PAGE_MASK)
|
| 400 | #define PTE_GET_PFN(pte) (PTE_GET_PA(pte) >> PAGE_SHIFT)
|
| 401 |
|
| 402 | struct guest_regs {
|
| 403 | u64 rax;
|
| 404 | u64 rcx;
|
| 405 | u64 rdx;
|
| 406 | u64 rbx;
|
| 407 | u64 rsp;
|
| 408 | u64 rbp;
|
| 409 | u64 rsi;
|
| 410 | u64 rdi;
|
| 411 | u64 r8;
|
| 412 | u64 r9;
|
| 413 | u64 r10;
|
| 414 | u64 r11;
|
| 415 | u64 r12;
|
| 416 | u64 r13;
|
| 417 | u64 r14;
|
| 418 | u64 r15;
|
| 419 | u64 rflags;
|
| 420 | };
|
| 421 |
|
| 422 | extern struct guest_regs guest_regs;
|
| 423 |
|
| 424 | #define GUEST_REG_OFFSET(name) \
|
| 425 | [off_##name] "i" (offsetof(struct guest_regs, name))
|
| 426 |
|
| 427 | #define GUEST_REGS_OFFSETS \
|
| 428 | GUEST_REG_OFFSET(rax), \
|
| 429 | GUEST_REG_OFFSET(rcx), \
|
| 430 | GUEST_REG_OFFSET(rdx), \
|
| 431 | GUEST_REG_OFFSET(rbx), \
|
| 432 | GUEST_REG_OFFSET(rsp), \
|
| 433 | GUEST_REG_OFFSET(rbp), \
|
| 434 | GUEST_REG_OFFSET(rsi), \
|
| 435 | GUEST_REG_OFFSET(rdi), \
|
| 436 | GUEST_REG_OFFSET(r8), \
|
| 437 | GUEST_REG_OFFSET(r9), \
|
| 438 | GUEST_REG_OFFSET(r10), \
|
| 439 | GUEST_REG_OFFSET(r11), \
|
| 440 | GUEST_REG_OFFSET(r12), \
|
| 441 | GUEST_REG_OFFSET(r13), \
|
| 442 | GUEST_REG_OFFSET(r14), \
|
| 443 | GUEST_REG_OFFSET(r15), \
|
| 444 | GUEST_REG_OFFSET(rflags)
|
| 445 |
|
| 446 | #define GUEST_REG(name) "guest_regs + %c[off_" #name "]"
|
| 447 |
|
| 448 | #define GUEST_SWITCH_GPR_ASM(name) \
|
| 449 | "xchg %%" #name ", " GUEST_REG(name) "\n\t"
|
| 450 |
|
| 451 | struct desc64 {
|
| 452 | u16 limit0;
|
| 453 | u16 base0;
|
| 454 | unsigned base1:8, type:4, s:1, dpl:2, p:1;
|
| 455 | unsigned limit1:4, avl:1, l:1, db:1, g:1, base2:8;
|
| 456 | u32 base3;
|
| 457 | u32 zero1;
|
| 458 | } __attribute__((packed));
|
| 459 |
|
| 460 | struct desc_ptr {
|
| 461 | u16 size;
|
| 462 | u64 address;
|
| 463 | } __attribute__((packed));
|
| 464 |
|
| 465 | struct kvm_x86_state {
|
| 466 | struct kvm_xsave *xsave;
|
| 467 | struct kvm_vcpu_events events;
|
| 468 | struct kvm_mp_state mp_state;
|
| 469 | struct kvm_regs regs;
|
| 470 | struct kvm_xcrs xcrs;
|
| 471 | struct kvm_sregs sregs;
|
| 472 | struct kvm_debugregs debugregs;
|
| 473 | union {
|
| 474 | struct kvm_nested_state nested;
|
| 475 | char nested_[16384];
|
| 476 | };
|
| 477 | struct kvm_msrs msrs;
|
| 478 | };
|
| 479 |
|
| 480 | static inline u64 get_desc64_base(const struct desc64 *desc)
|
| 481 | {
|
| 482 | return (u64)desc->base3 << 32 |
|
| 483 | (u64)desc->base2 << 24 |
|
| 484 | (u64)desc->base1 << 16 |
|
| 485 | (u64)desc->base0;
|
| 486 | }
|
| 487 |
|
| 488 | static inline u64 rdtsc(void)
|
| 489 | {
|
| 490 | u32 eax, edx;
|
| 491 | u64 tsc_val;
|
| 492 | |
| 493 | * The lfence is to wait (on Intel CPUs) until all previous
|
| 494 | * instructions have been executed. If software requires RDTSC to be
|
| 495 | * executed prior to execution of any subsequent instruction, it can
|
| 496 | * execute LFENCE immediately after RDTSC
|
| 497 |
|
| 498 | __asm__ __volatile__("lfence; rdtsc; lfence" : "=a"(eax), "=d"(edx));
|
| 499 | tsc_val = ((u64)edx) << 32 | eax;
|
| 500 | return tsc_val;
|
| 501 | }
|
| 502 |
|
| 503 | static inline u64 rdtscp(u32 *aux)
|
| 504 | {
|
| 505 | u32 eax, edx;
|
| 506 |
|
| 507 | __asm__ __volatile__("rdtscp" : "=a"(eax), "=d"(edx), "=c"(*aux));
|
| 508 | return ((u64)edx) << 32 | eax;
|
| 509 | }
|
| 510 |
|
| 511 | static inline u64 rdmsr(u32 msr)
|
| 512 | {
|
| 513 | u32 a, d;
|
| 514 |
|
| 515 | __asm__ __volatile__("rdmsr" : "=a"(a), "=d"(d) : "c"(msr) : "memory");
|
| 516 |
|
| 517 | return a | ((u64)d << 32);
|
| 518 | }
|
| 519 |
|
| 520 | static inline void wrmsr(u32 msr, u64 value)
|
| 521 | {
|
| 522 | u32 a = value;
|
| 523 | u32 d = value >> 32;
|
| 524 |
|
| 525 | __asm__ __volatile__("wrmsr" :: "a"(a), "d"(d), "c"(msr) : "memory");
|
| 526 | }
|
| 527 |
|
| 528 |
|
| 529 | static inline u16 inw(u16 port)
|
| 530 | {
|
| 531 | u16 tmp;
|
| 532 |
|
| 533 | __asm__ __volatile__("in %%dx, %%ax"
|
| 534 | : "=a" (tmp)
|
| 535 | : "d" (port));
|
| 536 |
|
| 537 | return tmp;
|
| 538 | }
|
| 539 |
|
| 540 | static inline u16 get_es(void)
|
| 541 | {
|
| 542 | u16 es;
|
| 543 |
|
| 544 | __asm__ __volatile__("mov %%es, %[es]"
|
| 545 | : [es]"=rm"(es));
|
| 546 | return es;
|
| 547 | }
|
| 548 |
|
| 549 | static inline u16 get_cs(void)
|
| 550 | {
|
| 551 | u16 cs;
|
| 552 |
|
| 553 | __asm__ __volatile__("mov %%cs, %[cs]"
|
| 554 | : [cs]"=rm"(cs));
|
| 555 | return cs;
|
| 556 | }
|
| 557 |
|
| 558 | static inline u16 get_ss(void)
|
| 559 | {
|
| 560 | u16 ss;
|
| 561 |
|
| 562 | __asm__ __volatile__("mov %%ss, %[ss]"
|
| 563 | : [ss]"=rm"(ss));
|
| 564 | return ss;
|
| 565 | }
|
| 566 |
|
| 567 | static inline u16 get_ds(void)
|
| 568 | {
|
| 569 | u16 ds;
|
| 570 |
|
| 571 | __asm__ __volatile__("mov %%ds, %[ds]"
|
| 572 | : [ds]"=rm"(ds));
|
| 573 | return ds;
|
| 574 | }
|
| 575 |
|
| 576 | static inline u16 get_fs(void)
|
| 577 | {
|
| 578 | u16 fs;
|
| 579 |
|
| 580 | __asm__ __volatile__("mov %%fs, %[fs]"
|
| 581 | : [fs]"=rm"(fs));
|
| 582 | return fs;
|
| 583 | }
|
| 584 |
|
| 585 | static inline u16 get_gs(void)
|
| 586 | {
|
| 587 | u16 gs;
|
| 588 |
|
| 589 | __asm__ __volatile__("mov %%gs, %[gs]"
|
| 590 | : [gs]"=rm"(gs));
|
| 591 | return gs;
|
| 592 | }
|
| 593 |
|
| 594 | static inline u16 get_tr(void)
|
| 595 | {
|
| 596 | u16 tr;
|
| 597 |
|
| 598 | __asm__ __volatile__("str %[tr]"
|
| 599 | : [tr]"=rm"(tr));
|
| 600 | return tr;
|
| 601 | }
|
| 602 |
|
| 603 | static inline u64 get_cr0(void)
|
| 604 | {
|
| 605 | u64 cr0;
|
| 606 |
|
| 607 | __asm__ __volatile__("mov %%cr0, %[cr0]"
|
| 608 | : [cr0]"=r"(cr0));
|
| 609 | return cr0;
|
| 610 | }
|
| 611 |
|
| 612 | static inline void set_cr0(u64 val)
|
| 613 | {
|
| 614 | __asm__ __volatile__("mov %0, %%cr0" : : "r" (val) : "memory");
|
| 615 | }
|
| 616 |
|
| 617 | static inline u64 get_cr2(void)
|
| 618 | {
|
| 619 | u64 cr2;
|
| 620 |
|
| 621 | __asm__ __volatile__("mov %%cr2, %[cr2]" : [cr2]"=r"(cr2));
|
| 622 | return cr2;
|
| 623 | }
|
| 624 |
|
| 625 | static inline u64 get_cr3(void)
|
| 626 | {
|
| 627 | u64 cr3;
|
| 628 |
|
| 629 | __asm__ __volatile__("mov %%cr3, %[cr3]"
|
| 630 | : [cr3]"=r"(cr3));
|
| 631 | return cr3;
|
| 632 | }
|
| 633 |
|
| 634 | static inline void set_cr3(u64 val)
|
| 635 | {
|
| 636 | __asm__ __volatile__("mov %0, %%cr3" : : "r" (val) : "memory");
|
| 637 | }
|
| 638 |
|
| 639 | static inline u64 get_cr4(void)
|
| 640 | {
|
| 641 | u64 cr4;
|
| 642 |
|
| 643 | __asm__ __volatile__("mov %%cr4, %[cr4]"
|
| 644 | : [cr4]"=r"(cr4));
|
| 645 | return cr4;
|
| 646 | }
|
| 647 |
|
| 648 | static inline void set_cr4(u64 val)
|
| 649 | {
|
| 650 | __asm__ __volatile__("mov %0, %%cr4" : : "r" (val) : "memory");
|
| 651 | }
|
| 652 |
|
| 653 | static inline u64 get_cr8(void)
|
| 654 | {
|
| 655 | u64 cr8;
|
| 656 |
|
| 657 | __asm__ __volatile__("mov %%cr8, %[cr8]" : [cr8]"=r"(cr8));
|
| 658 | return cr8;
|
| 659 | }
|
| 660 |
|
| 661 | static inline void set_cr8(u64 val)
|
| 662 | {
|
| 663 | __asm__ __volatile__("mov %0, %%cr8" : : "r" (val) : "memory");
|
| 664 | }
|
| 665 |
|
| 666 | static inline void set_idt(const struct desc_ptr *idt_desc)
|
| 667 | {
|
| 668 | __asm__ __volatile__("lidt %0"::"m"(*idt_desc));
|
| 669 | }
|
| 670 |
|
| 671 | static inline u64 xgetbv(u32 index)
|
| 672 | {
|
| 673 | u32 eax, edx;
|
| 674 |
|
| 675 | __asm__ __volatile__("xgetbv;"
|
| 676 | : "=a" (eax), "=d" (edx)
|
| 677 | : "c" (index));
|
| 678 | return eax | ((u64)edx << 32);
|
| 679 | }
|
| 680 |
|
| 681 | static inline void xsetbv(u32 index, u64 value)
|
| 682 | {
|
| 683 | u32 eax = value;
|
| 684 | u32 edx = value >> 32;
|
| 685 |
|
| 686 | __asm__ __volatile__("xsetbv" :: "a" (eax), "d" (edx), "c" (index));
|
| 687 | }
|
| 688 |
|
| 689 | static inline void wrpkru(u32 pkru)
|
| 690 | {
|
| 691 |
|
| 692 | asm volatile(".byte 0x0f,0x01,0xef\n\t"
|
| 693 | : : "a" (pkru), "c"(0), "d"(0));
|
| 694 | }
|
| 695 |
|
| 696 | static inline struct desc_ptr get_gdt(void)
|
| 697 | {
|
| 698 | struct desc_ptr gdt;
|
| 699 | __asm__ __volatile__("sgdt %[gdt]"
|
| 700 | : [gdt]"=m"(gdt));
|
| 701 | return gdt;
|
| 702 | }
|
| 703 |
|
| 704 | static inline struct desc_ptr get_idt(void)
|
| 705 | {
|
| 706 | struct desc_ptr idt;
|
| 707 | __asm__ __volatile__("sidt %[idt]"
|
| 708 | : [idt]"=m"(idt));
|
| 709 | return idt;
|
| 710 | }
|
| 711 |
|
| 712 | static inline void outl(u16 port, u32 value)
|
| 713 | {
|
| 714 | __asm__ __volatile__("outl %%eax, %%dx" : : "d"(port), "a"(value));
|
| 715 | }
|
| 716 |
|
| 717 | static inline void __cpuid(u32 function, u32 index,
|
| 718 | u32 *eax, u32 *ebx,
|
| 719 | u32 *ecx, u32 *edx)
|
| 720 | {
|
| 721 | *eax = function;
|
| 722 | *ecx = index;
|
| 723 |
|
| 724 | asm volatile("cpuid"
|
| 725 | : "=a" (*eax),
|
| 726 | "=b" (*ebx),
|
| 727 | "=c" (*ecx),
|
| 728 | "=d" (*edx)
|
| 729 | : "0" (*eax), "2" (*ecx)
|
| 730 | : "memory");
|
| 731 | }
|
| 732 |
|
| 733 | static inline void cpuid(u32 function,
|
| 734 | u32 *eax, u32 *ebx,
|
| 735 | u32 *ecx, u32 *edx)
|
| 736 | {
|
| 737 | return __cpuid(function, 0, eax, ebx, ecx, edx);
|
| 738 | }
|
| 739 |
|
| 740 | static inline u32 this_cpu_fms(void)
|
| 741 | {
|
| 742 | u32 eax, ebx, ecx, edx;
|
| 743 |
|
| 744 | cpuid(1, &eax, &ebx, &ecx, &edx);
|
| 745 | return eax;
|
| 746 | }
|
| 747 |
|
| 748 | static inline u32 this_cpu_family(void)
|
| 749 | {
|
| 750 | return x86_family(this_cpu_fms());
|
| 751 | }
|
| 752 |
|
| 753 | static inline u32 this_cpu_model(void)
|
| 754 | {
|
| 755 | return x86_model(this_cpu_fms());
|
| 756 | }
|
| 757 |
|
| 758 | static inline bool this_cpu_vendor_string_is(const char *vendor)
|
| 759 | {
|
| 760 | const u32 *chunk = (const u32 *)vendor;
|
| 761 | u32 eax, ebx, ecx, edx;
|
| 762 |
|
| 763 | cpuid(0, &eax, &ebx, &ecx, &edx);
|
| 764 | return (ebx == chunk[0] && edx == chunk[1] && ecx == chunk[2]);
|
| 765 | }
|
| 766 |
|
| 767 | static inline bool this_cpu_is_intel(void)
|
| 768 | {
|
| 769 | return this_cpu_vendor_string_is("GenuineIntel");
|
| 770 | }
|
| 771 |
|
| 772 | |
| 773 | * Exclude early K5 samples with a vendor string of "AMDisbetter!"
|
| 774 |
|
| 775 | static inline bool this_cpu_is_amd(void)
|
| 776 | {
|
| 777 | return this_cpu_vendor_string_is("AuthenticAMD");
|
| 778 | }
|
| 779 |
|
| 780 | static inline bool this_cpu_is_hygon(void)
|
| 781 | {
|
| 782 | return this_cpu_vendor_string_is("HygonGenuine");
|
| 783 | }
|
| 784 |
|
| 785 | static inline u32 __this_cpu_has(u32 function, u32 index, u8 reg, u8 lo, u8 hi)
|
| 786 | {
|
| 787 | u32 gprs[4];
|
| 788 |
|
| 789 | __cpuid(function, index,
|
| 790 | &gprs[KVM_CPUID_EAX], &gprs[KVM_CPUID_EBX],
|
| 791 | &gprs[KVM_CPUID_ECX], &gprs[KVM_CPUID_EDX]);
|
| 792 |
|
| 793 | return (gprs[reg] & GENMASK(hi, lo)) >> lo;
|
| 794 | }
|
| 795 |
|
| 796 | static inline bool this_cpu_has(struct kvm_x86_cpu_feature feature)
|
| 797 | {
|
| 798 | return __this_cpu_has(feature.function, feature.index,
|
| 799 | feature.reg, feature.bit, feature.bit);
|
| 800 | }
|
| 801 |
|
| 802 | static inline u32 this_cpu_property(struct kvm_x86_cpu_property property)
|
| 803 | {
|
| 804 | return __this_cpu_has(property.function, property.index,
|
| 805 | property.reg, property.lo_bit, property.hi_bit);
|
| 806 | }
|
| 807 |
|
| 808 | static __always_inline bool this_cpu_has_p(struct kvm_x86_cpu_property property)
|
| 809 | {
|
| 810 | u32 max_leaf;
|
| 811 |
|
| 812 | switch (property.function & 0xc0000000) {
|
| 813 | case 0:
|
| 814 | max_leaf = this_cpu_property(X86_PROPERTY_MAX_BASIC_LEAF);
|
| 815 | break;
|
| 816 | case 0x40000000:
|
| 817 | max_leaf = this_cpu_property(X86_PROPERTY_MAX_KVM_LEAF);
|
| 818 | break;
|
| 819 | case 0x80000000:
|
| 820 | max_leaf = this_cpu_property(X86_PROPERTY_MAX_EXT_LEAF);
|
| 821 | break;
|
| 822 | case 0xc0000000:
|
| 823 | max_leaf = this_cpu_property(X86_PROPERTY_MAX_CENTAUR_LEAF);
|
| 824 | }
|
| 825 | return max_leaf >= property.function;
|
| 826 | }
|
| 827 |
|
| 828 | static inline bool this_pmu_has(struct kvm_x86_pmu_feature feature)
|
| 829 | {
|
| 830 | u32 nr_bits;
|
| 831 |
|
| 832 | if (feature.f.reg == KVM_CPUID_EBX) {
|
| 833 | nr_bits = this_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);
|
| 834 | return nr_bits > feature.f.bit && !this_cpu_has(feature.f);
|
| 835 | }
|
| 836 |
|
| 837 | GUEST_ASSERT(feature.f.reg == KVM_CPUID_ECX);
|
| 838 | nr_bits = this_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);
|
| 839 | return nr_bits > feature.f.bit || this_cpu_has(feature.f);
|
| 840 | }
|
| 841 |
|
| 842 | static __always_inline u64 this_cpu_supported_xcr0(void)
|
| 843 | {
|
| 844 | if (!this_cpu_has_p(X86_PROPERTY_SUPPORTED_XCR0_LO))
|
| 845 | return 0;
|
| 846 |
|
| 847 | return this_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_LO) |
|
| 848 | ((u64)this_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_HI) << 32);
|
| 849 | }
|
| 850 |
|
| 851 | typedef u32 __attribute__((vector_size(16))) sse128_t;
|
| 852 | #define __sse128_u union { sse128_t vec; u64 as_u64[2]; u32 as_u32[4]; }
|
| 853 | #define sse128_lo(x) ({ __sse128_u t; t.vec = x; t.as_u64[0]; })
|
| 854 | #define sse128_hi(x) ({ __sse128_u t; t.vec = x; t.as_u64[1]; })
|
| 855 |
|
| 856 | static inline void read_sse_reg(int reg, sse128_t *data)
|
| 857 | {
|
| 858 | switch (reg) {
|
| 859 | case 0:
|
| 860 | asm("movdqa %%xmm0, %0" : "=m"(*data));
|
| 861 | break;
|
| 862 | case 1:
|
| 863 | asm("movdqa %%xmm1, %0" : "=m"(*data));
|
| 864 | break;
|
| 865 | case 2:
|
| 866 | asm("movdqa %%xmm2, %0" : "=m"(*data));
|
| 867 | break;
|
| 868 | case 3:
|
| 869 | asm("movdqa %%xmm3, %0" : "=m"(*data));
|
| 870 | break;
|
| 871 | case 4:
|
| 872 | asm("movdqa %%xmm4, %0" : "=m"(*data));
|
| 873 | break;
|
| 874 | case 5:
|
| 875 | asm("movdqa %%xmm5, %0" : "=m"(*data));
|
| 876 | break;
|
| 877 | case 6:
|
| 878 | asm("movdqa %%xmm6, %0" : "=m"(*data));
|
| 879 | break;
|
| 880 | case 7:
|
| 881 | asm("movdqa %%xmm7, %0" : "=m"(*data));
|
| 882 | break;
|
| 883 | default:
|
| 884 | BUG();
|
| 885 | }
|
| 886 | }
|
| 887 |
|
| 888 | static inline void write_sse_reg(int reg, const sse128_t *data)
|
| 889 | {
|
| 890 | switch (reg) {
|
| 891 | case 0:
|
| 892 | asm("movdqa %0, %%xmm0" : : "m"(*data));
|
| 893 | break;
|
| 894 | case 1:
|
| 895 | asm("movdqa %0, %%xmm1" : : "m"(*data));
|
| 896 | break;
|
| 897 | case 2:
|
| 898 | asm("movdqa %0, %%xmm2" : : "m"(*data));
|
| 899 | break;
|
| 900 | case 3:
|
| 901 | asm("movdqa %0, %%xmm3" : : "m"(*data));
|
| 902 | break;
|
| 903 | case 4:
|
| 904 | asm("movdqa %0, %%xmm4" : : "m"(*data));
|
| 905 | break;
|
| 906 | case 5:
|
| 907 | asm("movdqa %0, %%xmm5" : : "m"(*data));
|
| 908 | break;
|
| 909 | case 6:
|
| 910 | asm("movdqa %0, %%xmm6" : : "m"(*data));
|
| 911 | break;
|
| 912 | case 7:
|
| 913 | asm("movdqa %0, %%xmm7" : : "m"(*data));
|
| 914 | break;
|
| 915 | default:
|
| 916 | BUG();
|
| 917 | }
|
| 918 | }
|
| 919 |
|
| 920 | static inline void invlpg(u64 addr)
|
| 921 | {
|
| 922 | __asm__ __volatile__("invlpg (%0)" : : "r"(addr) : "memory");
|
| 923 | }
|
| 924 |
|
| 925 | static inline void cpu_relax(void)
|
| 926 | {
|
| 927 | asm volatile("rep; nop" ::: "memory");
|
| 928 | }
|
| 929 |
|
| 930 | static inline void udelay(unsigned long usec)
|
| 931 | {
|
| 932 | u64 start, now, cycles;
|
| 933 |
|
| 934 | GUEST_ASSERT(guest_tsc_khz);
|
| 935 | cycles = guest_tsc_khz / 1000 * usec;
|
| 936 |
|
| 937 | |
| 938 | * Deliberately don't PAUSE, a.k.a. cpu_relax(), so that the delay is
|
| 939 | * as accurate as possible, e.g. doesn't trigger PAUSE-Loop VM-Exits.
|
| 940 |
|
| 941 | start = rdtsc();
|
| 942 | do {
|
| 943 | now = rdtsc();
|
| 944 | } while (now - start < cycles);
|
| 945 | }
|
| 946 |
|
| 947 | #define ud2() \
|
| 948 | __asm__ __volatile__( \
|
| 949 | "ud2\n" \
|
| 950 | )
|
| 951 |
|
| 952 | #define hlt() \
|
| 953 | __asm__ __volatile__( \
|
| 954 | "hlt\n" \
|
| 955 | )
|
| 956 |
|
| 957 | struct kvm_x86_state *vcpu_save_state(struct kvm_vcpu *vcpu);
|
| 958 | void vcpu_load_state(struct kvm_vcpu *vcpu, struct kvm_x86_state *state);
|
| 959 | void kvm_x86_state_cleanup(struct kvm_x86_state *state);
|
| 960 |
|
| 961 | static inline bool kvm_x86_state_is_guest_mode(struct kvm_x86_state *state)
|
| 962 | {
|
| 963 | return state->nested.size && (state->nested.flags & KVM_STATE_NESTED_GUEST_MODE);
|
| 964 | }
|
| 965 |
|
| 966 | const struct kvm_msr_list *kvm_get_msr_index_list(void);
|
| 967 | const struct kvm_msr_list *kvm_get_feature_msr_index_list(void);
|
| 968 | bool kvm_msr_is_in_save_restore_list(u32 msr_index);
|
| 969 | u64 kvm_get_feature_msr(u64 msr_index);
|
| 970 |
|
| 971 | static inline void vcpu_msrs_get(struct kvm_vcpu *vcpu,
|
| 972 | struct kvm_msrs *msrs)
|
| 973 | {
|
| 974 | int r = __vcpu_ioctl(vcpu, KVM_GET_MSRS, msrs);
|
| 975 |
|
| 976 | TEST_ASSERT(r == msrs->nmsrs,
|
| 977 | "KVM_GET_MSRS failed, r: %i (failed on MSR %x)",
|
| 978 | r, r < 0 || r >= msrs->nmsrs ? -1 : msrs->entries[r].index);
|
| 979 | }
|
| 980 | static inline void vcpu_msrs_set(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs)
|
| 981 | {
|
| 982 | int r = __vcpu_ioctl(vcpu, KVM_SET_MSRS, msrs);
|
| 983 |
|
| 984 | TEST_ASSERT(r == msrs->nmsrs,
|
| 985 | "KVM_SET_MSRS failed, r: %i (failed on MSR %x)",
|
| 986 | r, r < 0 || r >= msrs->nmsrs ? -1 : msrs->entries[r].index);
|
| 987 | }
|
| 988 | static inline void vcpu_debugregs_get(struct kvm_vcpu *vcpu,
|
| 989 | struct kvm_debugregs *debugregs)
|
| 990 | {
|
| 991 | vcpu_ioctl(vcpu, KVM_GET_DEBUGREGS, debugregs);
|
| 992 | }
|
| 993 | static inline void vcpu_debugregs_set(struct kvm_vcpu *vcpu,
|
| 994 | struct kvm_debugregs *debugregs)
|
| 995 | {
|
| 996 | vcpu_ioctl(vcpu, KVM_SET_DEBUGREGS, debugregs);
|
| 997 | }
|
| 998 | static inline void vcpu_xsave_get(struct kvm_vcpu *vcpu,
|
| 999 | struct kvm_xsave *xsave)
|
| 1000 | {
|
| 1001 | vcpu_ioctl(vcpu, KVM_GET_XSAVE, xsave);
|
| 1002 | }
|
| 1003 | static inline void vcpu_xsave2_get(struct kvm_vcpu *vcpu,
|
| 1004 | struct kvm_xsave *xsave)
|
| 1005 | {
|
| 1006 | vcpu_ioctl(vcpu, KVM_GET_XSAVE2, xsave);
|
| 1007 | }
|
| 1008 | static inline void vcpu_xsave_set(struct kvm_vcpu *vcpu,
|
| 1009 | struct kvm_xsave *xsave)
|
| 1010 | {
|
| 1011 | vcpu_ioctl(vcpu, KVM_SET_XSAVE, xsave);
|
| 1012 | }
|
| 1013 | static inline void vcpu_xcrs_get(struct kvm_vcpu *vcpu,
|
| 1014 | struct kvm_xcrs *xcrs)
|
| 1015 | {
|
| 1016 | vcpu_ioctl(vcpu, KVM_GET_XCRS, xcrs);
|
| 1017 | }
|
| 1018 | static inline void vcpu_xcrs_set(struct kvm_vcpu *vcpu, struct kvm_xcrs *xcrs)
|
| 1019 | {
|
| 1020 | vcpu_ioctl(vcpu, KVM_SET_XCRS, xcrs);
|
| 1021 | }
|
| 1022 |
|
| 1023 | const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,
|
| 1024 | u32 function, u32 index);
|
| 1025 | const struct kvm_cpuid2 *kvm_get_supported_cpuid(void);
|
| 1026 |
|
| 1027 | static inline u32 kvm_cpu_fms(void)
|
| 1028 | {
|
| 1029 | return get_cpuid_entry(kvm_get_supported_cpuid(), 0x1, 0)->eax;
|
| 1030 | }
|
| 1031 |
|
| 1032 | static inline u32 kvm_cpu_family(void)
|
| 1033 | {
|
| 1034 | return x86_family(kvm_cpu_fms());
|
| 1035 | }
|
| 1036 |
|
| 1037 | static inline u32 kvm_cpu_model(void)
|
| 1038 | {
|
| 1039 | return x86_model(kvm_cpu_fms());
|
| 1040 | }
|
| 1041 |
|
| 1042 | bool kvm_cpuid_has(const struct kvm_cpuid2 *cpuid,
|
| 1043 | struct kvm_x86_cpu_feature feature);
|
| 1044 |
|
| 1045 | static inline bool kvm_cpu_has(struct kvm_x86_cpu_feature feature)
|
| 1046 | {
|
| 1047 | return kvm_cpuid_has(kvm_get_supported_cpuid(), feature);
|
| 1048 | }
|
| 1049 |
|
| 1050 | u32 kvm_cpuid_property(const struct kvm_cpuid2 *cpuid,
|
| 1051 | struct kvm_x86_cpu_property property);
|
| 1052 |
|
| 1053 | static inline u32 kvm_cpu_property(struct kvm_x86_cpu_property property)
|
| 1054 | {
|
| 1055 | return kvm_cpuid_property(kvm_get_supported_cpuid(), property);
|
| 1056 | }
|
| 1057 |
|
| 1058 | static __always_inline bool kvm_cpu_has_p(struct kvm_x86_cpu_property property)
|
| 1059 | {
|
| 1060 | u32 max_leaf;
|
| 1061 |
|
| 1062 | switch (property.function & 0xc0000000) {
|
| 1063 | case 0:
|
| 1064 | max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_BASIC_LEAF);
|
| 1065 | break;
|
| 1066 | case 0x40000000:
|
| 1067 | max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_KVM_LEAF);
|
| 1068 | break;
|
| 1069 | case 0x80000000:
|
| 1070 | max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_EXT_LEAF);
|
| 1071 | break;
|
| 1072 | case 0xc0000000:
|
| 1073 | max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_CENTAUR_LEAF);
|
| 1074 | }
|
| 1075 | return max_leaf >= property.function;
|
| 1076 | }
|
| 1077 |
|
| 1078 | static inline bool kvm_pmu_has(struct kvm_x86_pmu_feature feature)
|
| 1079 | {
|
| 1080 | u32 nr_bits;
|
| 1081 |
|
| 1082 | if (feature.f.reg == KVM_CPUID_EBX) {
|
| 1083 | nr_bits = kvm_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);
|
| 1084 | return nr_bits > feature.f.bit && !kvm_cpu_has(feature.f);
|
| 1085 | }
|
| 1086 |
|
| 1087 | TEST_ASSERT_EQ(feature.f.reg, KVM_CPUID_ECX);
|
| 1088 | nr_bits = kvm_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);
|
| 1089 | return nr_bits > feature.f.bit || kvm_cpu_has(feature.f);
|
| 1090 | }
|
| 1091 |
|
| 1092 | static __always_inline u64 kvm_cpu_supported_xcr0(void)
|
| 1093 | {
|
| 1094 | if (!kvm_cpu_has_p(X86_PROPERTY_SUPPORTED_XCR0_LO))
|
| 1095 | return 0;
|
| 1096 |
|
| 1097 | return kvm_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_LO) |
|
| 1098 | ((u64)kvm_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_HI) << 32);
|
| 1099 | }
|
| 1100 |
|
| 1101 | static inline size_t kvm_cpuid2_size(int nr_entries)
|
| 1102 | {
|
| 1103 | return sizeof(struct kvm_cpuid2) +
|
| 1104 | sizeof(struct kvm_cpuid_entry2) * nr_entries;
|
| 1105 | }
|
| 1106 |
|
| 1107 | |
| 1108 | * Allocate a "struct kvm_cpuid2* instance, with the 0-length arrary of
|
| 1109 | * entries sized to hold @nr_entries. The caller is responsible for freeing
|
| 1110 | * the struct.
|
| 1111 |
|
| 1112 | static inline struct kvm_cpuid2 *allocate_kvm_cpuid2(int nr_entries)
|
| 1113 | {
|
| 1114 | struct kvm_cpuid2 *cpuid;
|
| 1115 |
|
| 1116 | cpuid = malloc(kvm_cpuid2_size(nr_entries));
|
| 1117 | TEST_ASSERT(cpuid, "-ENOMEM when allocating kvm_cpuid2");
|
| 1118 |
|
| 1119 | cpuid->nent = nr_entries;
|
| 1120 |
|
| 1121 | return cpuid;
|
| 1122 | }
|
| 1123 |
|
| 1124 | void vcpu_init_cpuid(struct kvm_vcpu *vcpu, const struct kvm_cpuid2 *cpuid);
|
| 1125 |
|
| 1126 | static inline void vcpu_get_cpuid(struct kvm_vcpu *vcpu)
|
| 1127 | {
|
| 1128 | vcpu_ioctl(vcpu, KVM_GET_CPUID2, vcpu->cpuid);
|
| 1129 | }
|
| 1130 |
|
| 1131 | static inline struct kvm_cpuid_entry2 *__vcpu_get_cpuid_entry(struct kvm_vcpu *vcpu,
|
| 1132 | u32 function,
|
| 1133 | u32 index)
|
| 1134 | {
|
| 1135 | TEST_ASSERT(vcpu->cpuid, "Must do vcpu_init_cpuid() first (or equivalent)");
|
| 1136 |
|
| 1137 | vcpu_get_cpuid(vcpu);
|
| 1138 |
|
| 1139 | return (struct kvm_cpuid_entry2 *)get_cpuid_entry(vcpu->cpuid,
|
| 1140 | function, index);
|
| 1141 | }
|
| 1142 |
|
| 1143 | static inline struct kvm_cpuid_entry2 *vcpu_get_cpuid_entry(struct kvm_vcpu *vcpu,
|
| 1144 | u32 function)
|
| 1145 | {
|
| 1146 | return __vcpu_get_cpuid_entry(vcpu, function, 0);
|
| 1147 | }
|
| 1148 |
|
| 1149 | static inline int __vcpu_set_cpuid(struct kvm_vcpu *vcpu)
|
| 1150 | {
|
| 1151 | int r;
|
| 1152 |
|
| 1153 | TEST_ASSERT(vcpu->cpuid, "Must do vcpu_init_cpuid() first");
|
| 1154 | r = __vcpu_ioctl(vcpu, KVM_SET_CPUID2, vcpu->cpuid);
|
| 1155 | if (r)
|
| 1156 | return r;
|
| 1157 |
|
| 1158 |
|
| 1159 | vcpu_get_cpuid(vcpu);
|
| 1160 | return 0;
|
| 1161 | }
|
| 1162 |
|
| 1163 | static inline void vcpu_set_cpuid(struct kvm_vcpu *vcpu)
|
| 1164 | {
|
| 1165 | TEST_ASSERT(vcpu->cpuid, "Must do vcpu_init_cpuid() first");
|
| 1166 | vcpu_ioctl(vcpu, KVM_SET_CPUID2, vcpu->cpuid);
|
| 1167 |
|
| 1168 |
|
| 1169 | vcpu_get_cpuid(vcpu);
|
| 1170 | }
|
| 1171 |
|
| 1172 | void vcpu_set_cpuid_property(struct kvm_vcpu *vcpu,
|
| 1173 | struct kvm_x86_cpu_property property,
|
| 1174 | u32 value);
|
| 1175 | void vcpu_set_cpuid_maxphyaddr(struct kvm_vcpu *vcpu, u8 maxphyaddr);
|
| 1176 |
|
| 1177 | void vcpu_clear_cpuid_entry(struct kvm_vcpu *vcpu, u32 function);
|
| 1178 |
|
| 1179 | static inline bool vcpu_cpuid_has(struct kvm_vcpu *vcpu,
|
| 1180 | struct kvm_x86_cpu_feature feature)
|
| 1181 | {
|
| 1182 | struct kvm_cpuid_entry2 *entry;
|
| 1183 |
|
| 1184 | entry = __vcpu_get_cpuid_entry(vcpu, feature.function, feature.index);
|
| 1185 | return *((&entry->eax) + feature.reg) & BIT(feature.bit);
|
| 1186 | }
|
| 1187 |
|
| 1188 | void vcpu_set_or_clear_cpuid_feature(struct kvm_vcpu *vcpu,
|
| 1189 | struct kvm_x86_cpu_feature feature,
|
| 1190 | bool set);
|
| 1191 |
|
| 1192 | static inline void vcpu_set_cpuid_feature(struct kvm_vcpu *vcpu,
|
| 1193 | struct kvm_x86_cpu_feature feature)
|
| 1194 | {
|
| 1195 | vcpu_set_or_clear_cpuid_feature(vcpu, feature, true);
|
| 1196 |
|
| 1197 | }
|
| 1198 |
|
| 1199 | static inline void vcpu_clear_cpuid_feature(struct kvm_vcpu *vcpu,
|
| 1200 | struct kvm_x86_cpu_feature feature)
|
| 1201 | {
|
| 1202 | vcpu_set_or_clear_cpuid_feature(vcpu, feature, false);
|
| 1203 | }
|
| 1204 |
|
| 1205 | u64 vcpu_get_msr(struct kvm_vcpu *vcpu, u64 msr_index);
|
| 1206 | int _vcpu_set_msr(struct kvm_vcpu *vcpu, u64 msr_index, u64 msr_value);
|
| 1207 |
|
| 1208 | |
| 1209 | * Assert on an MSR access(es) and pretty print the MSR name when possible.
|
| 1210 | * Note, the caller provides the stringified name so that the name of macro is
|
| 1211 | * printed, not the value the macro resolves to (due to macro expansion).
|
| 1212 |
|
| 1213 | #define TEST_ASSERT_MSR(cond, fmt, msr, str, args...) \
|
| 1214 | do { \
|
| 1215 | if (__builtin_constant_p(msr)) { \
|
| 1216 | TEST_ASSERT(cond, fmt, str, args); \
|
| 1217 | } else if (!(cond)) { \
|
| 1218 | char buf[16]; \
|
| 1219 | \
|
| 1220 | snprintf(buf, sizeof(buf), "MSR 0x%x", msr); \
|
| 1221 | TEST_ASSERT(cond, fmt, buf, args); \
|
| 1222 | } \
|
| 1223 | } while (0)
|
| 1224 |
|
| 1225 | |
| 1226 | * Returns true if KVM should return the last written value when reading an MSR
|
| 1227 | * from userspace, e.g. the MSR isn't a command MSR, doesn't emulate state that
|
| 1228 | * is changing, etc. This is NOT an exhaustive list! The intent is to filter
|
| 1229 | * out MSRs that are not durable _and_ that a selftest wants to write.
|
| 1230 |
|
| 1231 | static inline bool is_durable_msr(u32 msr)
|
| 1232 | {
|
| 1233 | return msr != MSR_IA32_TSC;
|
| 1234 | }
|
| 1235 |
|
| 1236 | #define vcpu_set_msr(vcpu, msr, val) \
|
| 1237 | do { \
|
| 1238 | u64 r, v = val; \
|
| 1239 | \
|
| 1240 | TEST_ASSERT_MSR(_vcpu_set_msr(vcpu, msr, v) == 1, \
|
| 1241 | "KVM_SET_MSRS failed on %s, value = 0x%lx", msr, #msr, v); \
|
| 1242 | if (!is_durable_msr(msr)) \
|
| 1243 | break; \
|
| 1244 | r = vcpu_get_msr(vcpu, msr); \
|
| 1245 | TEST_ASSERT_MSR(r == v, "Set %s to '0x%lx', got back '0x%lx'", msr, #msr, v, r);\
|
| 1246 | } while (0)
|
| 1247 |
|
| 1248 | void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits);
|
| 1249 | void kvm_init_vm_address_properties(struct kvm_vm *vm);
|
| 1250 |
|
| 1251 | struct ex_regs {
|
| 1252 | u64 rax, rcx, rdx, rbx;
|
| 1253 | u64 rbp, rsi, rdi;
|
| 1254 | u64 r8, r9, r10, r11;
|
| 1255 | u64 r12, r13, r14, r15;
|
| 1256 | u64 vector;
|
| 1257 | u64 error_code;
|
| 1258 | u64 rip;
|
| 1259 | u64 cs;
|
| 1260 | u64 rflags;
|
| 1261 | };
|
| 1262 |
|
| 1263 | struct idt_entry {
|
| 1264 | u16 offset0;
|
| 1265 | u16 selector;
|
| 1266 | u16 ist : 3;
|
| 1267 | u16 : 5;
|
| 1268 | u16 type : 4;
|
| 1269 | u16 : 1;
|
| 1270 | u16 dpl : 2;
|
| 1271 | u16 p : 1;
|
| 1272 | u16 offset1;
|
| 1273 | u32 offset2; u32 reserved;
|
| 1274 | };
|
| 1275 |
|
| 1276 | void vm_install_exception_handler(struct kvm_vm *vm, int vector,
|
| 1277 | void (*handler)(struct ex_regs *));
|
| 1278 |
|
| 1279 | gva_t vm_alloc_stack(struct kvm_vm *vm, int nr_pages);
|
| 1280 |
|
| 1281 | |
| 1282 | * Exception fixup morphs #DE to an arbitrary magic vector so that '0' can be
|
| 1283 | * used to signal "no expcetion".
|
| 1284 |
|
| 1285 | #define KVM_MAGIC_DE_VECTOR 0xff
|
| 1286 |
|
| 1287 |
|
| 1288 | #define KVM_EXCEPTION_MAGIC 0xabacadabaULL
|
| 1289 |
|
| 1290 | |
| 1291 | * KVM selftest exception fixup uses registers to coordinate with the exception
|
| 1292 | * handler, versus the kernel's in-memory tables and KVM-Unit-Tests's in-memory
|
| 1293 | * per-CPU data. Using only registers avoids having to map memory into the
|
| 1294 | * guest, doesn't require a valid, stable GS.base, and reduces the risk of
|
| 1295 | * for recursive faults when accessing memory in the handler. The downside to
|
| 1296 | * using registers is that it restricts what registers can be used by the actual
|
| 1297 | * instruction. But, selftests are 64-bit only, making register* pressure a
|
| 1298 | * minor concern. Use r9-r11 as they are volatile, i.e. don't need to be saved
|
| 1299 | * by the callee, and except for r11 are not implicit parameters to any
|
| 1300 | * instructions. Ideally, fixup would use r8-r10 and thus avoid implicit
|
| 1301 | * parameters entirely, but Hyper-V's hypercall ABI uses r8 and testing Hyper-V
|
| 1302 | * is higher priority than testing non-faulting SYSCALL/SYSRET.
|
| 1303 | *
|
| 1304 | * Note, the fixup handler deliberately does not handle #DE, i.e. the vector
|
| 1305 | * is guaranteed to be non-zero on fault.
|
| 1306 | *
|
| 1307 | * REGISTER INPUTS:
|
| 1308 | * r9 = MAGIC
|
| 1309 | * r10 = RIP
|
| 1310 | * r11 = new RIP on fault
|
| 1311 | *
|
| 1312 | * REGISTER OUTPUTS:
|
| 1313 | * r9 = exception vector (non-zero)
|
| 1314 | * r10 = error code
|
| 1315 |
|
| 1316 | #define __KVM_ASM_SAFE(insn, fep) \
|
| 1317 | "mov $" __stringify(KVM_EXCEPTION_MAGIC) ", %%r9\n\t" \
|
| 1318 | "lea 1f(%%rip), %%r10\n\t" \
|
| 1319 | "lea 2f(%%rip), %%r11\n\t" \
|
| 1320 | fep "1: " insn "\n\t" \
|
| 1321 | "xor %%r9, %%r9\n\t" \
|
| 1322 | "2:\n\t" \
|
| 1323 | "mov %%r9b, %[vector]\n\t" \
|
| 1324 | "mov %%r10, %[error_code]\n\t"
|
| 1325 |
|
| 1326 | #define KVM_ASM_SAFE(insn) __KVM_ASM_SAFE(insn, "")
|
| 1327 | #define KVM_ASM_SAFE_FEP(insn) __KVM_ASM_SAFE(insn, KVM_FEP)
|
| 1328 |
|
| 1329 | #define KVM_ASM_SAFE_OUTPUTS(v, ec) [vector] "=qm"(v), [error_code] "=rm"(ec)
|
| 1330 | #define KVM_ASM_SAFE_CLOBBERS "r9", "r10", "r11"
|
| 1331 |
|
| 1332 | #define kvm_asm_safe(insn, inputs...) \
|
| 1333 | ({ \
|
| 1334 | u64 ign_error_code; \
|
| 1335 | u8 vector; \
|
| 1336 | \
|
| 1337 | asm volatile(KVM_ASM_SAFE(insn) \
|
| 1338 | : KVM_ASM_SAFE_OUTPUTS(vector, ign_error_code) \
|
| 1339 | : inputs \
|
| 1340 | : KVM_ASM_SAFE_CLOBBERS); \
|
| 1341 | vector; \
|
| 1342 | })
|
| 1343 |
|
| 1344 | #define kvm_asm_safe_ec(insn, error_code, inputs...) \
|
| 1345 | ({ \
|
| 1346 | u8 vector; \
|
| 1347 | \
|
| 1348 | asm volatile(KVM_ASM_SAFE(insn) \
|
| 1349 | : KVM_ASM_SAFE_OUTPUTS(vector, error_code) \
|
| 1350 | : inputs \
|
| 1351 | : KVM_ASM_SAFE_CLOBBERS); \
|
| 1352 | vector; \
|
| 1353 | })
|
| 1354 |
|
| 1355 | #define kvm_asm_safe_fep(insn, inputs...) \
|
| 1356 | ({ \
|
| 1357 | u64 ign_error_code; \
|
| 1358 | u8 vector; \
|
| 1359 | \
|
| 1360 | asm volatile(KVM_ASM_SAFE_FEP(insn) \
|
| 1361 | : KVM_ASM_SAFE_OUTPUTS(vector, ign_error_code) \
|
| 1362 | : inputs \
|
| 1363 | : KVM_ASM_SAFE_CLOBBERS); \
|
| 1364 | vector; \
|
| 1365 | })
|
| 1366 |
|
| 1367 | #define kvm_asm_safe_ec_fep(insn, error_code, inputs...) \
|
| 1368 | ({ \
|
| 1369 | u8 vector; \
|
| 1370 | \
|
| 1371 | asm volatile(KVM_ASM_SAFE_FEP(insn) \
|
| 1372 | : KVM_ASM_SAFE_OUTPUTS(vector, error_code) \
|
| 1373 | : inputs \
|
| 1374 | : KVM_ASM_SAFE_CLOBBERS); \
|
| 1375 | vector; \
|
| 1376 | })
|
| 1377 |
|
| 1378 | #define BUILD_READ_U64_SAFE_HELPER(insn, _fep, _FEP) \
|
| 1379 | static inline u8 insn##_safe ##_fep(u32 idx, u64 *val) \
|
| 1380 | { \
|
| 1381 | u64 error_code; \
|
| 1382 | u8 vector; \
|
| 1383 | u32 a, d; \
|
| 1384 | \
|
| 1385 | asm volatile(KVM_ASM_SAFE##_FEP(#insn) \
|
| 1386 | : "=a"(a), "=d"(d), \
|
| 1387 | KVM_ASM_SAFE_OUTPUTS(vector, error_code) \
|
| 1388 | : "c"(idx) \
|
| 1389 | : KVM_ASM_SAFE_CLOBBERS); \
|
| 1390 | \
|
| 1391 | *val = (u64)a | ((u64)d << 32); \
|
| 1392 | return vector; \
|
| 1393 | }
|
| 1394 |
|
| 1395 | |
| 1396 | * Generate {insn}_safe() and {insn}_safe_fep() helpers for instructions that
|
| 1397 | * use ECX as in input index, and EDX:EAX as a 64-bit output.
|
| 1398 |
|
| 1399 | #define BUILD_READ_U64_SAFE_HELPERS(insn) \
|
| 1400 | BUILD_READ_U64_SAFE_HELPER(insn, , ) \
|
| 1401 | BUILD_READ_U64_SAFE_HELPER(insn, _fep, _FEP) \
|
| 1402 |
|
| 1403 | BUILD_READ_U64_SAFE_HELPERS(rdmsr)
|
| 1404 | BUILD_READ_U64_SAFE_HELPERS(rdpmc)
|
| 1405 | BUILD_READ_U64_SAFE_HELPERS(xgetbv)
|
| 1406 |
|
| 1407 | static inline u8 wrmsr_safe(u32 msr, u64 val)
|
| 1408 | {
|
| 1409 | return kvm_asm_safe("wrmsr", "a"(val & -1u), "d"(val >> 32), "c"(msr));
|
| 1410 | }
|
| 1411 |
|
| 1412 | static inline u8 xsetbv_safe(u32 index, u64 value)
|
| 1413 | {
|
| 1414 | u32 eax = value;
|
| 1415 | u32 edx = value >> 32;
|
| 1416 |
|
| 1417 | return kvm_asm_safe("xsetbv", "a" (eax), "d" (edx), "c" (index));
|
| 1418 | }
|
| 1419 |
|
| 1420 | bool kvm_is_tdp_enabled(void);
|
| 1421 |
|
| 1422 | static inline bool get_kvm_intel_param_bool(const char *param)
|
| 1423 | {
|
| 1424 | return kvm_get_module_param_bool("kvm_intel", param);
|
| 1425 | }
|
| 1426 |
|
| 1427 | static inline bool get_kvm_amd_param_bool(const char *param)
|
| 1428 | {
|
| 1429 | return kvm_get_module_param_bool("kvm_amd", param);
|
| 1430 | }
|
| 1431 |
|
| 1432 | static inline int get_kvm_intel_param_integer(const char *param)
|
| 1433 | {
|
| 1434 | return kvm_get_module_param_integer("kvm_intel", param);
|
| 1435 | }
|
| 1436 |
|
| 1437 | static inline int get_kvm_amd_param_integer(const char *param)
|
| 1438 | {
|
| 1439 | return kvm_get_module_param_integer("kvm_amd", param);
|
| 1440 | }
|
| 1441 |
|
| 1442 | static inline bool kvm_is_pmu_enabled(void)
|
| 1443 | {
|
| 1444 | return get_kvm_param_bool("enable_pmu");
|
| 1445 | }
|
| 1446 |
|
| 1447 | static inline bool kvm_is_mediated_pmu_enabled(void)
|
| 1448 | {
|
| 1449 | if (host_cpu_is_intel)
|
| 1450 | return get_kvm_intel_param_bool("enable_mediated_pmu");
|
| 1451 |
|
| 1452 | return get_kvm_amd_param_bool("enable_mediated_pmu");
|
| 1453 | }
|
| 1454 |
|
| 1455 | static inline bool kvm_is_forced_emulation_enabled(void)
|
| 1456 | {
|
| 1457 | return !!get_kvm_param_integer("force_emulation_prefix");
|
| 1458 | }
|
| 1459 |
|
| 1460 | static inline bool kvm_is_unrestricted_guest_enabled(void)
|
| 1461 | {
|
| 1462 | return get_kvm_intel_param_bool("unrestricted_guest");
|
| 1463 | }
|
| 1464 |
|
| 1465 | static inline bool kvm_is_ignore_msrs(void)
|
| 1466 | {
|
| 1467 | return get_kvm_param_bool("ignore_msrs");
|
| 1468 | }
|
| 1469 |
|
| 1470 | static inline bool kvm_is_lbrv_enabled(void)
|
| 1471 | {
|
| 1472 | return !!get_kvm_amd_param_integer("lbrv");
|
| 1473 | }
|
| 1474 |
|
| 1475 | u64 *vm_get_pte(struct kvm_vm *vm, gva_t gva);
|
| 1476 |
|
| 1477 | u64 kvm_hypercall(u64 nr, u64 a0, u64 a1, u64 a2, u64 a3);
|
| 1478 | u64 __xen_hypercall(u64 nr, u64 a0, void *a1);
|
| 1479 | void xen_hypercall(u64 nr, u64 a0, void *a1);
|
| 1480 |
|
| 1481 | static inline u64 __kvm_hypercall_map_gpa_range(gpa_t gpa, u64 size, u64 flags)
|
| 1482 | {
|
| 1483 | return kvm_hypercall(KVM_HC_MAP_GPA_RANGE, gpa, size >> PAGE_SHIFT, flags, 0);
|
| 1484 | }
|
| 1485 |
|
| 1486 | static inline void kvm_hypercall_map_gpa_range(gpa_t gpa, u64 size, u64 flags)
|
| 1487 | {
|
| 1488 | u64 ret = __kvm_hypercall_map_gpa_range(gpa, size, flags);
|
| 1489 |
|
| 1490 | GUEST_ASSERT(!ret);
|
| 1491 | }
|
| 1492 |
|
| 1493 | |
| 1494 | * Execute HLT in an STI interrupt shadow to ensure that a pending IRQ that's
|
| 1495 | * intended to be a wake event arrives *after* HLT is executed. Modern CPUs,
|
| 1496 | * except for a few oddballs that KVM is unlikely to run on, block IRQs for one
|
| 1497 | * instruction after STI, *if* RFLAGS.IF=0 before STI. Note, Intel CPUs may
|
| 1498 | * block other events beyond regular IRQs, e.g. may block NMIs and SMIs too.
|
| 1499 |
|
| 1500 | static inline void safe_halt(void)
|
| 1501 | {
|
| 1502 | asm volatile("sti; hlt");
|
| 1503 | }
|
| 1504 |
|
| 1505 | |
| 1506 | * Enable interrupts and ensure that interrupts are evaluated upon return from
|
| 1507 | * this function, i.e. execute a nop to consume the STi interrupt shadow.
|
| 1508 |
|
| 1509 | static inline void sti_nop(void)
|
| 1510 | {
|
| 1511 | asm volatile ("sti; nop");
|
| 1512 | }
|
| 1513 |
|
| 1514 | |
| 1515 | * Enable interrupts for one instruction (nop), to allow the CPU to process all
|
| 1516 | * interrupts that are already pending.
|
| 1517 |
|
| 1518 | static inline void sti_nop_cli(void)
|
| 1519 | {
|
| 1520 | asm volatile ("sti; nop; cli");
|
| 1521 | }
|
| 1522 |
|
| 1523 | static inline void sti(void)
|
| 1524 | {
|
| 1525 | asm volatile("sti");
|
| 1526 | }
|
| 1527 |
|
| 1528 | static inline void cli(void)
|
| 1529 | {
|
| 1530 | asm volatile ("cli");
|
| 1531 | }
|
| 1532 |
|
| 1533 | void __vm_xsave_require_permission(u64 xfeature, const char *name);
|
| 1534 |
|
| 1535 | #define vm_xsave_require_permission(xfeature) \
|
| 1536 | __vm_xsave_require_permission(xfeature, #xfeature)
|
| 1537 |
|
| 1538 | enum pg_level {
|
| 1539 | PG_LEVEL_NONE,
|
| 1540 | PG_LEVEL_4K,
|
| 1541 | PG_LEVEL_2M,
|
| 1542 | PG_LEVEL_1G,
|
| 1543 | PG_LEVEL_512G,
|
| 1544 | PG_LEVEL_256T
|
| 1545 | };
|
| 1546 |
|
| 1547 | #define PG_LEVEL_SHIFT(_level) ((_level - 1) * 9 + 12)
|
| 1548 | #define PG_LEVEL_SIZE(_level) (1ull << PG_LEVEL_SHIFT(_level))
|
| 1549 |
|
| 1550 | #define PG_SIZE_4K PG_LEVEL_SIZE(PG_LEVEL_4K)
|
| 1551 | #define PG_SIZE_2M PG_LEVEL_SIZE(PG_LEVEL_2M)
|
| 1552 | #define PG_SIZE_1G PG_LEVEL_SIZE(PG_LEVEL_1G)
|
| 1553 |
|
| 1554 | #define PTE_PRESENT_MASK(mmu) ((mmu)->arch.pte_masks.present)
|
| 1555 | #define PTE_WRITABLE_MASK(mmu) ((mmu)->arch.pte_masks.writable)
|
| 1556 | #define PTE_USER_MASK(mmu) ((mmu)->arch.pte_masks.user)
|
| 1557 | #define PTE_READABLE_MASK(mmu) ((mmu)->arch.pte_masks.readable)
|
| 1558 | #define PTE_EXECUTABLE_MASK(mmu) ((mmu)->arch.pte_masks.executable)
|
| 1559 | #define PTE_ACCESSED_MASK(mmu) ((mmu)->arch.pte_masks.accessed)
|
| 1560 | #define PTE_DIRTY_MASK(mmu) ((mmu)->arch.pte_masks.dirty)
|
| 1561 | #define PTE_HUGE_MASK(mmu) ((mmu)->arch.pte_masks.huge)
|
| 1562 | #define PTE_NX_MASK(mmu) ((mmu)->arch.pte_masks.nx)
|
| 1563 | #define PTE_C_BIT_MASK(mmu) ((mmu)->arch.pte_masks.c)
|
| 1564 | #define PTE_S_BIT_MASK(mmu) ((mmu)->arch.pte_masks.s)
|
| 1565 | #define PTE_ALWAYS_SET_MASK(mmu) ((mmu)->arch.pte_masks.always_set)
|
| 1566 |
|
| 1567 | |
| 1568 | * For PTEs without a PRESENT bit (i.e. EPT entries), treat the PTE as present
|
| 1569 | * if it's executable or readable, as EPT supports execute-only PTEs, but not
|
| 1570 | * write-only PTEs.
|
| 1571 |
|
| 1572 | #define is_present_pte(mmu, pte) \
|
| 1573 | (PTE_PRESENT_MASK(mmu) ? \
|
| 1574 | !!(*(pte) & PTE_PRESENT_MASK(mmu)) : \
|
| 1575 | !!(*(pte) & (PTE_READABLE_MASK(mmu) | PTE_EXECUTABLE_MASK(mmu))))
|
| 1576 | #define is_executable_pte(mmu, pte) \
|
| 1577 | ((*(pte) & (PTE_EXECUTABLE_MASK(mmu) | PTE_NX_MASK(mmu))) == PTE_EXECUTABLE_MASK(mmu))
|
| 1578 | #define is_writable_pte(mmu, pte) (!!(*(pte) & PTE_WRITABLE_MASK(mmu)))
|
| 1579 | #define is_user_pte(mmu, pte) (!!(*(pte) & PTE_USER_MASK(mmu)))
|
| 1580 | #define is_accessed_pte(mmu, pte) (!!(*(pte) & PTE_ACCESSED_MASK(mmu)))
|
| 1581 | #define is_dirty_pte(mmu, pte) (!!(*(pte) & PTE_DIRTY_MASK(mmu)))
|
| 1582 | #define is_huge_pte(mmu, pte) (!!(*(pte) & PTE_HUGE_MASK(mmu)))
|
| 1583 | #define is_nx_pte(mmu, pte) (!is_executable_pte(mmu, pte))
|
| 1584 |
|
| 1585 | void tdp_mmu_init(struct kvm_vm *vm, int pgtable_levels,
|
| 1586 | struct pte_masks *pte_masks);
|
| 1587 |
|
| 1588 | void __virt_pg_map(struct kvm_vm *vm, struct kvm_mmu *mmu, gva_t gva,
|
| 1589 | gpa_t gpa, int level);
|
| 1590 | void virt_map_level(struct kvm_vm *vm, gva_t gva, gpa_t gpa,
|
| 1591 | u64 nr_bytes, int level);
|
| 1592 |
|
| 1593 | void vm_enable_tdp(struct kvm_vm *vm);
|
| 1594 | bool kvm_cpu_has_tdp(void);
|
| 1595 | void tdp_map(struct kvm_vm *vm, gpa_t l2_gpa, gpa_t gpa, u64 size);
|
| 1596 | void tdp_identity_map_default_memslots(struct kvm_vm *vm);
|
| 1597 | void tdp_identity_map_1g(struct kvm_vm *vm, u64 addr, u64 size);
|
| 1598 | u64 *tdp_get_pte(struct kvm_vm *vm, u64 l2_gpa);
|
| 1599 |
|
| 1600 | |
| 1601 | * Basic CPU control in CR0
|
| 1602 |
|
| 1603 | #define X86_CR0_PE (1UL<<0)
|
| 1604 | #define X86_CR0_MP (1UL<<1)
|
| 1605 | #define X86_CR0_EM (1UL<<2)
|
| 1606 | #define X86_CR0_TS (1UL<<3)
|
| 1607 | #define X86_CR0_ET (1UL<<4)
|
| 1608 | #define X86_CR0_NE (1UL<<5)
|
| 1609 | #define X86_CR0_WP (1UL<<16)
|
| 1610 | #define X86_CR0_AM (1UL<<18)
|
| 1611 | #define X86_CR0_NW (1UL<<29)
|
| 1612 | #define X86_CR0_CD (1UL<<30)
|
| 1613 | #define X86_CR0_PG (1UL<<31)
|
| 1614 |
|
| 1615 | #define PFERR_PRESENT_BIT 0
|
| 1616 | #define PFERR_WRITE_BIT 1
|
| 1617 | #define PFERR_USER_BIT 2
|
| 1618 | #define PFERR_RSVD_BIT 3
|
| 1619 | #define PFERR_FETCH_BIT 4
|
| 1620 | #define PFERR_PK_BIT 5
|
| 1621 | #define PFERR_SGX_BIT 15
|
| 1622 | #define PFERR_GUEST_FINAL_BIT 32
|
| 1623 | #define PFERR_GUEST_PAGE_BIT 33
|
| 1624 | #define PFERR_IMPLICIT_ACCESS_BIT 48
|
| 1625 |
|
| 1626 | #define PFERR_PRESENT_MASK BIT(PFERR_PRESENT_BIT)
|
| 1627 | #define PFERR_WRITE_MASK BIT(PFERR_WRITE_BIT)
|
| 1628 | #define PFERR_USER_MASK BIT(PFERR_USER_BIT)
|
| 1629 | #define PFERR_RSVD_MASK BIT(PFERR_RSVD_BIT)
|
| 1630 | #define PFERR_FETCH_MASK BIT(PFERR_FETCH_BIT)
|
| 1631 | #define PFERR_PK_MASK BIT(PFERR_PK_BIT)
|
| 1632 | #define PFERR_SGX_MASK BIT(PFERR_SGX_BIT)
|
| 1633 | #define PFERR_GUEST_FINAL_MASK BIT_ULL(PFERR_GUEST_FINAL_BIT)
|
| 1634 | #define PFERR_GUEST_PAGE_MASK BIT_ULL(PFERR_GUEST_PAGE_BIT)
|
| 1635 | #define PFERR_IMPLICIT_ACCESS BIT_ULL(PFERR_IMPLICIT_ACCESS_BIT)
|
| 1636 |
|
| 1637 | #define EPT_VIOLATION_ACC_READ BIT(0)
|
| 1638 | #define EPT_VIOLATION_ACC_WRITE BIT(1)
|
| 1639 | #define EPT_VIOLATION_ACC_INSTR BIT(2)
|
| 1640 | #define EPT_VIOLATION_PROT_READ BIT(3)
|
| 1641 | #define EPT_VIOLATION_PROT_WRITE BIT(4)
|
| 1642 | #define EPT_VIOLATION_PROT_EXEC BIT(5)
|
| 1643 | #define EPT_VIOLATION_GVA_IS_VALID BIT(7)
|
| 1644 | #define EPT_VIOLATION_GVA_TRANSLATED BIT(8)
|
| 1645 |
|
| 1646 | bool sys_clocksource_is_based_on_tsc(void);
|
| 1647 |
|
| 1648 | #endif
|