mirror of
https://github.com/torvalds/linux.git
synced 2026-09-24 06:24:02 +02:00
Supported EFER bits naturally fits into kvm_caps because it gets recomputed during vendor initialization (e.g. to account for EFER.SVME being allowed/disallowed based on nested being enabled/disabled). Move efer_supported_bits into kvm_caps as supported_efer_bits (for naming consistency). As the bitmask is now globally visible as part of kvm_caps, there's little use for helpers to enable/disable specific bits, so drop them and open-code updates to kvm_caps.supported_efer_bits. No functional change intended. Suggested-by: Sean Christopherson <seanjc@google.com> Reviewed-by: Nikolay Borisov <nik.borisov@suse.com> Signed-off-by: Yosry Ahmed <yosry@kernel.org> Link: https://patch.msgid.link/20260713181020.2735367-6-yosry@kernel.org Signed-off-by: Sean Christopherson <seanjc@google.com>
156 lines
5.6 KiB
C
156 lines
5.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
#ifndef ARCH_X86_KVM_MSRS_H
|
|
#define ARCH_X86_KVM_MSRS_H
|
|
|
|
#include <linux/kvm_host.h>
|
|
#include <linux/user-return-notifier.h>
|
|
|
|
#include "cpuid.h"
|
|
#include "regs.h"
|
|
|
|
extern bool report_ignored_msrs;
|
|
extern bool ignore_msrs;
|
|
|
|
extern u32 __read_mostly kvm_nr_uret_msrs;
|
|
|
|
static inline void kvm_pr_unimpl_wrmsr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
|
|
{
|
|
if (report_ignored_msrs)
|
|
vcpu_unimpl(vcpu, "Unhandled WRMSR(0x%x) = 0x%llx\n", msr, data);
|
|
}
|
|
|
|
static inline void kvm_pr_unimpl_rdmsr(struct kvm_vcpu *vcpu, u32 msr)
|
|
{
|
|
if (report_ignored_msrs)
|
|
vcpu_unimpl(vcpu, "Unhandled RDMSR(0x%x)\n", msr);
|
|
}
|
|
|
|
/*
|
|
* The first...last VMX feature MSRs that are emulated by KVM. This may or may
|
|
* not cover all known VMX MSRs, as KVM doesn't emulate an MSR until there's an
|
|
* associated feature that KVM supports for nested virtualization.
|
|
*/
|
|
#define KVM_FIRST_EMULATED_VMX_MSR MSR_IA32_VMX_BASIC
|
|
#define KVM_LAST_EMULATED_VMX_MSR MSR_IA32_VMX_VMFUNC
|
|
|
|
/*
|
|
* KVM's internal, non-ABI indices for synthetic MSRs. The values themselves
|
|
* are arbitrary and have no meaning, the only requirement is that they don't
|
|
* conflict with "real" MSRs that KVM supports. Use values at the upper end
|
|
* of KVM's reserved paravirtual MSR range to minimize churn, i.e. these values
|
|
* will be usable until KVM exhausts its supply of paravirtual MSR indices.
|
|
*/
|
|
#define MSR_KVM_INTERNAL_GUEST_SSP 0x4b564dff
|
|
|
|
#define MSR_IA32_CR_PAT_DEFAULT \
|
|
PAT_VALUE(WB, WT, UC_MINUS, UC, WB, WT, UC_MINUS, UC)
|
|
|
|
void kvm_init_msr_lists(void);
|
|
int kvm_get_msr_index_list(struct kvm_msr_list __user *user_msr_list);
|
|
int kvm_get_feature_msr_index_list(struct kvm_msr_list __user *user_msr_list);
|
|
int kvm_get_feature_msrs(struct kvm_msrs __user *user_msrs);
|
|
|
|
int kvm_get_msrs(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs);
|
|
int kvm_set_msrs(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs);
|
|
|
|
int kvm_get_set_one_reg(struct kvm_vcpu *vcpu, unsigned int ioctl,
|
|
void __user *argp);
|
|
int kvm_get_reg_list(struct kvm_vcpu *vcpu,
|
|
struct kvm_reg_list __user *user_list);
|
|
|
|
bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer);
|
|
int kvm_emulate_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data);
|
|
int kvm_emulate_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data);
|
|
int __kvm_emulate_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data);
|
|
int __kvm_emulate_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data);
|
|
int kvm_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data);
|
|
int kvm_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data);
|
|
int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu);
|
|
int kvm_emulate_rdmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg);
|
|
int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu);
|
|
int kvm_emulate_wrmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg);
|
|
|
|
fastpath_t handle_fastpath_wrmsr(struct kvm_vcpu *vcpu);
|
|
fastpath_t handle_fastpath_wrmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg);
|
|
|
|
int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr);
|
|
int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr);
|
|
|
|
int kvm_add_user_return_msr(u32 msr);
|
|
int kvm_find_user_return_msr(u32 msr);
|
|
int kvm_set_user_return_msr(unsigned index, u64 val, u64 mask);
|
|
u64 kvm_get_user_return_msr(unsigned int slot);
|
|
|
|
static inline bool kvm_is_supported_user_return_msr(u32 msr)
|
|
{
|
|
return kvm_find_user_return_msr(msr) >= 0;
|
|
}
|
|
|
|
void kvm_user_return_msr_cpu_online(void);
|
|
void drop_user_return_notifiers(void);
|
|
void kvm_destroy_user_return_msrs(void);
|
|
|
|
int kvm_emulator_get_msr_with_filter(struct kvm_vcpu *vcpu, u32 msr_index,
|
|
u64 *pdata);
|
|
int kvm_emulator_set_msr_with_filter(struct kvm_vcpu *vcpu, u32 msr_index,
|
|
u64 data);
|
|
int kvm_emulator_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
|
|
|
|
bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type);
|
|
|
|
enum kvm_msr_access {
|
|
MSR_TYPE_R = BIT(0),
|
|
MSR_TYPE_W = BIT(1),
|
|
MSR_TYPE_RW = MSR_TYPE_R | MSR_TYPE_W,
|
|
};
|
|
|
|
/*
|
|
* Internal error codes that are used to indicate that MSR emulation encountered
|
|
* an error that should result in #GP in the guest, unless userspace handles it.
|
|
* Note, '1', '0', and negative numbers are off limits, as they are used by KVM
|
|
* as part of KVM's lightly documented internal KVM_RUN return codes.
|
|
*
|
|
* UNSUPPORTED - The MSR isn't supported, either because it is completely
|
|
* unknown to KVM, or because the MSR should not exist according
|
|
* to the vCPU model.
|
|
*
|
|
* FILTERED - Access to the MSR is denied by a userspace MSR filter.
|
|
*/
|
|
#define KVM_MSR_RET_UNSUPPORTED 2
|
|
#define KVM_MSR_RET_FILTERED 3
|
|
|
|
int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, struct kvm_msr_filter *filter);
|
|
void kvm_free_msr_filter(struct kvm_x86_msr_filter *msr_filter);
|
|
|
|
int kvm_mtrr_set_msr(struct kvm_vcpu *vcpu, u32 msr, u64 data);
|
|
int kvm_mtrr_get_msr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
|
|
|
|
u64 kvm_get_arch_capabilities(void);
|
|
int kvm_spec_ctrl_test_value(u64 value);
|
|
|
|
#define CET_US_RESERVED_BITS GENMASK(9, 6)
|
|
#define CET_US_SHSTK_MASK_BITS GENMASK(1, 0)
|
|
#define CET_US_IBT_MASK_BITS (GENMASK_ULL(5, 2) | GENMASK_ULL(63, 10))
|
|
#define CET_US_LEGACY_BITMAP_BASE(data) ((data) >> 12)
|
|
|
|
static inline bool kvm_is_valid_u_s_cet(struct kvm_vcpu *vcpu, u64 data)
|
|
{
|
|
if (data & CET_US_RESERVED_BITS)
|
|
return false;
|
|
if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK) &&
|
|
(data & CET_US_SHSTK_MASK_BITS))
|
|
return false;
|
|
if (!guest_cpu_cap_has(vcpu, X86_FEATURE_IBT) &&
|
|
(data & CET_US_IBT_MASK_BITS))
|
|
return false;
|
|
if (!IS_ALIGNED(CET_US_LEGACY_BITMAP_BASE(data), 4))
|
|
return false;
|
|
/* IBT can be suppressed iff the TRACKER isn't WAIT_ENDBR. */
|
|
if ((data & CET_SUPPRESS) && (data & CET_WAIT_ENDBR))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif
|