xref: /linux/arch/x86/kvm/msrs.h (revision 67f8bc848ee31831336bd478e57d2f993551902e)
17a268308SSean Christopherson /* SPDX-License-Identifier: GPL-2.0 */
2*8821646eSSean Christopherson #ifndef ARCH_X86_KVM_MSRS_H
3*8821646eSSean Christopherson #define ARCH_X86_KVM_MSRS_H
47a268308SSean Christopherson 
57a268308SSean Christopherson #include <linux/kvm_host.h>
67a268308SSean Christopherson #include <linux/user-return-notifier.h>
77a268308SSean Christopherson 
87a268308SSean Christopherson #include "cpuid.h"
97a268308SSean Christopherson #include "regs.h"
107a268308SSean Christopherson 
117a268308SSean Christopherson extern bool report_ignored_msrs;
127a268308SSean Christopherson extern bool ignore_msrs;
137a268308SSean Christopherson 
14159a51a0SSean Christopherson extern u32 __read_mostly kvm_nr_uret_msrs;
15159a51a0SSean Christopherson 
167a268308SSean Christopherson static inline void kvm_pr_unimpl_wrmsr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
177a268308SSean Christopherson {
187a268308SSean Christopherson 	if (report_ignored_msrs)
197a268308SSean Christopherson 		vcpu_unimpl(vcpu, "Unhandled WRMSR(0x%x) = 0x%llx\n", msr, data);
207a268308SSean Christopherson }
217a268308SSean Christopherson 
227a268308SSean Christopherson static inline void kvm_pr_unimpl_rdmsr(struct kvm_vcpu *vcpu, u32 msr)
237a268308SSean Christopherson {
247a268308SSean Christopherson 	if (report_ignored_msrs)
257a268308SSean Christopherson 		vcpu_unimpl(vcpu, "Unhandled RDMSR(0x%x)\n", msr);
267a268308SSean Christopherson }
277a268308SSean Christopherson 
287a268308SSean Christopherson /*
297a268308SSean Christopherson  * The first...last VMX feature MSRs that are emulated by KVM.  This may or may
307a268308SSean Christopherson  * not cover all known VMX MSRs, as KVM doesn't emulate an MSR until there's an
317a268308SSean Christopherson  * associated feature that KVM supports for nested virtualization.
327a268308SSean Christopherson  */
337a268308SSean Christopherson #define KVM_FIRST_EMULATED_VMX_MSR	MSR_IA32_VMX_BASIC
347a268308SSean Christopherson #define KVM_LAST_EMULATED_VMX_MSR	MSR_IA32_VMX_VMFUNC
357a268308SSean Christopherson 
367a268308SSean Christopherson /*
377a268308SSean Christopherson  * KVM's internal, non-ABI indices for synthetic MSRs. The values themselves
387a268308SSean Christopherson  * are arbitrary and have no meaning, the only requirement is that they don't
397a268308SSean Christopherson  * conflict with "real" MSRs that KVM supports. Use values at the upper end
407a268308SSean Christopherson  * of KVM's reserved paravirtual MSR range to minimize churn, i.e. these values
417a268308SSean Christopherson  * will be usable until KVM exhausts its supply of paravirtual MSR indices.
427a268308SSean Christopherson  */
437a268308SSean Christopherson #define MSR_KVM_INTERNAL_GUEST_SSP	0x4b564dff
447a268308SSean Christopherson 
457a268308SSean Christopherson #define MSR_IA32_CR_PAT_DEFAULT	\
467a268308SSean Christopherson 	PAT_VALUE(WB, WT, UC_MINUS, UC, WB, WT, UC_MINUS, UC)
477a268308SSean Christopherson 
487a268308SSean Christopherson void kvm_init_msr_lists(void);
497a268308SSean Christopherson int kvm_get_msr_index_list(struct kvm_msr_list __user *user_msr_list);
507a268308SSean Christopherson int kvm_get_feature_msr_index_list(struct kvm_msr_list __user *user_msr_list);
517a268308SSean Christopherson int kvm_get_feature_msrs(struct kvm_msrs __user *user_msrs);
527a268308SSean Christopherson 
537a268308SSean Christopherson int kvm_get_msrs(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs);
547a268308SSean Christopherson int kvm_set_msrs(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs);
557a268308SSean Christopherson 
567a268308SSean Christopherson int kvm_get_set_one_reg(struct kvm_vcpu *vcpu, unsigned int ioctl,
577a268308SSean Christopherson 			void __user *argp);
587a268308SSean Christopherson int kvm_get_reg_list(struct kvm_vcpu *vcpu,
597a268308SSean Christopherson 		     struct kvm_reg_list __user *user_list);
607a268308SSean Christopherson 
61159a51a0SSean Christopherson bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer);
62159a51a0SSean Christopherson int kvm_emulate_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data);
63159a51a0SSean Christopherson int kvm_emulate_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data);
64159a51a0SSean Christopherson int __kvm_emulate_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data);
65159a51a0SSean Christopherson int __kvm_emulate_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data);
66159a51a0SSean Christopherson int kvm_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data);
67159a51a0SSean Christopherson int kvm_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data);
68159a51a0SSean Christopherson int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu);
69159a51a0SSean Christopherson int kvm_emulate_rdmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg);
70159a51a0SSean Christopherson int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu);
71159a51a0SSean Christopherson int kvm_emulate_wrmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg);
727a268308SSean Christopherson 
737a268308SSean Christopherson fastpath_t handle_fastpath_wrmsr(struct kvm_vcpu *vcpu);
747a268308SSean Christopherson fastpath_t handle_fastpath_wrmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg);
757a268308SSean Christopherson 
76159a51a0SSean Christopherson int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr);
77159a51a0SSean Christopherson int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr);
78159a51a0SSean Christopherson 
79159a51a0SSean Christopherson int kvm_add_user_return_msr(u32 msr);
80159a51a0SSean Christopherson int kvm_find_user_return_msr(u32 msr);
81159a51a0SSean Christopherson int kvm_set_user_return_msr(unsigned index, u64 val, u64 mask);
82159a51a0SSean Christopherson u64 kvm_get_user_return_msr(unsigned int slot);
83159a51a0SSean Christopherson 
84159a51a0SSean Christopherson static inline bool kvm_is_supported_user_return_msr(u32 msr)
85159a51a0SSean Christopherson {
86159a51a0SSean Christopherson 	return kvm_find_user_return_msr(msr) >= 0;
87159a51a0SSean Christopherson }
88159a51a0SSean Christopherson 
89159a51a0SSean Christopherson void kvm_user_return_msr_cpu_online(void);
90159a51a0SSean Christopherson void drop_user_return_notifiers(void);
91159a51a0SSean Christopherson void kvm_destroy_user_return_msrs(void);
92159a51a0SSean Christopherson 
937a268308SSean Christopherson int kvm_emulator_get_msr_with_filter(struct kvm_vcpu *vcpu, u32 msr_index,
947a268308SSean Christopherson 				     u64 *pdata);
957a268308SSean Christopherson int kvm_emulator_set_msr_with_filter(struct kvm_vcpu *vcpu, u32 msr_index,
967a268308SSean Christopherson 				     u64 data);
977a268308SSean Christopherson int kvm_emulator_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
987a268308SSean Christopherson 
997a268308SSean Christopherson bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type);
1007a268308SSean Christopherson 
1017a268308SSean Christopherson enum kvm_msr_access {
1027a268308SSean Christopherson 	MSR_TYPE_R	= BIT(0),
1037a268308SSean Christopherson 	MSR_TYPE_W	= BIT(1),
1047a268308SSean Christopherson 	MSR_TYPE_RW	= MSR_TYPE_R | MSR_TYPE_W,
1057a268308SSean Christopherson };
1067a268308SSean Christopherson 
1077a268308SSean Christopherson /*
1087a268308SSean Christopherson  * Internal error codes that are used to indicate that MSR emulation encountered
1097a268308SSean Christopherson  * an error that should result in #GP in the guest, unless userspace handles it.
1107a268308SSean Christopherson  * Note, '1', '0', and negative numbers are off limits, as they are used by KVM
1117a268308SSean Christopherson  * as part of KVM's lightly documented internal KVM_RUN return codes.
1127a268308SSean Christopherson  *
1137a268308SSean Christopherson  * UNSUPPORTED	- The MSR isn't supported, either because it is completely
1147a268308SSean Christopherson  *		  unknown to KVM, or because the MSR should not exist according
1157a268308SSean Christopherson  *		  to the vCPU model.
1167a268308SSean Christopherson  *
1177a268308SSean Christopherson  * FILTERED	- Access to the MSR is denied by a userspace MSR filter.
1187a268308SSean Christopherson  */
1197a268308SSean Christopherson #define  KVM_MSR_RET_UNSUPPORTED	2
1207a268308SSean Christopherson #define  KVM_MSR_RET_FILTERED		3
1217a268308SSean Christopherson 
1227a268308SSean Christopherson int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, struct kvm_msr_filter *filter);
1237a268308SSean Christopherson void kvm_free_msr_filter(struct kvm_x86_msr_filter *msr_filter);
1247a268308SSean Christopherson 
1257a268308SSean Christopherson int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
1267a268308SSean Christopherson int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
1277a268308SSean Christopherson 
1287a268308SSean Christopherson u64 kvm_get_arch_capabilities(void);
1297a268308SSean Christopherson int kvm_spec_ctrl_test_value(u64 value);
1307a268308SSean Christopherson 
1317a268308SSean Christopherson #define CET_US_RESERVED_BITS		GENMASK(9, 6)
1327a268308SSean Christopherson #define CET_US_SHSTK_MASK_BITS		GENMASK(1, 0)
1337a268308SSean Christopherson #define CET_US_IBT_MASK_BITS		(GENMASK_ULL(5, 2) | GENMASK_ULL(63, 10))
1347a268308SSean Christopherson #define CET_US_LEGACY_BITMAP_BASE(data)	((data) >> 12)
1357a268308SSean Christopherson 
1367a268308SSean Christopherson static inline bool kvm_is_valid_u_s_cet(struct kvm_vcpu *vcpu, u64 data)
1377a268308SSean Christopherson {
1387a268308SSean Christopherson 	if (data & CET_US_RESERVED_BITS)
1397a268308SSean Christopherson 		return false;
1407a268308SSean Christopherson 	if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK) &&
1417a268308SSean Christopherson 	    (data & CET_US_SHSTK_MASK_BITS))
1427a268308SSean Christopherson 		return false;
1437a268308SSean Christopherson 	if (!guest_cpu_cap_has(vcpu, X86_FEATURE_IBT) &&
1447a268308SSean Christopherson 	    (data & CET_US_IBT_MASK_BITS))
1457a268308SSean Christopherson 		return false;
1467a268308SSean Christopherson 	if (!IS_ALIGNED(CET_US_LEGACY_BITMAP_BASE(data), 4))
1477a268308SSean Christopherson 		return false;
1487a268308SSean Christopherson 	/* IBT can be suppressed iff the TRACKER isn't WAIT_ENDBR. */
1497a268308SSean Christopherson 	if ((data & CET_SUPPRESS) && (data & CET_WAIT_ENDBR))
1507a268308SSean Christopherson 		return false;
1517a268308SSean Christopherson 
1527a268308SSean Christopherson 	return true;
1537a268308SSean Christopherson }
1547a268308SSean Christopherson 
1557a268308SSean Christopherson #endif
156