| // SPDX-License-Identifier: GPL-2.0-only |
| #include <linux/kvm_host.h> |
| #include <asm/intel_pt.h> |
| #include <asm/vmx.h> |
| |
| #include "hyperv.h" |
| #include "lapic.h" |
| #include "msrs.h" |
| #include "pmu.h" |
| #include "trace.h" |
| #include "vmx/vmx.h" |
| #include "xen.h" |
| #include "x86.h" |
| |
| bool __read_mostly ignore_msrs = 0; |
| module_param(ignore_msrs, bool, 0644); |
| |
| bool __read_mostly report_ignored_msrs = true; |
| module_param(report_ignored_msrs, bool, 0644); |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(report_ignored_msrs); |
| |
| #define MAX_IO_MSRS 256 |
| |
| struct msr_bitmap_range { |
| u32 flags; |
| u32 nmsrs; |
| u32 base; |
| unsigned long *bitmap; |
| }; |
| |
| struct kvm_x86_msr_filter { |
| u8 count; |
| bool default_allow:1; |
| struct msr_bitmap_range ranges[16]; |
| }; |
| |
| /* |
| * Restoring the host value for MSRs that are only consumed when running in |
| * usermode, e.g. SYSCALL MSRs and TSC_AUX, can be deferred until the CPU |
| * returns to userspace, i.e. the kernel can run with the guest's value. |
| */ |
| #define KVM_MAX_NR_USER_RETURN_MSRS 16 |
| |
| struct kvm_user_return_msrs { |
| struct user_return_notifier urn; |
| bool registered; |
| struct kvm_user_return_msr_values { |
| u64 host; |
| u64 curr; |
| } values[KVM_MAX_NR_USER_RETURN_MSRS]; |
| }; |
| |
| u32 __read_mostly kvm_nr_uret_msrs; |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_nr_uret_msrs); |
| static u32 __read_mostly kvm_uret_msrs_list[KVM_MAX_NR_USER_RETURN_MSRS]; |
| static DEFINE_PER_CPU(struct kvm_user_return_msrs, user_return_msrs); |
| |
| void kvm_destroy_user_return_msrs(void) |
| { |
| int cpu; |
| |
| for_each_possible_cpu(cpu) |
| WARN_ON_ONCE(per_cpu(user_return_msrs, cpu).registered); |
| |
| kvm_nr_uret_msrs = 0; |
| } |
| |
| static void kvm_on_user_return(struct user_return_notifier *urn) |
| { |
| unsigned slot; |
| struct kvm_user_return_msrs *msrs |
| = container_of(urn, struct kvm_user_return_msrs, urn); |
| struct kvm_user_return_msr_values *values; |
| |
| msrs->registered = false; |
| user_return_notifier_unregister(urn); |
| |
| for (slot = 0; slot < kvm_nr_uret_msrs; ++slot) { |
| values = &msrs->values[slot]; |
| if (values->host != values->curr) { |
| wrmsrq(kvm_uret_msrs_list[slot], values->host); |
| values->curr = values->host; |
| } |
| } |
| } |
| |
| static int kvm_probe_user_return_msr(u32 msr) |
| { |
| u64 val; |
| int ret; |
| |
| preempt_disable(); |
| ret = rdmsrq_safe(msr, &val); |
| if (ret) |
| goto out; |
| ret = wrmsrq_safe(msr, val); |
| out: |
| preempt_enable(); |
| return ret; |
| } |
| |
| int kvm_add_user_return_msr(u32 msr) |
| { |
| BUG_ON(kvm_nr_uret_msrs >= KVM_MAX_NR_USER_RETURN_MSRS); |
| |
| if (kvm_probe_user_return_msr(msr)) |
| return -1; |
| |
| kvm_uret_msrs_list[kvm_nr_uret_msrs] = msr; |
| return kvm_nr_uret_msrs++; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_add_user_return_msr); |
| |
| int kvm_find_user_return_msr(u32 msr) |
| { |
| int i; |
| |
| for (i = 0; i < kvm_nr_uret_msrs; ++i) { |
| if (kvm_uret_msrs_list[i] == msr) |
| return i; |
| } |
| return -1; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_find_user_return_msr); |
| |
| void kvm_user_return_msr_cpu_online(void) |
| { |
| struct kvm_user_return_msrs *msrs = this_cpu_ptr(&user_return_msrs); |
| u64 value; |
| int i; |
| |
| for (i = 0; i < kvm_nr_uret_msrs; ++i) { |
| rdmsrq_safe(kvm_uret_msrs_list[i], &value); |
| msrs->values[i].host = value; |
| msrs->values[i].curr = value; |
| } |
| } |
| |
| static void kvm_user_return_register_notifier(struct kvm_user_return_msrs *msrs) |
| { |
| if (!msrs->registered) { |
| msrs->urn.on_user_return = kvm_on_user_return; |
| user_return_notifier_register(&msrs->urn); |
| msrs->registered = true; |
| } |
| } |
| |
| int kvm_set_user_return_msr(unsigned slot, u64 value, u64 mask) |
| { |
| struct kvm_user_return_msrs *msrs = this_cpu_ptr(&user_return_msrs); |
| int err; |
| |
| value = (value & mask) | (msrs->values[slot].host & ~mask); |
| if (value == msrs->values[slot].curr) |
| return 0; |
| err = wrmsrq_safe(kvm_uret_msrs_list[slot], value); |
| if (err) |
| return 1; |
| |
| msrs->values[slot].curr = value; |
| kvm_user_return_register_notifier(msrs); |
| return 0; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_set_user_return_msr); |
| |
| u64 kvm_get_user_return_msr(unsigned int slot) |
| { |
| return this_cpu_ptr(&user_return_msrs)->values[slot].curr; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_user_return_msr); |
| |
| void drop_user_return_notifiers(void) |
| { |
| struct kvm_user_return_msrs *msrs = this_cpu_ptr(&user_return_msrs); |
| |
| if (msrs->registered) |
| kvm_on_user_return(&msrs->urn); |
| } |
| |
| /* |
| * The three MSR lists(msrs_to_save, emulated_msrs, msr_based_features) track |
| * the set of MSRs that KVM exposes to userspace through KVM_GET_MSRS, |
| * KVM_SET_MSRS, and KVM_GET_MSR_INDEX_LIST. msrs_to_save holds MSRs that |
| * require host support, i.e. should be probed via RDMSR. emulated_msrs holds |
| * MSRs that KVM emulates without strictly requiring host support. |
| * msr_based_features holds MSRs that enumerate features, i.e. are effectively |
| * CPUID leafs. Note, msr_based_features isn't mutually exclusive with |
| * msrs_to_save and emulated_msrs. |
| */ |
| |
| static const u32 msrs_to_save_base[] = { |
| MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, |
| MSR_STAR, |
| #ifdef CONFIG_X86_64 |
| MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR, |
| #endif |
| MSR_IA32_TSC, MSR_IA32_CR_PAT, MSR_VM_HSAVE_PA, |
| MSR_IA32_FEAT_CTL, MSR_IA32_BNDCFGS, MSR_TSC_AUX, |
| MSR_IA32_SPEC_CTRL, MSR_IA32_TSX_CTRL, |
| MSR_IA32_RTIT_CTL, MSR_IA32_RTIT_STATUS, MSR_IA32_RTIT_CR3_MATCH, |
| MSR_IA32_RTIT_OUTPUT_BASE, MSR_IA32_RTIT_OUTPUT_MASK, |
| MSR_IA32_RTIT_ADDR0_A, MSR_IA32_RTIT_ADDR0_B, |
| MSR_IA32_RTIT_ADDR1_A, MSR_IA32_RTIT_ADDR1_B, |
| MSR_IA32_RTIT_ADDR2_A, MSR_IA32_RTIT_ADDR2_B, |
| MSR_IA32_RTIT_ADDR3_A, MSR_IA32_RTIT_ADDR3_B, |
| MSR_IA32_UMWAIT_CONTROL, |
| |
| MSR_IA32_XFD, MSR_IA32_XFD_ERR, MSR_IA32_XSS, |
| |
| MSR_IA32_U_CET, MSR_IA32_S_CET, |
| MSR_IA32_PL0_SSP, MSR_IA32_PL1_SSP, MSR_IA32_PL2_SSP, |
| MSR_IA32_PL3_SSP, MSR_IA32_INT_SSP_TAB, |
| MSR_IA32_DEBUGCTLMSR, |
| MSR_IA32_LASTBRANCHFROMIP, MSR_IA32_LASTBRANCHTOIP, |
| MSR_IA32_LASTINTFROMIP, MSR_IA32_LASTINTTOIP, |
| }; |
| |
| static const u32 msrs_to_save_pmu[] = { |
| MSR_ARCH_PERFMON_FIXED_CTR0, MSR_ARCH_PERFMON_FIXED_CTR1, |
| MSR_ARCH_PERFMON_FIXED_CTR0 + 2, |
| MSR_CORE_PERF_FIXED_CTR_CTRL, MSR_CORE_PERF_GLOBAL_STATUS, |
| MSR_CORE_PERF_GLOBAL_CTRL, |
| MSR_IA32_PEBS_ENABLE, MSR_IA32_DS_AREA, MSR_PEBS_DATA_CFG, |
| |
| /* This part of MSRs should match KVM_MAX_NR_INTEL_GP_COUNTERS. */ |
| MSR_ARCH_PERFMON_PERFCTR0, MSR_ARCH_PERFMON_PERFCTR1, |
| MSR_ARCH_PERFMON_PERFCTR0 + 2, MSR_ARCH_PERFMON_PERFCTR0 + 3, |
| MSR_ARCH_PERFMON_PERFCTR0 + 4, MSR_ARCH_PERFMON_PERFCTR0 + 5, |
| MSR_ARCH_PERFMON_PERFCTR0 + 6, MSR_ARCH_PERFMON_PERFCTR0 + 7, |
| MSR_ARCH_PERFMON_EVENTSEL0, MSR_ARCH_PERFMON_EVENTSEL1, |
| MSR_ARCH_PERFMON_EVENTSEL0 + 2, MSR_ARCH_PERFMON_EVENTSEL0 + 3, |
| MSR_ARCH_PERFMON_EVENTSEL0 + 4, MSR_ARCH_PERFMON_EVENTSEL0 + 5, |
| MSR_ARCH_PERFMON_EVENTSEL0 + 6, MSR_ARCH_PERFMON_EVENTSEL0 + 7, |
| |
| MSR_K7_EVNTSEL0, MSR_K7_EVNTSEL1, MSR_K7_EVNTSEL2, MSR_K7_EVNTSEL3, |
| MSR_K7_PERFCTR0, MSR_K7_PERFCTR1, MSR_K7_PERFCTR2, MSR_K7_PERFCTR3, |
| |
| /* This part of MSRs should match KVM_MAX_NR_AMD_GP_COUNTERS. */ |
| MSR_F15H_PERF_CTL0, MSR_F15H_PERF_CTL1, MSR_F15H_PERF_CTL2, |
| MSR_F15H_PERF_CTL3, MSR_F15H_PERF_CTL4, MSR_F15H_PERF_CTL5, |
| MSR_F15H_PERF_CTR0, MSR_F15H_PERF_CTR1, MSR_F15H_PERF_CTR2, |
| MSR_F15H_PERF_CTR3, MSR_F15H_PERF_CTR4, MSR_F15H_PERF_CTR5, |
| |
| MSR_AMD64_PERF_CNTR_GLOBAL_CTL, |
| MSR_AMD64_PERF_CNTR_GLOBAL_STATUS, |
| MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR, |
| MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET, |
| }; |
| |
| static u32 msrs_to_save[ARRAY_SIZE(msrs_to_save_base) + |
| ARRAY_SIZE(msrs_to_save_pmu)]; |
| static unsigned num_msrs_to_save; |
| |
| static const u32 emulated_msrs_all[] = { |
| MSR_KVM_SYSTEM_TIME, MSR_KVM_WALL_CLOCK, |
| MSR_KVM_SYSTEM_TIME_NEW, MSR_KVM_WALL_CLOCK_NEW, |
| |
| #ifdef CONFIG_KVM_HYPERV |
| HV_X64_MSR_GUEST_OS_ID, HV_X64_MSR_HYPERCALL, |
| HV_X64_MSR_TIME_REF_COUNT, HV_X64_MSR_REFERENCE_TSC, |
| HV_X64_MSR_TSC_FREQUENCY, HV_X64_MSR_APIC_FREQUENCY, |
| HV_X64_MSR_CRASH_P0, HV_X64_MSR_CRASH_P1, HV_X64_MSR_CRASH_P2, |
| HV_X64_MSR_CRASH_P3, HV_X64_MSR_CRASH_P4, HV_X64_MSR_CRASH_CTL, |
| HV_X64_MSR_RESET, |
| HV_X64_MSR_VP_INDEX, |
| HV_X64_MSR_VP_RUNTIME, |
| HV_X64_MSR_SCONTROL, |
| HV_X64_MSR_STIMER0_CONFIG, |
| HV_X64_MSR_VP_ASSIST_PAGE, |
| HV_X64_MSR_REENLIGHTENMENT_CONTROL, HV_X64_MSR_TSC_EMULATION_CONTROL, |
| HV_X64_MSR_TSC_EMULATION_STATUS, HV_X64_MSR_TSC_INVARIANT_CONTROL, |
| HV_X64_MSR_SYNDBG_OPTIONS, |
| HV_X64_MSR_SYNDBG_CONTROL, HV_X64_MSR_SYNDBG_STATUS, |
| HV_X64_MSR_SYNDBG_SEND_BUFFER, HV_X64_MSR_SYNDBG_RECV_BUFFER, |
| HV_X64_MSR_SYNDBG_PENDING_BUFFER, |
| #endif |
| |
| MSR_KVM_ASYNC_PF_EN, MSR_KVM_STEAL_TIME, |
| MSR_KVM_PV_EOI_EN, MSR_KVM_ASYNC_PF_INT, MSR_KVM_ASYNC_PF_ACK, |
| |
| MSR_IA32_TSC_ADJUST, |
| MSR_IA32_TSC_DEADLINE, |
| MSR_IA32_ARCH_CAPABILITIES, |
| MSR_IA32_PERF_CAPABILITIES, |
| MSR_IA32_MISC_ENABLE, |
| MSR_IA32_MCG_STATUS, |
| MSR_IA32_MCG_CTL, |
| MSR_IA32_MCG_EXT_CTL, |
| MSR_IA32_SMBASE, |
| MSR_SMI_COUNT, |
| MSR_PLATFORM_INFO, |
| MSR_MISC_FEATURES_ENABLES, |
| MSR_AMD64_VIRT_SPEC_CTRL, |
| MSR_AMD64_TSC_RATIO, |
| MSR_IA32_POWER_CTL, |
| MSR_IA32_UCODE_REV, |
| |
| /* |
| * KVM always supports the "true" VMX control MSRs, even if the host |
| * does not. The VMX MSRs as a whole are considered "emulated" as KVM |
| * doesn't strictly require them to exist in the host (ignoring that |
| * KVM would refuse to load in the first place if the core set of MSRs |
| * aren't supported). |
| */ |
| MSR_IA32_VMX_BASIC, |
| MSR_IA32_VMX_TRUE_PINBASED_CTLS, |
| MSR_IA32_VMX_TRUE_PROCBASED_CTLS, |
| MSR_IA32_VMX_TRUE_EXIT_CTLS, |
| MSR_IA32_VMX_TRUE_ENTRY_CTLS, |
| MSR_IA32_VMX_MISC, |
| MSR_IA32_VMX_CR0_FIXED0, |
| MSR_IA32_VMX_CR4_FIXED0, |
| MSR_IA32_VMX_VMCS_ENUM, |
| MSR_IA32_VMX_PROCBASED_CTLS2, |
| MSR_IA32_VMX_EPT_VPID_CAP, |
| MSR_IA32_VMX_VMFUNC, |
| |
| MSR_K7_HWCR, |
| MSR_KVM_POLL_CONTROL, |
| }; |
| |
| static u32 emulated_msrs[ARRAY_SIZE(emulated_msrs_all)]; |
| static unsigned num_emulated_msrs; |
| |
| /* |
| * List of MSRs that control the existence of MSR-based features, i.e. MSRs |
| * that are effectively CPUID leafs. VMX MSRs are also included in the set of |
| * feature MSRs, but are handled separately to allow expedited lookups. |
| */ |
| static const u32 msr_based_features_all_except_vmx[] = { |
| MSR_AMD64_DE_CFG, |
| MSR_IA32_UCODE_REV, |
| MSR_IA32_ARCH_CAPABILITIES, |
| MSR_IA32_PERF_CAPABILITIES, |
| MSR_PLATFORM_INFO, |
| }; |
| |
| static u32 msr_based_features[ARRAY_SIZE(msr_based_features_all_except_vmx) + |
| (KVM_LAST_EMULATED_VMX_MSR - KVM_FIRST_EMULATED_VMX_MSR + 1)]; |
| static unsigned int num_msr_based_features; |
| |
| int kvm_get_msr_index_list(struct kvm_msr_list __user *user_msr_list) |
| { |
| struct kvm_msr_list msr_list; |
| unsigned int n; |
| |
| if (copy_from_user(&msr_list, user_msr_list, sizeof(msr_list))) |
| return -EFAULT; |
| |
| n = msr_list.nmsrs; |
| msr_list.nmsrs = num_msrs_to_save + num_emulated_msrs; |
| if (copy_to_user(user_msr_list, &msr_list, sizeof(msr_list))) |
| return -EFAULT; |
| |
| if (n < msr_list.nmsrs) |
| return -E2BIG; |
| |
| if (copy_to_user(user_msr_list->indices, &msrs_to_save, |
| num_msrs_to_save * sizeof(u32))) |
| return -EFAULT; |
| |
| if (copy_to_user(user_msr_list->indices + num_msrs_to_save, |
| &emulated_msrs, num_emulated_msrs * sizeof(u32))) |
| return -EFAULT; |
| |
| return 0; |
| } |
| |
| int kvm_get_feature_msr_index_list(struct kvm_msr_list __user *user_msr_list) |
| { |
| struct kvm_msr_list msr_list; |
| unsigned int n; |
| |
| if (copy_from_user(&msr_list, user_msr_list, sizeof(msr_list))) |
| return -EFAULT; |
| |
| n = msr_list.nmsrs; |
| msr_list.nmsrs = num_msr_based_features; |
| if (copy_to_user(user_msr_list, &msr_list, sizeof(msr_list))) |
| return -EFAULT; |
| |
| if (n < msr_list.nmsrs) |
| return -E2BIG; |
| |
| if (copy_to_user(user_msr_list->indices, &msr_based_features, |
| num_msr_based_features * sizeof(u32))) |
| return -EFAULT; |
| |
| return 0; |
| } |
| |
| /* |
| * All feature MSRs except uCode revID, which tracks the currently loaded uCode |
| * patch, are immutable once the vCPU model is defined. |
| */ |
| static bool kvm_is_immutable_feature_msr(u32 msr) |
| { |
| int i; |
| |
| if (msr >= KVM_FIRST_EMULATED_VMX_MSR && msr <= KVM_LAST_EMULATED_VMX_MSR) |
| return true; |
| |
| for (i = 0; i < ARRAY_SIZE(msr_based_features_all_except_vmx); i++) { |
| if (msr == msr_based_features_all_except_vmx[i]) |
| return msr != MSR_IA32_UCODE_REV; |
| } |
| |
| return false; |
| } |
| |
| static bool kvm_is_advertised_msr(u32 msr_index) |
| { |
| unsigned int i; |
| |
| for (i = 0; i < num_msrs_to_save; i++) { |
| if (msrs_to_save[i] == msr_index) |
| return true; |
| } |
| |
| for (i = 0; i < num_emulated_msrs; i++) { |
| if (emulated_msrs[i] == msr_index) |
| return true; |
| } |
| |
| return false; |
| } |
| |
| |
| /* |
| * Some IA32_ARCH_CAPABILITIES bits have dependencies on MSRs that KVM |
| * does not yet virtualize. These include: |
| * 10 - MISC_PACKAGE_CTRLS |
| * 11 - ENERGY_FILTERING_CTL |
| * 12 - DOITM |
| * 18 - FB_CLEAR_CTRL |
| * 21 - XAPIC_DISABLE_STATUS |
| * 23 - OVERCLOCKING_STATUS |
| */ |
| |
| #define KVM_SUPPORTED_ARCH_CAP \ |
| (ARCH_CAP_RDCL_NO | ARCH_CAP_IBRS_ALL | ARCH_CAP_RSBA | \ |
| ARCH_CAP_SKIP_VMENTRY_L1DFLUSH | ARCH_CAP_SSB_NO | ARCH_CAP_MDS_NO | \ |
| ARCH_CAP_PSCHANGE_MC_NO | ARCH_CAP_TSX_CTRL_MSR | ARCH_CAP_TAA_NO | \ |
| ARCH_CAP_SBDR_SSDP_NO | ARCH_CAP_FBSDP_NO | ARCH_CAP_PSDP_NO | \ |
| ARCH_CAP_FB_CLEAR | ARCH_CAP_RRSBA | ARCH_CAP_PBRSB_NO | ARCH_CAP_GDS_NO | \ |
| ARCH_CAP_RFDS_NO | ARCH_CAP_RFDS_CLEAR | ARCH_CAP_BHI_NO | ARCH_CAP_ITS_NO) |
| |
| u64 kvm_get_arch_capabilities(void) |
| { |
| u64 data = kvm_host.arch_capabilities & KVM_SUPPORTED_ARCH_CAP; |
| |
| /* |
| * If nx_huge_pages is enabled, KVM's shadow paging will ensure that |
| * the nested hypervisor runs with NX huge pages. If it is not, |
| * L1 is anyway vulnerable to ITLB_MULTIHIT exploits from other |
| * L1 guests, so it need not worry about its own (L2) guests. |
| */ |
| data |= ARCH_CAP_PSCHANGE_MC_NO; |
| |
| /* |
| * If we're doing cache flushes (either "always" or "cond") |
| * we will do one whenever the guest does a vmlaunch/vmresume. |
| * If an outer hypervisor is doing the cache flush for us |
| * (ARCH_CAP_SKIP_VMENTRY_L1DFLUSH), we can safely pass that |
| * capability to the guest too, and if EPT is disabled we're not |
| * vulnerable. Overall, only VMENTER_L1D_FLUSH_NEVER will |
| * require a nested hypervisor to do a flush of its own. |
| */ |
| if (l1tf_vmx_mitigation != VMENTER_L1D_FLUSH_NEVER) |
| data |= ARCH_CAP_SKIP_VMENTRY_L1DFLUSH; |
| |
| if (!boot_cpu_has_bug(X86_BUG_CPU_MELTDOWN)) |
| data |= ARCH_CAP_RDCL_NO; |
| if (!boot_cpu_has_bug(X86_BUG_SPEC_STORE_BYPASS)) |
| data |= ARCH_CAP_SSB_NO; |
| if (!boot_cpu_has_bug(X86_BUG_MDS)) |
| data |= ARCH_CAP_MDS_NO; |
| if (!boot_cpu_has_bug(X86_BUG_RFDS)) |
| data |= ARCH_CAP_RFDS_NO; |
| if (!boot_cpu_has_bug(X86_BUG_ITS)) |
| data |= ARCH_CAP_ITS_NO; |
| |
| if (!boot_cpu_has(X86_FEATURE_RTM)) { |
| /* |
| * If RTM=0 because the kernel has disabled TSX, the host might |
| * have TAA_NO or TSX_CTRL. Clear TAA_NO (the guest sees RTM=0 |
| * and therefore knows that there cannot be TAA) but keep |
| * TSX_CTRL: some buggy userspaces leave it set on tsx=on hosts, |
| * and we want to allow migrating those guests to tsx=off hosts. |
| */ |
| data &= ~ARCH_CAP_TAA_NO; |
| } else if (!boot_cpu_has_bug(X86_BUG_TAA)) { |
| data |= ARCH_CAP_TAA_NO; |
| } else { |
| /* |
| * Nothing to do here; we emulate TSX_CTRL if present on the |
| * host so the guest can choose between disabling TSX or |
| * using VERW to clear CPU buffers. |
| */ |
| } |
| |
| if (!boot_cpu_has_bug(X86_BUG_GDS) || gds_ucode_mitigated()) |
| data |= ARCH_CAP_GDS_NO; |
| |
| return data; |
| } |
| |
| static int kvm_get_feature_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, |
| bool host_initiated) |
| { |
| WARN_ON_ONCE(!host_initiated); |
| |
| switch (index) { |
| case MSR_IA32_ARCH_CAPABILITIES: |
| *data = kvm_get_arch_capabilities(); |
| break; |
| case MSR_IA32_PERF_CAPABILITIES: |
| *data = kvm_caps.supported_perf_cap; |
| break; |
| case MSR_PLATFORM_INFO: |
| *data = MSR_PLATFORM_INFO_CPUID_FAULT; |
| break; |
| case MSR_IA32_UCODE_REV: |
| rdmsrq_safe(index, data); |
| break; |
| default: |
| return kvm_x86_call(get_feature_msr)(index, data); |
| } |
| return 0; |
| } |
| |
| typedef int (*msr_access_t)(struct kvm_vcpu *vcpu, u32 index, u64 *data, |
| bool host_initiated); |
| |
| static __always_inline int kvm_do_msr_access(struct kvm_vcpu *vcpu, u32 msr, |
| u64 *data, bool host_initiated, |
| enum kvm_msr_access rw, |
| msr_access_t msr_access_fn) |
| { |
| const char *op = rw == MSR_TYPE_W ? "wrmsr" : "rdmsr"; |
| int ret; |
| |
| BUILD_BUG_ON(rw != MSR_TYPE_R && rw != MSR_TYPE_W); |
| |
| /* |
| * Zero the data on read failures to avoid leaking stack data to the |
| * guest and/or userspace, e.g. if the failure is ignored below. |
| */ |
| ret = msr_access_fn(vcpu, msr, data, host_initiated); |
| if (ret && rw == MSR_TYPE_R) |
| *data = 0; |
| |
| if (ret != KVM_MSR_RET_UNSUPPORTED) |
| return ret; |
| |
| /* |
| * Userspace is allowed to read MSRs, and write '0' to MSRs, that KVM |
| * advertises to userspace, even if an MSR isn't fully supported. |
| * Simply check that @data is '0', which covers both the write '0' case |
| * and all reads (in which case @data is zeroed on failure; see above). |
| */ |
| if (host_initiated && !*data && kvm_is_advertised_msr(msr)) |
| return 0; |
| |
| if (!ignore_msrs) { |
| kvm_debug_ratelimited("unhandled %s: 0x%x data 0x%llx\n", |
| op, msr, *data); |
| return ret; |
| } |
| |
| if (report_ignored_msrs) |
| kvm_pr_unimpl("ignored %s: 0x%x data 0x%llx\n", op, msr, *data); |
| |
| return 0; |
| } |
| |
| static int do_get_feature_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) |
| { |
| return kvm_do_msr_access(vcpu, index, data, true, MSR_TYPE_R, |
| kvm_get_feature_msr); |
| } |
| |
| static bool __kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer) |
| { |
| if (efer & EFER_AUTOIBRS && !guest_cpu_cap_has(vcpu, X86_FEATURE_AUTOIBRS)) |
| return false; |
| |
| if (efer & EFER_FFXSR && !guest_cpu_cap_has(vcpu, X86_FEATURE_FXSR_OPT)) |
| return false; |
| |
| if (efer & EFER_SVME && !guest_cpu_cap_has(vcpu, X86_FEATURE_SVM)) |
| return false; |
| |
| if (efer & (EFER_LME | EFER_LMA) && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_LM)) |
| return false; |
| |
| if (efer & EFER_NX && !guest_cpu_cap_has(vcpu, X86_FEATURE_NX)) |
| return false; |
| |
| return true; |
| |
| } |
| bool kvm_valid_efer(struct kvm_vcpu *vcpu, u64 efer) |
| { |
| if (efer & ~kvm_caps.supported_efer_bits) |
| return false; |
| |
| return __kvm_valid_efer(vcpu, efer); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_valid_efer); |
| |
| static int set_efer(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| u64 old_efer = vcpu->arch.efer; |
| u64 efer = msr_info->data; |
| int r; |
| |
| if (efer & ~kvm_caps.supported_efer_bits) |
| return 1; |
| |
| if (!msr_info->host_initiated) { |
| if (!__kvm_valid_efer(vcpu, efer)) |
| return 1; |
| |
| if (is_paging(vcpu) && |
| (vcpu->arch.efer & EFER_LME) != (efer & EFER_LME)) |
| return 1; |
| } |
| |
| efer &= ~EFER_LMA; |
| efer |= vcpu->arch.efer & EFER_LMA; |
| |
| r = kvm_x86_call(set_efer)(vcpu, efer); |
| if (r) { |
| WARN_ON(r > 0); |
| return r; |
| } |
| |
| if ((efer ^ old_efer) & KVM_MMU_EFER_ROLE_BITS) |
| kvm_mmu_reset_context(vcpu); |
| |
| if (!cpu_feature_enabled(X86_FEATURE_XSAVES) && |
| (efer & EFER_SVME)) |
| kvm_hv_xsaves_xsavec_maybe_warn(vcpu); |
| |
| return 0; |
| } |
| |
| bool kvm_msr_allowed(struct kvm_vcpu *vcpu, u32 index, u32 type) |
| { |
| struct kvm_x86_msr_filter *msr_filter; |
| struct msr_bitmap_range *ranges; |
| struct kvm *kvm = vcpu->kvm; |
| bool allowed; |
| int idx; |
| u32 i; |
| |
| /* x2APIC MSRs do not support filtering. */ |
| if (index >= 0x800 && index <= 0x8ff) |
| return true; |
| |
| idx = srcu_read_lock(&kvm->srcu); |
| |
| msr_filter = srcu_dereference(kvm->arch.msr_filter, &kvm->srcu); |
| if (!msr_filter) { |
| allowed = true; |
| goto out; |
| } |
| |
| allowed = msr_filter->default_allow; |
| ranges = msr_filter->ranges; |
| |
| for (i = 0; i < msr_filter->count; i++) { |
| u32 start = ranges[i].base; |
| u32 end = start + ranges[i].nmsrs; |
| u32 flags = ranges[i].flags; |
| unsigned long *bitmap = ranges[i].bitmap; |
| |
| if ((index >= start) && (index < end) && (flags & type)) { |
| allowed = test_bit(index - start, bitmap); |
| break; |
| } |
| } |
| |
| out: |
| srcu_read_unlock(&kvm->srcu, idx); |
| |
| return allowed; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_msr_allowed); |
| |
| /* |
| * Write @data into the MSR specified by @index. Select MSR specific fault |
| * checks are bypassed if @host_initiated is %true. |
| * Returns 0 on success, non-0 otherwise. |
| * Assumes vcpu_load() was already called. |
| */ |
| static int __kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data, |
| bool host_initiated) |
| { |
| struct msr_data msr; |
| |
| switch (index) { |
| case MSR_FS_BASE: |
| case MSR_GS_BASE: |
| case MSR_KERNEL_GS_BASE: |
| case MSR_CSTAR: |
| case MSR_LSTAR: |
| if (is_noncanonical_msr_address(data, vcpu)) |
| return 1; |
| break; |
| case MSR_IA32_SYSENTER_EIP: |
| case MSR_IA32_SYSENTER_ESP: |
| /* |
| * IA32_SYSENTER_ESP and IA32_SYSENTER_EIP cause #GP if |
| * non-canonical address is written on Intel but not on |
| * AMD (which ignores the top 32-bits, because it does |
| * not implement 64-bit SYSENTER). |
| * |
| * 64-bit code should hence be able to write a non-canonical |
| * value on AMD. Making the address canonical ensures that |
| * vmentry does not fail on Intel after writing a non-canonical |
| * value, and that something deterministic happens if the guest |
| * invokes 64-bit SYSENTER. |
| */ |
| data = __canonical_address(data, max_host_virt_addr_bits()); |
| break; |
| case MSR_TSC_AUX: |
| if (!kvm_is_supported_user_return_msr(MSR_TSC_AUX)) |
| return 1; |
| |
| if (!host_initiated && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_RDTSCP) && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_RDPID)) |
| return 1; |
| |
| /* |
| * Per Intel's SDM, bits 63:32 are reserved, but AMD's APM has |
| * incomplete and conflicting architectural behavior. Current |
| * AMD CPUs completely ignore bits 63:32, i.e. they aren't |
| * reserved and always read as zeros. Enforce Intel's reserved |
| * bits check if the guest CPU is Intel compatible, otherwise |
| * clear the bits. This ensures cross-vendor migration will |
| * provide consistent behavior for the guest. |
| */ |
| if (guest_cpuid_is_intel_compatible(vcpu) && (data >> 32) != 0) |
| return 1; |
| |
| data = (u32)data; |
| break; |
| case MSR_IA32_U_CET: |
| case MSR_IA32_S_CET: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK) && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_IBT)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| if (!kvm_is_valid_u_s_cet(vcpu, data)) |
| return 1; |
| break; |
| case MSR_KVM_INTERNAL_GUEST_SSP: |
| if (!host_initiated) |
| return 1; |
| fallthrough; |
| /* |
| * Note that the MSR emulation here is flawed when a vCPU |
| * doesn't support the Intel 64 architecture. The expected |
| * architectural behavior in this case is that the upper 32 |
| * bits do not exist and should always read '0'. However, |
| * because the actual hardware on which the virtual CPU is |
| * running does support Intel 64, XRSTORS/XSAVES in the |
| * guest could observe behavior that violates the |
| * architecture. Intercepting XRSTORS/XSAVES for this |
| * special case isn't deemed worthwhile. |
| */ |
| case MSR_IA32_PL0_SSP ... MSR_IA32_INT_SSP_TAB: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| /* |
| * MSR_IA32_INT_SSP_TAB is not present on processors that do |
| * not support Intel 64 architecture. |
| */ |
| if (index == MSR_IA32_INT_SSP_TAB && !guest_cpu_cap_has(vcpu, X86_FEATURE_LM)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| if (is_noncanonical_msr_address(data, vcpu)) |
| return 1; |
| /* All SSP MSRs except MSR_IA32_INT_SSP_TAB must be 4-byte aligned */ |
| if (index != MSR_IA32_INT_SSP_TAB && !IS_ALIGNED(data, 4)) |
| return 1; |
| break; |
| } |
| |
| msr.data = data; |
| msr.index = index; |
| msr.host_initiated = host_initiated; |
| |
| return kvm_x86_call(set_msr)(vcpu, &msr); |
| } |
| |
| static int _kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, |
| bool host_initiated) |
| { |
| return __kvm_set_msr(vcpu, index, *data, host_initiated); |
| } |
| |
| static int kvm_set_msr_ignored_check(struct kvm_vcpu *vcpu, |
| u32 index, u64 data, bool host_initiated) |
| { |
| return kvm_do_msr_access(vcpu, index, &data, host_initiated, MSR_TYPE_W, |
| _kvm_set_msr); |
| } |
| |
| /* |
| * Read the MSR specified by @index into @data. Select MSR specific fault |
| * checks are bypassed if @host_initiated is %true. |
| * Returns 0 on success, non-0 otherwise. |
| * Assumes vcpu_load() was already called. |
| */ |
| static int __kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data, |
| bool host_initiated) |
| { |
| struct msr_data msr; |
| int ret; |
| |
| switch (index) { |
| case MSR_TSC_AUX: |
| if (!kvm_is_supported_user_return_msr(MSR_TSC_AUX)) |
| return 1; |
| |
| if (!host_initiated && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_RDTSCP) && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_RDPID)) |
| return 1; |
| break; |
| case MSR_IA32_U_CET: |
| case MSR_IA32_S_CET: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK) && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_IBT)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| break; |
| case MSR_KVM_INTERNAL_GUEST_SSP: |
| if (!host_initiated) |
| return 1; |
| fallthrough; |
| case MSR_IA32_PL0_SSP ... MSR_IA32_INT_SSP_TAB: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| break; |
| } |
| |
| msr.index = index; |
| msr.host_initiated = host_initiated; |
| |
| ret = kvm_x86_call(get_msr)(vcpu, &msr); |
| if (!ret) |
| *data = msr.data; |
| return ret; |
| } |
| |
| static int kvm_get_msr_ignored_check(struct kvm_vcpu *vcpu, |
| u32 index, u64 *data, bool host_initiated) |
| { |
| return kvm_do_msr_access(vcpu, index, data, host_initiated, MSR_TYPE_R, |
| __kvm_get_msr); |
| } |
| |
| int kvm_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data) |
| { |
| return __kvm_set_msr(vcpu, index, data, true); |
| } |
| |
| int kvm_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data) |
| { |
| return __kvm_get_msr(vcpu, index, data, true); |
| } |
| |
| int __kvm_emulate_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data) |
| { |
| return kvm_get_msr_ignored_check(vcpu, index, data, false); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(__kvm_emulate_msr_read); |
| |
| int __kvm_emulate_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data) |
| { |
| return kvm_set_msr_ignored_check(vcpu, index, data, false); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(__kvm_emulate_msr_write); |
| |
| int kvm_emulate_msr_read(struct kvm_vcpu *vcpu, u32 index, u64 *data) |
| { |
| if (!kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_READ)) |
| return KVM_MSR_RET_FILTERED; |
| |
| return __kvm_emulate_msr_read(vcpu, index, data); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_msr_read); |
| |
| int kvm_emulate_msr_write(struct kvm_vcpu *vcpu, u32 index, u64 data) |
| { |
| if (!kvm_msr_allowed(vcpu, index, KVM_MSR_FILTER_WRITE)) |
| return KVM_MSR_RET_FILTERED; |
| |
| return __kvm_emulate_msr_write(vcpu, index, data); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_msr_write); |
| |
| static fastpath_t __handle_fastpath_wrmsr(struct kvm_vcpu *vcpu, u32 msr, u64 data) |
| { |
| if (!kvm_pmu_is_fastpath_emulation_allowed(vcpu)) |
| return EXIT_FASTPATH_NONE; |
| |
| switch (msr) { |
| case APIC_BASE_MSR + (APIC_ICR >> 4): |
| if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(vcpu->arch.apic) || |
| kvm_x2apic_icr_write_fast(vcpu->arch.apic, data)) |
| return EXIT_FASTPATH_NONE; |
| break; |
| case MSR_IA32_TSC_DEADLINE: |
| kvm_set_lapic_tscdeadline_msr(vcpu, data); |
| break; |
| default: |
| return EXIT_FASTPATH_NONE; |
| } |
| |
| trace_kvm_msr_write(msr, data); |
| |
| if (!kvm_skip_emulated_instruction(vcpu)) |
| return EXIT_FASTPATH_EXIT_USERSPACE; |
| |
| return EXIT_FASTPATH_REENTER_GUEST; |
| } |
| |
| fastpath_t handle_fastpath_wrmsr(struct kvm_vcpu *vcpu) |
| { |
| return __handle_fastpath_wrmsr(vcpu, kvm_ecx_read(vcpu), |
| kvm_read_edx_eax(vcpu)); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(handle_fastpath_wrmsr); |
| |
| fastpath_t handle_fastpath_wrmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg) |
| { |
| return __handle_fastpath_wrmsr(vcpu, msr, kvm_register_read(vcpu, reg)); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(handle_fastpath_wrmsr_imm); |
| |
| static void complete_userspace_rdmsr(struct kvm_vcpu *vcpu) |
| { |
| if (!vcpu->run->msr.error) { |
| kvm_eax_write(vcpu, vcpu->run->msr.data); |
| kvm_edx_write(vcpu, vcpu->run->msr.data >> 32); |
| } |
| } |
| |
| static int complete_emulated_insn_gp(struct kvm_vcpu *vcpu, int err) |
| { |
| if (err) { |
| kvm_inject_gp(vcpu, 0); |
| return 1; |
| } |
| |
| return kvm_emulate_instruction(vcpu, EMULTYPE_NO_DECODE | EMULTYPE_SKIP | |
| EMULTYPE_COMPLETE_USER_EXIT); |
| } |
| |
| static int complete_emulated_msr_access(struct kvm_vcpu *vcpu) |
| { |
| return complete_emulated_insn_gp(vcpu, vcpu->run->msr.error); |
| } |
| |
| static int complete_emulated_rdmsr(struct kvm_vcpu *vcpu) |
| { |
| complete_userspace_rdmsr(vcpu); |
| return complete_emulated_msr_access(vcpu); |
| } |
| |
| static int complete_fast_msr_access(struct kvm_vcpu *vcpu) |
| { |
| return kvm_x86_call(complete_emulated_msr)(vcpu, vcpu->run->msr.error); |
| } |
| |
| static int complete_fast_rdmsr(struct kvm_vcpu *vcpu) |
| { |
| complete_userspace_rdmsr(vcpu); |
| return complete_fast_msr_access(vcpu); |
| } |
| |
| static int complete_fast_rdmsr_imm(struct kvm_vcpu *vcpu) |
| { |
| if (!vcpu->run->msr.error) |
| kvm_register_write(vcpu, vcpu->arch.cui_rdmsr_imm_reg, |
| vcpu->run->msr.data); |
| |
| return complete_fast_msr_access(vcpu); |
| } |
| |
| static u64 kvm_msr_reason(int r) |
| { |
| switch (r) { |
| case KVM_MSR_RET_UNSUPPORTED: |
| return KVM_MSR_EXIT_REASON_UNKNOWN; |
| case KVM_MSR_RET_FILTERED: |
| return KVM_MSR_EXIT_REASON_FILTER; |
| default: |
| return KVM_MSR_EXIT_REASON_INVAL; |
| } |
| } |
| |
| static int kvm_msr_user_space(struct kvm_vcpu *vcpu, u32 index, |
| u32 exit_reason, u64 data, |
| int (*completion)(struct kvm_vcpu *vcpu), |
| int r) |
| { |
| u64 msr_reason = kvm_msr_reason(r); |
| |
| /* Check if the user wanted to know about this MSR fault */ |
| if (!(vcpu->kvm->arch.user_space_msr_mask & msr_reason)) |
| return 0; |
| |
| vcpu->run->exit_reason = exit_reason; |
| vcpu->run->msr.error = 0; |
| memset(vcpu->run->msr.pad, 0, sizeof(vcpu->run->msr.pad)); |
| vcpu->run->msr.reason = msr_reason; |
| vcpu->run->msr.index = index; |
| vcpu->run->msr.data = data; |
| vcpu->arch.complete_userspace_io = completion; |
| |
| return 1; |
| } |
| |
| static int __kvm_emulate_rdmsr(struct kvm_vcpu *vcpu, u32 msr, int reg, |
| int (*complete_rdmsr)(struct kvm_vcpu *)) |
| { |
| u64 data; |
| int r; |
| |
| r = kvm_emulate_msr_read(vcpu, msr, &data); |
| |
| if (!r) { |
| trace_kvm_msr_read(msr, data); |
| |
| if (reg < 0) { |
| kvm_eax_write(vcpu, data); |
| kvm_edx_write(vcpu, data >> 32); |
| } else { |
| kvm_register_write(vcpu, reg, data); |
| } |
| } else { |
| /* MSR read failed? See if we should ask user space */ |
| if (kvm_msr_user_space(vcpu, msr, KVM_EXIT_X86_RDMSR, 0, |
| complete_rdmsr, r)) |
| return 0; |
| trace_kvm_msr_read_ex(msr); |
| } |
| |
| return kvm_x86_call(complete_emulated_msr)(vcpu, r); |
| } |
| |
| int kvm_emulate_rdmsr(struct kvm_vcpu *vcpu) |
| { |
| return __kvm_emulate_rdmsr(vcpu, kvm_ecx_read(vcpu), -1, |
| complete_fast_rdmsr); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_rdmsr); |
| |
| int kvm_emulate_rdmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg) |
| { |
| vcpu->arch.cui_rdmsr_imm_reg = reg; |
| |
| return __kvm_emulate_rdmsr(vcpu, msr, reg, complete_fast_rdmsr_imm); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_rdmsr_imm); |
| |
| static int __kvm_emulate_wrmsr(struct kvm_vcpu *vcpu, u32 msr, u64 data) |
| { |
| int r; |
| |
| r = kvm_emulate_msr_write(vcpu, msr, data); |
| if (!r) { |
| trace_kvm_msr_write(msr, data); |
| } else { |
| /* MSR write failed? See if we should ask user space */ |
| if (kvm_msr_user_space(vcpu, msr, KVM_EXIT_X86_WRMSR, data, |
| complete_fast_msr_access, r)) |
| return 0; |
| /* Signal all other negative errors to userspace */ |
| if (r < 0) |
| return r; |
| trace_kvm_msr_write_ex(msr, data); |
| } |
| |
| return kvm_x86_call(complete_emulated_msr)(vcpu, r); |
| } |
| |
| int kvm_emulate_wrmsr(struct kvm_vcpu *vcpu) |
| { |
| return __kvm_emulate_wrmsr(vcpu, kvm_ecx_read(vcpu), |
| kvm_read_edx_eax(vcpu)); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_wrmsr); |
| |
| int kvm_emulate_wrmsr_imm(struct kvm_vcpu *vcpu, u32 msr, int reg) |
| { |
| return __kvm_emulate_wrmsr(vcpu, msr, kvm_register_read(vcpu, reg)); |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_emulate_wrmsr_imm); |
| |
| int kvm_emulator_get_msr_with_filter(struct kvm_vcpu *vcpu, u32 msr_index, |
| u64 *pdata) |
| { |
| int r; |
| |
| r = kvm_emulate_msr_read(vcpu, msr_index, pdata); |
| if (r < 0) |
| return X86EMUL_UNHANDLEABLE; |
| |
| if (r) { |
| if (kvm_msr_user_space(vcpu, msr_index, KVM_EXIT_X86_RDMSR, 0, |
| complete_emulated_rdmsr, r)) |
| return X86EMUL_IO_NEEDED; |
| |
| trace_kvm_msr_read_ex(msr_index); |
| return X86EMUL_PROPAGATE_FAULT; |
| } |
| |
| trace_kvm_msr_read(msr_index, *pdata); |
| return X86EMUL_CONTINUE; |
| } |
| |
| int kvm_emulator_set_msr_with_filter(struct kvm_vcpu *vcpu, u32 msr_index, |
| u64 data) |
| { |
| int r; |
| |
| r = kvm_emulate_msr_write(vcpu, msr_index, data); |
| if (r < 0) |
| return X86EMUL_UNHANDLEABLE; |
| |
| if (r) { |
| if (kvm_msr_user_space(vcpu, msr_index, KVM_EXIT_X86_WRMSR, data, |
| complete_emulated_msr_access, r)) |
| return X86EMUL_IO_NEEDED; |
| |
| trace_kvm_msr_write_ex(msr_index, data); |
| return X86EMUL_PROPAGATE_FAULT; |
| } |
| |
| trace_kvm_msr_write(msr_index, data); |
| return X86EMUL_CONTINUE; |
| } |
| |
| int kvm_emulator_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata) |
| { |
| /* |
| * Treat emulator accesses to the current shadow stack pointer as host- |
| * initiated, as they aren't true MSR accesses (SSP is a "just a reg"), |
| * and this API is used only for implicit accesses, i.e. not RDMSR, and |
| * so the index is fully KVM-controlled. |
| */ |
| if (unlikely(msr_index == MSR_KVM_INTERNAL_GUEST_SSP)) |
| return kvm_msr_read(vcpu, msr_index, pdata); |
| |
| return __kvm_emulate_msr_read(vcpu, msr_index, pdata); |
| } |
| |
| /* |
| * Returns true if the MSR in question is managed via XSTATE, i.e. is context |
| * switched with the rest of guest FPU state. |
| * |
| * Note, S_CET is _not_ saved/restored via XSAVES/XRSTORS. |
| */ |
| static bool is_xstate_managed_msr(struct kvm_vcpu *vcpu, u32 msr) |
| { |
| if (!vcpu) |
| return false; |
| |
| switch (msr) { |
| case MSR_IA32_U_CET: |
| return guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK) || |
| guest_cpu_cap_has(vcpu, X86_FEATURE_IBT); |
| case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: |
| return guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK); |
| default: |
| return false; |
| } |
| } |
| |
| /* |
| * Lock (and if necessary, re-load) the guest FPU, i.e. XSTATE, and access an |
| * MSR that is managed via XSTATE. Note, the caller is responsible for doing |
| * the initial FPU load, this helper only ensures that guest state is resident |
| * in hardware (the kernel can load its FPU state in IRQ context). |
| * |
| * Note, loading guest values for U_CET and PL[0-3]_SSP while executing in the |
| * kernel is safe, as U_CET is specific to userspace, and PL[0-3]_SSP are only |
| * consumed when transitioning to lower privilege levels, i.e. are effectively |
| * only consumed by userspace as well. |
| */ |
| static __always_inline void kvm_access_xstate_msr(struct kvm_vcpu *vcpu, |
| struct msr_data *msr_info, |
| int access) |
| { |
| BUILD_BUG_ON(access != MSR_TYPE_R && access != MSR_TYPE_W); |
| |
| KVM_BUG_ON(!is_xstate_managed_msr(vcpu, msr_info->index), vcpu->kvm); |
| KVM_BUG_ON(!vcpu->arch.guest_fpu.fpstate->in_use, vcpu->kvm); |
| |
| kvm_fpu_get(); |
| if (access == MSR_TYPE_R) |
| rdmsrq(msr_info->index, msr_info->data); |
| else |
| wrmsrq(msr_info->index, msr_info->data); |
| kvm_fpu_put(); |
| } |
| |
| static void kvm_set_xstate_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| kvm_access_xstate_msr(vcpu, msr_info, MSR_TYPE_W); |
| } |
| |
| static void kvm_get_xstate_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| kvm_access_xstate_msr(vcpu, msr_info, MSR_TYPE_R); |
| } |
| |
| static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock, int sec_hi_ofs) |
| { |
| int version; |
| int r; |
| struct pvclock_wall_clock wc; |
| u32 wc_sec_hi; |
| u64 wall_nsec; |
| |
| if (!wall_clock) |
| return; |
| |
| r = kvm_read_guest(kvm, wall_clock, &version, sizeof(version)); |
| if (r) |
| return; |
| |
| if (version & 1) |
| ++version; /* first time write, random junk */ |
| |
| ++version; |
| |
| if (kvm_write_guest(kvm, wall_clock, &version, sizeof(version))) |
| return; |
| |
| wall_nsec = kvm_get_wall_clock_epoch(kvm); |
| |
| wc.nsec = do_div(wall_nsec, NSEC_PER_SEC); |
| wc.sec = (u32)wall_nsec; /* overflow in 2106 guest time */ |
| wc.version = version; |
| |
| kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc)); |
| |
| if (sec_hi_ofs) { |
| wc_sec_hi = wall_nsec >> 32; |
| kvm_write_guest(kvm, wall_clock + sec_hi_ofs, |
| &wc_sec_hi, sizeof(wc_sec_hi)); |
| } |
| |
| version++; |
| kvm_write_guest(kvm, wall_clock, &version, sizeof(version)); |
| } |
| |
| static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time, |
| bool old_msr, bool host_initiated) |
| { |
| struct kvm_arch *ka = &vcpu->kvm->arch; |
| |
| if (vcpu->vcpu_id == 0 && !host_initiated) { |
| if (ka->boot_vcpu_runs_old_kvmclock != old_msr) |
| kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu); |
| |
| ka->boot_vcpu_runs_old_kvmclock = old_msr; |
| } |
| |
| vcpu->arch.time = system_time; |
| kvm_make_request(KVM_REQ_GLOBAL_CLOCK_UPDATE, vcpu); |
| |
| /* we verify if the enable bit is set... */ |
| if (system_time & 1) |
| kvm_gpc_activate(&vcpu->arch.pv_time, system_time & ~1ULL, |
| sizeof(struct pvclock_vcpu_time_info)); |
| else |
| kvm_gpc_deactivate(&vcpu->arch.pv_time); |
| |
| return; |
| } |
| |
| /* These helpers are safe iff @msr is known to be an MCx bank MSR. */ |
| static bool is_mci_control_msr(u32 msr) |
| { |
| return (msr & 3) == 0; |
| } |
| static bool is_mci_status_msr(u32 msr) |
| { |
| return (msr & 3) == 1; |
| } |
| |
| /* |
| * On AMD, HWCR[McStatusWrEn] controls whether setting MCi_STATUS results in #GP. |
| */ |
| static bool can_set_mci_status(struct kvm_vcpu *vcpu) |
| { |
| /* McStatusWrEn enabled? */ |
| if (guest_cpuid_is_amd_compatible(vcpu)) |
| return !!(vcpu->arch.msr_hwcr & BIT_ULL(18)); |
| |
| return false; |
| } |
| |
| static int set_msr_mce(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| u64 mcg_cap = vcpu->arch.mcg_cap; |
| unsigned bank_num = mcg_cap & 0xff; |
| u32 msr = msr_info->index; |
| u64 data = msr_info->data; |
| u32 offset, last_msr; |
| |
| switch (msr) { |
| case MSR_IA32_MCG_STATUS: |
| vcpu->arch.mcg_status = data; |
| break; |
| case MSR_IA32_MCG_CTL: |
| if (!(mcg_cap & MCG_CTL_P) && |
| (data || !msr_info->host_initiated)) |
| return 1; |
| if (data != 0 && data != ~(u64)0) |
| return 1; |
| vcpu->arch.mcg_ctl = data; |
| break; |
| case MSR_IA32_MC0_CTL2 ... MSR_IA32_MCx_CTL2(KVM_MAX_MCE_BANKS) - 1: |
| last_msr = MSR_IA32_MCx_CTL2(bank_num) - 1; |
| if (msr > last_msr) |
| return 1; |
| |
| if (!(mcg_cap & MCG_CMCI_P) && (data || !msr_info->host_initiated)) |
| return 1; |
| /* An attempt to write a 1 to a reserved bit raises #GP */ |
| if (data & ~(MCI_CTL2_CMCI_EN | MCI_CTL2_CMCI_THRESHOLD_MASK)) |
| return 1; |
| offset = array_index_nospec(msr - MSR_IA32_MC0_CTL2, |
| last_msr + 1 - MSR_IA32_MC0_CTL2); |
| vcpu->arch.mci_ctl2_banks[offset] = data; |
| break; |
| case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1: |
| last_msr = MSR_IA32_MCx_CTL(bank_num) - 1; |
| if (msr > last_msr) |
| return 1; |
| |
| /* |
| * Only 0 or all 1s can be written to IA32_MCi_CTL, all other |
| * values are architecturally undefined. But, some Linux |
| * kernels clear bit 10 in bank 4 to workaround a BIOS/GART TLB |
| * issue on AMD K8s, allow bit 10 to be clear when setting all |
| * other bits in order to avoid an uncaught #GP in the guest. |
| * |
| * UNIXWARE clears bit 0 of MC1_CTL to ignore correctable, |
| * single-bit ECC data errors. |
| */ |
| if (is_mci_control_msr(msr) && |
| data != 0 && (data | (1 << 10) | 1) != ~(u64)0) |
| return 1; |
| |
| /* |
| * All CPUs allow writing 0 to MCi_STATUS MSRs to clear the MSR. |
| * AMD-based CPUs allow non-zero values, but if and only if |
| * HWCR[McStatusWrEn] is set. |
| */ |
| if (!msr_info->host_initiated && is_mci_status_msr(msr) && |
| data != 0 && !can_set_mci_status(vcpu)) |
| return 1; |
| |
| offset = array_index_nospec(msr - MSR_IA32_MC0_CTL, |
| last_msr + 1 - MSR_IA32_MC0_CTL); |
| vcpu->arch.mce_banks[offset] = data; |
| break; |
| default: |
| return 1; |
| } |
| return 0; |
| } |
| |
| static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) |
| { |
| gpa_t gpa = data & ~0x3f; |
| |
| /* Bits 4:5 are reserved, Should be zero */ |
| if (data & 0x30) |
| return 1; |
| |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_VMEXIT) && |
| (data & KVM_ASYNC_PF_DELIVERY_AS_PF_VMEXIT)) |
| return 1; |
| |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT) && |
| (data & KVM_ASYNC_PF_DELIVERY_AS_INT)) |
| return 1; |
| |
| if (!lapic_in_kernel(vcpu)) |
| return data ? 1 : 0; |
| |
| if (__kvm_pv_async_pf_enabled(data) && |
| kvm_gfn_to_hva_cache_init(vcpu->kvm, &vcpu->arch.apf.data, gpa, |
| sizeof(u64))) |
| return 1; |
| |
| vcpu->arch.apf.msr_en_val = data; |
| |
| if (__kvm_pv_async_pf_enabled(data)) { |
| kvm_async_pf_wakeup_all(vcpu); |
| } else { |
| kvm_clear_async_pf_completion_queue(vcpu); |
| kvm_async_pf_hash_reset(vcpu); |
| } |
| return 0; |
| } |
| |
| static int kvm_pv_enable_async_pf_int(struct kvm_vcpu *vcpu, u64 data) |
| { |
| /* Bits 8-63 are reserved */ |
| if (data >> 8) |
| return 1; |
| |
| if (!lapic_in_kernel(vcpu)) |
| return 1; |
| |
| vcpu->arch.apf.msr_int_val = data; |
| |
| vcpu->arch.apf.vec = data & KVM_ASYNC_PF_VEC_MASK; |
| |
| return 0; |
| } |
| |
| #ifdef CONFIG_X86_64 |
| static inline u64 kvm_guest_supported_xfd(struct kvm_vcpu *vcpu) |
| { |
| return vcpu->arch.guest_supported_xcr0 & XFEATURE_MASK_USER_DYNAMIC; |
| } |
| #endif |
| |
| int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| u32 msr = msr_info->index; |
| u64 data = msr_info->data; |
| |
| /* |
| * Do not allow host-initiated writes to trigger the Xen hypercall |
| * page setup; it could incur locking paths which are not expected |
| * if userspace sets the MSR in an unusual location. |
| */ |
| if (kvm_xen_is_hypercall_page_msr(vcpu->kvm, msr) && |
| !msr_info->host_initiated) |
| return kvm_xen_write_hypercall_page(vcpu, data); |
| |
| switch (msr) { |
| case MSR_AMD64_NB_CFG: |
| case MSR_IA32_UCODE_WRITE: |
| case MSR_VM_HSAVE_PA: |
| case MSR_AMD64_PATCH_LOADER: |
| case MSR_AMD64_BU_CFG2: |
| case MSR_AMD64_DC_CFG: |
| case MSR_AMD64_TW_CFG: |
| case MSR_F15H_EX_CFG: |
| break; |
| |
| case MSR_IA32_UCODE_REV: |
| if (msr_info->host_initiated) |
| vcpu->arch.microcode_version = data; |
| break; |
| case MSR_IA32_ARCH_CAPABILITIES: |
| if (!msr_info->host_initiated || |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_ARCH_CAPABILITIES)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| vcpu->arch.arch_capabilities = data; |
| break; |
| case MSR_IA32_PERF_CAPABILITIES: |
| if (!msr_info->host_initiated || |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_PDCM)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| if (data & ~kvm_caps.supported_perf_cap) |
| return 1; |
| |
| /* |
| * Note, this is not just a performance optimization! KVM |
| * disallows changing feature MSRs after the vCPU has run; PMU |
| * refresh will bug the VM if called after the vCPU has run. |
| */ |
| if (vcpu->arch.perf_capabilities == data) |
| break; |
| |
| vcpu->arch.perf_capabilities = data; |
| kvm_pmu_refresh(vcpu); |
| kvm_make_request(KVM_REQ_RECALC_INTERCEPTS, vcpu); |
| break; |
| case MSR_IA32_PRED_CMD: { |
| u64 reserved_bits = ~(PRED_CMD_IBPB | PRED_CMD_SBPB); |
| |
| if (!msr_info->host_initiated) { |
| if ((!guest_has_pred_cmd_msr(vcpu))) |
| return 1; |
| |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SPEC_CTRL) && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_AMD_IBPB)) |
| reserved_bits |= PRED_CMD_IBPB; |
| |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SBPB)) |
| reserved_bits |= PRED_CMD_SBPB; |
| } |
| |
| if (!boot_cpu_has(X86_FEATURE_IBPB)) |
| reserved_bits |= PRED_CMD_IBPB; |
| |
| if (!boot_cpu_has(X86_FEATURE_SBPB)) |
| reserved_bits |= PRED_CMD_SBPB; |
| |
| if (data & reserved_bits) |
| return 1; |
| |
| if (!data) |
| break; |
| |
| wrmsrq(MSR_IA32_PRED_CMD, data); |
| break; |
| } |
| case MSR_IA32_FLUSH_CMD: |
| if (!msr_info->host_initiated && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_FLUSH_L1D)) |
| return 1; |
| |
| if (!boot_cpu_has(X86_FEATURE_FLUSH_L1D) || (data & ~L1D_FLUSH)) |
| return 1; |
| if (!data) |
| break; |
| |
| wrmsrq(MSR_IA32_FLUSH_CMD, L1D_FLUSH); |
| break; |
| case MSR_EFER: |
| return set_efer(vcpu, msr_info); |
| case MSR_K7_HWCR: { |
| /* |
| * Allow McStatusWrEn and TscFreqSel. (Linux guests from v3.2 |
| * through at least v6.6 whine if TscFreqSel is clear, |
| * depending on F/M/S. |
| */ |
| u64 valid = BIT_ULL(18) | BIT_ULL(24); |
| |
| data &= ~(u64)0x40; /* ignore flush filter disable */ |
| data &= ~(u64)0x100; /* ignore ignne emulation enable */ |
| data &= ~(u64)0x8; /* ignore TLB cache disable */ |
| |
| if (guest_cpu_cap_has(vcpu, X86_FEATURE_GP_ON_USER_CPUID)) |
| valid |= MSR_K7_HWCR_CPUID_USER_DIS; |
| |
| if (data & ~valid) { |
| kvm_pr_unimpl_wrmsr(vcpu, msr, data); |
| return 1; |
| } |
| vcpu->arch.msr_hwcr = data; |
| break; |
| } |
| case MSR_FAM10H_MMIO_CONF_BASE: |
| if (data != 0) { |
| kvm_pr_unimpl_wrmsr(vcpu, msr, data); |
| return 1; |
| } |
| break; |
| case MSR_IA32_CR_PAT: |
| if (!kvm_pat_valid(data)) |
| return 1; |
| |
| vcpu->arch.pat = data; |
| break; |
| case MTRRphysBase_MSR(0) ... MSR_MTRRfix4K_F8000: |
| case MSR_MTRRdefType: |
| return kvm_mtrr_set_msr(vcpu, msr, data); |
| case MSR_IA32_APICBASE: |
| return kvm_apic_set_base(vcpu, data, msr_info->host_initiated); |
| case APIC_BASE_MSR ... APIC_BASE_MSR + 0xff: |
| return kvm_x2apic_msr_write(vcpu, msr, data); |
| case MSR_IA32_TSC_DEADLINE: |
| kvm_set_lapic_tscdeadline_msr(vcpu, data); |
| break; |
| case MSR_IA32_TSC_ADJUST: |
| if (guest_cpu_cap_has(vcpu, X86_FEATURE_TSC_ADJUST)) { |
| if (!msr_info->host_initiated) { |
| s64 adj = data - vcpu->arch.ia32_tsc_adjust_msr; |
| adjust_tsc_offset_guest(vcpu, adj); |
| /* Before back to guest, tsc_timestamp must be adjusted |
| * as well, otherwise guest's percpu pvclock time could jump. |
| */ |
| kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu); |
| } |
| vcpu->arch.ia32_tsc_adjust_msr = data; |
| } |
| break; |
| case MSR_IA32_MISC_ENABLE: { |
| u64 old_val = vcpu->arch.ia32_misc_enable_msr; |
| |
| if (!msr_info->host_initiated) { |
| /* RO bits */ |
| if ((old_val ^ data) & MSR_IA32_MISC_ENABLE_PMU_RO_MASK) |
| return 1; |
| |
| /* R bits, i.e. writes are ignored, but don't fault. */ |
| data = data & ~MSR_IA32_MISC_ENABLE_EMON; |
| data |= old_val & MSR_IA32_MISC_ENABLE_EMON; |
| } |
| |
| if (!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT) && |
| ((old_val ^ data) & MSR_IA32_MISC_ENABLE_MWAIT)) { |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_XMM3)) |
| return 1; |
| vcpu->arch.ia32_misc_enable_msr = data; |
| vcpu->arch.cpuid_dynamic_bits_dirty = true; |
| } else { |
| vcpu->arch.ia32_misc_enable_msr = data; |
| } |
| break; |
| } |
| case MSR_IA32_SMBASE: |
| if (!IS_ENABLED(CONFIG_KVM_SMM) || !msr_info->host_initiated) |
| return 1; |
| vcpu->arch.smbase = data; |
| break; |
| case MSR_IA32_POWER_CTL: |
| vcpu->arch.msr_ia32_power_ctl = data; |
| break; |
| case MSR_IA32_TSC: |
| if (msr_info->host_initiated) { |
| kvm_synchronize_tsc(vcpu, &data); |
| } else if (!vcpu->arch.guest_tsc_protected) { |
| u64 adj = kvm_compute_l1_tsc_offset(vcpu, data) - vcpu->arch.l1_tsc_offset; |
| adjust_tsc_offset_guest(vcpu, adj); |
| vcpu->arch.ia32_tsc_adjust_msr += adj; |
| } |
| break; |
| case MSR_IA32_XSS: |
| if (!guest_cpuid_has(vcpu, X86_FEATURE_XSAVES)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| if (data & ~vcpu->arch.guest_supported_xss) |
| return 1; |
| if (vcpu->arch.ia32_xss == data) |
| break; |
| vcpu->arch.ia32_xss = data; |
| vcpu->arch.cpuid_dynamic_bits_dirty = true; |
| break; |
| case MSR_SMI_COUNT: |
| if (!msr_info->host_initiated) |
| return 1; |
| vcpu->arch.smi_count = data; |
| break; |
| case MSR_KVM_WALL_CLOCK_NEW: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| vcpu->kvm->arch.wall_clock = data; |
| kvm_write_wall_clock(vcpu->kvm, data, 0); |
| break; |
| case MSR_KVM_WALL_CLOCK: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| vcpu->kvm->arch.wall_clock = data; |
| kvm_write_wall_clock(vcpu->kvm, data, 0); |
| break; |
| case MSR_KVM_SYSTEM_TIME_NEW: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| kvm_write_system_time(vcpu, data, false, msr_info->host_initiated); |
| break; |
| case MSR_KVM_SYSTEM_TIME: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| kvm_write_system_time(vcpu, data, true, msr_info->host_initiated); |
| break; |
| case MSR_KVM_ASYNC_PF_EN: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| if (kvm_pv_enable_async_pf(vcpu, data)) |
| return 1; |
| break; |
| case MSR_KVM_ASYNC_PF_INT: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| if (kvm_pv_enable_async_pf_int(vcpu, data)) |
| return 1; |
| break; |
| case MSR_KVM_ASYNC_PF_ACK: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| if (data & 0x1) { |
| /* |
| * Pairs with the smp_mb__after_atomic() in |
| * kvm_arch_async_page_present_queued(). |
| */ |
| smp_store_mb(vcpu->arch.apf.pageready_pending, false); |
| |
| kvm_check_async_pf_completion(vcpu); |
| } |
| break; |
| case MSR_KVM_STEAL_TIME: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_STEAL_TIME)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| if (unlikely(!sched_info_on())) |
| return 1; |
| |
| if (data & KVM_STEAL_RESERVED_MASK) |
| return 1; |
| |
| vcpu->arch.st.msr_val = data; |
| |
| if (!(data & KVM_MSR_ENABLED)) |
| break; |
| |
| kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu); |
| |
| break; |
| case MSR_KVM_PV_EOI_EN: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_PV_EOI)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| if (kvm_lapic_set_pv_eoi(vcpu, data, sizeof(u8))) |
| return 1; |
| break; |
| |
| case MSR_KVM_POLL_CONTROL: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_POLL_CONTROL)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| /* only enable bit supported */ |
| if (data & (-1ULL << 1)) |
| return 1; |
| |
| vcpu->arch.msr_kvm_poll_control = data; |
| break; |
| |
| case MSR_IA32_MCG_CTL: |
| case MSR_IA32_MCG_STATUS: |
| case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1: |
| case MSR_IA32_MC0_CTL2 ... MSR_IA32_MCx_CTL2(KVM_MAX_MCE_BANKS) - 1: |
| return set_msr_mce(vcpu, msr_info); |
| |
| case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3: |
| case MSR_P6_PERFCTR0 ... MSR_P6_PERFCTR1: |
| case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3: |
| case MSR_P6_EVNTSEL0 ... MSR_P6_EVNTSEL1: |
| if (kvm_pmu_is_valid_msr(vcpu, msr)) |
| return kvm_pmu_set_msr(vcpu, msr_info); |
| |
| if (data) |
| kvm_pr_unimpl_wrmsr(vcpu, msr, data); |
| break; |
| case MSR_K7_CLK_CTL: |
| /* |
| * Ignore all writes to this no longer documented MSR. |
| * Writes are only relevant for old K7 processors, |
| * all pre-dating SVM, but a recommended workaround from |
| * AMD for these chips. It is possible to specify the |
| * affected processor models on the command line, hence |
| * the need to ignore the workaround. |
| */ |
| break; |
| #ifdef CONFIG_KVM_HYPERV |
| case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15: |
| case HV_X64_MSR_SYNDBG_CONTROL ... HV_X64_MSR_SYNDBG_PENDING_BUFFER: |
| case HV_X64_MSR_SYNDBG_OPTIONS: |
| case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4: |
| case HV_X64_MSR_CRASH_CTL: |
| case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT: |
| case HV_X64_MSR_REENLIGHTENMENT_CONTROL: |
| case HV_X64_MSR_TSC_EMULATION_CONTROL: |
| case HV_X64_MSR_TSC_EMULATION_STATUS: |
| case HV_X64_MSR_TSC_INVARIANT_CONTROL: |
| return kvm_hv_set_msr_common(vcpu, msr, data, |
| msr_info->host_initiated); |
| #endif |
| case MSR_IA32_BBL_CR_CTL3: |
| /* Drop writes to this legacy MSR -- see rdmsr |
| * counterpart for further detail. |
| */ |
| kvm_pr_unimpl_wrmsr(vcpu, msr, data); |
| break; |
| case MSR_AMD64_OSVW_ID_LENGTH: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_OSVW)) |
| return 1; |
| vcpu->arch.osvw.length = data; |
| break; |
| case MSR_AMD64_OSVW_STATUS: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_OSVW)) |
| return 1; |
| vcpu->arch.osvw.status = data; |
| break; |
| case MSR_PLATFORM_INFO: |
| if (!msr_info->host_initiated) |
| return 1; |
| vcpu->arch.msr_platform_info = data; |
| break; |
| case MSR_MISC_FEATURES_ENABLES: |
| if (data & ~MSR_MISC_FEATURES_ENABLES_CPUID_FAULT || |
| (data & MSR_MISC_FEATURES_ENABLES_CPUID_FAULT && |
| !(vcpu->arch.msr_platform_info & MSR_PLATFORM_INFO_CPUID_FAULT))) |
| return 1; |
| vcpu->arch.msr_misc_features_enables = data; |
| break; |
| #ifdef CONFIG_X86_64 |
| case MSR_IA32_XFD: |
| if (!msr_info->host_initiated && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_XFD)) |
| return 1; |
| |
| if (data & ~kvm_guest_supported_xfd(vcpu)) |
| return 1; |
| |
| fpu_update_guest_xfd(&vcpu->arch.guest_fpu, data); |
| break; |
| case MSR_IA32_XFD_ERR: |
| if (!msr_info->host_initiated && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_XFD)) |
| return 1; |
| |
| if (data & ~kvm_guest_supported_xfd(vcpu)) |
| return 1; |
| |
| vcpu->arch.guest_fpu.xfd_err = data; |
| break; |
| #endif |
| case MSR_IA32_U_CET: |
| case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: |
| kvm_set_xstate_msr(vcpu, msr_info); |
| break; |
| default: |
| if (kvm_pmu_is_valid_msr(vcpu, msr)) |
| return kvm_pmu_set_msr(vcpu, msr_info); |
| |
| return KVM_MSR_RET_UNSUPPORTED; |
| } |
| return 0; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_set_msr_common); |
| |
| static int get_msr_mce(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata, bool host) |
| { |
| u64 data; |
| u64 mcg_cap = vcpu->arch.mcg_cap; |
| unsigned bank_num = mcg_cap & 0xff; |
| u32 offset, last_msr; |
| |
| switch (msr) { |
| case MSR_IA32_P5_MC_ADDR: |
| case MSR_IA32_P5_MC_TYPE: |
| data = 0; |
| break; |
| case MSR_IA32_MCG_CAP: |
| data = vcpu->arch.mcg_cap; |
| break; |
| case MSR_IA32_MCG_CTL: |
| if (!(mcg_cap & MCG_CTL_P) && !host) |
| return 1; |
| data = vcpu->arch.mcg_ctl; |
| break; |
| case MSR_IA32_MCG_STATUS: |
| data = vcpu->arch.mcg_status; |
| break; |
| case MSR_IA32_MC0_CTL2 ... MSR_IA32_MCx_CTL2(KVM_MAX_MCE_BANKS) - 1: |
| last_msr = MSR_IA32_MCx_CTL2(bank_num) - 1; |
| if (msr > last_msr) |
| return 1; |
| |
| if (!(mcg_cap & MCG_CMCI_P) && !host) |
| return 1; |
| offset = array_index_nospec(msr - MSR_IA32_MC0_CTL2, |
| last_msr + 1 - MSR_IA32_MC0_CTL2); |
| data = vcpu->arch.mci_ctl2_banks[offset]; |
| break; |
| case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1: |
| last_msr = MSR_IA32_MCx_CTL(bank_num) - 1; |
| if (msr > last_msr) |
| return 1; |
| |
| offset = array_index_nospec(msr - MSR_IA32_MC0_CTL, |
| last_msr + 1 - MSR_IA32_MC0_CTL); |
| data = vcpu->arch.mce_banks[offset]; |
| break; |
| default: |
| return 1; |
| } |
| *pdata = data; |
| return 0; |
| } |
| |
| int kvm_get_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) |
| { |
| switch (msr_info->index) { |
| case MSR_IA32_PLATFORM_ID: |
| case MSR_IA32_EBL_CR_POWERON: |
| case MSR_IA32_LASTBRANCHFROMIP: |
| case MSR_IA32_LASTBRANCHTOIP: |
| case MSR_IA32_LASTINTFROMIP: |
| case MSR_IA32_LASTINTTOIP: |
| case MSR_AMD64_SYSCFG: |
| case MSR_K8_TSEG_ADDR: |
| case MSR_K8_TSEG_MASK: |
| case MSR_VM_HSAVE_PA: |
| case MSR_K8_INT_PENDING_MSG: |
| case MSR_AMD64_NB_CFG: |
| case MSR_FAM10H_MMIO_CONF_BASE: |
| case MSR_AMD64_BU_CFG2: |
| case MSR_IA32_PERF_CTL: |
| case MSR_AMD64_DC_CFG: |
| case MSR_AMD64_TW_CFG: |
| case MSR_F15H_EX_CFG: |
| /* |
| * Intel Sandy Bridge CPUs must support the RAPL (running average power |
| * limit) MSRs. Just return 0, as we do not want to expose the host |
| * data here. Do not conditionalize this on CPUID, as KVM does not do |
| * so for existing CPU-specific MSRs. |
| */ |
| case MSR_RAPL_POWER_UNIT: |
| case MSR_PP0_ENERGY_STATUS: /* Power plane 0 (core) */ |
| case MSR_PP1_ENERGY_STATUS: /* Power plane 1 (graphics uncore) */ |
| case MSR_PKG_ENERGY_STATUS: /* Total package */ |
| case MSR_DRAM_ENERGY_STATUS: /* DRAM controller */ |
| msr_info->data = 0; |
| break; |
| case MSR_K7_EVNTSEL0 ... MSR_K7_EVNTSEL3: |
| case MSR_K7_PERFCTR0 ... MSR_K7_PERFCTR3: |
| case MSR_P6_PERFCTR0 ... MSR_P6_PERFCTR1: |
| case MSR_P6_EVNTSEL0 ... MSR_P6_EVNTSEL1: |
| if (kvm_pmu_is_valid_msr(vcpu, msr_info->index)) |
| return kvm_pmu_get_msr(vcpu, msr_info); |
| msr_info->data = 0; |
| break; |
| case MSR_IA32_UCODE_REV: |
| msr_info->data = vcpu->arch.microcode_version; |
| break; |
| case MSR_IA32_ARCH_CAPABILITIES: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_ARCH_CAPABILITIES)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| msr_info->data = vcpu->arch.arch_capabilities; |
| break; |
| case MSR_IA32_PERF_CAPABILITIES: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_PDCM)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| msr_info->data = vcpu->arch.perf_capabilities; |
| break; |
| case MSR_IA32_POWER_CTL: |
| msr_info->data = vcpu->arch.msr_ia32_power_ctl; |
| break; |
| case MSR_IA32_TSC: { |
| /* |
| * Intel SDM states that MSR_IA32_TSC read adds the TSC offset |
| * even when not intercepted. AMD manual doesn't explicitly |
| * state this but appears to behave the same. |
| * |
| * On userspace reads and writes, however, we unconditionally |
| * return L1's TSC value to ensure backwards-compatible |
| * behavior for migration. |
| */ |
| u64 offset, ratio; |
| |
| if (msr_info->host_initiated) { |
| offset = vcpu->arch.l1_tsc_offset; |
| ratio = vcpu->arch.l1_tsc_scaling_ratio; |
| } else { |
| offset = vcpu->arch.tsc_offset; |
| ratio = vcpu->arch.tsc_scaling_ratio; |
| } |
| |
| msr_info->data = kvm_scale_tsc(rdtsc(), ratio) + offset; |
| break; |
| } |
| case MSR_IA32_CR_PAT: |
| msr_info->data = vcpu->arch.pat; |
| break; |
| case MSR_MTRRcap: |
| case MTRRphysBase_MSR(0) ... MSR_MTRRfix4K_F8000: |
| case MSR_MTRRdefType: |
| return kvm_mtrr_get_msr(vcpu, msr_info->index, &msr_info->data); |
| case 0xcd: /* fsb frequency */ |
| msr_info->data = 3; |
| break; |
| /* |
| * MSR_EBC_FREQUENCY_ID |
| * Conservative value valid for even the basic CPU models. |
| * Models 0,1: 000 in bits 23:21 indicating a bus speed of |
| * 100MHz, model 2 000 in bits 18:16 indicating 100MHz, |
| * and 266MHz for model 3, or 4. Set Core Clock |
| * Frequency to System Bus Frequency Ratio to 1 (bits |
| * 31:24) even though these are only valid for CPU |
| * models > 2, however guests may end up dividing or |
| * multiplying by zero otherwise. |
| */ |
| case MSR_EBC_FREQUENCY_ID: |
| msr_info->data = 1 << 24; |
| break; |
| case MSR_IA32_APICBASE: |
| msr_info->data = vcpu->arch.apic_base; |
| break; |
| case APIC_BASE_MSR ... APIC_BASE_MSR + 0xff: |
| return kvm_x2apic_msr_read(vcpu, msr_info->index, &msr_info->data); |
| case MSR_IA32_TSC_DEADLINE: |
| msr_info->data = kvm_get_lapic_tscdeadline_msr(vcpu); |
| break; |
| case MSR_IA32_TSC_ADJUST: |
| msr_info->data = (u64)vcpu->arch.ia32_tsc_adjust_msr; |
| break; |
| case MSR_IA32_MISC_ENABLE: |
| msr_info->data = vcpu->arch.ia32_misc_enable_msr; |
| break; |
| case MSR_IA32_SMBASE: |
| if (!IS_ENABLED(CONFIG_KVM_SMM) || !msr_info->host_initiated) |
| return 1; |
| msr_info->data = vcpu->arch.smbase; |
| break; |
| case MSR_SMI_COUNT: |
| msr_info->data = vcpu->arch.smi_count; |
| break; |
| case MSR_IA32_PERF_STATUS: |
| /* TSC increment by tick */ |
| msr_info->data = 1000ULL; |
| /* CPU multiplier */ |
| msr_info->data |= (((uint64_t)4ULL) << 40); |
| break; |
| case MSR_EFER: |
| msr_info->data = vcpu->arch.efer; |
| break; |
| case MSR_KVM_WALL_CLOCK: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->kvm->arch.wall_clock; |
| break; |
| case MSR_KVM_WALL_CLOCK_NEW: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->kvm->arch.wall_clock; |
| break; |
| case MSR_KVM_SYSTEM_TIME: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->arch.time; |
| break; |
| case MSR_KVM_SYSTEM_TIME_NEW: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_CLOCKSOURCE2)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->arch.time; |
| break; |
| case MSR_KVM_ASYNC_PF_EN: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->arch.apf.msr_en_val; |
| break; |
| case MSR_KVM_ASYNC_PF_INT: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->arch.apf.msr_int_val; |
| break; |
| case MSR_KVM_ASYNC_PF_ACK: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_ASYNC_PF_INT)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = 0; |
| break; |
| case MSR_KVM_STEAL_TIME: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_STEAL_TIME)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->arch.st.msr_val; |
| break; |
| case MSR_KVM_PV_EOI_EN: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_PV_EOI)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->arch.pv_eoi.msr_val; |
| break; |
| case MSR_KVM_POLL_CONTROL: |
| if (!guest_pv_has(vcpu, KVM_FEATURE_POLL_CONTROL)) |
| return KVM_MSR_RET_UNSUPPORTED; |
| |
| msr_info->data = vcpu->arch.msr_kvm_poll_control; |
| break; |
| case MSR_IA32_P5_MC_ADDR: |
| case MSR_IA32_P5_MC_TYPE: |
| case MSR_IA32_MCG_CAP: |
| case MSR_IA32_MCG_CTL: |
| case MSR_IA32_MCG_STATUS: |
| case MSR_IA32_MC0_CTL ... MSR_IA32_MCx_CTL(KVM_MAX_MCE_BANKS) - 1: |
| case MSR_IA32_MC0_CTL2 ... MSR_IA32_MCx_CTL2(KVM_MAX_MCE_BANKS) - 1: |
| return get_msr_mce(vcpu, msr_info->index, &msr_info->data, |
| msr_info->host_initiated); |
| case MSR_IA32_XSS: |
| if (!msr_info->host_initiated && |
| !guest_cpuid_has(vcpu, X86_FEATURE_XSAVES)) |
| return 1; |
| msr_info->data = vcpu->arch.ia32_xss; |
| break; |
| case MSR_K7_CLK_CTL: |
| /* |
| * Provide expected ramp-up count for K7. All other |
| * are set to zero, indicating minimum divisors for |
| * every field. |
| * |
| * This prevents guest kernels on AMD host with CPU |
| * type 6, model 8 and higher from exploding due to |
| * the rdmsr failing. |
| */ |
| msr_info->data = 0x20000000; |
| break; |
| #ifdef CONFIG_KVM_HYPERV |
| case HV_X64_MSR_GUEST_OS_ID ... HV_X64_MSR_SINT15: |
| case HV_X64_MSR_SYNDBG_CONTROL ... HV_X64_MSR_SYNDBG_PENDING_BUFFER: |
| case HV_X64_MSR_SYNDBG_OPTIONS: |
| case HV_X64_MSR_CRASH_P0 ... HV_X64_MSR_CRASH_P4: |
| case HV_X64_MSR_CRASH_CTL: |
| case HV_X64_MSR_STIMER0_CONFIG ... HV_X64_MSR_STIMER3_COUNT: |
| case HV_X64_MSR_REENLIGHTENMENT_CONTROL: |
| case HV_X64_MSR_TSC_EMULATION_CONTROL: |
| case HV_X64_MSR_TSC_EMULATION_STATUS: |
| case HV_X64_MSR_TSC_INVARIANT_CONTROL: |
| return kvm_hv_get_msr_common(vcpu, |
| msr_info->index, &msr_info->data, |
| msr_info->host_initiated); |
| #endif |
| case MSR_IA32_BBL_CR_CTL3: |
| /* This legacy MSR exists but isn't fully documented in current |
| * silicon. It is however accessed by winxp in very narrow |
| * scenarios where it sets bit #19, itself documented as |
| * a "reserved" bit. Best effort attempt to source coherent |
| * read data here should the balance of the register be |
| * interpreted by the guest: |
| * |
| * L2 cache control register 3: 64GB range, 256KB size, |
| * enabled, latency 0x1, configured |
| */ |
| msr_info->data = 0xbe702111; |
| break; |
| case MSR_AMD64_OSVW_ID_LENGTH: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_OSVW)) |
| return 1; |
| msr_info->data = vcpu->arch.osvw.length; |
| break; |
| case MSR_AMD64_OSVW_STATUS: |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_OSVW)) |
| return 1; |
| msr_info->data = vcpu->arch.osvw.status; |
| break; |
| case MSR_PLATFORM_INFO: |
| if (!msr_info->host_initiated && |
| !vcpu->kvm->arch.guest_can_read_msr_platform_info) |
| return 1; |
| msr_info->data = vcpu->arch.msr_platform_info; |
| break; |
| case MSR_MISC_FEATURES_ENABLES: |
| msr_info->data = vcpu->arch.msr_misc_features_enables; |
| break; |
| case MSR_K7_HWCR: |
| msr_info->data = vcpu->arch.msr_hwcr; |
| break; |
| #ifdef CONFIG_X86_64 |
| case MSR_IA32_XFD: |
| if (!msr_info->host_initiated && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_XFD)) |
| return 1; |
| |
| msr_info->data = vcpu->arch.guest_fpu.fpstate->xfd; |
| break; |
| case MSR_IA32_XFD_ERR: |
| if (!msr_info->host_initiated && |
| !guest_cpu_cap_has(vcpu, X86_FEATURE_XFD)) |
| return 1; |
| |
| msr_info->data = vcpu->arch.guest_fpu.xfd_err; |
| break; |
| #endif |
| case MSR_IA32_U_CET: |
| case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: |
| kvm_get_xstate_msr(vcpu, msr_info); |
| break; |
| default: |
| if (kvm_pmu_is_valid_msr(vcpu, msr_info->index)) |
| return kvm_pmu_get_msr(vcpu, msr_info); |
| |
| return KVM_MSR_RET_UNSUPPORTED; |
| } |
| return 0; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_get_msr_common); |
| |
| static int do_get_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) |
| { |
| return kvm_get_msr_ignored_check(vcpu, index, data, true); |
| } |
| |
| static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) |
| { |
| u64 val; |
| |
| /* |
| * Reject writes to immutable feature MSRs if the vCPU model is frozen, |
| * as KVM doesn't support modifying the guest vCPU model on the fly, |
| * e.g. changing the VMX capabilities MSRs while L2 is active is |
| * nonsensical. Allow writes of the same value, e.g. so that userspace |
| * can blindly stuff all MSRs when emulating RESET. |
| */ |
| if (!kvm_can_set_cpuid_and_feature_msrs(vcpu) && |
| kvm_is_immutable_feature_msr(index) && |
| (do_get_msr(vcpu, index, &val) || *data != val)) |
| return -EINVAL; |
| |
| return kvm_set_msr_ignored_check(vcpu, index, *data, true); |
| } |
| |
| /* |
| * Read or write a bunch of msrs. All parameters are kernel addresses. |
| * |
| * @return number of msrs set successfully. |
| */ |
| static int __msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs *msrs, |
| struct kvm_msr_entry *entries, |
| int (*do_msr)(struct kvm_vcpu *vcpu, |
| unsigned index, u64 *data)) |
| { |
| bool fpu_loaded = false; |
| int i; |
| |
| for (i = 0; i < msrs->nmsrs; ++i) { |
| /* |
| * If userspace is accessing one or more XSTATE-managed MSRs, |
| * temporarily load the guest's FPU state so that the guest's |
| * MSR value(s) is resident in hardware and thus can be accessed |
| * via RDMSR/WRMSR. |
| */ |
| if (!fpu_loaded && is_xstate_managed_msr(vcpu, entries[i].index)) { |
| kvm_load_guest_fpu(vcpu); |
| fpu_loaded = true; |
| } |
| if (do_msr(vcpu, entries[i].index, &entries[i].data)) |
| break; |
| } |
| if (fpu_loaded) |
| kvm_put_guest_fpu(vcpu); |
| |
| return i; |
| } |
| |
| /* |
| * Read or write a bunch of msrs. Parameters are user addresses. |
| * |
| * @return number of msrs set successfully. |
| */ |
| static int msr_io(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs, |
| int (*do_msr)(struct kvm_vcpu *vcpu, |
| unsigned index, u64 *data), |
| int writeback) |
| { |
| struct kvm_msrs msrs; |
| struct kvm_msr_entry *entries; |
| unsigned size; |
| int r; |
| |
| r = -EFAULT; |
| if (copy_from_user(&msrs, user_msrs, sizeof(msrs))) |
| goto out; |
| |
| r = -E2BIG; |
| if (msrs.nmsrs >= MAX_IO_MSRS) |
| goto out; |
| |
| size = sizeof(struct kvm_msr_entry) * msrs.nmsrs; |
| entries = memdup_user(user_msrs->entries, size); |
| if (IS_ERR(entries)) { |
| r = PTR_ERR(entries); |
| goto out; |
| } |
| |
| r = __msr_io(vcpu, &msrs, entries, do_msr); |
| |
| if (writeback && copy_to_user(user_msrs->entries, entries, size)) |
| r = -EFAULT; |
| |
| kfree(entries); |
| out: |
| return r; |
| } |
| |
| int kvm_get_feature_msrs(struct kvm_msrs __user *user_msrs) |
| { |
| return msr_io(NULL, user_msrs, do_get_feature_msr, 1); |
| } |
| |
| int kvm_get_msrs(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs) |
| { |
| guard(srcu)(&vcpu->kvm->srcu); |
| |
| return msr_io(vcpu, user_msrs, do_get_msr, 1); |
| } |
| |
| int kvm_set_msrs(struct kvm_vcpu *vcpu, struct kvm_msrs __user *user_msrs) |
| { |
| guard(srcu)(&vcpu->kvm->srcu); |
| |
| return msr_io(vcpu, user_msrs, do_set_msr, 0); |
| } |
| |
| static int kvm_get_one_msr(struct kvm_vcpu *vcpu, u32 msr, u64 __user *user_val) |
| { |
| u64 val; |
| |
| if (do_get_msr(vcpu, msr, &val)) |
| return -EINVAL; |
| |
| if (put_user(val, user_val)) |
| return -EFAULT; |
| |
| return 0; |
| } |
| |
| static int kvm_set_one_msr(struct kvm_vcpu *vcpu, u32 msr, u64 __user *user_val) |
| { |
| u64 val; |
| |
| if (get_user(val, user_val)) |
| return -EFAULT; |
| |
| if (do_set_msr(vcpu, msr, &val)) |
| return -EINVAL; |
| |
| return 0; |
| } |
| |
| struct kvm_x86_reg_id { |
| __u32 index; |
| __u8 type; |
| __u8 rsvd1; |
| __u8 rsvd2:4; |
| __u8 size:4; |
| __u8 x86; |
| }; |
| |
| static int kvm_translate_kvm_reg(struct kvm_vcpu *vcpu, |
| struct kvm_x86_reg_id *reg) |
| { |
| switch (reg->index) { |
| case KVM_REG_GUEST_SSP: |
| /* |
| * FIXME: If host-initiated accesses are ever exempted from |
| * ignore_msrs (in kvm_do_msr_access()), drop this manual check |
| * and rely on KVM's standard checks to reject accesses to regs |
| * that don't exist. |
| */ |
| if (!guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK)) |
| return -EINVAL; |
| |
| reg->type = KVM_X86_REG_TYPE_MSR; |
| reg->index = MSR_KVM_INTERNAL_GUEST_SSP; |
| break; |
| default: |
| return -EINVAL; |
| } |
| return 0; |
| } |
| |
| int kvm_get_set_one_reg(struct kvm_vcpu *vcpu, unsigned int ioctl, |
| void __user *argp) |
| { |
| struct kvm_one_reg one_reg; |
| struct kvm_x86_reg_id *reg; |
| u64 __user *user_val; |
| bool load_fpu; |
| int r; |
| |
| if (copy_from_user(&one_reg, argp, sizeof(one_reg))) |
| return -EFAULT; |
| |
| if ((one_reg.id & KVM_REG_ARCH_MASK) != KVM_REG_X86) |
| return -EINVAL; |
| |
| reg = (struct kvm_x86_reg_id *)&one_reg.id; |
| if (reg->rsvd1 || reg->rsvd2) |
| return -EINVAL; |
| |
| if (reg->type == KVM_X86_REG_TYPE_KVM) { |
| r = kvm_translate_kvm_reg(vcpu, reg); |
| if (r) |
| return r; |
| } |
| |
| if (reg->type != KVM_X86_REG_TYPE_MSR) |
| return -EINVAL; |
| |
| if ((one_reg.id & KVM_REG_SIZE_MASK) != KVM_REG_SIZE_U64) |
| return -EINVAL; |
| |
| guard(srcu)(&vcpu->kvm->srcu); |
| |
| load_fpu = is_xstate_managed_msr(vcpu, reg->index); |
| if (load_fpu) |
| kvm_load_guest_fpu(vcpu); |
| |
| user_val = u64_to_user_ptr(one_reg.addr); |
| if (ioctl == KVM_GET_ONE_REG) |
| r = kvm_get_one_msr(vcpu, reg->index, user_val); |
| else |
| r = kvm_set_one_msr(vcpu, reg->index, user_val); |
| |
| if (load_fpu) |
| kvm_put_guest_fpu(vcpu); |
| return r; |
| } |
| |
| int kvm_get_reg_list(struct kvm_vcpu *vcpu, |
| struct kvm_reg_list __user *user_list) |
| { |
| u64 nr_regs = guest_cpu_cap_has(vcpu, X86_FEATURE_SHSTK) ? 1 : 0; |
| u64 user_nr_regs; |
| |
| if (get_user(user_nr_regs, &user_list->n)) |
| return -EFAULT; |
| |
| if (put_user(nr_regs, &user_list->n)) |
| return -EFAULT; |
| |
| if (user_nr_regs < nr_regs) |
| return -E2BIG; |
| |
| if (nr_regs && |
| put_user(KVM_X86_REG_KVM(KVM_REG_GUEST_SSP), &user_list->reg[0])) |
| return -EFAULT; |
| |
| return 0; |
| } |
| |
| static struct kvm_x86_msr_filter *kvm_alloc_msr_filter(bool default_allow) |
| { |
| struct kvm_x86_msr_filter *msr_filter; |
| |
| msr_filter = kzalloc_obj(*msr_filter, GFP_KERNEL_ACCOUNT); |
| if (!msr_filter) |
| return NULL; |
| |
| msr_filter->default_allow = default_allow; |
| return msr_filter; |
| } |
| |
| void kvm_free_msr_filter(struct kvm_x86_msr_filter *msr_filter) |
| { |
| u32 i; |
| |
| if (!msr_filter) |
| return; |
| |
| for (i = 0; i < msr_filter->count; i++) |
| kfree(msr_filter->ranges[i].bitmap); |
| |
| kfree(msr_filter); |
| } |
| |
| static int kvm_add_msr_filter(struct kvm_x86_msr_filter *msr_filter, |
| struct kvm_msr_filter_range *user_range) |
| { |
| unsigned long *bitmap; |
| size_t bitmap_size; |
| |
| if (!user_range->nmsrs) |
| return 0; |
| |
| if (user_range->flags & ~KVM_MSR_FILTER_RANGE_VALID_MASK) |
| return -EINVAL; |
| |
| if (!user_range->flags) |
| return -EINVAL; |
| |
| bitmap_size = BITS_TO_LONGS(user_range->nmsrs) * sizeof(long); |
| if (!bitmap_size || bitmap_size > KVM_MSR_FILTER_MAX_BITMAP_SIZE) |
| return -EINVAL; |
| |
| bitmap = memdup_user((__user u8*)user_range->bitmap, bitmap_size); |
| if (IS_ERR(bitmap)) |
| return PTR_ERR(bitmap); |
| |
| msr_filter->ranges[msr_filter->count] = (struct msr_bitmap_range) { |
| .flags = user_range->flags, |
| .base = user_range->base, |
| .nmsrs = user_range->nmsrs, |
| .bitmap = bitmap, |
| }; |
| |
| msr_filter->count++; |
| return 0; |
| } |
| |
| int kvm_vm_ioctl_set_msr_filter(struct kvm *kvm, struct kvm_msr_filter *filter) |
| { |
| struct kvm_x86_msr_filter *new_filter, *old_filter; |
| bool default_allow; |
| bool empty = true; |
| int r; |
| u32 i; |
| |
| if (filter->flags & ~KVM_MSR_FILTER_VALID_MASK) |
| return -EINVAL; |
| |
| for (i = 0; i < ARRAY_SIZE(filter->ranges); i++) |
| empty &= !filter->ranges[i].nmsrs; |
| |
| default_allow = !(filter->flags & KVM_MSR_FILTER_DEFAULT_DENY); |
| if (empty && !default_allow) |
| return -EINVAL; |
| |
| new_filter = kvm_alloc_msr_filter(default_allow); |
| if (!new_filter) |
| return -ENOMEM; |
| |
| for (i = 0; i < ARRAY_SIZE(filter->ranges); i++) { |
| r = kvm_add_msr_filter(new_filter, &filter->ranges[i]); |
| if (r) { |
| kvm_free_msr_filter(new_filter); |
| return r; |
| } |
| } |
| |
| mutex_lock(&kvm->lock); |
| old_filter = rcu_replace_pointer(kvm->arch.msr_filter, new_filter, |
| mutex_is_locked(&kvm->lock)); |
| mutex_unlock(&kvm->lock); |
| synchronize_srcu(&kvm->srcu); |
| |
| kvm_free_msr_filter(old_filter); |
| |
| /* |
| * Recalc MSR intercepts as userspace may want to intercept accesses to |
| * MSRs that KVM would otherwise pass through to the guest. |
| */ |
| kvm_make_all_cpus_request(kvm, KVM_REQ_RECALC_INTERCEPTS); |
| |
| return 0; |
| } |
| |
| |
| static void kvm_probe_feature_msr(u32 msr_index) |
| { |
| u64 data; |
| |
| if (kvm_get_feature_msr(NULL, msr_index, &data, true)) |
| return; |
| |
| msr_based_features[num_msr_based_features++] = msr_index; |
| } |
| |
| static void kvm_probe_msr_to_save(u32 msr_index) |
| { |
| u64 dummy; |
| |
| if (rdmsrq_safe(msr_index, &dummy)) |
| return; |
| |
| /* |
| * Even MSRs that are valid in the host may not be exposed to guests in |
| * some cases. |
| */ |
| switch (msr_index) { |
| case MSR_IA32_BNDCFGS: |
| if (!kvm_mpx_supported()) |
| return; |
| break; |
| case MSR_TSC_AUX: |
| if (!kvm_cpu_cap_has(X86_FEATURE_RDTSCP) && |
| !kvm_cpu_cap_has(X86_FEATURE_RDPID)) |
| return; |
| break; |
| case MSR_IA32_UMWAIT_CONTROL: |
| if (!kvm_cpu_cap_has(X86_FEATURE_WAITPKG)) |
| return; |
| break; |
| case MSR_IA32_RTIT_CTL: |
| case MSR_IA32_RTIT_STATUS: |
| if (!kvm_cpu_cap_has(X86_FEATURE_INTEL_PT)) |
| return; |
| break; |
| case MSR_IA32_RTIT_CR3_MATCH: |
| if (!kvm_cpu_cap_has(X86_FEATURE_INTEL_PT) || |
| !intel_pt_validate_hw_cap(PT_CAP_cr3_filtering)) |
| return; |
| break; |
| case MSR_IA32_RTIT_OUTPUT_BASE: |
| case MSR_IA32_RTIT_OUTPUT_MASK: |
| if (!kvm_cpu_cap_has(X86_FEATURE_INTEL_PT) || |
| (!intel_pt_validate_hw_cap(PT_CAP_topa_output) && |
| !intel_pt_validate_hw_cap(PT_CAP_single_range_output))) |
| return; |
| break; |
| case MSR_IA32_RTIT_ADDR0_A ... MSR_IA32_RTIT_ADDR3_B: |
| if (!kvm_cpu_cap_has(X86_FEATURE_INTEL_PT) || |
| (msr_index - MSR_IA32_RTIT_ADDR0_A >= |
| intel_pt_validate_hw_cap(PT_CAP_num_address_ranges) * 2)) |
| return; |
| break; |
| case MSR_ARCH_PERFMON_PERFCTR0 ... |
| MSR_ARCH_PERFMON_PERFCTR0 + KVM_MAX_NR_GP_COUNTERS - 1: |
| if (msr_index - MSR_ARCH_PERFMON_PERFCTR0 >= |
| kvm_pmu_cap.num_counters_gp) |
| return; |
| break; |
| case MSR_ARCH_PERFMON_EVENTSEL0 ... |
| MSR_ARCH_PERFMON_EVENTSEL0 + KVM_MAX_NR_GP_COUNTERS - 1: |
| if (msr_index - MSR_ARCH_PERFMON_EVENTSEL0 >= |
| kvm_pmu_cap.num_counters_gp) |
| return; |
| break; |
| case MSR_ARCH_PERFMON_FIXED_CTR0 ... |
| MSR_ARCH_PERFMON_FIXED_CTR0 + KVM_MAX_NR_FIXED_COUNTERS - 1: |
| if (msr_index - MSR_ARCH_PERFMON_FIXED_CTR0 >= |
| kvm_pmu_cap.num_counters_fixed) |
| return; |
| break; |
| case MSR_AMD64_PERF_CNTR_GLOBAL_CTL: |
| case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS: |
| case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_CLR: |
| case MSR_AMD64_PERF_CNTR_GLOBAL_STATUS_SET: |
| if (!kvm_cpu_cap_has(X86_FEATURE_PERFMON_V2)) |
| return; |
| break; |
| case MSR_IA32_XFD: |
| case MSR_IA32_XFD_ERR: |
| if (!kvm_cpu_cap_has(X86_FEATURE_XFD)) |
| return; |
| break; |
| case MSR_IA32_TSX_CTRL: |
| if (!(kvm_get_arch_capabilities() & ARCH_CAP_TSX_CTRL_MSR)) |
| return; |
| break; |
| case MSR_IA32_XSS: |
| if (!kvm_caps.supported_xss) |
| return; |
| break; |
| case MSR_IA32_U_CET: |
| case MSR_IA32_S_CET: |
| if (!kvm_cpu_cap_has(X86_FEATURE_SHSTK) && |
| !kvm_cpu_cap_has(X86_FEATURE_IBT)) |
| return; |
| break; |
| case MSR_IA32_INT_SSP_TAB: |
| if (!kvm_cpu_cap_has(X86_FEATURE_LM)) |
| return; |
| fallthrough; |
| case MSR_IA32_PL0_SSP ... MSR_IA32_PL3_SSP: |
| if (!kvm_cpu_cap_has(X86_FEATURE_SHSTK)) |
| return; |
| break; |
| default: |
| break; |
| } |
| |
| msrs_to_save[num_msrs_to_save++] = msr_index; |
| } |
| |
| void kvm_init_msr_lists(void) |
| { |
| unsigned i; |
| |
| BUILD_BUG_ON_MSG(KVM_MAX_NR_FIXED_COUNTERS != 3, |
| "Please update the fixed PMCs in msrs_to_save_pmu[]"); |
| |
| num_msrs_to_save = 0; |
| num_emulated_msrs = 0; |
| num_msr_based_features = 0; |
| |
| for (i = 0; i < ARRAY_SIZE(msrs_to_save_base); i++) |
| kvm_probe_msr_to_save(msrs_to_save_base[i]); |
| |
| if (enable_pmu) { |
| for (i = 0; i < ARRAY_SIZE(msrs_to_save_pmu); i++) |
| kvm_probe_msr_to_save(msrs_to_save_pmu[i]); |
| } |
| |
| for (i = 0; i < ARRAY_SIZE(emulated_msrs_all); i++) { |
| if (!kvm_x86_call(has_emulated_msr)(NULL, |
| emulated_msrs_all[i])) |
| continue; |
| |
| emulated_msrs[num_emulated_msrs++] = emulated_msrs_all[i]; |
| } |
| |
| for (i = KVM_FIRST_EMULATED_VMX_MSR; i <= KVM_LAST_EMULATED_VMX_MSR; i++) |
| kvm_probe_feature_msr(i); |
| |
| for (i = 0; i < ARRAY_SIZE(msr_based_features_all_except_vmx); i++) |
| kvm_probe_feature_msr(msr_based_features_all_except_vmx[i]); |
| } |
| |
| int kvm_spec_ctrl_test_value(u64 value) |
| { |
| /* |
| * test that setting IA32_SPEC_CTRL to given value |
| * is allowed by the host processor |
| */ |
| |
| u64 saved_value; |
| unsigned long flags; |
| int ret = 0; |
| |
| local_irq_save(flags); |
| |
| if (rdmsrq_safe(MSR_IA32_SPEC_CTRL, &saved_value)) |
| ret = 1; |
| else if (wrmsrq_safe(MSR_IA32_SPEC_CTRL, value)) |
| ret = 1; |
| else |
| wrmsrq(MSR_IA32_SPEC_CTRL, saved_value); |
| |
| local_irq_restore(flags); |
| |
| return ret; |
| } |
| EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_spec_ctrl_test_value); |