18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef ARCH_X86_KVM_X86_H
38c2ecf20Sopenharmony_ci#define ARCH_X86_KVM_X86_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#include <linux/kvm_host.h>
68c2ecf20Sopenharmony_ci#include <asm/pvclock.h>
78c2ecf20Sopenharmony_ci#include "kvm_cache_regs.h"
88c2ecf20Sopenharmony_ci#include "kvm_emulate.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#define KVM_DEFAULT_PLE_GAP		128
118c2ecf20Sopenharmony_ci#define KVM_VMX_DEFAULT_PLE_WINDOW	4096
128c2ecf20Sopenharmony_ci#define KVM_DEFAULT_PLE_WINDOW_GROW	2
138c2ecf20Sopenharmony_ci#define KVM_DEFAULT_PLE_WINDOW_SHRINK	0
148c2ecf20Sopenharmony_ci#define KVM_VMX_DEFAULT_PLE_WINDOW_MAX	UINT_MAX
158c2ecf20Sopenharmony_ci#define KVM_SVM_DEFAULT_PLE_WINDOW_MAX	USHRT_MAX
168c2ecf20Sopenharmony_ci#define KVM_SVM_DEFAULT_PLE_WINDOW	3000
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic inline unsigned int __grow_ple_window(unsigned int val,
198c2ecf20Sopenharmony_ci		unsigned int base, unsigned int modifier, unsigned int max)
208c2ecf20Sopenharmony_ci{
218c2ecf20Sopenharmony_ci	u64 ret = val;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci	if (modifier < 1)
248c2ecf20Sopenharmony_ci		return base;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci	if (modifier < base)
278c2ecf20Sopenharmony_ci		ret *= modifier;
288c2ecf20Sopenharmony_ci	else
298c2ecf20Sopenharmony_ci		ret += modifier;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	return min(ret, (u64)max);
328c2ecf20Sopenharmony_ci}
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_cistatic inline unsigned int __shrink_ple_window(unsigned int val,
358c2ecf20Sopenharmony_ci		unsigned int base, unsigned int modifier, unsigned int min)
368c2ecf20Sopenharmony_ci{
378c2ecf20Sopenharmony_ci	if (modifier < 1)
388c2ecf20Sopenharmony_ci		return base;
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	if (modifier < base)
418c2ecf20Sopenharmony_ci		val /= modifier;
428c2ecf20Sopenharmony_ci	else
438c2ecf20Sopenharmony_ci		val -= modifier;
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci	return max(val, min);
468c2ecf20Sopenharmony_ci}
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci#define MSR_IA32_CR_PAT_DEFAULT  0x0007040600070406ULL
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic inline void kvm_clear_exception_queue(struct kvm_vcpu *vcpu)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	vcpu->arch.exception.pending = false;
538c2ecf20Sopenharmony_ci	vcpu->arch.exception.injected = false;
548c2ecf20Sopenharmony_ci}
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_cistatic inline void kvm_queue_interrupt(struct kvm_vcpu *vcpu, u8 vector,
578c2ecf20Sopenharmony_ci	bool soft)
588c2ecf20Sopenharmony_ci{
598c2ecf20Sopenharmony_ci	vcpu->arch.interrupt.injected = true;
608c2ecf20Sopenharmony_ci	vcpu->arch.interrupt.soft = soft;
618c2ecf20Sopenharmony_ci	vcpu->arch.interrupt.nr = vector;
628c2ecf20Sopenharmony_ci}
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_cistatic inline void kvm_clear_interrupt_queue(struct kvm_vcpu *vcpu)
658c2ecf20Sopenharmony_ci{
668c2ecf20Sopenharmony_ci	vcpu->arch.interrupt.injected = false;
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_cistatic inline bool kvm_event_needs_reinjection(struct kvm_vcpu *vcpu)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	return vcpu->arch.exception.injected || vcpu->arch.interrupt.injected ||
728c2ecf20Sopenharmony_ci		vcpu->arch.nmi_injected;
738c2ecf20Sopenharmony_ci}
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_cistatic inline bool kvm_exception_is_soft(unsigned int nr)
768c2ecf20Sopenharmony_ci{
778c2ecf20Sopenharmony_ci	return (nr == BP_VECTOR) || (nr == OF_VECTOR);
788c2ecf20Sopenharmony_ci}
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_cistatic inline bool is_protmode(struct kvm_vcpu *vcpu)
818c2ecf20Sopenharmony_ci{
828c2ecf20Sopenharmony_ci	return kvm_read_cr0_bits(vcpu, X86_CR0_PE);
838c2ecf20Sopenharmony_ci}
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_cistatic inline int is_long_mode(struct kvm_vcpu *vcpu)
868c2ecf20Sopenharmony_ci{
878c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
888c2ecf20Sopenharmony_ci	return vcpu->arch.efer & EFER_LMA;
898c2ecf20Sopenharmony_ci#else
908c2ecf20Sopenharmony_ci	return 0;
918c2ecf20Sopenharmony_ci#endif
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic inline bool is_64_bit_mode(struct kvm_vcpu *vcpu)
958c2ecf20Sopenharmony_ci{
968c2ecf20Sopenharmony_ci	int cs_db, cs_l;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	if (!is_long_mode(vcpu))
998c2ecf20Sopenharmony_ci		return false;
1008c2ecf20Sopenharmony_ci	kvm_x86_ops.get_cs_db_l_bits(vcpu, &cs_db, &cs_l);
1018c2ecf20Sopenharmony_ci	return cs_l;
1028c2ecf20Sopenharmony_ci}
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_cistatic inline bool is_la57_mode(struct kvm_vcpu *vcpu)
1058c2ecf20Sopenharmony_ci{
1068c2ecf20Sopenharmony_ci#ifdef CONFIG_X86_64
1078c2ecf20Sopenharmony_ci	return (vcpu->arch.efer & EFER_LMA) &&
1088c2ecf20Sopenharmony_ci		 kvm_read_cr4_bits(vcpu, X86_CR4_LA57);
1098c2ecf20Sopenharmony_ci#else
1108c2ecf20Sopenharmony_ci	return 0;
1118c2ecf20Sopenharmony_ci#endif
1128c2ecf20Sopenharmony_ci}
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_cistatic inline bool x86_exception_has_error_code(unsigned int vector)
1158c2ecf20Sopenharmony_ci{
1168c2ecf20Sopenharmony_ci	static u32 exception_has_error_code = BIT(DF_VECTOR) | BIT(TS_VECTOR) |
1178c2ecf20Sopenharmony_ci			BIT(NP_VECTOR) | BIT(SS_VECTOR) | BIT(GP_VECTOR) |
1188c2ecf20Sopenharmony_ci			BIT(PF_VECTOR) | BIT(AC_VECTOR);
1198c2ecf20Sopenharmony_ci
1208c2ecf20Sopenharmony_ci	return (1U << vector) & exception_has_error_code;
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_cistatic inline bool mmu_is_nested(struct kvm_vcpu *vcpu)
1248c2ecf20Sopenharmony_ci{
1258c2ecf20Sopenharmony_ci	return vcpu->arch.walk_mmu == &vcpu->arch.nested_mmu;
1268c2ecf20Sopenharmony_ci}
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_cistatic inline void kvm_vcpu_flush_tlb_current(struct kvm_vcpu *vcpu)
1298c2ecf20Sopenharmony_ci{
1308c2ecf20Sopenharmony_ci	++vcpu->stat.tlb_flush;
1318c2ecf20Sopenharmony_ci	kvm_x86_ops.tlb_flush_current(vcpu);
1328c2ecf20Sopenharmony_ci}
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_cistatic inline int is_pae(struct kvm_vcpu *vcpu)
1358c2ecf20Sopenharmony_ci{
1368c2ecf20Sopenharmony_ci	return kvm_read_cr4_bits(vcpu, X86_CR4_PAE);
1378c2ecf20Sopenharmony_ci}
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistatic inline int is_pse(struct kvm_vcpu *vcpu)
1408c2ecf20Sopenharmony_ci{
1418c2ecf20Sopenharmony_ci	return kvm_read_cr4_bits(vcpu, X86_CR4_PSE);
1428c2ecf20Sopenharmony_ci}
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_cistatic inline int is_paging(struct kvm_vcpu *vcpu)
1458c2ecf20Sopenharmony_ci{
1468c2ecf20Sopenharmony_ci	return likely(kvm_read_cr0_bits(vcpu, X86_CR0_PG));
1478c2ecf20Sopenharmony_ci}
1488c2ecf20Sopenharmony_ci
1498c2ecf20Sopenharmony_cistatic inline bool is_pae_paging(struct kvm_vcpu *vcpu)
1508c2ecf20Sopenharmony_ci{
1518c2ecf20Sopenharmony_ci	return !is_long_mode(vcpu) && is_pae(vcpu) && is_paging(vcpu);
1528c2ecf20Sopenharmony_ci}
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_cistatic inline u8 vcpu_virt_addr_bits(struct kvm_vcpu *vcpu)
1558c2ecf20Sopenharmony_ci{
1568c2ecf20Sopenharmony_ci	return kvm_read_cr4_bits(vcpu, X86_CR4_LA57) ? 57 : 48;
1578c2ecf20Sopenharmony_ci}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_cistatic inline bool is_noncanonical_address(u64 la, struct kvm_vcpu *vcpu)
1608c2ecf20Sopenharmony_ci{
1618c2ecf20Sopenharmony_ci	return !__is_canonical_address(la, vcpu_virt_addr_bits(vcpu));
1628c2ecf20Sopenharmony_ci}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_cistatic inline void vcpu_cache_mmio_info(struct kvm_vcpu *vcpu,
1658c2ecf20Sopenharmony_ci					gva_t gva, gfn_t gfn, unsigned access)
1668c2ecf20Sopenharmony_ci{
1678c2ecf20Sopenharmony_ci	u64 gen = kvm_memslots(vcpu->kvm)->generation;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	if (unlikely(gen & KVM_MEMSLOT_GEN_UPDATE_IN_PROGRESS))
1708c2ecf20Sopenharmony_ci		return;
1718c2ecf20Sopenharmony_ci
1728c2ecf20Sopenharmony_ci	/*
1738c2ecf20Sopenharmony_ci	 * If this is a shadow nested page table, the "GVA" is
1748c2ecf20Sopenharmony_ci	 * actually a nGPA.
1758c2ecf20Sopenharmony_ci	 */
1768c2ecf20Sopenharmony_ci	vcpu->arch.mmio_gva = mmu_is_nested(vcpu) ? 0 : gva & PAGE_MASK;
1778c2ecf20Sopenharmony_ci	vcpu->arch.mmio_access = access;
1788c2ecf20Sopenharmony_ci	vcpu->arch.mmio_gfn = gfn;
1798c2ecf20Sopenharmony_ci	vcpu->arch.mmio_gen = gen;
1808c2ecf20Sopenharmony_ci}
1818c2ecf20Sopenharmony_ci
1828c2ecf20Sopenharmony_cistatic inline bool vcpu_match_mmio_gen(struct kvm_vcpu *vcpu)
1838c2ecf20Sopenharmony_ci{
1848c2ecf20Sopenharmony_ci	return vcpu->arch.mmio_gen == kvm_memslots(vcpu->kvm)->generation;
1858c2ecf20Sopenharmony_ci}
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci/*
1888c2ecf20Sopenharmony_ci * Clear the mmio cache info for the given gva. If gva is MMIO_GVA_ANY, we
1898c2ecf20Sopenharmony_ci * clear all mmio cache info.
1908c2ecf20Sopenharmony_ci */
1918c2ecf20Sopenharmony_ci#define MMIO_GVA_ANY (~(gva_t)0)
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_cistatic inline void vcpu_clear_mmio_info(struct kvm_vcpu *vcpu, gva_t gva)
1948c2ecf20Sopenharmony_ci{
1958c2ecf20Sopenharmony_ci	if (gva != MMIO_GVA_ANY && vcpu->arch.mmio_gva != (gva & PAGE_MASK))
1968c2ecf20Sopenharmony_ci		return;
1978c2ecf20Sopenharmony_ci
1988c2ecf20Sopenharmony_ci	vcpu->arch.mmio_gva = 0;
1998c2ecf20Sopenharmony_ci}
2008c2ecf20Sopenharmony_ci
2018c2ecf20Sopenharmony_cistatic inline bool vcpu_match_mmio_gva(struct kvm_vcpu *vcpu, unsigned long gva)
2028c2ecf20Sopenharmony_ci{
2038c2ecf20Sopenharmony_ci	if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gva &&
2048c2ecf20Sopenharmony_ci	      vcpu->arch.mmio_gva == (gva & PAGE_MASK))
2058c2ecf20Sopenharmony_ci		return true;
2068c2ecf20Sopenharmony_ci
2078c2ecf20Sopenharmony_ci	return false;
2088c2ecf20Sopenharmony_ci}
2098c2ecf20Sopenharmony_ci
2108c2ecf20Sopenharmony_cistatic inline bool vcpu_match_mmio_gpa(struct kvm_vcpu *vcpu, gpa_t gpa)
2118c2ecf20Sopenharmony_ci{
2128c2ecf20Sopenharmony_ci	if (vcpu_match_mmio_gen(vcpu) && vcpu->arch.mmio_gfn &&
2138c2ecf20Sopenharmony_ci	      vcpu->arch.mmio_gfn == gpa >> PAGE_SHIFT)
2148c2ecf20Sopenharmony_ci		return true;
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_ci	return false;
2178c2ecf20Sopenharmony_ci}
2188c2ecf20Sopenharmony_ci
2198c2ecf20Sopenharmony_cistatic inline unsigned long kvm_register_readl(struct kvm_vcpu *vcpu, int reg)
2208c2ecf20Sopenharmony_ci{
2218c2ecf20Sopenharmony_ci	unsigned long val = kvm_register_read(vcpu, reg);
2228c2ecf20Sopenharmony_ci
2238c2ecf20Sopenharmony_ci	return is_64_bit_mode(vcpu) ? val : (u32)val;
2248c2ecf20Sopenharmony_ci}
2258c2ecf20Sopenharmony_ci
2268c2ecf20Sopenharmony_cistatic inline void kvm_register_writel(struct kvm_vcpu *vcpu,
2278c2ecf20Sopenharmony_ci				       int reg, unsigned long val)
2288c2ecf20Sopenharmony_ci{
2298c2ecf20Sopenharmony_ci	if (!is_64_bit_mode(vcpu))
2308c2ecf20Sopenharmony_ci		val = (u32)val;
2318c2ecf20Sopenharmony_ci	return kvm_register_write(vcpu, reg, val);
2328c2ecf20Sopenharmony_ci}
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_cistatic inline bool kvm_check_has_quirk(struct kvm *kvm, u64 quirk)
2358c2ecf20Sopenharmony_ci{
2368c2ecf20Sopenharmony_ci	return !(kvm->arch.disabled_quirks & quirk);
2378c2ecf20Sopenharmony_ci}
2388c2ecf20Sopenharmony_ci
2398c2ecf20Sopenharmony_cistatic inline bool kvm_vcpu_latch_init(struct kvm_vcpu *vcpu)
2408c2ecf20Sopenharmony_ci{
2418c2ecf20Sopenharmony_ci	return is_smm(vcpu) || kvm_x86_ops.apic_init_signal_blocked(vcpu);
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_civoid kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_civoid kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr);
2478c2ecf20Sopenharmony_ciu64 get_kvmclock_ns(struct kvm *kvm);
2488c2ecf20Sopenharmony_ci
2498c2ecf20Sopenharmony_ciint kvm_read_guest_virt(struct kvm_vcpu *vcpu,
2508c2ecf20Sopenharmony_ci	gva_t addr, void *val, unsigned int bytes,
2518c2ecf20Sopenharmony_ci	struct x86_exception *exception);
2528c2ecf20Sopenharmony_ci
2538c2ecf20Sopenharmony_ciint kvm_write_guest_virt_system(struct kvm_vcpu *vcpu,
2548c2ecf20Sopenharmony_ci	gva_t addr, void *val, unsigned int bytes,
2558c2ecf20Sopenharmony_ci	struct x86_exception *exception);
2568c2ecf20Sopenharmony_ci
2578c2ecf20Sopenharmony_ciint handle_ud(struct kvm_vcpu *vcpu);
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_civoid kvm_deliver_exception_payload(struct kvm_vcpu *vcpu);
2608c2ecf20Sopenharmony_ci
2618c2ecf20Sopenharmony_civoid kvm_vcpu_mtrr_init(struct kvm_vcpu *vcpu);
2628c2ecf20Sopenharmony_ciu8 kvm_mtrr_get_guest_memory_type(struct kvm_vcpu *vcpu, gfn_t gfn);
2638c2ecf20Sopenharmony_cibool kvm_mtrr_valid(struct kvm_vcpu *vcpu, u32 msr, u64 data);
2648c2ecf20Sopenharmony_ciint kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
2658c2ecf20Sopenharmony_ciint kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
2668c2ecf20Sopenharmony_cibool kvm_mtrr_check_gfn_range_consistency(struct kvm_vcpu *vcpu, gfn_t gfn,
2678c2ecf20Sopenharmony_ci					  int page_num);
2688c2ecf20Sopenharmony_cibool kvm_vector_hashing_enabled(void);
2698c2ecf20Sopenharmony_civoid kvm_fixup_and_inject_pf_error(struct kvm_vcpu *vcpu, gva_t gva, u16 error_code);
2708c2ecf20Sopenharmony_ciint x86_decode_emulated_instruction(struct kvm_vcpu *vcpu, int emulation_type,
2718c2ecf20Sopenharmony_ci				    void *insn, int insn_len);
2728c2ecf20Sopenharmony_ciint x86_emulate_instruction(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa,
2738c2ecf20Sopenharmony_ci			    int emulation_type, void *insn, int insn_len);
2748c2ecf20Sopenharmony_cifastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu);
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ciextern u64 host_xcr0;
2778c2ecf20Sopenharmony_ciextern u64 supported_xcr0;
2788c2ecf20Sopenharmony_ciextern u64 supported_xss;
2798c2ecf20Sopenharmony_ci
2808c2ecf20Sopenharmony_cistatic inline bool kvm_mpx_supported(void)
2818c2ecf20Sopenharmony_ci{
2828c2ecf20Sopenharmony_ci	return (supported_xcr0 & (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR))
2838c2ecf20Sopenharmony_ci		== (XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR);
2848c2ecf20Sopenharmony_ci}
2858c2ecf20Sopenharmony_ci
2868c2ecf20Sopenharmony_ciextern unsigned int min_timer_period_us;
2878c2ecf20Sopenharmony_ci
2888c2ecf20Sopenharmony_ciextern bool enable_vmware_backdoor;
2898c2ecf20Sopenharmony_ci
2908c2ecf20Sopenharmony_ciextern int pi_inject_timer;
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ciextern struct static_key kvm_no_apic_vcpu;
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_cistatic inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
2958c2ecf20Sopenharmony_ci{
2968c2ecf20Sopenharmony_ci	return pvclock_scale_delta(nsec, vcpu->arch.virtual_tsc_mult,
2978c2ecf20Sopenharmony_ci				   vcpu->arch.virtual_tsc_shift);
2988c2ecf20Sopenharmony_ci}
2998c2ecf20Sopenharmony_ci
3008c2ecf20Sopenharmony_ci/* Same "calling convention" as do_div:
3018c2ecf20Sopenharmony_ci * - divide (n << 32) by base
3028c2ecf20Sopenharmony_ci * - put result in n
3038c2ecf20Sopenharmony_ci * - return remainder
3048c2ecf20Sopenharmony_ci */
3058c2ecf20Sopenharmony_ci#define do_shl32_div32(n, base)					\
3068c2ecf20Sopenharmony_ci	({							\
3078c2ecf20Sopenharmony_ci	    u32 __quot, __rem;					\
3088c2ecf20Sopenharmony_ci	    asm("divl %2" : "=a" (__quot), "=d" (__rem)		\
3098c2ecf20Sopenharmony_ci			: "rm" (base), "0" (0), "1" ((u32) n));	\
3108c2ecf20Sopenharmony_ci	    n = __quot;						\
3118c2ecf20Sopenharmony_ci	    __rem;						\
3128c2ecf20Sopenharmony_ci	 })
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_cistatic inline bool kvm_mwait_in_guest(struct kvm *kvm)
3158c2ecf20Sopenharmony_ci{
3168c2ecf20Sopenharmony_ci	return kvm->arch.mwait_in_guest;
3178c2ecf20Sopenharmony_ci}
3188c2ecf20Sopenharmony_ci
3198c2ecf20Sopenharmony_cistatic inline bool kvm_hlt_in_guest(struct kvm *kvm)
3208c2ecf20Sopenharmony_ci{
3218c2ecf20Sopenharmony_ci	return kvm->arch.hlt_in_guest;
3228c2ecf20Sopenharmony_ci}
3238c2ecf20Sopenharmony_ci
3248c2ecf20Sopenharmony_cistatic inline bool kvm_pause_in_guest(struct kvm *kvm)
3258c2ecf20Sopenharmony_ci{
3268c2ecf20Sopenharmony_ci	return kvm->arch.pause_in_guest;
3278c2ecf20Sopenharmony_ci}
3288c2ecf20Sopenharmony_ci
3298c2ecf20Sopenharmony_cistatic inline bool kvm_cstate_in_guest(struct kvm *kvm)
3308c2ecf20Sopenharmony_ci{
3318c2ecf20Sopenharmony_ci	return kvm->arch.cstate_in_guest;
3328c2ecf20Sopenharmony_ci}
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ciDECLARE_PER_CPU(struct kvm_vcpu *, current_vcpu);
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_cistatic inline void kvm_before_interrupt(struct kvm_vcpu *vcpu)
3378c2ecf20Sopenharmony_ci{
3388c2ecf20Sopenharmony_ci	__this_cpu_write(current_vcpu, vcpu);
3398c2ecf20Sopenharmony_ci}
3408c2ecf20Sopenharmony_ci
3418c2ecf20Sopenharmony_cistatic inline void kvm_after_interrupt(struct kvm_vcpu *vcpu)
3428c2ecf20Sopenharmony_ci{
3438c2ecf20Sopenharmony_ci	__this_cpu_write(current_vcpu, NULL);
3448c2ecf20Sopenharmony_ci}
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_cistatic inline bool kvm_pat_valid(u64 data)
3488c2ecf20Sopenharmony_ci{
3498c2ecf20Sopenharmony_ci	if (data & 0xF8F8F8F8F8F8F8F8ull)
3508c2ecf20Sopenharmony_ci		return false;
3518c2ecf20Sopenharmony_ci	/* 0, 1, 4, 5, 6, 7 are valid values.  */
3528c2ecf20Sopenharmony_ci	return (data | ((data & 0x0202020202020202ull) << 1)) == data;
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_cistatic inline bool kvm_dr7_valid(u64 data)
3568c2ecf20Sopenharmony_ci{
3578c2ecf20Sopenharmony_ci	/* Bits [63:32] are reserved */
3588c2ecf20Sopenharmony_ci	return !(data >> 32);
3598c2ecf20Sopenharmony_ci}
3608c2ecf20Sopenharmony_cistatic inline bool kvm_dr6_valid(u64 data)
3618c2ecf20Sopenharmony_ci{
3628c2ecf20Sopenharmony_ci	/* Bits [63:32] are reserved */
3638c2ecf20Sopenharmony_ci	return !(data >> 32);
3648c2ecf20Sopenharmony_ci}
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_civoid kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu);
3678c2ecf20Sopenharmony_civoid kvm_load_host_xsave_state(struct kvm_vcpu *vcpu);
3688c2ecf20Sopenharmony_ciint kvm_spec_ctrl_test_value(u64 value);
3698c2ecf20Sopenharmony_ciint kvm_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4);
3708c2ecf20Sopenharmony_cibool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu);
3718c2ecf20Sopenharmony_ciint kvm_handle_memory_failure(struct kvm_vcpu *vcpu, int r,
3728c2ecf20Sopenharmony_ci			      struct x86_exception *e);
3738c2ecf20Sopenharmony_ciint kvm_handle_invpcid(struct kvm_vcpu *vcpu, unsigned long type, gva_t gva);
3748c2ecf20Sopenharmony_cibool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type);
3758c2ecf20Sopenharmony_ci
3768c2ecf20Sopenharmony_ci/*
3778c2ecf20Sopenharmony_ci * Internal error codes that are used to indicate that MSR emulation encountered
3788c2ecf20Sopenharmony_ci * an error that should result in #GP in the guest, unless userspace
3798c2ecf20Sopenharmony_ci * handles it.
3808c2ecf20Sopenharmony_ci */
3818c2ecf20Sopenharmony_ci#define  KVM_MSR_RET_INVALID	2	/* in-kernel MSR emulation #GP condition */
3828c2ecf20Sopenharmony_ci#define  KVM_MSR_RET_FILTERED	3	/* #GP due to userspace MSR filter */
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci#define __cr4_reserved_bits(__cpu_has, __c)             \
3858c2ecf20Sopenharmony_ci({                                                      \
3868c2ecf20Sopenharmony_ci	u64 __reserved_bits = CR4_RESERVED_BITS;        \
3878c2ecf20Sopenharmony_ci                                                        \
3888c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_XSAVE))         \
3898c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_OSXSAVE;     \
3908c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_SMEP))          \
3918c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_SMEP;        \
3928c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_SMAP))          \
3938c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_SMAP;        \
3948c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_FSGSBASE))      \
3958c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_FSGSBASE;    \
3968c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_PKU))           \
3978c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_PKE;         \
3988c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_LA57))          \
3998c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_LA57;        \
4008c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_UMIP))          \
4018c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_UMIP;        \
4028c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_VMX))           \
4038c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_VMXE;        \
4048c2ecf20Sopenharmony_ci	if (!__cpu_has(__c, X86_FEATURE_PCID))          \
4058c2ecf20Sopenharmony_ci		__reserved_bits |= X86_CR4_PCIDE;       \
4068c2ecf20Sopenharmony_ci	__reserved_bits;                                \
4078c2ecf20Sopenharmony_ci})
4088c2ecf20Sopenharmony_ci
4098c2ecf20Sopenharmony_ci#endif
410