Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/x86/kvm/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 374 kB image not shown  

Quelle  x86.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Kernel-based Virtual Machine driver for Linux
 *
 * derived from drivers/kvm/kvm_main.c
 *
 * Copyright (C) 2006 Qumranet, Inc.
 * Copyright (C) 2008 Qumranet, Inc.
 * Copyright IBM Corporation, 2008
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * Authors:
 *   Avi Kivity   <avi@qumranet.com>
 *   Yaniv Kamay  <yaniv@qumranet.com>
 *   Amit Shah    <amit.shah@qumranet.com>
 *   Ben-Ami Yassour <benami@il.ibm.com>
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kvm_host.h>
#include "irq.h"
#include "ioapic.h"
#include "mmu.h"
#include "i8254.h"
#include "tss.h"
#include "kvm_cache_regs.h"
#include "kvm_emulate.h"
#include "mmu/page_track.h"
#include "x86.h"
#include "cpuid.h"
#include "pmu.h"
#include "hyperv.h"
#include "lapic.h"
#include "xen.h"
#include "smm.h"

#include <linux/clocksource.h>
#include <linux/interrupt.h>
#include <linux/kvm.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
#include <linux/export.h>
#include <linux/moduleparam.h>
#include <linux/mman.h>
#include <linux/highmem.h>
#include <linux/iommu.h>
#include <linux/cpufreq.h>
#include <linux/user-return-notifier.h>
#include <linux/srcu.h>
#include <linux/slab.h>
#include <linux/perf_event.h>
#include <linux/uaccess.h>
#include <linux/hash.h>
#include <linux/pci.h>
#include <linux/timekeeper_internal.h>
#include <linux/pvclock_gtod.h>
#include <linux/kvm_irqfd.h>
#include <linux/irqbypass.h>
#include <linux/sched/stat.h>
#include <linux/sched/isolation.h>
#include <linux/mem_encrypt.h>
#include <linux/entry-kvm.h>
#include <linux/suspend.h>
#include <linux/smp.h>

#include <trace/events/ipi.h>
#include <trace/events/kvm.h>

#include <asm/debugreg.h>
#include <asm/msr.h>
#include <asm/desc.h>
#include <asm/mce.h>
#include <asm/pkru.h>
#include <linux/kernel_stat.h>
#include <asm/fpu/api.h>
#include <asm/fpu/xcr.h>
#include <asm/fpu/xstate.h>
#include <asm/pvclock.h>
#include <asm/div64.h>
#include <asm/irq_remapping.h>
#include <asm/mshyperv.h>
#include <asm/hypervisor.h>
#include <asm/tlbflush.h>
#include <asm/intel_pt.h>
#include <asm/emulate_prefix.h>
#include <asm/sgx.h>
#include <clocksource/hyperv_timer.h>

#define CREATE_TRACE_POINTS
#include "trace.h"

#define MAX_IO_MSRS 256

/*
 * Note, kvm_caps fields should *never* have default values, all fields must be
 * recomputed from scratch during vendor module load, e.g. to account for a
 * vendor module being reloaded with different module parameters.
 */

struct kvm_caps kvm_caps __read_mostly;
EXPORT_SYMBOL_GPL(kvm_caps);

struct kvm_host_values kvm_host __read_mostly;
EXPORT_SYMBOL_GPL(kvm_host);

#define  ERR_PTR_USR(e)  ((void __user *)ERR_PTR(e))

#define emul_to_vcpu(ctxt) \
 ((struct kvm_vcpu *)(ctxt)->vcpu)

/* EFER defaults:
 * - enable syscall per default because its emulated by KVM
 * - enable LME and LMA per default on 64 bit KVM
 */

#ifdef CONFIG_X86_64
static
u64 __read_mostly efer_reserved_bits = ~((u64)(EFER_SCE | EFER_LME | EFER_LMA));
#else
static u64 __read_mostly efer_reserved_bits = ~((u64)EFER_SCE);
#endif

#define KVM_EXIT_HYPERCALL_VALID_MASK (1 << KVM_HC_MAP_GPA_RANGE)

#define KVM_CAP_PMU_VALID_MASK KVM_PMU_CAP_DISABLE

#define KVM_X2APIC_API_VALID_FLAGS (KVM_X2APIC_API_USE_32BIT_IDS | \
                                    KVM_X2APIC_API_DISABLE_BROADCAST_QUIRK)

static void update_cr8_intercept(struct kvm_vcpu *vcpu);
static void process_nmi(struct kvm_vcpu *vcpu);
static void __kvm_set_rflags(struct kvm_vcpu *vcpu, unsigned long rflags);
static void store_regs(struct kvm_vcpu *vcpu);
static int sync_regs(struct kvm_vcpu *vcpu);
static int kvm_vcpu_do_singlestep(struct kvm_vcpu *vcpu);

static int __set_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);
static void __get_sregs2(struct kvm_vcpu *vcpu, struct kvm_sregs2 *sregs2);

static DEFINE_MUTEX(vendor_module_lock);
struct kvm_x86_ops kvm_x86_ops __read_mostly;

#define KVM_X86_OP(func)          \
 DEFINE_STATIC_CALL_NULL(kvm_x86_##func,        \
    *(((struct kvm_x86_ops *)0)->func));
#define KVM_X86_OP_OPTIONAL KVM_X86_OP
#define KVM_X86_OP_OPTIONAL_RET0 KVM_X86_OP
#include <asm/kvm-x86-ops.h>
EXPORT_STATIC_CALL_GPL(kvm_x86_get_cs_db_l_bits);
EXPORT_STATIC_CALL_GPL(kvm_x86_cache_reg);

static 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_GPL(report_ignored_msrs);

unsigned int min_timer_period_us = 200;
module_param(min_timer_period_us, uint, 0644);

static bool __read_mostly kvmclock_periodic_sync = true;
module_param(kvmclock_periodic_sync, bool, 0444);

/* tsc tolerance in parts per million - default to 1/2 of the NTP threshold */
static u32 __read_mostly tsc_tolerance_ppm = 250;
module_param(tsc_tolerance_ppm, uint, 0644);

static bool __read_mostly vector_hashing = true;
module_param(vector_hashing, bool, 0444);

bool __read_mostly enable_vmware_backdoor = false;
module_param(enable_vmware_backdoor, bool, 0444);
EXPORT_SYMBOL_GPL(enable_vmware_backdoor);

/*
 * Flags to manipulate forced emulation behavior (any non-zero value will
 * enable forced emulation).
 */

#define KVM_FEP_CLEAR_RFLAGS_RF BIT(1)
static int __read_mostly force_emulation_prefix;
module_param(force_emulation_prefix, int, 0644);

int __read_mostly pi_inject_timer = -1;
module_param(pi_inject_timer, bint, 0644);

/* Enable/disable PMU virtualization */
bool __read_mostly enable_pmu = true;
EXPORT_SYMBOL_GPL(enable_pmu);
module_param(enable_pmu, bool, 0444);

bool __read_mostly eager_page_split = true;
module_param(eager_page_split, bool, 0644);

/* Enable/disable SMT_RSB bug mitigation */
static bool __read_mostly mitigate_smt_rsb;
module_param(mitigate_smt_rsb, bool, 0444);

/*
 * 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_GPL(kvm_nr_uret_msrs);
static u32 __read_mostly kvm_uret_msrs_list[KVM_MAX_NR_USER_RETURN_MSRS];
static struct kvm_user_return_msrs __percpu *user_return_msrs;

#define KVM_SUPPORTED_XCR0     (XFEATURE_MASK_FP | XFEATURE_MASK_SSE \
    | XFEATURE_MASK_YMM | XFEATURE_MASK_BNDREGS \
    | XFEATURE_MASK_BNDCSR | XFEATURE_MASK_AVX512 \
    | XFEATURE_MASK_PKRU | XFEATURE_MASK_XTILE)

bool __read_mostly allow_smaller_maxphyaddr = 0;
EXPORT_SYMBOL_GPL(allow_smaller_maxphyaddr);

bool __read_mostly enable_apicv = true;
EXPORT_SYMBOL_GPL(enable_apicv);

bool __read_mostly enable_ipiv = true;
EXPORT_SYMBOL_GPL(enable_ipiv);

bool __read_mostly enable_device_posted_irqs = true;
EXPORT_SYMBOL_GPL(enable_device_posted_irqs);

const struct _kvm_stats_desc kvm_vm_stats_desc[] = {
 KVM_GENERIC_VM_STATS(),
 STATS_DESC_COUNTER(VM, mmu_shadow_zapped),
 STATS_DESC_COUNTER(VM, mmu_pte_write),
 STATS_DESC_COUNTER(VM, mmu_pde_zapped),
 STATS_DESC_COUNTER(VM, mmu_flooded),
 STATS_DESC_COUNTER(VM, mmu_recycled),
 STATS_DESC_COUNTER(VM, mmu_cache_miss),
 STATS_DESC_ICOUNTER(VM, mmu_unsync),
 STATS_DESC_ICOUNTER(VM, pages_4k),
 STATS_DESC_ICOUNTER(VM, pages_2m),
 STATS_DESC_ICOUNTER(VM, pages_1g),
 STATS_DESC_ICOUNTER(VM, nx_lpage_splits),
 STATS_DESC_PCOUNTER(VM, max_mmu_rmap_size),
 STATS_DESC_PCOUNTER(VM, max_mmu_page_hash_collisions)
};

const struct kvm_stats_header kvm_vm_stats_header = {
 .name_size = KVM_STATS_NAME_SIZE,
 .num_desc = ARRAY_SIZE(kvm_vm_stats_desc),
 .id_offset = sizeof(struct kvm_stats_header),
 .desc_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE,
 .data_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE +
         sizeof(kvm_vm_stats_desc),
};

const struct _kvm_stats_desc kvm_vcpu_stats_desc[] = {
 KVM_GENERIC_VCPU_STATS(),
 STATS_DESC_COUNTER(VCPU, pf_taken),
 STATS_DESC_COUNTER(VCPU, pf_fixed),
 STATS_DESC_COUNTER(VCPU, pf_emulate),
 STATS_DESC_COUNTER(VCPU, pf_spurious),
 STATS_DESC_COUNTER(VCPU, pf_fast),
 STATS_DESC_COUNTER(VCPU, pf_mmio_spte_created),
 STATS_DESC_COUNTER(VCPU, pf_guest),
 STATS_DESC_COUNTER(VCPU, tlb_flush),
 STATS_DESC_COUNTER(VCPU, invlpg),
 STATS_DESC_COUNTER(VCPU, exits),
 STATS_DESC_COUNTER(VCPU, io_exits),
 STATS_DESC_COUNTER(VCPU, mmio_exits),
 STATS_DESC_COUNTER(VCPU, signal_exits),
 STATS_DESC_COUNTER(VCPU, irq_window_exits),
 STATS_DESC_COUNTER(VCPU, nmi_window_exits),
 STATS_DESC_COUNTER(VCPU, l1d_flush),
 STATS_DESC_COUNTER(VCPU, halt_exits),
 STATS_DESC_COUNTER(VCPU, request_irq_exits),
 STATS_DESC_COUNTER(VCPU, irq_exits),
 STATS_DESC_COUNTER(VCPU, host_state_reload),
 STATS_DESC_COUNTER(VCPU, fpu_reload),
 STATS_DESC_COUNTER(VCPU, insn_emulation),
 STATS_DESC_COUNTER(VCPU, insn_emulation_fail),
 STATS_DESC_COUNTER(VCPU, hypercalls),
 STATS_DESC_COUNTER(VCPU, irq_injections),
 STATS_DESC_COUNTER(VCPU, nmi_injections),
 STATS_DESC_COUNTER(VCPU, req_event),
 STATS_DESC_COUNTER(VCPU, nested_run),
 STATS_DESC_COUNTER(VCPU, directed_yield_attempted),
 STATS_DESC_COUNTER(VCPU, directed_yield_successful),
 STATS_DESC_COUNTER(VCPU, preemption_reported),
 STATS_DESC_COUNTER(VCPU, preemption_other),
 STATS_DESC_IBOOLEAN(VCPU, guest_mode),
 STATS_DESC_COUNTER(VCPU, notify_window_exits),
};

const struct kvm_stats_header kvm_vcpu_stats_header = {
 .name_size = KVM_STATS_NAME_SIZE,
 .num_desc = ARRAY_SIZE(kvm_vcpu_stats_desc),
 .id_offset = sizeof(struct kvm_stats_header),
 .desc_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE,
 .data_offset = sizeof(struct kvm_stats_header) + KVM_STATS_NAME_SIZE +
         sizeof(kvm_vcpu_stats_desc),
};

static struct kmem_cache *x86_emulator_cache;

/*
 * 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,
};

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;

/*
 * 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;
}

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 struct kmem_cache *kvm_alloc_emulator_cache(void)
{
 unsigned int useroffset = offsetof(struct x86_emulate_ctxt, src);
 unsigned int size = sizeof(struct x86_emulate_ctxt);

 return kmem_cache_create_usercopy("x86_emulator", size,
       __alignof__(struct x86_emulate_ctxt),
       SLAB_ACCOUNT, useroffset,
       size - useroffset, NULL);
}

static int emulator_fix_hypercall(struct x86_emulate_ctxt *ctxt);

static inline void kvm_async_pf_hash_reset(struct kvm_vcpu *vcpu)
{
 int i;
 for (i = 0; i < ASYNC_PF_PER_VCPU; i++)
  vcpu->arch.apf.gfns[i] = ~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;
 unsigned long flags;

 /*
 * Disabling irqs at this point since the following code could be
 * interrupted and executed through kvm_arch_disable_virtualization_cpu()
 */

 local_irq_save(flags);
 if (msrs->registered) {
  msrs->registered = false;
  user_return_notifier_unregister(urn);
 }
 local_irq_restore(flags);
 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_GPL(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_GPL(kvm_find_user_return_msr);

static 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_GPL(kvm_set_user_return_msr);

void kvm_user_return_msr_update_cache(unsigned int slot, u64 value)
{
 struct kvm_user_return_msrs *msrs = this_cpu_ptr(user_return_msrs);

 msrs->values[slot].curr = value;
 kvm_user_return_register_notifier(msrs);
}
EXPORT_SYMBOL_GPL(kvm_user_return_msr_update_cache);

u64 kvm_get_user_return_msr(unsigned int slot)
{
 return this_cpu_ptr(user_return_msrs)->values[slot].curr;
}
EXPORT_SYMBOL_GPL(kvm_get_user_return_msr);

static 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);
}

/*
 * Handle a fault on a hardware virtualization (VMX or SVM) instruction.
 *
 * Hardware virtualization extension instructions may fault if a reboot turns
 * off virtualization while processes are running.  Usually after catching the
 * fault we just panic; during reboot instead the instruction is ignored.
 */

noinstr void kvm_spurious_fault(void)
{
 /* Fault while not rebooting.  We want the trace. */
 BUG_ON(!kvm_rebooting);
}
EXPORT_SYMBOL_GPL(kvm_spurious_fault);

#define EXCPT_BENIGN  0
#define EXCPT_CONTRIBUTORY 1
#define EXCPT_PF  2

static int exception_class(int vector)
{
 switch (vector) {
 case PF_VECTOR:
  return EXCPT_PF;
 case DE_VECTOR:
 case TS_VECTOR:
 case NP_VECTOR:
 case SS_VECTOR:
 case GP_VECTOR:
  return EXCPT_CONTRIBUTORY;
 default:
  break;
 }
 return EXCPT_BENIGN;
}

#define EXCPT_FAULT  0
#define EXCPT_TRAP  1
#define EXCPT_ABORT  2
#define EXCPT_INTERRUPT  3
#define EXCPT_DB  4

static int exception_type(int vector)
{
 unsigned int mask;

 if (WARN_ON(vector > 31 || vector == NMI_VECTOR))
  return EXCPT_INTERRUPT;

 mask = 1 << vector;

 /*
 * #DBs can be trap-like or fault-like, the caller must check other CPU
 * state, e.g. DR6, to determine whether a #DB is a trap or fault.
 */

 if (mask & (1 << DB_VECTOR))
  return EXCPT_DB;

 if (mask & ((1 << BP_VECTOR) | (1 << OF_VECTOR)))
  return EXCPT_TRAP;

 if (mask & ((1 << DF_VECTOR) | (1 << MC_VECTOR)))
  return EXCPT_ABORT;

 /* Reserved exceptions will result in fault */
 return EXCPT_FAULT;
}

void kvm_deliver_exception_payload(struct kvm_vcpu *vcpu,
       struct kvm_queued_exception *ex)
{
 if (!ex->has_payload)
  return;

 switch (ex->vector) {
 case DB_VECTOR:
  /*
 * "Certain debug exceptions may clear bit 0-3.  The
 * remaining contents of the DR6 register are never
 * cleared by the processor".
 */

  vcpu->arch.dr6 &= ~DR_TRAP_BITS;
  /*
 * In order to reflect the #DB exception payload in guest
 * dr6, three components need to be considered: active low
 * bit, FIXED_1 bits and active high bits (e.g. DR6_BD,
 * DR6_BS and DR6_BT)
 * DR6_ACTIVE_LOW contains the FIXED_1 and active low bits.
 * In the target guest dr6:
 * FIXED_1 bits should always be set.
 * Active low bits should be cleared if 1-setting in payload.
 * Active high bits should be set if 1-setting in payload.
 *
 * Note, the payload is compatible with the pending debug
 * exceptions/exit qualification under VMX, that active_low bits
 * are active high in payload.
 * So they need to be flipped for DR6.
 */

  vcpu->arch.dr6 |= DR6_ACTIVE_LOW;
  vcpu->arch.dr6 |= ex->payload;
  vcpu->arch.dr6 ^= ex->payload & DR6_ACTIVE_LOW;

  /*
 * The #DB payload is defined as compatible with the 'pending
 * debug exceptions' field under VMX, not DR6. While bit 12 is
 * defined in the 'pending debug exceptions' field (enabled
 * breakpoint), it is reserved and must be zero in DR6.
 */

  vcpu->arch.dr6 &= ~BIT(12);
  break;
 case PF_VECTOR:
  vcpu->arch.cr2 = ex->payload;
  break;
 }

 ex->has_payload = false;
 ex->payload = 0;
}
EXPORT_SYMBOL_GPL(kvm_deliver_exception_payload);

static void kvm_queue_exception_vmexit(struct kvm_vcpu *vcpu, unsigned int vector,
           bool has_error_code, u32 error_code,
           bool has_payload, unsigned long payload)
{
 struct kvm_queued_exception *ex = &vcpu->arch.exception_vmexit;

 ex->vector = vector;
 ex->injected = false;
 ex->pending = true;
 ex->has_error_code = has_error_code;
 ex->error_code = error_code;
 ex->has_payload = has_payload;
 ex->payload = payload;
}

static void kvm_multiple_exception(struct kvm_vcpu *vcpu, unsigned int nr,
       bool has_error, u32 error_code,
       bool has_payload, unsigned long payload)
{
 u32 prev_nr;
 int class1, class2;

 kvm_make_request(KVM_REQ_EVENT, vcpu);

 /*
 * If the exception is destined for L2, morph it to a VM-Exit if L1
 * wants to intercept the exception.
 */

 if (is_guest_mode(vcpu) &&
     kvm_x86_ops.nested_ops->is_exception_vmexit(vcpu, nr, error_code)) {
  kvm_queue_exception_vmexit(vcpu, nr, has_error, error_code,
        has_payload, payload);
  return;
 }

 if (!vcpu->arch.exception.pending && !vcpu->arch.exception.injected) {
 queue:
  vcpu->arch.exception.pending = true;
  vcpu->arch.exception.injected = false;

  vcpu->arch.exception.has_error_code = has_error;
  vcpu->arch.exception.vector = nr;
  vcpu->arch.exception.error_code = error_code;
  vcpu->arch.exception.has_payload = has_payload;
  vcpu->arch.exception.payload = payload;
  if (!is_guest_mode(vcpu))
   kvm_deliver_exception_payload(vcpu,
            &vcpu->arch.exception);
  return;
 }

 /* to check exception */
 prev_nr = vcpu->arch.exception.vector;
 if (prev_nr == DF_VECTOR) {
  /* triple fault -> shutdown */
  kvm_make_request(KVM_REQ_TRIPLE_FAULT, vcpu);
  return;
 }
 class1 = exception_class(prev_nr);
 class2 = exception_class(nr);
 if ((class1 == EXCPT_CONTRIBUTORY && class2 == EXCPT_CONTRIBUTORY) ||
     (class1 == EXCPT_PF && class2 != EXCPT_BENIGN)) {
  /*
 * Synthesize #DF.  Clear the previously injected or pending
 * exception so as not to incorrectly trigger shutdown.
 */

  vcpu->arch.exception.injected = false;
  vcpu->arch.exception.pending = false;

  kvm_queue_exception_e(vcpu, DF_VECTOR, 0);
 } else {
  /* replace previous exception with a new one in a hope
   that instruction re-execution will regenerate lost
   exception */

  goto queue;
 }
}

void kvm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr)
{
 kvm_multiple_exception(vcpu, nr, false, 0, false, 0);
}
EXPORT_SYMBOL_GPL(kvm_queue_exception);


void kvm_queue_exception_p(struct kvm_vcpu *vcpu, unsigned nr,
      unsigned long payload)
{
 kvm_multiple_exception(vcpu, nr, false, 0, true, payload);
}
EXPORT_SYMBOL_GPL(kvm_queue_exception_p);

static void kvm_queue_exception_e_p(struct kvm_vcpu *vcpu, unsigned nr,
        u32 error_code, unsigned long payload)
{
 kvm_multiple_exception(vcpu, nr, true, error_code, true, payload);
}

void kvm_requeue_exception(struct kvm_vcpu *vcpu, unsigned int nr,
      bool has_error_code, u32 error_code)
{

 /*
 * On VM-Entry, an exception can be pending if and only if event
 * injection was blocked by nested_run_pending.  In that case, however,
 * vcpu_enter_guest() requests an immediate exit, and the guest
 * shouldn't proceed far enough to need reinjection.
 */

 WARN_ON_ONCE(kvm_is_exception_pending(vcpu));

 /*
 * Do not check for interception when injecting an event for L2, as the
 * exception was checked for intercept when it was original queued, and
 * re-checking is incorrect if _L1_ injected the exception, in which
 * case it's exempt from interception.
 */

 kvm_make_request(KVM_REQ_EVENT, vcpu);

 vcpu->arch.exception.injected = true;
 vcpu->arch.exception.has_error_code = has_error_code;
 vcpu->arch.exception.vector = nr;
 vcpu->arch.exception.error_code = error_code;
 vcpu->arch.exception.has_payload = false;
 vcpu->arch.exception.payload = 0;
}
EXPORT_SYMBOL_GPL(kvm_requeue_exception);

int kvm_complete_insn_gp(struct kvm_vcpu *vcpu, int err)
{
 if (err)
  kvm_inject_gp(vcpu, 0);
 else
  return kvm_skip_emulated_instruction(vcpu);

 return 1;
}
EXPORT_SYMBOL_GPL(kvm_complete_insn_gp);

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);
}

void kvm_inject_page_fault(struct kvm_vcpu *vcpu, struct x86_exception *fault)
{
 ++vcpu->stat.pf_guest;

 /*
 * Async #PF in L2 is always forwarded to L1 as a VM-Exit regardless of
 * whether or not L1 wants to intercept "regular" #PF.
 */

 if (is_guest_mode(vcpu) && fault->async_page_fault)
  kvm_queue_exception_vmexit(vcpu, PF_VECTOR,
        true, fault->error_code,
        true, fault->address);
 else
  kvm_queue_exception_e_p(vcpu, PF_VECTOR, fault->error_code,
     fault->address);
}

void kvm_inject_emulated_page_fault(struct kvm_vcpu *vcpu,
        struct x86_exception *fault)
{
 struct kvm_mmu *fault_mmu;
 WARN_ON_ONCE(fault->vector != PF_VECTOR);

 fault_mmu = fault->nested_page_fault ? vcpu->arch.mmu :
            vcpu->arch.walk_mmu;

 /*
 * Invalidate the TLB entry for the faulting address, if it exists,
 * else the access will fault indefinitely (and to emulate hardware).
 */

 if ((fault->error_code & PFERR_PRESENT_MASK) &&
     !(fault->error_code & PFERR_RSVD_MASK))
  kvm_mmu_invalidate_addr(vcpu, fault_mmu, fault->address,
     KVM_MMU_ROOT_CURRENT);

 fault_mmu->inject_page_fault(vcpu, fault);
}
EXPORT_SYMBOL_GPL(kvm_inject_emulated_page_fault);

void kvm_inject_nmi(struct kvm_vcpu *vcpu)
{
 atomic_inc(&vcpu->arch.nmi_queued);
 kvm_make_request(KVM_REQ_NMI, vcpu);
}

void kvm_queue_exception_e(struct kvm_vcpu *vcpu, unsigned nr, u32 error_code)
{
 kvm_multiple_exception(vcpu, nr, true, error_code, false, 0);
}
EXPORT_SYMBOL_GPL(kvm_queue_exception_e);

/*
 * Checks if cpl <= required_cpl; if true, return true.  Otherwise queue
 * a #GP and return false.
 */

bool kvm_require_cpl(struct kvm_vcpu *vcpu, int required_cpl)
{
 if (kvm_x86_call(get_cpl)(vcpu) <= required_cpl)
  return true;
 kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
 return false;
}

bool kvm_require_dr(struct kvm_vcpu *vcpu, int dr)
{
 if ((dr != 4 && dr != 5) || !kvm_is_cr4_bit_set(vcpu, X86_CR4_DE))
  return true;

 kvm_queue_exception(vcpu, UD_VECTOR);
 return false;
}
EXPORT_SYMBOL_GPL(kvm_require_dr);

static inline u64 pdptr_rsvd_bits(struct kvm_vcpu *vcpu)
{
 return vcpu->arch.reserved_gpa_bits | rsvd_bits(5, 8) | rsvd_bits(1, 2);
}

/*
 * Load the pae pdptrs.  Return 1 if they are all valid, 0 otherwise.
 */

int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
{
 struct kvm_mmu *mmu = vcpu->arch.walk_mmu;
 gfn_t pdpt_gfn = cr3 >> PAGE_SHIFT;
 gpa_t real_gpa;
 int i;
 int ret;
 u64 pdpte[ARRAY_SIZE(mmu->pdptrs)];

 /*
 * If the MMU is nested, CR3 holds an L2 GPA and needs to be translated
 * to an L1 GPA.
 */

 real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn),
         PFERR_USER_MASK | PFERR_WRITE_MASK, NULL);
 if (real_gpa == INVALID_GPA)
  return 0;

 /* Note the offset, PDPTRs are 32 byte aligned when using PAE paging. */
 ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(real_gpa), pdpte,
           cr3 & GENMASK(11, 5), sizeof(pdpte));
 if (ret < 0)
  return 0;

 for (i = 0; i < ARRAY_SIZE(pdpte); ++i) {
  if ((pdpte[i] & PT_PRESENT_MASK) &&
      (pdpte[i] & pdptr_rsvd_bits(vcpu))) {
   return 0;
  }
 }

 /*
 * Marking VCPU_EXREG_PDPTR dirty doesn't work for !tdp_enabled.
 * Shadow page roots need to be reconstructed instead.
 */

 if (!tdp_enabled && memcmp(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs)))
  kvm_mmu_free_roots(vcpu->kvm, mmu, KVM_MMU_ROOT_CURRENT);

 memcpy(mmu->pdptrs, pdpte, sizeof(mmu->pdptrs));
 kvm_register_mark_dirty(vcpu, VCPU_EXREG_PDPTR);
 kvm_make_request(KVM_REQ_LOAD_MMU_PGD, vcpu);
 vcpu->arch.pdptrs_from_userspace = false;

 return 1;
}
EXPORT_SYMBOL_GPL(load_pdptrs);

static bool kvm_is_valid_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
#ifdef CONFIG_X86_64
 if (cr0 & 0xffffffff00000000UL)
  return false;
#endif

 if ((cr0 & X86_CR0_NW) && !(cr0 & X86_CR0_CD))
  return false;

 if ((cr0 & X86_CR0_PG) && !(cr0 & X86_CR0_PE))
  return false;

 return kvm_x86_call(is_valid_cr0)(vcpu, cr0);
}

void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned long cr0)
{
 /*
 * CR0.WP is incorporated into the MMU role, but only for non-nested,
 * indirect shadow MMUs.  If paging is disabled, no updates are needed
 * as there are no permission bits to emulate.  If TDP is enabled, the
 * MMU's metadata needs to be updated, e.g. so that emulating guest
 * translations does the right thing, but there's no need to unload the
 * root as CR0.WP doesn't affect SPTEs.
 */

 if ((cr0 ^ old_cr0) == X86_CR0_WP) {
  if (!(cr0 & X86_CR0_PG))
   return;

  if (tdp_enabled) {
   kvm_init_mmu(vcpu);
   return;
  }
 }

 if ((cr0 ^ old_cr0) & X86_CR0_PG) {
  kvm_clear_async_pf_completion_queue(vcpu);
  kvm_async_pf_hash_reset(vcpu);

  /*
 * Clearing CR0.PG is defined to flush the TLB from the guest's
 * perspective.
 */

  if (!(cr0 & X86_CR0_PG))
   kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
 }

 if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS)
  kvm_mmu_reset_context(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_post_set_cr0);

int kvm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
{
 unsigned long old_cr0 = kvm_read_cr0(vcpu);

 if (!kvm_is_valid_cr0(vcpu, cr0))
  return 1;

 cr0 |= X86_CR0_ET;

 /* Write to CR0 reserved bits are ignored, even on Intel. */
 cr0 &= ~CR0_RESERVED_BITS;

#ifdef CONFIG_X86_64
 if ((vcpu->arch.efer & EFER_LME) && !is_paging(vcpu) &&
     (cr0 & X86_CR0_PG)) {
  int cs_db, cs_l;

  if (!is_pae(vcpu))
   return 1;
  kvm_x86_call(get_cs_db_l_bits)(vcpu, &cs_db, &cs_l);
  if (cs_l)
   return 1;
 }
#endif
 if (!(vcpu->arch.efer & EFER_LME) && (cr0 & X86_CR0_PG) &&
     is_pae(vcpu) && ((cr0 ^ old_cr0) & X86_CR0_PDPTR_BITS) &&
     !load_pdptrs(vcpu, kvm_read_cr3(vcpu)))
  return 1;

 if (!(cr0 & X86_CR0_PG) &&
     (is_64_bit_mode(vcpu) || kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE)))
  return 1;

 kvm_x86_call(set_cr0)(vcpu, cr0);

 kvm_post_set_cr0(vcpu, old_cr0, cr0);

 return 0;
}
EXPORT_SYMBOL_GPL(kvm_set_cr0);

void kvm_lmsw(struct kvm_vcpu *vcpu, unsigned long msw)
{
 (void)kvm_set_cr0(vcpu, kvm_read_cr0_bits(vcpu, ~0x0eul) | (msw & 0x0f));
}
EXPORT_SYMBOL_GPL(kvm_lmsw);

void kvm_load_guest_xsave_state(struct kvm_vcpu *vcpu)
{
 if (vcpu->arch.guest_state_protected)
  return;

 if (kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE)) {

  if (vcpu->arch.xcr0 != kvm_host.xcr0)
   xsetbv(XCR_XFEATURE_ENABLED_MASK, vcpu->arch.xcr0);

  if (guest_cpu_cap_has(vcpu, X86_FEATURE_XSAVES) &&
      vcpu->arch.ia32_xss != kvm_host.xss)
   wrmsrq(MSR_IA32_XSS, vcpu->arch.ia32_xss);
 }

 if (cpu_feature_enabled(X86_FEATURE_PKU) &&
     vcpu->arch.pkru != vcpu->arch.host_pkru &&
     ((vcpu->arch.xcr0 & XFEATURE_MASK_PKRU) ||
      kvm_is_cr4_bit_set(vcpu, X86_CR4_PKE)))
  wrpkru(vcpu->arch.pkru);
}
EXPORT_SYMBOL_GPL(kvm_load_guest_xsave_state);

void kvm_load_host_xsave_state(struct kvm_vcpu *vcpu)
{
 if (vcpu->arch.guest_state_protected)
  return;

 if (cpu_feature_enabled(X86_FEATURE_PKU) &&
     ((vcpu->arch.xcr0 & XFEATURE_MASK_PKRU) ||
      kvm_is_cr4_bit_set(vcpu, X86_CR4_PKE))) {
  vcpu->arch.pkru = rdpkru();
  if (vcpu->arch.pkru != vcpu->arch.host_pkru)
   wrpkru(vcpu->arch.host_pkru);
 }

 if (kvm_is_cr4_bit_set(vcpu, X86_CR4_OSXSAVE)) {

  if (vcpu->arch.xcr0 != kvm_host.xcr0)
   xsetbv(XCR_XFEATURE_ENABLED_MASK, kvm_host.xcr0);

  if (guest_cpu_cap_has(vcpu, X86_FEATURE_XSAVES) &&
      vcpu->arch.ia32_xss != kvm_host.xss)
   wrmsrq(MSR_IA32_XSS, kvm_host.xss);
 }

}
EXPORT_SYMBOL_GPL(kvm_load_host_xsave_state);

#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

static int __kvm_set_xcr(struct kvm_vcpu *vcpu, u32 index, u64 xcr)
{
 u64 xcr0 = xcr;
 u64 old_xcr0 = vcpu->arch.xcr0;
 u64 valid_bits;

 /* Only support XCR_XFEATURE_ENABLED_MASK(xcr0) now  */
 if (index != XCR_XFEATURE_ENABLED_MASK)
  return 1;
 if (!(xcr0 & XFEATURE_MASK_FP))
  return 1;
 if ((xcr0 & XFEATURE_MASK_YMM) && !(xcr0 & XFEATURE_MASK_SSE))
  return 1;

 /*
 * Do not allow the guest to set bits that we do not support
 * saving.  However, xcr0 bit 0 is always set, even if the
 * emulated CPU does not support XSAVE (see kvm_vcpu_reset()).
 */

 valid_bits = vcpu->arch.guest_supported_xcr0 | XFEATURE_MASK_FP;
 if (xcr0 & ~valid_bits)
  return 1;

 if ((!(xcr0 & XFEATURE_MASK_BNDREGS)) !=
     (!(xcr0 & XFEATURE_MASK_BNDCSR)))
  return 1;

 if (xcr0 & XFEATURE_MASK_AVX512) {
  if (!(xcr0 & XFEATURE_MASK_YMM))
   return 1;
  if ((xcr0 & XFEATURE_MASK_AVX512) != XFEATURE_MASK_AVX512)
   return 1;
 }

 if ((xcr0 & XFEATURE_MASK_XTILE) &&
     ((xcr0 & XFEATURE_MASK_XTILE) != XFEATURE_MASK_XTILE))
  return 1;

 vcpu->arch.xcr0 = xcr0;

 if ((xcr0 ^ old_xcr0) & XFEATURE_MASK_EXTEND)
  vcpu->arch.cpuid_dynamic_bits_dirty = true;
 return 0;
}

int kvm_emulate_xsetbv(struct kvm_vcpu *vcpu)
{
 /* Note, #UD due to CR4.OSXSAVE=0 has priority over the intercept. */
 if (kvm_x86_call(get_cpl)(vcpu) != 0 ||
     __kvm_set_xcr(vcpu, kvm_rcx_read(vcpu), kvm_read_edx_eax(vcpu))) {
  kvm_inject_gp(vcpu, 0);
  return 1;
 }

 return kvm_skip_emulated_instruction(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_emulate_xsetbv);

static bool kvm_is_valid_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
{
 return __kvm_is_valid_cr4(vcpu, cr4) &&
        kvm_x86_call(is_valid_cr4)(vcpu, cr4);
}

void kvm_post_set_cr4(struct kvm_vcpu *vcpu, unsigned long old_cr4, unsigned long cr4)
{
 if ((cr4 ^ old_cr4) & KVM_MMU_CR4_ROLE_BITS)
  kvm_mmu_reset_context(vcpu);

 /*
 * If CR4.PCIDE is changed 0 -> 1, there is no need to flush the TLB
 * according to the SDM; however, stale prev_roots could be reused
 * incorrectly in the future after a MOV to CR3 with NOFLUSH=1, so we
 * free them all.  This is *not* a superset of KVM_REQ_TLB_FLUSH_GUEST
 * or KVM_REQ_TLB_FLUSH_CURRENT, because the hardware TLB is not flushed,
 * so fall through.
 */

 if (!tdp_enabled &&
     (cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE))
  kvm_mmu_unload(vcpu);

 /*
 * The TLB has to be flushed for all PCIDs if any of the following
 * (architecturally required) changes happen:
 * - CR4.PCIDE is changed from 1 to 0
 * - CR4.PGE is toggled
 *
 * This is a superset of KVM_REQ_TLB_FLUSH_CURRENT.
 */

 if (((cr4 ^ old_cr4) & X86_CR4_PGE) ||
     (!(cr4 & X86_CR4_PCIDE) && (old_cr4 & X86_CR4_PCIDE)))
  kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);

 /*
 * The TLB has to be flushed for the current PCID if any of the
 * following (architecturally required) changes happen:
 * - CR4.SMEP is changed from 0 to 1
 * - CR4.PAE is toggled
 */

 else if (((cr4 ^ old_cr4) & X86_CR4_PAE) ||
   ((cr4 & X86_CR4_SMEP) && !(old_cr4 & X86_CR4_SMEP)))
  kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);

}
EXPORT_SYMBOL_GPL(kvm_post_set_cr4);

int kvm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
{
 unsigned long old_cr4 = kvm_read_cr4(vcpu);

 if (!kvm_is_valid_cr4(vcpu, cr4))
  return 1;

 if (is_long_mode(vcpu)) {
  if (!(cr4 & X86_CR4_PAE))
   return 1;
  if ((cr4 ^ old_cr4) & X86_CR4_LA57)
   return 1;
 } else if (is_paging(vcpu) && (cr4 & X86_CR4_PAE)
     && ((cr4 ^ old_cr4) & X86_CR4_PDPTR_BITS)
     && !load_pdptrs(vcpu, kvm_read_cr3(vcpu)))
  return 1;

 if ((cr4 & X86_CR4_PCIDE) && !(old_cr4 & X86_CR4_PCIDE)) {
  /* PCID can not be enabled when cr3[11:0]!=000H or EFER.LMA=0 */
  if ((kvm_read_cr3(vcpu) & X86_CR3_PCID_MASK) || !is_long_mode(vcpu))
   return 1;
 }

 kvm_x86_call(set_cr4)(vcpu, cr4);

 kvm_post_set_cr4(vcpu, old_cr4, cr4);

 return 0;
}
EXPORT_SYMBOL_GPL(kvm_set_cr4);

static void kvm_invalidate_pcid(struct kvm_vcpu *vcpu, unsigned long pcid)
{
 struct kvm_mmu *mmu = vcpu->arch.mmu;
 unsigned long roots_to_free = 0;
 int i;

 /*
 * MOV CR3 and INVPCID are usually not intercepted when using TDP, but
 * this is reachable when running EPT=1 and unrestricted_guest=0,  and
 * also via the emulator.  KVM's TDP page tables are not in the scope of
 * the invalidation, but the guest's TLB entries need to be flushed as
 * the CPU may have cached entries in its TLB for the target PCID.
 */

 if (unlikely(tdp_enabled)) {
  kvm_make_request(KVM_REQ_TLB_FLUSH_GUEST, vcpu);
  return;
 }

 /*
 * If neither the current CR3 nor any of the prev_roots use the given
 * PCID, then nothing needs to be done here because a resync will
 * happen anyway before switching to any other CR3.
 */

 if (kvm_get_active_pcid(vcpu) == pcid) {
  kvm_make_request(KVM_REQ_MMU_SYNC, vcpu);
  kvm_make_request(KVM_REQ_TLB_FLUSH_CURRENT, vcpu);
 }

 /*
 * If PCID is disabled, there is no need to free prev_roots even if the
 * PCIDs for them are also 0, because MOV to CR3 always flushes the TLB
 * with PCIDE=0.
 */

 if (!kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE))
  return;

 for (i = 0; i < KVM_MMU_NUM_PREV_ROOTS; i++)
  if (kvm_get_pcid(vcpu, mmu->prev_roots[i].pgd) == pcid)
   roots_to_free |= KVM_MMU_ROOT_PREVIOUS(i);

 kvm_mmu_free_roots(vcpu->kvm, mmu, roots_to_free);
}

int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
{
 bool skip_tlb_flush = false;
 unsigned long pcid = 0;
#ifdef CONFIG_X86_64
 if (kvm_is_cr4_bit_set(vcpu, X86_CR4_PCIDE)) {
  skip_tlb_flush = cr3 & X86_CR3_PCID_NOFLUSH;
  cr3 &= ~X86_CR3_PCID_NOFLUSH;
  pcid = cr3 & X86_CR3_PCID_MASK;
 }
#endif

 /* PDPTRs are always reloaded for PAE paging. */
 if (cr3 == kvm_read_cr3(vcpu) && !is_pae_paging(vcpu))
  goto handle_tlb_flush;

 /*
 * Do not condition the GPA check on long mode, this helper is used to
 * stuff CR3, e.g. for RSM emulation, and there is no guarantee that
 * the current vCPU mode is accurate.
 */

 if (!kvm_vcpu_is_legal_cr3(vcpu, cr3))
  return 1;

 if (is_pae_paging(vcpu) && !load_pdptrs(vcpu, cr3))
  return 1;

 if (cr3 != kvm_read_cr3(vcpu))
  kvm_mmu_new_pgd(vcpu, cr3);

 vcpu->arch.cr3 = cr3;
 kvm_register_mark_dirty(vcpu, VCPU_EXREG_CR3);
 /* Do not call post_set_cr3, we do not get here for confidential guests.  */

handle_tlb_flush:
 /*
 * A load of CR3 that flushes the TLB flushes only the current PCID,
 * even if PCID is disabled, in which case PCID=0 is flushed.  It's a
 * moot point in the end because _disabling_ PCID will flush all PCIDs,
 * and it's impossible to use a non-zero PCID when PCID is disabled,
 * i.e. only PCID=0 can be relevant.
 */

 if (!skip_tlb_flush)
  kvm_invalidate_pcid(vcpu, pcid);

 return 0;
}
EXPORT_SYMBOL_GPL(kvm_set_cr3);

int kvm_set_cr8(struct kvm_vcpu *vcpu, unsigned long cr8)
{
 if (cr8 & CR8_RESERVED_BITS)
  return 1;
 if (lapic_in_kernel(vcpu))
  kvm_lapic_set_tpr(vcpu, cr8);
 else
  vcpu->arch.cr8 = cr8;
 return 0;
}
EXPORT_SYMBOL_GPL(kvm_set_cr8);

unsigned long kvm_get_cr8(struct kvm_vcpu *vcpu)
{
 if (lapic_in_kernel(vcpu))
  return kvm_lapic_get_cr8(vcpu);
 else
  return vcpu->arch.cr8;
}
EXPORT_SYMBOL_GPL(kvm_get_cr8);

static void kvm_update_dr0123(struct kvm_vcpu *vcpu)
{
 int i;

 if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) {
  for (i = 0; i < KVM_NR_DB_REGS; i++)
   vcpu->arch.eff_db[i] = vcpu->arch.db[i];
 }
}

void kvm_update_dr7(struct kvm_vcpu *vcpu)
{
 unsigned long dr7;

 if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)
  dr7 = vcpu->arch.guest_debug_dr7;
 else
  dr7 = vcpu->arch.dr7;
 kvm_x86_call(set_dr7)(vcpu, dr7);
 vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_BP_ENABLED;
 if (dr7 & DR7_BP_EN_MASK)
  vcpu->arch.switch_db_regs |= KVM_DEBUGREG_BP_ENABLED;
}
EXPORT_SYMBOL_GPL(kvm_update_dr7);

static u64 kvm_dr6_fixed(struct kvm_vcpu *vcpu)
{
 u64 fixed = DR6_FIXED_1;

 if (!guest_cpu_cap_has(vcpu, X86_FEATURE_RTM))
  fixed |= DR6_RTM;

 if (!guest_cpu_cap_has(vcpu, X86_FEATURE_BUS_LOCK_DETECT))
  fixed |= DR6_BUS_LOCK;
 return fixed;
}

int kvm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long val)
{
 size_t size = ARRAY_SIZE(vcpu->arch.db);

 switch (dr) {
 case 0 ... 3:
  vcpu->arch.db[array_index_nospec(dr, size)] = val;
  if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP))
   vcpu->arch.eff_db[dr] = val;
  break;
 case 4:
 case 6:
  if (!kvm_dr6_valid(val))
   return 1; /* #GP */
  vcpu->arch.dr6 = (val & DR6_VOLATILE) | kvm_dr6_fixed(vcpu);
  break;
 case 5:
 default/* 7 */
  if (!kvm_dr7_valid(val))
   return 1; /* #GP */
  vcpu->arch.dr7 = (val & DR7_VOLATILE) | DR7_FIXED_1;
  kvm_update_dr7(vcpu);
  break;
 }

 return 0;
}
EXPORT_SYMBOL_GPL(kvm_set_dr);

unsigned long kvm_get_dr(struct kvm_vcpu *vcpu, int dr)
{
 size_t size = ARRAY_SIZE(vcpu->arch.db);

 switch (dr) {
 case 0 ... 3:
  return vcpu->arch.db[array_index_nospec(dr, size)];
 case 4:
 case 6:
  return vcpu->arch.dr6;
 case 5:
 default/* 7 */
  return vcpu->arch.dr7;
 }
}
EXPORT_SYMBOL_GPL(kvm_get_dr);

int kvm_emulate_rdpmc(struct kvm_vcpu *vcpu)
{
 u32 pmc = kvm_rcx_read(vcpu);
 u64 data;

 if (kvm_pmu_rdpmc(vcpu, pmc, &data)) {
  kvm_inject_gp(vcpu, 0);
  return 1;
 }

 kvm_rax_write(vcpu, (u32)data);
 kvm_rdx_write(vcpu, data >> 32);
 return kvm_skip_emulated_instruction(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_emulate_rdpmc);

/*
 * 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)

static 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;
}

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 & efer_reserved_bits)
  return false;

 return __kvm_valid_efer(vcpu, efer);
}
EXPORT_SYMBOL_GPL(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 & efer_reserved_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 (!static_cpu_has(X86_FEATURE_XSAVES) &&
     (efer & EFER_SVME))
  kvm_hv_xsaves_xsavec_maybe_warn(vcpu);

 return 0;
}

void kvm_enable_efer_bits(u64 mask)
{
       efer_reserved_bits &= ~mask;
}
EXPORT_SYMBOL_GPL(kvm_enable_efer_bits);

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_GPL(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;
 }

 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.
 */

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;
 }

 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_get_msr_with_filter(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_get_msr_ignored_check(vcpu, index, data, false);
}
EXPORT_SYMBOL_GPL(kvm_get_msr_with_filter);

int kvm_set_msr_with_filter(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_set_msr_ignored_check(vcpu, index, data, false);
}
EXPORT_SYMBOL_GPL(kvm_set_msr_with_filter);

int kvm_get_msr(struct kvm_vcpu *vcpu, u32 index, u64 *data)
{
 return kvm_get_msr_ignored_check(vcpu, index, data, false);
}
EXPORT_SYMBOL_GPL(kvm_get_msr);

int kvm_set_msr(struct kvm_vcpu *vcpu, u32 index, u64 data)
{
 return kvm_set_msr_ignored_check(vcpu, index, data, false);
}
EXPORT_SYMBOL_GPL(kvm_set_msr);

static void complete_userspace_rdmsr(struct kvm_vcpu *vcpu)
{
 if (!vcpu->run->msr.error) {
  kvm_rax_write(vcpu, (u32)vcpu->run->msr.data);
  kvm_rdx_write(vcpu, vcpu->run->msr.data >> 32);
 }
}

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_get_msr_with_filter(vcpu, msr, &data);
 if (!r) {
  trace_kvm_msr_read(msr, data);

  if (reg < 0) {
   kvm_rax_write(vcpu, data & -1u);
   kvm_rdx_write(vcpu, (data >> 32) & -1u);
  } 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_rcx_read(vcpu), -1,
       complete_fast_rdmsr);
}
EXPORT_SYMBOL_GPL(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_GPL(kvm_emulate_rdmsr_imm);

static int __kvm_emulate_wrmsr(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
 int r;

 r = kvm_set_msr_with_filter(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_rcx_read(vcpu),
       kvm_read_edx_eax(vcpu));
}
EXPORT_SYMBOL_GPL(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_GPL(kvm_emulate_wrmsr_imm);

int kvm_emulate_as_nop(struct kvm_vcpu *vcpu)
{
 return kvm_skip_emulated_instruction(vcpu);
}

int kvm_emulate_invd(struct kvm_vcpu *vcpu)
{
 /* Treat an INVD instruction as a NOP and just skip it. */
 return kvm_emulate_as_nop(vcpu);
}
EXPORT_SYMBOL_GPL(kvm_emulate_invd);

int kvm_handle_invalid_op(struct kvm_vcpu *vcpu)
{
 kvm_queue_exception(vcpu, UD_VECTOR);
 return 1;
}
EXPORT_SYMBOL_GPL(kvm_handle_invalid_op);


static int kvm_emulate_monitor_mwait(struct kvm_vcpu *vcpu, const char *insn)
{
 bool enabled;

 if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS))
  goto emulate_as_nop;

 if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT))
  enabled = guest_cpu_cap_has(vcpu, X86_FEATURE_MWAIT);
 else
  enabled = vcpu->arch.ia32_misc_enable_msr & MSR_IA32_MISC_ENABLE_MWAIT;

 if (!enabled)
  return kvm_handle_invalid_op(vcpu);

emulate_as_nop:
 pr_warn_once("%s instruction emulated as NOP!\n", insn);
 return kvm_emulate_as_nop(vcpu);
}
int kvm_emulate_mwait(struct kvm_vcpu *vcpu)
{
 return kvm_emulate_monitor_mwait(vcpu, "MWAIT");
}
EXPORT_SYMBOL_GPL(kvm_emulate_mwait);

int kvm_emulate_monitor(struct kvm_vcpu *vcpu)
{
 return kvm_emulate_monitor_mwait(vcpu, "MONITOR");
}
EXPORT_SYMBOL_GPL(kvm_emulate_monitor);

static inline bool kvm_vcpu_exit_request(struct kvm_vcpu *vcpu)
{
 xfer_to_guest_mode_prepare();

 return READ_ONCE(vcpu->mode) == EXITING_GUEST_MODE ||
        kvm_request_pending(vcpu) || xfer_to_guest_mode_work_pending();
}

/*
 * The fast path for frequent and performance sensitive wrmsr emulation,
 * i.e. the sending of IPI, sending IPI early in the VM-Exit flow reduces
 * the latency of virtual IPI by avoiding the expensive bits of transitioning
 * from guest to host, e.g. reacquiring KVM's SRCU lock. In contrast to the
 * other cases which must be called after interrupts are enabled on the host.
 */

static int handle_fastpath_set_x2apic_icr_irqoff(struct kvm_vcpu *vcpu, u64 data)
{
 if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(vcpu->arch.apic))
  return 1;

 if (((data & APIC_SHORT_MASK) == APIC_DEST_NOSHORT) &&
     ((data & APIC_DEST_MASK) == APIC_DEST_PHYSICAL) &&
     ((data & APIC_MODE_MASK) == APIC_DM_FIXED) &&
     ((u32)(data >> 32) != X2APIC_BROADCAST))
  return kvm_x2apic_icr_write(vcpu->arch.apic, data);

 return 1;
}

static int handle_fastpath_set_tscdeadline(struct kvm_vcpu *vcpu, u64 data)
{
 if (!kvm_can_use_hv_timer(vcpu))
  return 1;

 kvm_set_lapic_tscdeadline_msr(vcpu, data);
 return 0;
}

fastpath_t handle_fastpath_set_msr_irqoff(struct kvm_vcpu *vcpu)
{
 u32 msr = kvm_rcx_read(vcpu);
 u64 data;
 fastpath_t ret;
 bool handled;

 kvm_vcpu_srcu_read_lock(vcpu);

 switch (msr) {
 case APIC_BASE_MSR + (APIC_ICR >> 4):
  data = kvm_read_edx_eax(vcpu);
  handled = !handle_fastpath_set_x2apic_icr_irqoff(vcpu, data);
  break;
 case MSR_IA32_TSC_DEADLINE:
  data = kvm_read_edx_eax(vcpu);
  handled = !handle_fastpath_set_tscdeadline(vcpu, data);
  break;
 default:
  handled = false;
  break;
 }

 if (handled) {
  if (!kvm_skip_emulated_instruction(vcpu))
   ret = EXIT_FASTPATH_EXIT_USERSPACE;
  else
   ret = EXIT_FASTPATH_REENTER_GUEST;
  trace_kvm_msr_write(msr, data);
 } else {
  ret = EXIT_FASTPATH_NONE;
 }

 kvm_vcpu_srcu_read_unlock(vcpu);

 return ret;
}
EXPORT_SYMBOL_GPL(handle_fastpath_set_msr_irqoff);

/*
 * Adapt set_msr() to msr_io()'s calling convention
 */

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;

 /*
 * Disallow writes to immutable feature MSRs after KVM_RUN.  KVM does
 * not support modifying the guest vCPU model on the fly, e.g. changing
 * the nVMX capabilities while L2 is running is nonsensical.  Allow
 * writes of the same value, e.g. to allow userspace to blindly stuff
 * all MSRs when emulating RESET.
 */

 if (kvm_vcpu_has_run(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);
}

#ifdef CONFIG_X86_64
struct pvclock_clock {
 int vclock_mode;
 u64 cycle_last;
 u64 mask;
 u32 mult;
 u32 shift;
 u64 base_cycles;
 u64 offset;
};

struct pvclock_gtod_data {
 seqcount_t seq;

 struct pvclock_clock clock; /* extract of a clocksource struct */
 struct pvclock_clock raw_clock; /* extract of a clocksource struct */

 ktime_t  offs_boot;
 u64  wall_time_sec;
};

static struct pvclock_gtod_data pvclock_gtod_data;

static void update_pvclock_gtod(struct timekeeper *tk)
{
 struct pvclock_gtod_data *vdata = &pvclock_gtod_data;

 write_seqcount_begin(&vdata->seq);

 /* copy pvclock gtod data */
 vdata->clock.vclock_mode = tk->tkr_mono.clock->vdso_clock_mode;
 vdata->clock.cycle_last  = tk->tkr_mono.cycle_last;
 vdata->clock.mask  = tk->tkr_mono.mask;
 vdata->clock.mult  = tk->tkr_mono.mult;
 vdata->clock.shift  = tk->tkr_mono.shift;
 vdata->clock.base_cycles = tk->tkr_mono.xtime_nsec;
 vdata->clock.offset  = tk->tkr_mono.base;

 vdata->raw_clock.vclock_mode = tk->tkr_raw.clock->vdso_clock_mode;
 vdata->raw_clock.cycle_last = tk->tkr_raw.cycle_last;
 vdata->raw_clock.mask  = tk->tkr_raw.mask;
 vdata->raw_clock.mult  = tk->tkr_raw.mult;
 vdata->raw_clock.shift  = tk->tkr_raw.shift;
 vdata->raw_clock.base_cycles = tk->tkr_raw.xtime_nsec;
 vdata->raw_clock.offset  = tk->tkr_raw.base;

 vdata->wall_time_sec            = tk->xtime_sec;

 vdata->offs_boot  = tk->offs_boot;

 write_seqcount_end(&vdata->seq);
}

static s64 get_kvmclock_base_ns(void)
{
 /* Count up from boot time, but with the frequency of the raw clock.  */
 return ktime_to_ns(ktime_add(ktime_get_raw(), pvclock_gtod_data.offs_boot));
}
#else
static s64 get_kvmclock_base_ns(void)
{
 /* Master clock not used, so we can just use CLOCK_BOOTTIME.  */
 return ktime_get_boottime_ns();
}
--> --------------------

--> maximum size reached

--> --------------------

Messung V0.5
C=97 H=94 G=95

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.61Angebot  Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.