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