Path: blob/master/tools/testing/selftests/kvm/include/x86/processor.h
49473 views
/* SPDX-License-Identifier: GPL-2.0-only */1/*2* Copyright (C) 2018, Google LLC.3*/45#ifndef SELFTEST_KVM_PROCESSOR_H6#define SELFTEST_KVM_PROCESSOR_H78#include <assert.h>9#include <stdint.h>10#include <syscall.h>1112#include <asm/msr-index.h>13#include <asm/prctl.h>1415#include <linux/kvm_para.h>16#include <linux/stringify.h>1718#include "kvm_util.h"19#include "ucall_common.h"2021extern bool host_cpu_is_intel;22extern bool host_cpu_is_amd;23extern uint64_t guest_tsc_khz;2425#ifndef MAX_NR_CPUID_ENTRIES26#define MAX_NR_CPUID_ENTRIES 10027#endif2829#define NONCANONICAL 0xaaaaaaaaaaaaaaaaull3031/* Forced emulation prefix, used to invoke the emulator unconditionally. */32#define KVM_FEP "ud2; .byte 'k', 'v', 'm';"3334#define NMI_VECTOR 0x023536const char *ex_str(int vector);3738#define X86_EFLAGS_FIXED (1u << 1)3940#define X86_CR4_VME (1ul << 0)41#define X86_CR4_PVI (1ul << 1)42#define X86_CR4_TSD (1ul << 2)43#define X86_CR4_DE (1ul << 3)44#define X86_CR4_PSE (1ul << 4)45#define X86_CR4_PAE (1ul << 5)46#define X86_CR4_MCE (1ul << 6)47#define X86_CR4_PGE (1ul << 7)48#define X86_CR4_PCE (1ul << 8)49#define X86_CR4_OSFXSR (1ul << 9)50#define X86_CR4_OSXMMEXCPT (1ul << 10)51#define X86_CR4_UMIP (1ul << 11)52#define X86_CR4_LA57 (1ul << 12)53#define X86_CR4_VMXE (1ul << 13)54#define X86_CR4_SMXE (1ul << 14)55#define X86_CR4_FSGSBASE (1ul << 16)56#define X86_CR4_PCIDE (1ul << 17)57#define X86_CR4_OSXSAVE (1ul << 18)58#define X86_CR4_SMEP (1ul << 20)59#define X86_CR4_SMAP (1ul << 21)60#define X86_CR4_PKE (1ul << 22)6162struct xstate_header {63u64 xstate_bv;64u64 xcomp_bv;65u64 reserved[6];66} __attribute__((packed));6768struct xstate {69u8 i387[512];70struct xstate_header header;71u8 extended_state_area[0];72} __attribute__ ((packed, aligned (64)));7374#define XFEATURE_MASK_FP BIT_ULL(0)75#define XFEATURE_MASK_SSE BIT_ULL(1)76#define XFEATURE_MASK_YMM BIT_ULL(2)77#define XFEATURE_MASK_BNDREGS BIT_ULL(3)78#define XFEATURE_MASK_BNDCSR BIT_ULL(4)79#define XFEATURE_MASK_OPMASK BIT_ULL(5)80#define XFEATURE_MASK_ZMM_Hi256 BIT_ULL(6)81#define XFEATURE_MASK_Hi16_ZMM BIT_ULL(7)82#define XFEATURE_MASK_PT BIT_ULL(8)83#define XFEATURE_MASK_PKRU BIT_ULL(9)84#define XFEATURE_MASK_PASID BIT_ULL(10)85#define XFEATURE_MASK_CET_USER BIT_ULL(11)86#define XFEATURE_MASK_CET_KERNEL BIT_ULL(12)87#define XFEATURE_MASK_LBR BIT_ULL(15)88#define XFEATURE_MASK_XTILE_CFG BIT_ULL(17)89#define XFEATURE_MASK_XTILE_DATA BIT_ULL(18)9091#define XFEATURE_MASK_AVX512 (XFEATURE_MASK_OPMASK | \92XFEATURE_MASK_ZMM_Hi256 | \93XFEATURE_MASK_Hi16_ZMM)94#define XFEATURE_MASK_XTILE (XFEATURE_MASK_XTILE_DATA | \95XFEATURE_MASK_XTILE_CFG)9697/* Note, these are ordered alphabetically to match kvm_cpuid_entry2. Eww. */98enum cpuid_output_regs {99KVM_CPUID_EAX,100KVM_CPUID_EBX,101KVM_CPUID_ECX,102KVM_CPUID_EDX103};104105/*106* Pack the information into a 64-bit value so that each X86_FEATURE_XXX can be107* passed by value with no overhead.108*/109struct kvm_x86_cpu_feature {110u32 function;111u16 index;112u8 reg;113u8 bit;114};115#define KVM_X86_CPU_FEATURE(fn, idx, gpr, __bit) \116({ \117struct kvm_x86_cpu_feature feature = { \118.function = fn, \119.index = idx, \120.reg = KVM_CPUID_##gpr, \121.bit = __bit, \122}; \123\124kvm_static_assert((fn & 0xc0000000) == 0 || \125(fn & 0xc0000000) == 0x40000000 || \126(fn & 0xc0000000) == 0x80000000 || \127(fn & 0xc0000000) == 0xc0000000); \128kvm_static_assert(idx < BIT(sizeof(feature.index) * BITS_PER_BYTE)); \129feature; \130})131132/*133* Basic Leafs, a.k.a. Intel defined134*/135#define X86_FEATURE_MWAIT KVM_X86_CPU_FEATURE(0x1, 0, ECX, 3)136#define X86_FEATURE_VMX KVM_X86_CPU_FEATURE(0x1, 0, ECX, 5)137#define X86_FEATURE_SMX KVM_X86_CPU_FEATURE(0x1, 0, ECX, 6)138#define X86_FEATURE_PDCM KVM_X86_CPU_FEATURE(0x1, 0, ECX, 15)139#define X86_FEATURE_PCID KVM_X86_CPU_FEATURE(0x1, 0, ECX, 17)140#define X86_FEATURE_X2APIC KVM_X86_CPU_FEATURE(0x1, 0, ECX, 21)141#define X86_FEATURE_MOVBE KVM_X86_CPU_FEATURE(0x1, 0, ECX, 22)142#define X86_FEATURE_TSC_DEADLINE_TIMER KVM_X86_CPU_FEATURE(0x1, 0, ECX, 24)143#define X86_FEATURE_XSAVE KVM_X86_CPU_FEATURE(0x1, 0, ECX, 26)144#define X86_FEATURE_OSXSAVE KVM_X86_CPU_FEATURE(0x1, 0, ECX, 27)145#define X86_FEATURE_RDRAND KVM_X86_CPU_FEATURE(0x1, 0, ECX, 30)146#define X86_FEATURE_HYPERVISOR KVM_X86_CPU_FEATURE(0x1, 0, ECX, 31)147#define X86_FEATURE_PAE KVM_X86_CPU_FEATURE(0x1, 0, EDX, 6)148#define X86_FEATURE_MCE KVM_X86_CPU_FEATURE(0x1, 0, EDX, 7)149#define X86_FEATURE_APIC KVM_X86_CPU_FEATURE(0x1, 0, EDX, 9)150#define X86_FEATURE_CLFLUSH KVM_X86_CPU_FEATURE(0x1, 0, EDX, 19)151#define X86_FEATURE_XMM KVM_X86_CPU_FEATURE(0x1, 0, EDX, 25)152#define X86_FEATURE_XMM2 KVM_X86_CPU_FEATURE(0x1, 0, EDX, 26)153#define X86_FEATURE_FSGSBASE KVM_X86_CPU_FEATURE(0x7, 0, EBX, 0)154#define X86_FEATURE_TSC_ADJUST KVM_X86_CPU_FEATURE(0x7, 0, EBX, 1)155#define X86_FEATURE_SGX KVM_X86_CPU_FEATURE(0x7, 0, EBX, 2)156#define X86_FEATURE_HLE KVM_X86_CPU_FEATURE(0x7, 0, EBX, 4)157#define X86_FEATURE_SMEP KVM_X86_CPU_FEATURE(0x7, 0, EBX, 7)158#define X86_FEATURE_INVPCID KVM_X86_CPU_FEATURE(0x7, 0, EBX, 10)159#define X86_FEATURE_RTM KVM_X86_CPU_FEATURE(0x7, 0, EBX, 11)160#define X86_FEATURE_MPX KVM_X86_CPU_FEATURE(0x7, 0, EBX, 14)161#define X86_FEATURE_SMAP KVM_X86_CPU_FEATURE(0x7, 0, EBX, 20)162#define X86_FEATURE_PCOMMIT KVM_X86_CPU_FEATURE(0x7, 0, EBX, 22)163#define X86_FEATURE_CLFLUSHOPT KVM_X86_CPU_FEATURE(0x7, 0, EBX, 23)164#define X86_FEATURE_CLWB KVM_X86_CPU_FEATURE(0x7, 0, EBX, 24)165#define X86_FEATURE_UMIP KVM_X86_CPU_FEATURE(0x7, 0, ECX, 2)166#define X86_FEATURE_PKU KVM_X86_CPU_FEATURE(0x7, 0, ECX, 3)167#define X86_FEATURE_OSPKE KVM_X86_CPU_FEATURE(0x7, 0, ECX, 4)168#define X86_FEATURE_LA57 KVM_X86_CPU_FEATURE(0x7, 0, ECX, 16)169#define X86_FEATURE_RDPID KVM_X86_CPU_FEATURE(0x7, 0, ECX, 22)170#define X86_FEATURE_SGX_LC KVM_X86_CPU_FEATURE(0x7, 0, ECX, 30)171#define X86_FEATURE_SHSTK KVM_X86_CPU_FEATURE(0x7, 0, ECX, 7)172#define X86_FEATURE_IBT KVM_X86_CPU_FEATURE(0x7, 0, EDX, 20)173#define X86_FEATURE_AMX_TILE KVM_X86_CPU_FEATURE(0x7, 0, EDX, 24)174#define X86_FEATURE_SPEC_CTRL KVM_X86_CPU_FEATURE(0x7, 0, EDX, 26)175#define X86_FEATURE_ARCH_CAPABILITIES KVM_X86_CPU_FEATURE(0x7, 0, EDX, 29)176#define X86_FEATURE_PKS KVM_X86_CPU_FEATURE(0x7, 0, ECX, 31)177#define X86_FEATURE_XTILECFG KVM_X86_CPU_FEATURE(0xD, 0, EAX, 17)178#define X86_FEATURE_XTILEDATA KVM_X86_CPU_FEATURE(0xD, 0, EAX, 18)179#define X86_FEATURE_XSAVES KVM_X86_CPU_FEATURE(0xD, 1, EAX, 3)180#define X86_FEATURE_XFD KVM_X86_CPU_FEATURE(0xD, 1, EAX, 4)181#define X86_FEATURE_XTILEDATA_XFD KVM_X86_CPU_FEATURE(0xD, 18, ECX, 2)182183/*184* Extended Leafs, a.k.a. AMD defined185*/186#define X86_FEATURE_SVM KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 2)187#define X86_FEATURE_PERFCTR_CORE KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 23)188#define X86_FEATURE_PERFCTR_NB KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 24)189#define X86_FEATURE_PERFCTR_LLC KVM_X86_CPU_FEATURE(0x80000001, 0, ECX, 28)190#define X86_FEATURE_NX KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 20)191#define X86_FEATURE_GBPAGES KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 26)192#define X86_FEATURE_RDTSCP KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 27)193#define X86_FEATURE_LM KVM_X86_CPU_FEATURE(0x80000001, 0, EDX, 29)194#define X86_FEATURE_INVTSC KVM_X86_CPU_FEATURE(0x80000007, 0, EDX, 8)195#define X86_FEATURE_RDPRU KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 4)196#define X86_FEATURE_AMD_IBPB KVM_X86_CPU_FEATURE(0x80000008, 0, EBX, 12)197#define X86_FEATURE_NPT KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 0)198#define X86_FEATURE_LBRV KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 1)199#define X86_FEATURE_NRIPS KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 3)200#define X86_FEATURE_TSCRATEMSR KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 4)201#define X86_FEATURE_PAUSEFILTER KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 10)202#define X86_FEATURE_PFTHRESHOLD KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 12)203#define X86_FEATURE_VGIF KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 16)204#define X86_FEATURE_IDLE_HLT KVM_X86_CPU_FEATURE(0x8000000A, 0, EDX, 30)205#define X86_FEATURE_SEV KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 1)206#define X86_FEATURE_SEV_ES KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 3)207#define X86_FEATURE_SEV_SNP KVM_X86_CPU_FEATURE(0x8000001F, 0, EAX, 4)208#define X86_FEATURE_PERFMON_V2 KVM_X86_CPU_FEATURE(0x80000022, 0, EAX, 0)209#define X86_FEATURE_LBR_PMC_FREEZE KVM_X86_CPU_FEATURE(0x80000022, 0, EAX, 2)210211/*212* KVM defined paravirt features.213*/214#define X86_FEATURE_KVM_CLOCKSOURCE KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 0)215#define X86_FEATURE_KVM_NOP_IO_DELAY KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 1)216#define X86_FEATURE_KVM_MMU_OP KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 2)217#define X86_FEATURE_KVM_CLOCKSOURCE2 KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 3)218#define X86_FEATURE_KVM_ASYNC_PF KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 4)219#define X86_FEATURE_KVM_STEAL_TIME KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 5)220#define X86_FEATURE_KVM_PV_EOI KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 6)221#define X86_FEATURE_KVM_PV_UNHALT KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 7)222/* Bit 8 apparently isn't used?!?! */223#define X86_FEATURE_KVM_PV_TLB_FLUSH KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 9)224#define X86_FEATURE_KVM_ASYNC_PF_VMEXIT KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 10)225#define X86_FEATURE_KVM_PV_SEND_IPI KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 11)226#define X86_FEATURE_KVM_POLL_CONTROL KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 12)227#define X86_FEATURE_KVM_PV_SCHED_YIELD KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 13)228#define X86_FEATURE_KVM_ASYNC_PF_INT KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 14)229#define X86_FEATURE_KVM_MSI_EXT_DEST_ID KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 15)230#define X86_FEATURE_KVM_HC_MAP_GPA_RANGE KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 16)231#define X86_FEATURE_KVM_MIGRATION_CONTROL KVM_X86_CPU_FEATURE(0x40000001, 0, EAX, 17)232233/*234* Same idea as X86_FEATURE_XXX, but X86_PROPERTY_XXX retrieves a multi-bit235* value/property as opposed to a single-bit feature. Again, pack the info236* into a 64-bit value to pass by value with no overhead.237*/238struct kvm_x86_cpu_property {239u32 function;240u8 index;241u8 reg;242u8 lo_bit;243u8 hi_bit;244};245#define KVM_X86_CPU_PROPERTY(fn, idx, gpr, low_bit, high_bit) \246({ \247struct kvm_x86_cpu_property property = { \248.function = fn, \249.index = idx, \250.reg = KVM_CPUID_##gpr, \251.lo_bit = low_bit, \252.hi_bit = high_bit, \253}; \254\255kvm_static_assert(low_bit < high_bit); \256kvm_static_assert((fn & 0xc0000000) == 0 || \257(fn & 0xc0000000) == 0x40000000 || \258(fn & 0xc0000000) == 0x80000000 || \259(fn & 0xc0000000) == 0xc0000000); \260kvm_static_assert(idx < BIT(sizeof(property.index) * BITS_PER_BYTE)); \261property; \262})263264#define X86_PROPERTY_MAX_BASIC_LEAF KVM_X86_CPU_PROPERTY(0, 0, EAX, 0, 31)265#define X86_PROPERTY_PMU_VERSION KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 0, 7)266#define X86_PROPERTY_PMU_NR_GP_COUNTERS KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 8, 15)267#define X86_PROPERTY_PMU_GP_COUNTERS_BIT_WIDTH KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 16, 23)268#define X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH KVM_X86_CPU_PROPERTY(0xa, 0, EAX, 24, 31)269#define X86_PROPERTY_PMU_EVENTS_MASK KVM_X86_CPU_PROPERTY(0xa, 0, EBX, 0, 12)270#define X86_PROPERTY_PMU_FIXED_COUNTERS_BITMASK KVM_X86_CPU_PROPERTY(0xa, 0, ECX, 0, 31)271#define X86_PROPERTY_PMU_NR_FIXED_COUNTERS KVM_X86_CPU_PROPERTY(0xa, 0, EDX, 0, 4)272#define X86_PROPERTY_PMU_FIXED_COUNTERS_BIT_WIDTH KVM_X86_CPU_PROPERTY(0xa, 0, EDX, 5, 12)273274#define X86_PROPERTY_SUPPORTED_XCR0_LO KVM_X86_CPU_PROPERTY(0xd, 0, EAX, 0, 31)275#define X86_PROPERTY_XSTATE_MAX_SIZE_XCR0 KVM_X86_CPU_PROPERTY(0xd, 0, EBX, 0, 31)276#define X86_PROPERTY_XSTATE_MAX_SIZE KVM_X86_CPU_PROPERTY(0xd, 0, ECX, 0, 31)277#define X86_PROPERTY_SUPPORTED_XCR0_HI KVM_X86_CPU_PROPERTY(0xd, 0, EDX, 0, 31)278279#define X86_PROPERTY_XSTATE_TILE_SIZE KVM_X86_CPU_PROPERTY(0xd, 18, EAX, 0, 31)280#define X86_PROPERTY_XSTATE_TILE_OFFSET KVM_X86_CPU_PROPERTY(0xd, 18, EBX, 0, 31)281#define X86_PROPERTY_AMX_MAX_PALETTE_TABLES KVM_X86_CPU_PROPERTY(0x1d, 0, EAX, 0, 31)282#define X86_PROPERTY_AMX_TOTAL_TILE_BYTES KVM_X86_CPU_PROPERTY(0x1d, 1, EAX, 0, 15)283#define X86_PROPERTY_AMX_BYTES_PER_TILE KVM_X86_CPU_PROPERTY(0x1d, 1, EAX, 16, 31)284#define X86_PROPERTY_AMX_BYTES_PER_ROW KVM_X86_CPU_PROPERTY(0x1d, 1, EBX, 0, 15)285#define X86_PROPERTY_AMX_NR_TILE_REGS KVM_X86_CPU_PROPERTY(0x1d, 1, EBX, 16, 31)286#define X86_PROPERTY_AMX_MAX_ROWS KVM_X86_CPU_PROPERTY(0x1d, 1, ECX, 0, 15)287288#define X86_PROPERTY_MAX_KVM_LEAF KVM_X86_CPU_PROPERTY(0x40000000, 0, EAX, 0, 31)289290#define X86_PROPERTY_MAX_EXT_LEAF KVM_X86_CPU_PROPERTY(0x80000000, 0, EAX, 0, 31)291#define X86_PROPERTY_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 0, 7)292#define X86_PROPERTY_MAX_VIRT_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 8, 15)293#define X86_PROPERTY_GUEST_MAX_PHY_ADDR KVM_X86_CPU_PROPERTY(0x80000008, 0, EAX, 16, 23)294#define X86_PROPERTY_SEV_C_BIT KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 0, 5)295#define X86_PROPERTY_PHYS_ADDR_REDUCTION KVM_X86_CPU_PROPERTY(0x8000001F, 0, EBX, 6, 11)296#define X86_PROPERTY_NR_PERFCTR_CORE KVM_X86_CPU_PROPERTY(0x80000022, 0, EBX, 0, 3)297#define X86_PROPERTY_NR_PERFCTR_NB KVM_X86_CPU_PROPERTY(0x80000022, 0, EBX, 10, 15)298299#define X86_PROPERTY_MAX_CENTAUR_LEAF KVM_X86_CPU_PROPERTY(0xC0000000, 0, EAX, 0, 31)300301/*302* Intel's architectural PMU events are bizarre. They have a "feature" bit303* that indicates the feature is _not_ supported, and a property that states304* the length of the bit mask of unsupported features. A feature is supported305* if the size of the bit mask is larger than the "unavailable" bit, and said306* bit is not set. Fixed counters also bizarre enumeration, but inverted from307* arch events for general purpose counters. Fixed counters are supported if a308* feature flag is set **OR** the total number of fixed counters is greater309* than index of the counter.310*311* Wrap the events for general purpose and fixed counters to simplify checking312* whether or not a given architectural event is supported.313*/314struct kvm_x86_pmu_feature {315struct kvm_x86_cpu_feature f;316};317#define KVM_X86_PMU_FEATURE(__reg, __bit) \318({ \319struct kvm_x86_pmu_feature feature = { \320.f = KVM_X86_CPU_FEATURE(0xa, 0, __reg, __bit), \321}; \322\323kvm_static_assert(KVM_CPUID_##__reg == KVM_CPUID_EBX || \324KVM_CPUID_##__reg == KVM_CPUID_ECX); \325feature; \326})327328#define X86_PMU_FEATURE_CPU_CYCLES KVM_X86_PMU_FEATURE(EBX, 0)329#define X86_PMU_FEATURE_INSNS_RETIRED KVM_X86_PMU_FEATURE(EBX, 1)330#define X86_PMU_FEATURE_REFERENCE_CYCLES KVM_X86_PMU_FEATURE(EBX, 2)331#define X86_PMU_FEATURE_LLC_REFERENCES KVM_X86_PMU_FEATURE(EBX, 3)332#define X86_PMU_FEATURE_LLC_MISSES KVM_X86_PMU_FEATURE(EBX, 4)333#define X86_PMU_FEATURE_BRANCH_INSNS_RETIRED KVM_X86_PMU_FEATURE(EBX, 5)334#define X86_PMU_FEATURE_BRANCHES_MISPREDICTED KVM_X86_PMU_FEATURE(EBX, 6)335#define X86_PMU_FEATURE_TOPDOWN_SLOTS KVM_X86_PMU_FEATURE(EBX, 7)336#define X86_PMU_FEATURE_TOPDOWN_BE_BOUND KVM_X86_PMU_FEATURE(EBX, 8)337#define X86_PMU_FEATURE_TOPDOWN_BAD_SPEC KVM_X86_PMU_FEATURE(EBX, 9)338#define X86_PMU_FEATURE_TOPDOWN_FE_BOUND KVM_X86_PMU_FEATURE(EBX, 10)339#define X86_PMU_FEATURE_TOPDOWN_RETIRING KVM_X86_PMU_FEATURE(EBX, 11)340#define X86_PMU_FEATURE_LBR_INSERTS KVM_X86_PMU_FEATURE(EBX, 12)341342#define X86_PMU_FEATURE_INSNS_RETIRED_FIXED KVM_X86_PMU_FEATURE(ECX, 0)343#define X86_PMU_FEATURE_CPU_CYCLES_FIXED KVM_X86_PMU_FEATURE(ECX, 1)344#define X86_PMU_FEATURE_REFERENCE_TSC_CYCLES_FIXED KVM_X86_PMU_FEATURE(ECX, 2)345#define X86_PMU_FEATURE_TOPDOWN_SLOTS_FIXED KVM_X86_PMU_FEATURE(ECX, 3)346347static inline unsigned int x86_family(unsigned int eax)348{349unsigned int x86;350351x86 = (eax >> 8) & 0xf;352353if (x86 == 0xf)354x86 += (eax >> 20) & 0xff;355356return x86;357}358359static inline unsigned int x86_model(unsigned int eax)360{361return ((eax >> 12) & 0xf0) | ((eax >> 4) & 0x0f);362}363364/* Page table bitfield declarations */365#define PTE_PRESENT_MASK BIT_ULL(0)366#define PTE_WRITABLE_MASK BIT_ULL(1)367#define PTE_USER_MASK BIT_ULL(2)368#define PTE_ACCESSED_MASK BIT_ULL(5)369#define PTE_DIRTY_MASK BIT_ULL(6)370#define PTE_LARGE_MASK BIT_ULL(7)371#define PTE_GLOBAL_MASK BIT_ULL(8)372#define PTE_NX_MASK BIT_ULL(63)373374#define PHYSICAL_PAGE_MASK GENMASK_ULL(51, 12)375376#define PAGE_SHIFT 12377#define PAGE_SIZE (1ULL << PAGE_SHIFT)378#define PAGE_MASK (~(PAGE_SIZE-1) & PHYSICAL_PAGE_MASK)379380#define HUGEPAGE_SHIFT(x) (PAGE_SHIFT + (((x) - 1) * 9))381#define HUGEPAGE_SIZE(x) (1UL << HUGEPAGE_SHIFT(x))382#define HUGEPAGE_MASK(x) (~(HUGEPAGE_SIZE(x) - 1) & PHYSICAL_PAGE_MASK)383384#define PTE_GET_PA(pte) ((pte) & PHYSICAL_PAGE_MASK)385#define PTE_GET_PFN(pte) (PTE_GET_PA(pte) >> PAGE_SHIFT)386387/* General Registers in 64-Bit Mode */388struct gpr64_regs {389u64 rax;390u64 rcx;391u64 rdx;392u64 rbx;393u64 rsp;394u64 rbp;395u64 rsi;396u64 rdi;397u64 r8;398u64 r9;399u64 r10;400u64 r11;401u64 r12;402u64 r13;403u64 r14;404u64 r15;405};406407struct desc64 {408uint16_t limit0;409uint16_t base0;410unsigned base1:8, type:4, s:1, dpl:2, p:1;411unsigned limit1:4, avl:1, l:1, db:1, g:1, base2:8;412uint32_t base3;413uint32_t zero1;414} __attribute__((packed));415416struct desc_ptr {417uint16_t size;418uint64_t address;419} __attribute__((packed));420421struct kvm_x86_state {422struct kvm_xsave *xsave;423struct kvm_vcpu_events events;424struct kvm_mp_state mp_state;425struct kvm_regs regs;426struct kvm_xcrs xcrs;427struct kvm_sregs sregs;428struct kvm_debugregs debugregs;429union {430struct kvm_nested_state nested;431char nested_[16384];432};433struct kvm_msrs msrs;434};435436static inline uint64_t get_desc64_base(const struct desc64 *desc)437{438return ((uint64_t)desc->base3 << 32) |439(desc->base0 | ((desc->base1) << 16) | ((desc->base2) << 24));440}441442static inline uint64_t rdtsc(void)443{444uint32_t eax, edx;445uint64_t tsc_val;446/*447* The lfence is to wait (on Intel CPUs) until all previous448* instructions have been executed. If software requires RDTSC to be449* executed prior to execution of any subsequent instruction, it can450* execute LFENCE immediately after RDTSC451*/452__asm__ __volatile__("lfence; rdtsc; lfence" : "=a"(eax), "=d"(edx));453tsc_val = ((uint64_t)edx) << 32 | eax;454return tsc_val;455}456457static inline uint64_t rdtscp(uint32_t *aux)458{459uint32_t eax, edx;460461__asm__ __volatile__("rdtscp" : "=a"(eax), "=d"(edx), "=c"(*aux));462return ((uint64_t)edx) << 32 | eax;463}464465static inline uint64_t rdmsr(uint32_t msr)466{467uint32_t a, d;468469__asm__ __volatile__("rdmsr" : "=a"(a), "=d"(d) : "c"(msr) : "memory");470471return a | ((uint64_t) d << 32);472}473474static inline void wrmsr(uint32_t msr, uint64_t value)475{476uint32_t a = value;477uint32_t d = value >> 32;478479__asm__ __volatile__("wrmsr" :: "a"(a), "d"(d), "c"(msr) : "memory");480}481482483static inline uint16_t inw(uint16_t port)484{485uint16_t tmp;486487__asm__ __volatile__("in %%dx, %%ax"488: /* output */ "=a" (tmp)489: /* input */ "d" (port));490491return tmp;492}493494static inline uint16_t get_es(void)495{496uint16_t es;497498__asm__ __volatile__("mov %%es, %[es]"499: /* output */ [es]"=rm"(es));500return es;501}502503static inline uint16_t get_cs(void)504{505uint16_t cs;506507__asm__ __volatile__("mov %%cs, %[cs]"508: /* output */ [cs]"=rm"(cs));509return cs;510}511512static inline uint16_t get_ss(void)513{514uint16_t ss;515516__asm__ __volatile__("mov %%ss, %[ss]"517: /* output */ [ss]"=rm"(ss));518return ss;519}520521static inline uint16_t get_ds(void)522{523uint16_t ds;524525__asm__ __volatile__("mov %%ds, %[ds]"526: /* output */ [ds]"=rm"(ds));527return ds;528}529530static inline uint16_t get_fs(void)531{532uint16_t fs;533534__asm__ __volatile__("mov %%fs, %[fs]"535: /* output */ [fs]"=rm"(fs));536return fs;537}538539static inline uint16_t get_gs(void)540{541uint16_t gs;542543__asm__ __volatile__("mov %%gs, %[gs]"544: /* output */ [gs]"=rm"(gs));545return gs;546}547548static inline uint16_t get_tr(void)549{550uint16_t tr;551552__asm__ __volatile__("str %[tr]"553: /* output */ [tr]"=rm"(tr));554return tr;555}556557static inline uint64_t get_cr0(void)558{559uint64_t cr0;560561__asm__ __volatile__("mov %%cr0, %[cr0]"562: /* output */ [cr0]"=r"(cr0));563return cr0;564}565566static inline uint64_t get_cr3(void)567{568uint64_t cr3;569570__asm__ __volatile__("mov %%cr3, %[cr3]"571: /* output */ [cr3]"=r"(cr3));572return cr3;573}574575static inline uint64_t get_cr4(void)576{577uint64_t cr4;578579__asm__ __volatile__("mov %%cr4, %[cr4]"580: /* output */ [cr4]"=r"(cr4));581return cr4;582}583584static inline void set_cr4(uint64_t val)585{586__asm__ __volatile__("mov %0, %%cr4" : : "r" (val) : "memory");587}588589static inline void set_idt(const struct desc_ptr *idt_desc)590{591__asm__ __volatile__("lidt %0"::"m"(*idt_desc));592}593594static inline u64 xgetbv(u32 index)595{596u32 eax, edx;597598__asm__ __volatile__("xgetbv;"599: "=a" (eax), "=d" (edx)600: "c" (index));601return eax | ((u64)edx << 32);602}603604static inline void xsetbv(u32 index, u64 value)605{606u32 eax = value;607u32 edx = value >> 32;608609__asm__ __volatile__("xsetbv" :: "a" (eax), "d" (edx), "c" (index));610}611612static inline void wrpkru(u32 pkru)613{614/* Note, ECX and EDX are architecturally required to be '0'. */615asm volatile(".byte 0x0f,0x01,0xef\n\t"616: : "a" (pkru), "c"(0), "d"(0));617}618619static inline struct desc_ptr get_gdt(void)620{621struct desc_ptr gdt;622__asm__ __volatile__("sgdt %[gdt]"623: /* output */ [gdt]"=m"(gdt));624return gdt;625}626627static inline struct desc_ptr get_idt(void)628{629struct desc_ptr idt;630__asm__ __volatile__("sidt %[idt]"631: /* output */ [idt]"=m"(idt));632return idt;633}634635static inline void outl(uint16_t port, uint32_t value)636{637__asm__ __volatile__("outl %%eax, %%dx" : : "d"(port), "a"(value));638}639640static inline void __cpuid(uint32_t function, uint32_t index,641uint32_t *eax, uint32_t *ebx,642uint32_t *ecx, uint32_t *edx)643{644*eax = function;645*ecx = index;646647asm volatile("cpuid"648: "=a" (*eax),649"=b" (*ebx),650"=c" (*ecx),651"=d" (*edx)652: "0" (*eax), "2" (*ecx)653: "memory");654}655656static inline void cpuid(uint32_t function,657uint32_t *eax, uint32_t *ebx,658uint32_t *ecx, uint32_t *edx)659{660return __cpuid(function, 0, eax, ebx, ecx, edx);661}662663static inline uint32_t this_cpu_fms(void)664{665uint32_t eax, ebx, ecx, edx;666667cpuid(1, &eax, &ebx, &ecx, &edx);668return eax;669}670671static inline uint32_t this_cpu_family(void)672{673return x86_family(this_cpu_fms());674}675676static inline uint32_t this_cpu_model(void)677{678return x86_model(this_cpu_fms());679}680681static inline bool this_cpu_vendor_string_is(const char *vendor)682{683const uint32_t *chunk = (const uint32_t *)vendor;684uint32_t eax, ebx, ecx, edx;685686cpuid(0, &eax, &ebx, &ecx, &edx);687return (ebx == chunk[0] && edx == chunk[1] && ecx == chunk[2]);688}689690static inline bool this_cpu_is_intel(void)691{692return this_cpu_vendor_string_is("GenuineIntel");693}694695/*696* Exclude early K5 samples with a vendor string of "AMDisbetter!"697*/698static inline bool this_cpu_is_amd(void)699{700return this_cpu_vendor_string_is("AuthenticAMD");701}702703static inline uint32_t __this_cpu_has(uint32_t function, uint32_t index,704uint8_t reg, uint8_t lo, uint8_t hi)705{706uint32_t gprs[4];707708__cpuid(function, index,709&gprs[KVM_CPUID_EAX], &gprs[KVM_CPUID_EBX],710&gprs[KVM_CPUID_ECX], &gprs[KVM_CPUID_EDX]);711712return (gprs[reg] & GENMASK(hi, lo)) >> lo;713}714715static inline bool this_cpu_has(struct kvm_x86_cpu_feature feature)716{717return __this_cpu_has(feature.function, feature.index,718feature.reg, feature.bit, feature.bit);719}720721static inline uint32_t this_cpu_property(struct kvm_x86_cpu_property property)722{723return __this_cpu_has(property.function, property.index,724property.reg, property.lo_bit, property.hi_bit);725}726727static __always_inline bool this_cpu_has_p(struct kvm_x86_cpu_property property)728{729uint32_t max_leaf;730731switch (property.function & 0xc0000000) {732case 0:733max_leaf = this_cpu_property(X86_PROPERTY_MAX_BASIC_LEAF);734break;735case 0x40000000:736max_leaf = this_cpu_property(X86_PROPERTY_MAX_KVM_LEAF);737break;738case 0x80000000:739max_leaf = this_cpu_property(X86_PROPERTY_MAX_EXT_LEAF);740break;741case 0xc0000000:742max_leaf = this_cpu_property(X86_PROPERTY_MAX_CENTAUR_LEAF);743}744return max_leaf >= property.function;745}746747static inline bool this_pmu_has(struct kvm_x86_pmu_feature feature)748{749uint32_t nr_bits;750751if (feature.f.reg == KVM_CPUID_EBX) {752nr_bits = this_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);753return nr_bits > feature.f.bit && !this_cpu_has(feature.f);754}755756GUEST_ASSERT(feature.f.reg == KVM_CPUID_ECX);757nr_bits = this_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);758return nr_bits > feature.f.bit || this_cpu_has(feature.f);759}760761static __always_inline uint64_t this_cpu_supported_xcr0(void)762{763if (!this_cpu_has_p(X86_PROPERTY_SUPPORTED_XCR0_LO))764return 0;765766return this_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_LO) |767((uint64_t)this_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_HI) << 32);768}769770typedef u32 __attribute__((vector_size(16))) sse128_t;771#define __sse128_u union { sse128_t vec; u64 as_u64[2]; u32 as_u32[4]; }772#define sse128_lo(x) ({ __sse128_u t; t.vec = x; t.as_u64[0]; })773#define sse128_hi(x) ({ __sse128_u t; t.vec = x; t.as_u64[1]; })774775static inline void read_sse_reg(int reg, sse128_t *data)776{777switch (reg) {778case 0:779asm("movdqa %%xmm0, %0" : "=m"(*data));780break;781case 1:782asm("movdqa %%xmm1, %0" : "=m"(*data));783break;784case 2:785asm("movdqa %%xmm2, %0" : "=m"(*data));786break;787case 3:788asm("movdqa %%xmm3, %0" : "=m"(*data));789break;790case 4:791asm("movdqa %%xmm4, %0" : "=m"(*data));792break;793case 5:794asm("movdqa %%xmm5, %0" : "=m"(*data));795break;796case 6:797asm("movdqa %%xmm6, %0" : "=m"(*data));798break;799case 7:800asm("movdqa %%xmm7, %0" : "=m"(*data));801break;802default:803BUG();804}805}806807static inline void write_sse_reg(int reg, const sse128_t *data)808{809switch (reg) {810case 0:811asm("movdqa %0, %%xmm0" : : "m"(*data));812break;813case 1:814asm("movdqa %0, %%xmm1" : : "m"(*data));815break;816case 2:817asm("movdqa %0, %%xmm2" : : "m"(*data));818break;819case 3:820asm("movdqa %0, %%xmm3" : : "m"(*data));821break;822case 4:823asm("movdqa %0, %%xmm4" : : "m"(*data));824break;825case 5:826asm("movdqa %0, %%xmm5" : : "m"(*data));827break;828case 6:829asm("movdqa %0, %%xmm6" : : "m"(*data));830break;831case 7:832asm("movdqa %0, %%xmm7" : : "m"(*data));833break;834default:835BUG();836}837}838839static inline void cpu_relax(void)840{841asm volatile("rep; nop" ::: "memory");842}843844static inline void udelay(unsigned long usec)845{846uint64_t start, now, cycles;847848GUEST_ASSERT(guest_tsc_khz);849cycles = guest_tsc_khz / 1000 * usec;850851/*852* Deliberately don't PAUSE, a.k.a. cpu_relax(), so that the delay is853* as accurate as possible, e.g. doesn't trigger PAUSE-Loop VM-Exits.854*/855start = rdtsc();856do {857now = rdtsc();858} while (now - start < cycles);859}860861#define ud2() \862__asm__ __volatile__( \863"ud2\n" \864)865866#define hlt() \867__asm__ __volatile__( \868"hlt\n" \869)870871struct kvm_x86_state *vcpu_save_state(struct kvm_vcpu *vcpu);872void vcpu_load_state(struct kvm_vcpu *vcpu, struct kvm_x86_state *state);873void kvm_x86_state_cleanup(struct kvm_x86_state *state);874875const struct kvm_msr_list *kvm_get_msr_index_list(void);876const struct kvm_msr_list *kvm_get_feature_msr_index_list(void);877bool kvm_msr_is_in_save_restore_list(uint32_t msr_index);878uint64_t kvm_get_feature_msr(uint64_t msr_index);879880static inline void vcpu_msrs_get(struct kvm_vcpu *vcpu,881struct kvm_msrs *msrs)882{883int r = __vcpu_ioctl(vcpu, KVM_GET_MSRS, msrs);884885TEST_ASSERT(r == msrs->nmsrs,886"KVM_GET_MSRS failed, r: %i (failed on MSR %x)",887r, r < 0 || r >= msrs->nmsrs ? -1 : msrs->entries[r].index);888}889static inline void vcpu_msrs_set(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs)890{891int r = __vcpu_ioctl(vcpu, KVM_SET_MSRS, msrs);892893TEST_ASSERT(r == msrs->nmsrs,894"KVM_SET_MSRS failed, r: %i (failed on MSR %x)",895r, r < 0 || r >= msrs->nmsrs ? -1 : msrs->entries[r].index);896}897static inline void vcpu_debugregs_get(struct kvm_vcpu *vcpu,898struct kvm_debugregs *debugregs)899{900vcpu_ioctl(vcpu, KVM_GET_DEBUGREGS, debugregs);901}902static inline void vcpu_debugregs_set(struct kvm_vcpu *vcpu,903struct kvm_debugregs *debugregs)904{905vcpu_ioctl(vcpu, KVM_SET_DEBUGREGS, debugregs);906}907static inline void vcpu_xsave_get(struct kvm_vcpu *vcpu,908struct kvm_xsave *xsave)909{910vcpu_ioctl(vcpu, KVM_GET_XSAVE, xsave);911}912static inline void vcpu_xsave2_get(struct kvm_vcpu *vcpu,913struct kvm_xsave *xsave)914{915vcpu_ioctl(vcpu, KVM_GET_XSAVE2, xsave);916}917static inline void vcpu_xsave_set(struct kvm_vcpu *vcpu,918struct kvm_xsave *xsave)919{920vcpu_ioctl(vcpu, KVM_SET_XSAVE, xsave);921}922static inline void vcpu_xcrs_get(struct kvm_vcpu *vcpu,923struct kvm_xcrs *xcrs)924{925vcpu_ioctl(vcpu, KVM_GET_XCRS, xcrs);926}927static inline void vcpu_xcrs_set(struct kvm_vcpu *vcpu, struct kvm_xcrs *xcrs)928{929vcpu_ioctl(vcpu, KVM_SET_XCRS, xcrs);930}931932const struct kvm_cpuid_entry2 *get_cpuid_entry(const struct kvm_cpuid2 *cpuid,933uint32_t function, uint32_t index);934const struct kvm_cpuid2 *kvm_get_supported_cpuid(void);935936static inline uint32_t kvm_cpu_fms(void)937{938return get_cpuid_entry(kvm_get_supported_cpuid(), 0x1, 0)->eax;939}940941static inline uint32_t kvm_cpu_family(void)942{943return x86_family(kvm_cpu_fms());944}945946static inline uint32_t kvm_cpu_model(void)947{948return x86_model(kvm_cpu_fms());949}950951bool kvm_cpuid_has(const struct kvm_cpuid2 *cpuid,952struct kvm_x86_cpu_feature feature);953954static inline bool kvm_cpu_has(struct kvm_x86_cpu_feature feature)955{956return kvm_cpuid_has(kvm_get_supported_cpuid(), feature);957}958959uint32_t kvm_cpuid_property(const struct kvm_cpuid2 *cpuid,960struct kvm_x86_cpu_property property);961962static inline uint32_t kvm_cpu_property(struct kvm_x86_cpu_property property)963{964return kvm_cpuid_property(kvm_get_supported_cpuid(), property);965}966967static __always_inline bool kvm_cpu_has_p(struct kvm_x86_cpu_property property)968{969uint32_t max_leaf;970971switch (property.function & 0xc0000000) {972case 0:973max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_BASIC_LEAF);974break;975case 0x40000000:976max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_KVM_LEAF);977break;978case 0x80000000:979max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_EXT_LEAF);980break;981case 0xc0000000:982max_leaf = kvm_cpu_property(X86_PROPERTY_MAX_CENTAUR_LEAF);983}984return max_leaf >= property.function;985}986987static inline bool kvm_pmu_has(struct kvm_x86_pmu_feature feature)988{989uint32_t nr_bits;990991if (feature.f.reg == KVM_CPUID_EBX) {992nr_bits = kvm_cpu_property(X86_PROPERTY_PMU_EBX_BIT_VECTOR_LENGTH);993return nr_bits > feature.f.bit && !kvm_cpu_has(feature.f);994}995996TEST_ASSERT_EQ(feature.f.reg, KVM_CPUID_ECX);997nr_bits = kvm_cpu_property(X86_PROPERTY_PMU_NR_FIXED_COUNTERS);998return nr_bits > feature.f.bit || kvm_cpu_has(feature.f);999}10001001static __always_inline uint64_t kvm_cpu_supported_xcr0(void)1002{1003if (!kvm_cpu_has_p(X86_PROPERTY_SUPPORTED_XCR0_LO))1004return 0;10051006return kvm_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_LO) |1007((uint64_t)kvm_cpu_property(X86_PROPERTY_SUPPORTED_XCR0_HI) << 32);1008}10091010static inline size_t kvm_cpuid2_size(int nr_entries)1011{1012return sizeof(struct kvm_cpuid2) +1013sizeof(struct kvm_cpuid_entry2) * nr_entries;1014}10151016/*1017* Allocate a "struct kvm_cpuid2* instance, with the 0-length arrary of1018* entries sized to hold @nr_entries. The caller is responsible for freeing1019* the struct.1020*/1021static inline struct kvm_cpuid2 *allocate_kvm_cpuid2(int nr_entries)1022{1023struct kvm_cpuid2 *cpuid;10241025cpuid = malloc(kvm_cpuid2_size(nr_entries));1026TEST_ASSERT(cpuid, "-ENOMEM when allocating kvm_cpuid2");10271028cpuid->nent = nr_entries;10291030return cpuid;1031}10321033void vcpu_init_cpuid(struct kvm_vcpu *vcpu, const struct kvm_cpuid2 *cpuid);10341035static inline void vcpu_get_cpuid(struct kvm_vcpu *vcpu)1036{1037vcpu_ioctl(vcpu, KVM_GET_CPUID2, vcpu->cpuid);1038}10391040static inline struct kvm_cpuid_entry2 *__vcpu_get_cpuid_entry(struct kvm_vcpu *vcpu,1041uint32_t function,1042uint32_t index)1043{1044TEST_ASSERT(vcpu->cpuid, "Must do vcpu_init_cpuid() first (or equivalent)");10451046vcpu_get_cpuid(vcpu);10471048return (struct kvm_cpuid_entry2 *)get_cpuid_entry(vcpu->cpuid,1049function, index);1050}10511052static inline struct kvm_cpuid_entry2 *vcpu_get_cpuid_entry(struct kvm_vcpu *vcpu,1053uint32_t function)1054{1055return __vcpu_get_cpuid_entry(vcpu, function, 0);1056}10571058static inline int __vcpu_set_cpuid(struct kvm_vcpu *vcpu)1059{1060int r;10611062TEST_ASSERT(vcpu->cpuid, "Must do vcpu_init_cpuid() first");1063r = __vcpu_ioctl(vcpu, KVM_SET_CPUID2, vcpu->cpuid);1064if (r)1065return r;10661067/* On success, refresh the cache to pick up adjustments made by KVM. */1068vcpu_get_cpuid(vcpu);1069return 0;1070}10711072static inline void vcpu_set_cpuid(struct kvm_vcpu *vcpu)1073{1074TEST_ASSERT(vcpu->cpuid, "Must do vcpu_init_cpuid() first");1075vcpu_ioctl(vcpu, KVM_SET_CPUID2, vcpu->cpuid);10761077/* Refresh the cache to pick up adjustments made by KVM. */1078vcpu_get_cpuid(vcpu);1079}10801081void vcpu_set_cpuid_property(struct kvm_vcpu *vcpu,1082struct kvm_x86_cpu_property property,1083uint32_t value);1084void vcpu_set_cpuid_maxphyaddr(struct kvm_vcpu *vcpu, uint8_t maxphyaddr);10851086void vcpu_clear_cpuid_entry(struct kvm_vcpu *vcpu, uint32_t function);10871088static inline bool vcpu_cpuid_has(struct kvm_vcpu *vcpu,1089struct kvm_x86_cpu_feature feature)1090{1091struct kvm_cpuid_entry2 *entry;10921093entry = __vcpu_get_cpuid_entry(vcpu, feature.function, feature.index);1094return *((&entry->eax) + feature.reg) & BIT(feature.bit);1095}10961097void vcpu_set_or_clear_cpuid_feature(struct kvm_vcpu *vcpu,1098struct kvm_x86_cpu_feature feature,1099bool set);11001101static inline void vcpu_set_cpuid_feature(struct kvm_vcpu *vcpu,1102struct kvm_x86_cpu_feature feature)1103{1104vcpu_set_or_clear_cpuid_feature(vcpu, feature, true);11051106}11071108static inline void vcpu_clear_cpuid_feature(struct kvm_vcpu *vcpu,1109struct kvm_x86_cpu_feature feature)1110{1111vcpu_set_or_clear_cpuid_feature(vcpu, feature, false);1112}11131114uint64_t vcpu_get_msr(struct kvm_vcpu *vcpu, uint64_t msr_index);1115int _vcpu_set_msr(struct kvm_vcpu *vcpu, uint64_t msr_index, uint64_t msr_value);11161117/*1118* Assert on an MSR access(es) and pretty print the MSR name when possible.1119* Note, the caller provides the stringified name so that the name of macro is1120* printed, not the value the macro resolves to (due to macro expansion).1121*/1122#define TEST_ASSERT_MSR(cond, fmt, msr, str, args...) \1123do { \1124if (__builtin_constant_p(msr)) { \1125TEST_ASSERT(cond, fmt, str, args); \1126} else if (!(cond)) { \1127char buf[16]; \1128\1129snprintf(buf, sizeof(buf), "MSR 0x%x", msr); \1130TEST_ASSERT(cond, fmt, buf, args); \1131} \1132} while (0)11331134/*1135* Returns true if KVM should return the last written value when reading an MSR1136* from userspace, e.g. the MSR isn't a command MSR, doesn't emulate state that1137* is changing, etc. This is NOT an exhaustive list! The intent is to filter1138* out MSRs that are not durable _and_ that a selftest wants to write.1139*/1140static inline bool is_durable_msr(uint32_t msr)1141{1142return msr != MSR_IA32_TSC;1143}11441145#define vcpu_set_msr(vcpu, msr, val) \1146do { \1147uint64_t r, v = val; \1148\1149TEST_ASSERT_MSR(_vcpu_set_msr(vcpu, msr, v) == 1, \1150"KVM_SET_MSRS failed on %s, value = 0x%lx", msr, #msr, v); \1151if (!is_durable_msr(msr)) \1152break; \1153r = vcpu_get_msr(vcpu, msr); \1154TEST_ASSERT_MSR(r == v, "Set %s to '0x%lx', got back '0x%lx'", msr, #msr, v, r);\1155} while (0)11561157void kvm_get_cpu_address_width(unsigned int *pa_bits, unsigned int *va_bits);1158void kvm_init_vm_address_properties(struct kvm_vm *vm);11591160struct ex_regs {1161uint64_t rax, rcx, rdx, rbx;1162uint64_t rbp, rsi, rdi;1163uint64_t r8, r9, r10, r11;1164uint64_t r12, r13, r14, r15;1165uint64_t vector;1166uint64_t error_code;1167uint64_t rip;1168uint64_t cs;1169uint64_t rflags;1170};11711172struct idt_entry {1173uint16_t offset0;1174uint16_t selector;1175uint16_t ist : 3;1176uint16_t : 5;1177uint16_t type : 4;1178uint16_t : 1;1179uint16_t dpl : 2;1180uint16_t p : 1;1181uint16_t offset1;1182uint32_t offset2; uint32_t reserved;1183};11841185void vm_install_exception_handler(struct kvm_vm *vm, int vector,1186void (*handler)(struct ex_regs *));11871188/*1189* Exception fixup morphs #DE to an arbitrary magic vector so that '0' can be1190* used to signal "no expcetion".1191*/1192#define KVM_MAGIC_DE_VECTOR 0xff11931194/* If a toddler were to say "abracadabra". */1195#define KVM_EXCEPTION_MAGIC 0xabacadabaULL11961197/*1198* KVM selftest exception fixup uses registers to coordinate with the exception1199* handler, versus the kernel's in-memory tables and KVM-Unit-Tests's in-memory1200* per-CPU data. Using only registers avoids having to map memory into the1201* guest, doesn't require a valid, stable GS.base, and reduces the risk of1202* for recursive faults when accessing memory in the handler. The downside to1203* using registers is that it restricts what registers can be used by the actual1204* instruction. But, selftests are 64-bit only, making register* pressure a1205* minor concern. Use r9-r11 as they are volatile, i.e. don't need to be saved1206* by the callee, and except for r11 are not implicit parameters to any1207* instructions. Ideally, fixup would use r8-r10 and thus avoid implicit1208* parameters entirely, but Hyper-V's hypercall ABI uses r8 and testing Hyper-V1209* is higher priority than testing non-faulting SYSCALL/SYSRET.1210*1211* Note, the fixup handler deliberately does not handle #DE, i.e. the vector1212* is guaranteed to be non-zero on fault.1213*1214* REGISTER INPUTS:1215* r9 = MAGIC1216* r10 = RIP1217* r11 = new RIP on fault1218*1219* REGISTER OUTPUTS:1220* r9 = exception vector (non-zero)1221* r10 = error code1222*/1223#define __KVM_ASM_SAFE(insn, fep) \1224"mov $" __stringify(KVM_EXCEPTION_MAGIC) ", %%r9\n\t" \1225"lea 1f(%%rip), %%r10\n\t" \1226"lea 2f(%%rip), %%r11\n\t" \1227fep "1: " insn "\n\t" \1228"xor %%r9, %%r9\n\t" \1229"2:\n\t" \1230"mov %%r9b, %[vector]\n\t" \1231"mov %%r10, %[error_code]\n\t"12321233#define KVM_ASM_SAFE(insn) __KVM_ASM_SAFE(insn, "")1234#define KVM_ASM_SAFE_FEP(insn) __KVM_ASM_SAFE(insn, KVM_FEP)12351236#define KVM_ASM_SAFE_OUTPUTS(v, ec) [vector] "=qm"(v), [error_code] "=rm"(ec)1237#define KVM_ASM_SAFE_CLOBBERS "r9", "r10", "r11"12381239#define kvm_asm_safe(insn, inputs...) \1240({ \1241uint64_t ign_error_code; \1242uint8_t vector; \1243\1244asm volatile(KVM_ASM_SAFE(insn) \1245: KVM_ASM_SAFE_OUTPUTS(vector, ign_error_code) \1246: inputs \1247: KVM_ASM_SAFE_CLOBBERS); \1248vector; \1249})12501251#define kvm_asm_safe_ec(insn, error_code, inputs...) \1252({ \1253uint8_t vector; \1254\1255asm volatile(KVM_ASM_SAFE(insn) \1256: KVM_ASM_SAFE_OUTPUTS(vector, error_code) \1257: inputs \1258: KVM_ASM_SAFE_CLOBBERS); \1259vector; \1260})12611262#define kvm_asm_safe_fep(insn, inputs...) \1263({ \1264uint64_t ign_error_code; \1265uint8_t vector; \1266\1267asm volatile(KVM_ASM_SAFE_FEP(insn) \1268: KVM_ASM_SAFE_OUTPUTS(vector, ign_error_code) \1269: inputs \1270: KVM_ASM_SAFE_CLOBBERS); \1271vector; \1272})12731274#define kvm_asm_safe_ec_fep(insn, error_code, inputs...) \1275({ \1276uint8_t vector; \1277\1278asm volatile(KVM_ASM_SAFE_FEP(insn) \1279: KVM_ASM_SAFE_OUTPUTS(vector, error_code) \1280: inputs \1281: KVM_ASM_SAFE_CLOBBERS); \1282vector; \1283})12841285#define BUILD_READ_U64_SAFE_HELPER(insn, _fep, _FEP) \1286static inline uint8_t insn##_safe ##_fep(uint32_t idx, uint64_t *val) \1287{ \1288uint64_t error_code; \1289uint8_t vector; \1290uint32_t a, d; \1291\1292asm volatile(KVM_ASM_SAFE##_FEP(#insn) \1293: "=a"(a), "=d"(d), \1294KVM_ASM_SAFE_OUTPUTS(vector, error_code) \1295: "c"(idx) \1296: KVM_ASM_SAFE_CLOBBERS); \1297\1298*val = (uint64_t)a | ((uint64_t)d << 32); \1299return vector; \1300}13011302/*1303* Generate {insn}_safe() and {insn}_safe_fep() helpers for instructions that1304* use ECX as in input index, and EDX:EAX as a 64-bit output.1305*/1306#define BUILD_READ_U64_SAFE_HELPERS(insn) \1307BUILD_READ_U64_SAFE_HELPER(insn, , ) \1308BUILD_READ_U64_SAFE_HELPER(insn, _fep, _FEP) \13091310BUILD_READ_U64_SAFE_HELPERS(rdmsr)1311BUILD_READ_U64_SAFE_HELPERS(rdpmc)1312BUILD_READ_U64_SAFE_HELPERS(xgetbv)13131314static inline uint8_t wrmsr_safe(uint32_t msr, uint64_t val)1315{1316return kvm_asm_safe("wrmsr", "a"(val & -1u), "d"(val >> 32), "c"(msr));1317}13181319static inline uint8_t xsetbv_safe(uint32_t index, uint64_t value)1320{1321u32 eax = value;1322u32 edx = value >> 32;13231324return kvm_asm_safe("xsetbv", "a" (eax), "d" (edx), "c" (index));1325}13261327bool kvm_is_tdp_enabled(void);13281329static inline bool get_kvm_intel_param_bool(const char *param)1330{1331return kvm_get_module_param_bool("kvm_intel", param);1332}13331334static inline bool get_kvm_amd_param_bool(const char *param)1335{1336return kvm_get_module_param_bool("kvm_amd", param);1337}13381339static inline int get_kvm_intel_param_integer(const char *param)1340{1341return kvm_get_module_param_integer("kvm_intel", param);1342}13431344static inline int get_kvm_amd_param_integer(const char *param)1345{1346return kvm_get_module_param_integer("kvm_amd", param);1347}13481349static inline bool kvm_is_pmu_enabled(void)1350{1351return get_kvm_param_bool("enable_pmu");1352}13531354static inline bool kvm_is_forced_emulation_enabled(void)1355{1356return !!get_kvm_param_integer("force_emulation_prefix");1357}13581359static inline bool kvm_is_unrestricted_guest_enabled(void)1360{1361return get_kvm_intel_param_bool("unrestricted_guest");1362}13631364static inline bool kvm_is_ignore_msrs(void)1365{1366return get_kvm_param_bool("ignore_msrs");1367}13681369uint64_t *__vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr,1370int *level);1371uint64_t *vm_get_page_table_entry(struct kvm_vm *vm, uint64_t vaddr);13721373uint64_t kvm_hypercall(uint64_t nr, uint64_t a0, uint64_t a1, uint64_t a2,1374uint64_t a3);1375uint64_t __xen_hypercall(uint64_t nr, uint64_t a0, void *a1);1376void xen_hypercall(uint64_t nr, uint64_t a0, void *a1);13771378static inline uint64_t __kvm_hypercall_map_gpa_range(uint64_t gpa,1379uint64_t size, uint64_t flags)1380{1381return kvm_hypercall(KVM_HC_MAP_GPA_RANGE, gpa, size >> PAGE_SHIFT, flags, 0);1382}13831384static inline void kvm_hypercall_map_gpa_range(uint64_t gpa, uint64_t size,1385uint64_t flags)1386{1387uint64_t ret = __kvm_hypercall_map_gpa_range(gpa, size, flags);13881389GUEST_ASSERT(!ret);1390}13911392/*1393* Execute HLT in an STI interrupt shadow to ensure that a pending IRQ that's1394* intended to be a wake event arrives *after* HLT is executed. Modern CPUs,1395* except for a few oddballs that KVM is unlikely to run on, block IRQs for one1396* instruction after STI, *if* RFLAGS.IF=0 before STI. Note, Intel CPUs may1397* block other events beyond regular IRQs, e.g. may block NMIs and SMIs too.1398*/1399static inline void safe_halt(void)1400{1401asm volatile("sti; hlt");1402}14031404/*1405* Enable interrupts and ensure that interrupts are evaluated upon return from1406* this function, i.e. execute a nop to consume the STi interrupt shadow.1407*/1408static inline void sti_nop(void)1409{1410asm volatile ("sti; nop");1411}14121413/*1414* Enable interrupts for one instruction (nop), to allow the CPU to process all1415* interrupts that are already pending.1416*/1417static inline void sti_nop_cli(void)1418{1419asm volatile ("sti; nop; cli");1420}14211422static inline void sti(void)1423{1424asm volatile("sti");1425}14261427static inline void cli(void)1428{1429asm volatile ("cli");1430}14311432void __vm_xsave_require_permission(uint64_t xfeature, const char *name);14331434#define vm_xsave_require_permission(xfeature) \1435__vm_xsave_require_permission(xfeature, #xfeature)14361437enum pg_level {1438PG_LEVEL_NONE,1439PG_LEVEL_4K,1440PG_LEVEL_2M,1441PG_LEVEL_1G,1442PG_LEVEL_512G,1443PG_LEVEL_256T1444};14451446#define PG_LEVEL_SHIFT(_level) ((_level - 1) * 9 + 12)1447#define PG_LEVEL_SIZE(_level) (1ull << PG_LEVEL_SHIFT(_level))14481449#define PG_SIZE_4K PG_LEVEL_SIZE(PG_LEVEL_4K)1450#define PG_SIZE_2M PG_LEVEL_SIZE(PG_LEVEL_2M)1451#define PG_SIZE_1G PG_LEVEL_SIZE(PG_LEVEL_1G)14521453void __virt_pg_map(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr, int level);1454void virt_map_level(struct kvm_vm *vm, uint64_t vaddr, uint64_t paddr,1455uint64_t nr_bytes, int level);14561457/*1458* Basic CPU control in CR01459*/1460#define X86_CR0_PE (1UL<<0) /* Protection Enable */1461#define X86_CR0_MP (1UL<<1) /* Monitor Coprocessor */1462#define X86_CR0_EM (1UL<<2) /* Emulation */1463#define X86_CR0_TS (1UL<<3) /* Task Switched */1464#define X86_CR0_ET (1UL<<4) /* Extension Type */1465#define X86_CR0_NE (1UL<<5) /* Numeric Error */1466#define X86_CR0_WP (1UL<<16) /* Write Protect */1467#define X86_CR0_AM (1UL<<18) /* Alignment Mask */1468#define X86_CR0_NW (1UL<<29) /* Not Write-through */1469#define X86_CR0_CD (1UL<<30) /* Cache Disable */1470#define X86_CR0_PG (1UL<<31) /* Paging */14711472#define PFERR_PRESENT_BIT 01473#define PFERR_WRITE_BIT 11474#define PFERR_USER_BIT 21475#define PFERR_RSVD_BIT 31476#define PFERR_FETCH_BIT 41477#define PFERR_PK_BIT 51478#define PFERR_SGX_BIT 151479#define PFERR_GUEST_FINAL_BIT 321480#define PFERR_GUEST_PAGE_BIT 331481#define PFERR_IMPLICIT_ACCESS_BIT 4814821483#define PFERR_PRESENT_MASK BIT(PFERR_PRESENT_BIT)1484#define PFERR_WRITE_MASK BIT(PFERR_WRITE_BIT)1485#define PFERR_USER_MASK BIT(PFERR_USER_BIT)1486#define PFERR_RSVD_MASK BIT(PFERR_RSVD_BIT)1487#define PFERR_FETCH_MASK BIT(PFERR_FETCH_BIT)1488#define PFERR_PK_MASK BIT(PFERR_PK_BIT)1489#define PFERR_SGX_MASK BIT(PFERR_SGX_BIT)1490#define PFERR_GUEST_FINAL_MASK BIT_ULL(PFERR_GUEST_FINAL_BIT)1491#define PFERR_GUEST_PAGE_MASK BIT_ULL(PFERR_GUEST_PAGE_BIT)1492#define PFERR_IMPLICIT_ACCESS BIT_ULL(PFERR_IMPLICIT_ACCESS_BIT)14931494bool sys_clocksource_is_based_on_tsc(void);14951496#endif /* SELFTEST_KVM_PROCESSOR_H */149714981499