]> Git Repo - J-linux.git/commitdiff
Merge tag 'kvm-x86-lam-6.8' of https://github.com/kvm-x86/linux into HEAD
authorPaolo Bonzini <[email protected]>
Mon, 8 Jan 2024 13:10:12 +0000 (08:10 -0500)
committerPaolo Bonzini <[email protected]>
Mon, 8 Jan 2024 13:10:12 +0000 (08:10 -0500)
KVM x86 support for virtualizing Linear Address Masking (LAM)

Add KVM support for Linear Address Masking (LAM).  LAM tweaks the canonicality
checks for most virtual address usage in 64-bit mode, such that only the most
significant bit of the untranslated address bits must match the polarity of the
last translated address bit.  This allows software to use ignored, untranslated
address bits for metadata, e.g. to efficiently tag pointers for address
sanitization.

LAM can be enabled separately for user pointers and supervisor pointers, and
for userspace LAM can be select between 48-bit and 57-bit masking

 - 48-bit LAM: metadata bits 62:48, i.e. LAM width of 15.
 - 57-bit LAM: metadata bits 62:57, i.e. LAM width of 6.

For user pointers, LAM enabling utilizes two previously-reserved high bits from
CR3 (similar to how PCID_NOFLUSH uses bit 63): LAM_U48 and LAM_U57, bits 62 and
61 respectively.  Note, if LAM_57 is set, LAM_U48 is ignored, i.e.:

 - CR3.LAM_U48=0 && CR3.LAM_U57=0 == LAM disabled for user pointers
 - CR3.LAM_U48=1 && CR3.LAM_U57=0 == LAM-48 enabled for user pointers
 - CR3.LAM_U48=x && CR3.LAM_U57=1 == LAM-57 enabled for user pointers

For supervisor pointers, LAM is controlled by a single bit, CR4.LAM_SUP, with
the 48-bit versus 57-bit LAM behavior following the current paging mode, i.e.:

 - CR4.LAM_SUP=0 && CR4.LA57=x == LAM disabled for supervisor pointers
 - CR4.LAM_SUP=1 && CR4.LA57=0 == LAM-48 enabled for supervisor pointers
 - CR4.LAM_SUP=1 && CR4.LA57=1 == LAM-57 enabled for supervisor pointers

The modified LAM canonicality checks:
 - LAM_S48                : [ 1 ][ metadata ][ 1 ]
                              63               47
 - LAM_U48                : [ 0 ][ metadata ][ 0 ]
                              63               47
 - LAM_S57                : [ 1 ][ metadata ][ 1 ]
                              63               56
 - LAM_U57 + 5-lvl paging : [ 0 ][ metadata ][ 0 ]
                              63               56
 - LAM_U57 + 4-lvl paging : [ 0 ][ metadata ][ 0...0 ]
                              63               56..47

The bulk of KVM support for LAM is to emulate LAM's modified canonicality
checks.  The approach taken by KVM is to "fill" the metadata bits using the
highest bit of the translated address, e.g. for LAM-48, bit 47 is sign-extended
to bits 62:48.  The most significant bit, 63, is *not* modified, i.e. its value
from the raw, untagged virtual address is kept for the canonicality check. This
untagging allows

Aside from emulating LAM's canonical checks behavior, LAM has the usual KVM
touchpoints for selectable features: enumeration (CPUID.7.1:EAX.LAM[bit 26],
enabling via CR3 and CR4 bits, etc.

1  2 
arch/x86/include/asm/kvm-x86-ops.h
arch/x86/include/asm/kvm_host.h
arch/x86/kvm/cpuid.c
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/svm/nested.c
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/vmx/vmx.h
arch/x86/kvm/x86.c

index f482216bbdb89719931c53b7a84a7aab09899941,756791665117b983defc43a97b3c2e820ddbb026..378ed944b849fb0448a13bd7f12a7a542ab7e388
@@@ -55,10 -55,8 +55,10 @@@ KVM_X86_OP(set_rflags
  KVM_X86_OP(get_if_flag)
  KVM_X86_OP(flush_tlb_all)
  KVM_X86_OP(flush_tlb_current)
 +#if IS_ENABLED(CONFIG_HYPERV)
  KVM_X86_OP_OPTIONAL(flush_remote_tlbs)
  KVM_X86_OP_OPTIONAL(flush_remote_tlbs_range)
 +#endif
  KVM_X86_OP(flush_tlb_gva)
  KVM_X86_OP(flush_tlb_guest)
  KVM_X86_OP(vcpu_pre_run)
@@@ -137,6 -135,7 +137,7 @@@ KVM_X86_OP(msr_filter_changed
  KVM_X86_OP(complete_emulated_msr)
  KVM_X86_OP(vcpu_deliver_sipi_vector)
  KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons);
+ KVM_X86_OP_OPTIONAL(get_untagged_addr)
  
  #undef KVM_X86_OP
  #undef KVM_X86_OP_OPTIONAL
index c17e38ac8b7a36253337157a7b27b2c8b2d18302,f96988f283d5759f242746e3fa166bf596e56f1e..c5e362e2116f5d0cf43dea830c0b21f935ac7999
                          | X86_CR4_PGE | X86_CR4_PCE | X86_CR4_OSFXSR | X86_CR4_PCIDE \
                          | X86_CR4_OSXSAVE | X86_CR4_SMEP | X86_CR4_FSGSBASE \
                          | X86_CR4_OSXMMEXCPT | X86_CR4_LA57 | X86_CR4_VMXE \
-                         | X86_CR4_SMAP | X86_CR4_PKE | X86_CR4_UMIP))
+                         | X86_CR4_SMAP | X86_CR4_PKE | X86_CR4_UMIP \
+                         | X86_CR4_LAM_SUP))
  
  #define CR8_RESERVED_BITS (~(unsigned long)X86_CR8_TPR)
  
@@@ -500,23 -501,8 +501,23 @@@ struct kvm_pmc 
        u8 idx;
        bool is_paused;
        bool intr;
 +      /*
 +       * Base value of the PMC counter, relative to the *consumed* count in
 +       * the associated perf_event.  This value includes counter updates from
 +       * the perf_event and emulated_count since the last time the counter
 +       * was reprogrammed, but it is *not* the current value as seen by the
 +       * guest or userspace.
 +       *
 +       * The count is relative to the associated perf_event so that KVM
 +       * doesn't need to reprogram the perf_event every time the guest writes
 +       * to the counter.
 +       */
        u64 counter;
 -      u64 prev_counter;
 +      /*
 +       * PMC events triggered by KVM emulation that haven't been fully
 +       * processed, i.e. haven't undergone overflow detection.
 +       */
 +      u64 emulated_counter;
        u64 eventsel;
        struct perf_event *perf_event;
        struct kvm_vcpu *vcpu;
@@@ -952,10 -938,8 +953,10 @@@ struct kvm_vcpu_arch 
        /* used for guest single stepping over the given code position */
        unsigned long singlestep_rip;
  
 +#ifdef CONFIG_KVM_HYPERV
        bool hyperv_enabled;
        struct kvm_vcpu_hv *hyperv;
 +#endif
  #ifdef CONFIG_KVM_XEN
        struct kvm_vcpu_xen xen;
  #endif
@@@ -1112,7 -1096,6 +1113,7 @@@ enum hv_tsc_page_status 
        HV_TSC_PAGE_BROKEN,
  };
  
 +#ifdef CONFIG_KVM_HYPERV
  /* Hyper-V emulation context */
  struct kvm_hv {
        struct mutex hv_lock;
         */
        unsigned int synic_auto_eoi_used;
  
 -      struct hv_partition_assist_pg *hv_pa_pg;
        struct kvm_hv_syndbg hv_syndbg;
  };
 +#endif
  
  struct msr_bitmap_range {
        u32 flags;
        unsigned long *bitmap;
  };
  
 +#ifdef CONFIG_KVM_XEN
  /* Xen emulation context */
  struct kvm_xen {
        struct mutex xen_lock;
        struct idr evtchn_ports;
        unsigned long poll_mask[BITS_TO_LONGS(KVM_MAX_VCPUS)];
  };
 +#endif
  
  enum kvm_irqchip_mode {
        KVM_IRQCHIP_NONE,
@@@ -1368,13 -1349,8 +1369,13 @@@ struct kvm_arch 
        /* reads protected by irq_srcu, writes by irq_lock */
        struct hlist_head mask_notifier_list;
  
 +#ifdef CONFIG_KVM_HYPERV
        struct kvm_hv hyperv;
 +#endif
 +
 +#ifdef CONFIG_KVM_XEN
        struct kvm_xen xen;
 +#endif
  
        bool backwards_tsc_observed;
        bool boot_vcpu_runs_old_kvmclock;
  #if IS_ENABLED(CONFIG_HYPERV)
        hpa_t   hv_root_tdp;
        spinlock_t hv_root_tdp_lock;
 +      struct hv_partition_assist_pg *hv_pa_pg;
  #endif
        /*
         * VM-scope maximum vCPU ID. Used to determine the size of structures
@@@ -1640,11 -1615,9 +1641,11 @@@ struct kvm_x86_ops 
  
        void (*flush_tlb_all)(struct kvm_vcpu *vcpu);
        void (*flush_tlb_current)(struct kvm_vcpu *vcpu);
 +#if IS_ENABLED(CONFIG_HYPERV)
        int  (*flush_remote_tlbs)(struct kvm *kvm);
        int  (*flush_remote_tlbs_range)(struct kvm *kvm, gfn_t gfn,
                                        gfn_t nr_pages);
 +#endif
  
        /*
         * Flush any TLB entries associated with the given GVA.
         * Returns vCPU specific APICv inhibit reasons
         */
        unsigned long (*vcpu_get_apicv_inhibit_reasons)(struct kvm_vcpu *vcpu);
+       gva_t (*get_untagged_addr)(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
  };
  
  struct kvm_x86_nested_ops {
@@@ -1853,7 -1828,6 +1856,7 @@@ static inline struct kvm *kvm_arch_allo
  #define __KVM_HAVE_ARCH_VM_FREE
  void kvm_arch_free_vm(struct kvm *kvm);
  
 +#if IS_ENABLED(CONFIG_HYPERV)
  #define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS
  static inline int kvm_arch_flush_remote_tlbs(struct kvm *kvm)
  {
  }
  
  #define __KVM_HAVE_ARCH_FLUSH_REMOTE_TLBS_RANGE
 +static inline int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn,
 +                                                 u64 nr_pages)
 +{
 +      if (!kvm_x86_ops.flush_remote_tlbs_range)
 +              return -EOPNOTSUPP;
 +
 +      return static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages);
 +}
 +#endif /* CONFIG_HYPERV */
  
  #define kvm_arch_pmi_in_guest(vcpu) \
        ((vcpu) && (vcpu)->arch.handling_intr_from_guest)
diff --combined arch/x86/kvm/cpuid.c
index 727b6551e1dfc0483bc3514e6ddfd52495f01b4d,40d68fef748a3bb95d58e55f369115be63428294..294e5bd5f8a0ed06fcb482a8d7ffd3dc2ac6e636
@@@ -314,15 -314,11 +314,15 @@@ EXPORT_SYMBOL_GPL(kvm_update_cpuid_runt
  
  static bool kvm_cpuid_has_hyperv(struct kvm_cpuid_entry2 *entries, int nent)
  {
 +#ifdef CONFIG_KVM_HYPERV
        struct kvm_cpuid_entry2 *entry;
  
        entry = cpuid_entry2_find(entries, nent, HYPERV_CPUID_INTERFACE,
                                  KVM_CPUID_INDEX_NOT_SIGNIFICANT);
        return entry && entry->eax == HYPERV_CPUID_SIGNATURE_EAX;
 +#else
 +      return false;
 +#endif
  }
  
  static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
@@@ -437,13 -433,11 +437,13 @@@ static int kvm_set_cpuid(struct kvm_vcp
                return 0;
        }
  
 +#ifdef CONFIG_KVM_HYPERV
        if (kvm_cpuid_has_hyperv(e2, nent)) {
                r = kvm_hv_vcpu_init(vcpu);
                if (r)
                        return r;
        }
 +#endif
  
        r = kvm_check_cpuid(vcpu, e2, nent);
        if (r)
@@@ -475,7 -469,7 +475,7 @@@ int kvm_vcpu_ioctl_set_cpuid(struct kvm
                return -E2BIG;
  
        if (cpuid->nent) {
 -              e = vmemdup_user(entries, array_size(sizeof(*e), cpuid->nent));
 +              e = vmemdup_array_user(entries, cpuid->nent, sizeof(*e));
                if (IS_ERR(e))
                        return PTR_ERR(e);
  
@@@ -519,7 -513,7 +519,7 @@@ int kvm_vcpu_ioctl_set_cpuid2(struct kv
                return -E2BIG;
  
        if (cpuid->nent) {
 -              e2 = vmemdup_user(entries, array_size(sizeof(*e2), cpuid->nent));
 +              e2 = vmemdup_array_user(entries, cpuid->nent, sizeof(*e2));
                if (IS_ERR(e2))
                        return PTR_ERR(e2);
        }
@@@ -677,7 -671,7 +677,7 @@@ void kvm_set_cpu_caps(void
        kvm_cpu_cap_mask(CPUID_7_1_EAX,
                F(AVX_VNNI) | F(AVX512_BF16) | F(CMPCCXADD) |
                F(FZRM) | F(FSRS) | F(FSRC) |
-               F(AMX_FP16) | F(AVX_IFMA)
+               F(AMX_FP16) | F(AVX_IFMA) | F(LAM)
        );
  
        kvm_cpu_cap_init_kvm_defined(CPUID_7_1_EDX,
                F(AMX_COMPLEX)
        );
  
 +      kvm_cpu_cap_init_kvm_defined(CPUID_7_2_EDX,
 +              F(INTEL_PSFD) | F(IPRED_CTRL) | F(RRSBA_CTRL) | F(DDPD_U) |
 +              F(BHI_CTRL) | F(MCDT_NO)
 +      );
 +
        kvm_cpu_cap_mask(CPUID_D_1_EAX,
                F(XSAVEOPT) | F(XSAVEC) | F(XGETBV1) | F(XSAVES) | f_xfd
        );
@@@ -971,13 -960,13 +971,13 @@@ static inline int __do_cpuid_func(struc
                break;
        /* function 7 has additional index. */
        case 7:
 -              entry->eax = min(entry->eax, 1u);
 +              max_idx = entry->eax = min(entry->eax, 2u);
                cpuid_entry_override(entry, CPUID_7_0_EBX);
                cpuid_entry_override(entry, CPUID_7_ECX);
                cpuid_entry_override(entry, CPUID_7_EDX);
  
 -              /* KVM only supports 0x7.0 and 0x7.1, capped above via min(). */
 -              if (entry->eax == 1) {
 +              /* KVM only supports up to 0x7.2, capped above via min(). */
 +              if (max_idx >= 1) {
                        entry = do_host_cpuid(array, function, 1);
                        if (!entry)
                                goto out;
                        entry->ebx = 0;
                        entry->ecx = 0;
                }
 +              if (max_idx >= 2) {
 +                      entry = do_host_cpuid(array, function, 2);
 +                      if (!entry)
 +                              goto out;
 +
 +                      cpuid_entry_override(entry, CPUID_7_2_EDX);
 +                      entry->ecx = 0;
 +                      entry->ebx = 0;
 +                      entry->eax = 0;
 +              }
                break;
        case 0xa: { /* Architectural Performance Monitoring */
                union cpuid10_eax eax;
diff --combined arch/x86/kvm/mmu/mmu.c
index 8531480e5da4899ee7ef00e090e42e165c6f6e6d,73070650b14352f6d9b1a1fca76e9e1ab5e02677..d0590b417d3005cf28546ef6c380f3ee1e85d9e1
@@@ -271,11 -271,15 +271,11 @@@ static inline unsigned long kvm_mmu_get
  
  static inline bool kvm_available_flush_remote_tlbs_range(void)
  {
 +#if IS_ENABLED(CONFIG_HYPERV)
        return kvm_x86_ops.flush_remote_tlbs_range;
 -}
 -
 -int kvm_arch_flush_remote_tlbs_range(struct kvm *kvm, gfn_t gfn, u64 nr_pages)
 -{
 -      if (!kvm_x86_ops.flush_remote_tlbs_range)
 -              return -EOPNOTSUPP;
 -
 -      return static_call(kvm_x86_flush_remote_tlbs_range)(kvm, gfn, nr_pages);
 +#else
 +      return false;
 +#endif
  }
  
  static gfn_t kvm_mmu_page_get_gfn(struct kvm_mmu_page *sp, int index);
@@@ -3802,7 -3806,7 +3802,7 @@@ static int mmu_alloc_shadow_roots(struc
        hpa_t root;
  
        root_pgd = kvm_mmu_get_guest_pgd(vcpu, mmu);
-       root_gfn = root_pgd >> PAGE_SHIFT;
+       root_gfn = (root_pgd & __PT_BASE_ADDR_MASK) >> PAGE_SHIFT;
  
        if (!kvm_vcpu_is_visible_gfn(vcpu, root_gfn)) {
                mmu->root.hpa = kvm_mmu_get_dummy_root();
index 20212aac050b800534b2157d515e52b2721e217d,90ca9489aab63e4ef3b778d05afe6f2208b1fa1f..0cd34d011a973be77ae10d6856da0c41bde5d622
@@@ -187,6 -187,7 +187,6 @@@ void recalc_intercepts(struct vcpu_svm 
   */
  static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm)
  {
 -      struct hv_vmcb_enlightenments *hve = &svm->nested.ctl.hv_enlightenments;
        int i;
  
        /*
         * - Nested hypervisor (L1) is using Hyper-V emulation interface and
         * tells KVM (L0) there were no changes in MSR bitmap for L2.
         */
 -      if (!svm->nested.force_msr_bitmap_recalc &&
 -          kvm_hv_hypercall_enabled(&svm->vcpu) &&
 -          hve->hv_enlightenments_control.msr_bitmap &&
 -          (svm->nested.ctl.clean & BIT(HV_VMCB_NESTED_ENLIGHTENMENTS)))
 -              goto set_msrpm_base_pa;
 +#ifdef CONFIG_KVM_HYPERV
 +      if (!svm->nested.force_msr_bitmap_recalc) {
 +              struct hv_vmcb_enlightenments *hve = &svm->nested.ctl.hv_enlightenments;
 +
 +              if (kvm_hv_hypercall_enabled(&svm->vcpu) &&
 +                  hve->hv_enlightenments_control.msr_bitmap &&
 +                  (svm->nested.ctl.clean & BIT(HV_VMCB_NESTED_ENLIGHTENMENTS)))
 +                      goto set_msrpm_base_pa;
 +      }
 +#endif
  
        if (!(vmcb12_is_intercept(&svm->nested.ctl, INTERCEPT_MSR_PROT)))
                return true;
  
        svm->nested.force_msr_bitmap_recalc = false;
  
 +#ifdef CONFIG_KVM_HYPERV
  set_msrpm_base_pa:
 +#endif
        svm->vmcb->control.msrpm_base_pa = __sme_set(__pa(svm->nested.msrpm));
  
        return true;
@@@ -317,7 -311,7 +317,7 @@@ static bool __nested_vmcb_check_save(st
        if ((save->efer & EFER_LME) && (save->cr0 & X86_CR0_PG)) {
                if (CC(!(save->cr4 & X86_CR4_PAE)) ||
                    CC(!(save->cr0 & X86_CR0_PE)) ||
-                   CC(kvm_vcpu_is_illegal_gpa(vcpu, save->cr3)))
+                   CC(!kvm_vcpu_is_legal_cr3(vcpu, save->cr3)))
                        return false;
        }
  
@@@ -384,14 -378,12 +384,14 @@@ void __nested_copy_vmcb_control_to_cach
        to->msrpm_base_pa &= ~0x0fffULL;
        to->iopm_base_pa  &= ~0x0fffULL;
  
 +#ifdef CONFIG_KVM_HYPERV
        /* Hyper-V extensions (Enlightened VMCB) */
        if (kvm_hv_hypercall_enabled(vcpu)) {
                to->clean = from->clean;
                memcpy(&to->hv_enlightenments, &from->hv_enlightenments,
                       sizeof(to->hv_enlightenments));
        }
 +#endif
  }
  
  void nested_copy_vmcb_control_to_cache(struct vcpu_svm *svm,
@@@ -495,8 -487,14 +495,8 @@@ static void nested_save_pending_event_t
  
  static void nested_svm_transition_tlb_flush(struct kvm_vcpu *vcpu)
  {
 -      /*
 -       * KVM_REQ_HV_TLB_FLUSH flushes entries from either L1's VP_ID or
 -       * L2's VP_ID upon request from the guest. Make sure we check for
 -       * pending entries in the right FIFO upon L1/L2 transition as these
 -       * requests are put by other vCPUs asynchronously.
 -       */
 -      if (to_hv_vcpu(vcpu) && npt_enabled)
 -              kvm_make_request(KVM_REQ_HV_TLB_FLUSH, vcpu);
 +      /* Handle pending Hyper-V TLB flush requests */
 +      kvm_hv_nested_transtion_tlb_flush(vcpu, npt_enabled);
  
        /*
         * TODO: optimize unconditional TLB flush/MMU sync.  A partial list of
  static int nested_svm_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3,
                               bool nested_npt, bool reload_pdptrs)
  {
-       if (CC(kvm_vcpu_is_illegal_gpa(vcpu, cr3)))
+       if (CC(!kvm_vcpu_is_legal_cr3(vcpu, cr3)))
                return -EINVAL;
  
        if (reload_pdptrs && !nested_npt && is_pae_paging(vcpu) &&
index cf47b8b7f40f4f78365a7c1b3a68460bc97e318d,4ba46e1b29d2b23f13adf8773cef07dc9e74e696..db0ad1e6ec4b0bc2dfa07c2328f4877efe86e474
@@@ -179,7 -179,7 +179,7 @@@ static int nested_vmx_failValid(struct 
         * VM_INSTRUCTION_ERROR is not shadowed. Enlightened VMCS 'shadows' all
         * fields and thus must be synced.
         */
 -      if (to_vmx(vcpu)->nested.hv_evmcs_vmptr != EVMPTR_INVALID)
 +      if (nested_vmx_is_evmptr12_set(to_vmx(vcpu)))
                to_vmx(vcpu)->nested.need_vmcs12_to_shadow_sync = true;
  
        return kvm_skip_emulated_instruction(vcpu);
@@@ -194,7 -194,7 +194,7 @@@ static int nested_vmx_fail(struct kvm_v
         * can't be done if there isn't a current VMCS.
         */
        if (vmx->nested.current_vmptr == INVALID_GPA &&
 -          !evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 +          !nested_vmx_is_evmptr12_valid(vmx))
                return nested_vmx_failInvalid(vcpu);
  
        return nested_vmx_failValid(vcpu, vm_instruction_error);
@@@ -226,11 -226,10 +226,11 @@@ static void vmx_disable_shadow_vmcs(str
  
  static inline void nested_release_evmcs(struct kvm_vcpu *vcpu)
  {
 +#ifdef CONFIG_KVM_HYPERV
        struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(vcpu);
        struct vcpu_vmx *vmx = to_vmx(vcpu);
  
 -      if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
 +      if (nested_vmx_is_evmptr12_valid(vmx)) {
                kvm_vcpu_unmap(vcpu, &vmx->nested.hv_evmcs_map, true);
                vmx->nested.hv_evmcs = NULL;
        }
                hv_vcpu->nested.vm_id = 0;
                hv_vcpu->nested.vp_id = 0;
        }
 +#endif
 +}
 +
 +static bool nested_evmcs_handle_vmclear(struct kvm_vcpu *vcpu, gpa_t vmptr)
 +{
 +#ifdef CONFIG_KVM_HYPERV
 +      struct vcpu_vmx *vmx = to_vmx(vcpu);
 +      /*
 +       * When Enlightened VMEntry is enabled on the calling CPU we treat
 +       * memory area pointer by vmptr as Enlightened VMCS (as there's no good
 +       * way to distinguish it from VMCS12) and we must not corrupt it by
 +       * writing to the non-existent 'launch_state' field. The area doesn't
 +       * have to be the currently active EVMCS on the calling CPU and there's
 +       * nothing KVM has to do to transition it from 'active' to 'non-active'
 +       * state. It is possible that the area will stay mapped as
 +       * vmx->nested.hv_evmcs but this shouldn't be a problem.
 +       */
 +      if (!guest_cpuid_has_evmcs(vcpu) ||
 +          !evmptr_is_valid(nested_get_evmptr(vcpu)))
 +              return false;
 +
 +      if (nested_vmx_evmcs(vmx) && vmptr == vmx->nested.hv_evmcs_vmptr)
 +              nested_release_evmcs(vcpu);
 +
 +      return true;
 +#else
 +      return false;
 +#endif
  }
  
  static void vmx_sync_vmcs_host_state(struct vcpu_vmx *vmx,
@@@ -601,6 -572,7 +601,6 @@@ static inline bool nested_vmx_prepare_m
        int msr;
        unsigned long *msr_bitmap_l1;
        unsigned long *msr_bitmap_l0 = vmx->nested.vmcs02.msr_bitmap;
 -      struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
        struct kvm_host_map *map = &vmx->nested.msr_bitmap_map;
  
        /* Nothing to do if the MSR bitmap is not in use.  */
         * - Nested hypervisor (L1) has enabled 'Enlightened MSR Bitmap' feature
         *   and tells KVM (L0) there were no changes in MSR bitmap for L2.
         */
 -      if (!vmx->nested.force_msr_bitmap_recalc && evmcs &&
 -          evmcs->hv_enlightenments_control.msr_bitmap &&
 -          evmcs->hv_clean_fields & HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP)
 -              return true;
 +      if (!vmx->nested.force_msr_bitmap_recalc) {
 +              struct hv_enlightened_vmcs *evmcs = nested_vmx_evmcs(vmx);
 +
 +              if (evmcs && evmcs->hv_enlightenments_control.msr_bitmap &&
 +                  evmcs->hv_clean_fields & HV_VMX_ENLIGHTENED_CLEAN_FIELD_MSR_BITMAP)
 +                      return true;
 +      }
  
        if (kvm_vcpu_map(vcpu, gpa_to_gfn(vmcs12->msr_bitmap), map))
                return false;
@@@ -1116,7 -1085,7 +1116,7 @@@ static int nested_vmx_load_cr3(struct k
                               bool nested_ept, bool reload_pdptrs,
                               enum vm_entry_failure_code *entry_failure_code)
  {
-       if (CC(kvm_vcpu_is_illegal_gpa(vcpu, cr3))) {
+       if (CC(!kvm_vcpu_is_legal_cr3(vcpu, cr3))) {
                *entry_failure_code = ENTRY_FAIL_DEFAULT;
                return -EINVAL;
        }
@@@ -1170,8 -1139,14 +1170,8 @@@ static void nested_vmx_transition_tlb_f
  {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
  
 -      /*
 -       * KVM_REQ_HV_TLB_FLUSH flushes entries from either L1's VP_ID or
 -       * L2's VP_ID upon request from the guest. Make sure we check for
 -       * pending entries in the right FIFO upon L1/L2 transition as these
 -       * requests are put by other vCPUs asynchronously.
 -       */
 -      if (to_hv_vcpu(vcpu) && enable_ept)
 -              kvm_make_request(KVM_REQ_HV_TLB_FLUSH, vcpu);
 +      /* Handle pending Hyper-V TLB flush requests */
 +      kvm_hv_nested_transtion_tlb_flush(vcpu, enable_ept);
  
        /*
         * If vmcs12 doesn't use VPID, L1 expects linear and combined mappings
@@@ -1603,9 -1578,8 +1603,9 @@@ static void copy_vmcs12_to_shadow(struc
  
  static void copy_enlightened_to_vmcs12(struct vcpu_vmx *vmx, u32 hv_clean_fields)
  {
 +#ifdef CONFIG_KVM_HYPERV
        struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
 -      struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
 +      struct hv_enlightened_vmcs *evmcs = nested_vmx_evmcs(vmx);
        struct kvm_vcpu_hv *hv_vcpu = to_hv_vcpu(&vmx->vcpu);
  
        /* HV_VMX_ENLIGHTENED_CLEAN_FIELD_NONE */
         */
  
        return;
 +#else /* CONFIG_KVM_HYPERV */
 +      KVM_BUG_ON(1, vmx->vcpu.kvm);
 +#endif /* CONFIG_KVM_HYPERV */
  }
  
  static void copy_vmcs12_to_enlightened(struct vcpu_vmx *vmx)
  {
 +#ifdef CONFIG_KVM_HYPERV
        struct vmcs12 *vmcs12 = vmx->nested.cached_vmcs12;
 -      struct hv_enlightened_vmcs *evmcs = vmx->nested.hv_evmcs;
 +      struct hv_enlightened_vmcs *evmcs = nested_vmx_evmcs(vmx);
  
        /*
         * Should not be changed by KVM:
        evmcs->guest_bndcfgs = vmcs12->guest_bndcfgs;
  
        return;
 +#else /* CONFIG_KVM_HYPERV */
 +      KVM_BUG_ON(1, vmx->vcpu.kvm);
 +#endif /* CONFIG_KVM_HYPERV */
  }
  
  /*
  static enum nested_evmptrld_status nested_vmx_handle_enlightened_vmptrld(
        struct kvm_vcpu *vcpu, bool from_launch)
  {
 +#ifdef CONFIG_KVM_HYPERV
        struct vcpu_vmx *vmx = to_vmx(vcpu);
        bool evmcs_gpa_changed = false;
        u64 evmcs_gpa;
        }
  
        return EVMPTRLD_SUCCEEDED;
 +#else
 +      return EVMPTRLD_DISABLED;
 +#endif
  }
  
  void nested_sync_vmcs12_to_shadow(struct kvm_vcpu *vcpu)
  {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
  
 -      if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 +      if (nested_vmx_is_evmptr12_valid(vmx))
                copy_vmcs12_to_enlightened(vmx);
        else
                copy_vmcs12_to_shadow(vmx);
@@@ -2279,7 -2242,7 +2279,7 @@@ static void prepare_vmcs02_early(struc
        u32 exec_control;
        u64 guest_efer = nested_vmx_calc_efer(vmx, vmcs12);
  
 -      if (vmx->nested.dirty_vmcs12 || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 +      if (vmx->nested.dirty_vmcs12 || nested_vmx_is_evmptr12_valid(vmx))
                prepare_vmcs02_early_rare(vmx, vmcs12);
  
        /*
  
  static void prepare_vmcs02_rare(struct vcpu_vmx *vmx, struct vmcs12 *vmcs12)
  {
 -      struct hv_enlightened_vmcs *hv_evmcs = vmx->nested.hv_evmcs;
 +      struct hv_enlightened_vmcs *hv_evmcs = nested_vmx_evmcs(vmx);
  
        if (!hv_evmcs || !(hv_evmcs->hv_clean_fields &
                           HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP2)) {
@@@ -2572,15 -2535,15 +2572,15 @@@ static int prepare_vmcs02(struct kvm_vc
                          enum vm_entry_failure_code *entry_failure_code)
  {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
 +      struct hv_enlightened_vmcs *evmcs = nested_vmx_evmcs(vmx);
        bool load_guest_pdptrs_vmcs12 = false;
  
 -      if (vmx->nested.dirty_vmcs12 || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
 +      if (vmx->nested.dirty_vmcs12 || nested_vmx_is_evmptr12_valid(vmx)) {
                prepare_vmcs02_rare(vmx, vmcs12);
                vmx->nested.dirty_vmcs12 = false;
  
 -              load_guest_pdptrs_vmcs12 = !evmptr_is_valid(vmx->nested.hv_evmcs_vmptr) ||
 -                      !(vmx->nested.hv_evmcs->hv_clean_fields &
 -                        HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1);
 +              load_guest_pdptrs_vmcs12 = !nested_vmx_is_evmptr12_valid(vmx) ||
 +                      !(evmcs->hv_clean_fields & HV_VMX_ENLIGHTENED_CLEAN_FIELD_GUEST_GRP1);
        }
  
        if (vmx->nested.nested_run_pending &&
         * bits when it changes a field in eVMCS. Mark all fields as clean
         * here.
         */
 -      if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 -              vmx->nested.hv_evmcs->hv_clean_fields |=
 -                      HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL;
 +      if (nested_vmx_is_evmptr12_valid(vmx))
 +              evmcs->hv_clean_fields |= HV_VMX_ENLIGHTENED_CLEAN_FIELD_ALL;
  
        return 0;
  }
@@@ -2753,7 -2717,7 +2753,7 @@@ static bool nested_vmx_check_eptp(struc
        }
  
        /* Reserved bits should not be set */
-       if (CC(kvm_vcpu_is_illegal_gpa(vcpu, new_eptp) || ((new_eptp >> 7) & 0x1f)))
+       if (CC(!kvm_vcpu_is_legal_gpa(vcpu, new_eptp) || ((new_eptp >> 7) & 0x1f)))
                return false;
  
        /* AD, if set, should be supported */
@@@ -2924,10 -2888,8 +2924,10 @@@ static int nested_vmx_check_controls(st
            nested_check_vm_entry_controls(vcpu, vmcs12))
                return -EINVAL;
  
 +#ifdef CONFIG_KVM_HYPERV
        if (guest_cpuid_has_evmcs(vcpu))
                return nested_evmcs_check_controls(vmcs12);
 +#endif
  
        return 0;
  }
@@@ -2950,7 -2912,7 +2950,7 @@@ static int nested_vmx_check_host_state(
  
        if (CC(!nested_host_cr0_valid(vcpu, vmcs12->host_cr0)) ||
            CC(!nested_host_cr4_valid(vcpu, vmcs12->host_cr4)) ||
-           CC(kvm_vcpu_is_illegal_gpa(vcpu, vmcs12->host_cr3)))
+           CC(!kvm_vcpu_is_legal_cr3(vcpu, vmcs12->host_cr3)))
                return -EINVAL;
  
        if (CC(is_noncanonical_address(vmcs12->host_ia32_sysenter_esp, vcpu)) ||
@@@ -3199,7 -3161,6 +3199,7 @@@ static int nested_vmx_check_vmentry_hw(
        return 0;
  }
  
 +#ifdef CONFIG_KVM_HYPERV
  static bool nested_get_evmcs_page(struct kvm_vcpu *vcpu)
  {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
  
        return true;
  }
 +#endif
  
  static bool nested_get_vmcs12_pages(struct kvm_vcpu *vcpu)
  {
  
  static bool vmx_get_nested_state_pages(struct kvm_vcpu *vcpu)
  {
 +#ifdef CONFIG_KVM_HYPERV
        /*
         * Note: nested_get_evmcs_page() also updates 'vp_assist_page' copy
         * in 'struct kvm_vcpu_hv' in case eVMCS is in use, this is mandatory
  
                return false;
        }
 +#endif
  
        if (is_guest_mode(vcpu) && !nested_get_vmcs12_pages(vcpu))
                return false;
@@@ -3580,7 -3538,7 +3580,7 @@@ vmentry_fail_vmexit
  
        load_vmcs12_host_state(vcpu, vmcs12);
        vmcs12->vm_exit_reason = exit_reason.full;
 -      if (enable_shadow_vmcs || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 +      if (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx))
                vmx->nested.need_vmcs12_to_shadow_sync = true;
        return NVMX_VMENTRY_VMEXIT;
  }
@@@ -3611,7 -3569,7 +3611,7 @@@ static int nested_vmx_run(struct kvm_vc
        if (CC(evmptrld_status == EVMPTRLD_VMFAIL))
                return nested_vmx_failInvalid(vcpu);
  
 -      if (CC(!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr) &&
 +      if (CC(!nested_vmx_is_evmptr12_valid(vmx) &&
               vmx->nested.current_vmptr == INVALID_GPA))
                return nested_vmx_failInvalid(vcpu);
  
        if (CC(vmcs12->hdr.shadow_vmcs))
                return nested_vmx_failInvalid(vcpu);
  
 -      if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
 -              copy_enlightened_to_vmcs12(vmx, vmx->nested.hv_evmcs->hv_clean_fields);
 +      if (nested_vmx_is_evmptr12_valid(vmx)) {
 +              struct hv_enlightened_vmcs *evmcs = nested_vmx_evmcs(vmx);
 +
 +              copy_enlightened_to_vmcs12(vmx, evmcs->hv_clean_fields);
                /* Enlightened VMCS doesn't have launch state */
                vmcs12->launch_state = !launch;
        } else if (enable_shadow_vmcs) {
@@@ -4373,11 -4329,11 +4373,11 @@@ static void sync_vmcs02_to_vmcs12(struc
  {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
  
 -      if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 +      if (nested_vmx_is_evmptr12_valid(vmx))
                sync_vmcs02_to_vmcs12_rare(vcpu, vmcs12);
  
        vmx->nested.need_sync_vmcs02_to_vmcs12_rare =
 -              !evmptr_is_valid(vmx->nested.hv_evmcs_vmptr);
 +              !nested_vmx_is_evmptr12_valid(vmx);
  
        vmcs12->guest_cr0 = vmcs12_guest_cr0(vcpu, vmcs12);
        vmcs12->guest_cr4 = vmcs12_guest_cr4(vcpu, vmcs12);
@@@ -4776,7 -4732,6 +4776,7 @@@ void nested_vmx_vmexit(struct kvm_vcpu 
        /* trying to cancel vmlaunch/vmresume is a bug */
        WARN_ON_ONCE(vmx->nested.nested_run_pending);
  
 +#ifdef CONFIG_KVM_HYPERV
        if (kvm_check_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu)) {
                /*
                 * KVM_REQ_GET_NESTED_STATE_PAGES is also used to map
                 */
                (void)nested_get_evmcs_page(vcpu);
        }
 +#endif
  
        /* Service pending TLB flush requests for L2 before switching to L1. */
        kvm_service_local_tlb_flush_requests(vcpu);
        }
  
        if ((vm_exit_reason != -1) &&
 -          (enable_shadow_vmcs || evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)))
 +          (enable_shadow_vmcs || nested_vmx_is_evmptr12_valid(vmx)))
                vmx->nested.need_vmcs12_to_shadow_sync = true;
  
        /* in case we halted in L2 */
@@@ -5026,6 -4980,7 +5026,7 @@@ int get_vmx_mem_address(struct kvm_vcp
                else
                        *ret = off;
  
+               *ret = vmx_get_untagged_addr(vcpu, *ret, 0);
                /* Long mode: #GP(0)/#SS(0) if the memory address is in a
                 * non-canonical form. This is the only check on the memory
                 * destination for long mode!
@@@ -5338,7 -5293,18 +5339,7 @@@ static int handle_vmclear(struct kvm_vc
        if (vmptr == vmx->nested.vmxon_ptr)
                return nested_vmx_fail(vcpu, VMXERR_VMCLEAR_VMXON_POINTER);
  
 -      /*
 -       * When Enlightened VMEntry is enabled on the calling CPU we treat
 -       * memory area pointer by vmptr as Enlightened VMCS (as there's no good
 -       * way to distinguish it from VMCS12) and we must not corrupt it by
 -       * writing to the non-existent 'launch_state' field. The area doesn't
 -       * have to be the currently active EVMCS on the calling CPU and there's
 -       * nothing KVM has to do to transition it from 'active' to 'non-active'
 -       * state. It is possible that the area will stay mapped as
 -       * vmx->nested.hv_evmcs but this shouldn't be a problem.
 -       */
 -      if (likely(!guest_cpuid_has_evmcs(vcpu) ||
 -                 !evmptr_is_valid(nested_get_evmptr(vcpu)))) {
 +      if (likely(!nested_evmcs_handle_vmclear(vcpu, vmptr))) {
                if (vmptr == vmx->nested.current_vmptr)
                        nested_release_vmcs12(vcpu);
  
                                           vmptr + offsetof(struct vmcs12,
                                                            launch_state),
                                           &zero, sizeof(zero));
 -      } else if (vmx->nested.hv_evmcs && vmptr == vmx->nested.hv_evmcs_vmptr) {
 -              nested_release_evmcs(vcpu);
        }
  
        return nested_vmx_succeed(vcpu);
@@@ -5393,7 -5361,7 +5394,7 @@@ static int handle_vmread(struct kvm_vcp
        /* Decode instruction info and find the field to read */
        field = kvm_register_read(vcpu, (((instr_info) >> 28) & 0xf));
  
 -      if (!evmptr_is_valid(vmx->nested.hv_evmcs_vmptr)) {
 +      if (!nested_vmx_is_evmptr12_valid(vmx)) {
                /*
                 * In VMX non-root operation, when the VMCS-link pointer is INVALID_GPA,
                 * any VMREAD sets the ALU flags for VMfailInvalid.
                        return nested_vmx_fail(vcpu, VMXERR_UNSUPPORTED_VMCS_COMPONENT);
  
                /* Read the field, zero-extended to a u64 value */
 -              value = evmcs_read_any(vmx->nested.hv_evmcs, field, offset);
 +              value = evmcs_read_any(nested_vmx_evmcs(vmx), field, offset);
        }
  
        /*
@@@ -5619,7 -5587,7 +5620,7 @@@ static int handle_vmptrld(struct kvm_vc
                return nested_vmx_fail(vcpu, VMXERR_VMPTRLD_VMXON_POINTER);
  
        /* Forbid normal VMPTRLD if Enlightened version was used */
 -      if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 +      if (nested_vmx_is_evmptr12_valid(vmx))
                return 1;
  
        if (vmx->nested.current_vmptr != vmptr) {
@@@ -5682,7 -5650,7 +5683,7 @@@ static int handle_vmptrst(struct kvm_vc
        if (!nested_vmx_check_permission(vcpu))
                return 1;
  
 -      if (unlikely(evmptr_is_valid(to_vmx(vcpu)->nested.hv_evmcs_vmptr)))
 +      if (unlikely(nested_vmx_is_evmptr12_valid(to_vmx(vcpu))))
                return 1;
  
        if (get_vmx_mem_address(vcpu, exit_qual, instr_info,
@@@ -5830,6 -5798,10 +5831,10 @@@ static int handle_invvpid(struct kvm_vc
        vpid02 = nested_get_vpid02(vcpu);
        switch (type) {
        case VMX_VPID_EXTENT_INDIVIDUAL_ADDR:
+               /*
+                * LAM doesn't apply to addresses that are inputs to TLB
+                * invalidation.
+                */
                if (!operand.vpid ||
                    is_noncanonical_address(operand.gla, vcpu))
                        return nested_vmx_fail(vcpu,
@@@ -6241,13 -6213,11 +6246,13 @@@ static bool nested_vmx_l0_wants_exit(st
                 * Handle L2's bus locks in L0 directly.
                 */
                return true;
 +#ifdef CONFIG_KVM_HYPERV
        case EXIT_REASON_VMCALL:
                /* Hyper-V L2 TLB flush hypercall is handled by L0 */
                return guest_hv_cpuid_has_l2_tlb_flush(vcpu) &&
                        nested_evmcs_l2_tlb_flush_enabled(vcpu) &&
                        kvm_hv_is_tlb_flush_hcall(vcpu);
 +#endif
        default:
                break;
        }
@@@ -6470,7 -6440,7 +6475,7 @@@ static int vmx_get_nested_state(struct 
                        kvm_state.size += sizeof(user_vmx_nested_state->vmcs12);
  
                        /* 'hv_evmcs_vmptr' can also be EVMPTR_MAP_PENDING here */
 -                      if (vmx->nested.hv_evmcs_vmptr != EVMPTR_INVALID)
 +                      if (nested_vmx_is_evmptr12_set(vmx))
                                kvm_state.flags |= KVM_STATE_NESTED_EVMCS;
  
                        if (is_guest_mode(vcpu) &&
        } else  {
                copy_vmcs02_to_vmcs12_rare(vcpu, get_vmcs12(vcpu));
                if (!vmx->nested.need_vmcs12_to_shadow_sync) {
 -                      if (evmptr_is_valid(vmx->nested.hv_evmcs_vmptr))
 +                      if (nested_vmx_is_evmptr12_valid(vmx))
                                /*
                                 * L1 hypervisor is not obliged to keep eVMCS
                                 * clean fields data always up-to-date while
@@@ -6667,7 -6637,6 +6672,7 @@@ static int vmx_set_nested_state(struct 
                        return -EINVAL;
  
                set_current_vmptr(vmx, kvm_state->hdr.vmx.vmcs12_pa);
 +#ifdef CONFIG_KVM_HYPERV
        } else if (kvm_state->flags & KVM_STATE_NESTED_EVMCS) {
                /*
                 * nested_vmx_handle_enlightened_vmptrld() cannot be called
                 */
                vmx->nested.hv_evmcs_vmptr = EVMPTR_MAP_PENDING;
                kvm_make_request(KVM_REQ_GET_NESTED_STATE_PAGES, vcpu);
 +#endif
        } else {
                return -EINVAL;
        }
@@@ -7133,9 -7101,7 +7138,9 @@@ struct kvm_x86_nested_ops vmx_nested_op
        .set_state = vmx_set_nested_state,
        .get_nested_state_pages = vmx_get_nested_state_pages,
        .write_log_dirty = nested_vmx_write_pml_buffer,
 +#ifdef CONFIG_KVM_HYPERV
        .enable_evmcs = nested_enable_evmcs,
        .get_evmcs_version = nested_get_evmcs_version,
        .hv_inject_synthetic_vmexit_post_tlb_flush = vmx_hv_inject_synthetic_vmexit_post_tlb_flush,
 +#endif
  };
diff --combined arch/x86/kvm/vmx/vmx.c
index a26603ddc968fe172702052a7793a94911c3b3f0,d30df9b3fe3e52012634fafd305a267103b14eb7..d21f55f323ea24000e115032338823879de9c997
@@@ -66,7 -66,6 +66,7 @@@
  #include "vmx.h"
  #include "x86.h"
  #include "smm.h"
 +#include "vmx_onhyperv.h"
  
  MODULE_AUTHOR("Qumranet");
  MODULE_LICENSE("GPL");
@@@ -524,14 -523,22 +524,14 @@@ module_param(enlightened_vmcs, bool, 04
  static int hv_enable_l2_tlb_flush(struct kvm_vcpu *vcpu)
  {
        struct hv_enlightened_vmcs *evmcs;
 -      struct hv_partition_assist_pg **p_hv_pa_pg =
 -                      &to_kvm_hv(vcpu->kvm)->hv_pa_pg;
 -      /*
 -       * Synthetic VM-Exit is not enabled in current code and so All
 -       * evmcs in singe VM shares same assist page.
 -       */
 -      if (!*p_hv_pa_pg)
 -              *p_hv_pa_pg = kzalloc(PAGE_SIZE, GFP_KERNEL_ACCOUNT);
 +      hpa_t partition_assist_page = hv_get_partition_assist_page(vcpu);
  
 -      if (!*p_hv_pa_pg)
 +      if (partition_assist_page == INVALID_PAGE)
                return -ENOMEM;
  
        evmcs = (struct hv_enlightened_vmcs *)to_vmx(vcpu)->loaded_vmcs->vmcs;
  
 -      evmcs->partition_assist_page =
 -              __pa(*p_hv_pa_pg);
 +      evmcs->partition_assist_page = partition_assist_page;
        evmcs->hv_vm_id = (unsigned long)vcpu->kvm;
        evmcs->hv_enlightenments_control.nested_flush_hypercall = 1;
  
@@@ -2048,7 -2055,6 +2048,7 @@@ static int vmx_get_msr(struct kvm_vcpu 
                if (vmx_get_vmx_msr(&vmx->nested.msrs, msr_info->index,
                                    &msr_info->data))
                        return 1;
 +#ifdef CONFIG_KVM_HYPERV
                /*
                 * Enlightened VMCS v1 doesn't have certain VMCS fields but
                 * instead of just ignoring the features, different Hyper-V
                if (!msr_info->host_initiated && guest_cpuid_has_evmcs(vcpu))
                        nested_evmcs_filter_control_msr(vcpu, msr_info->index,
                                                        &msr_info->data);
 +#endif
                break;
        case MSR_IA32_RTIT_CTL:
                if (!vmx_pt_mode_is_host_guest())
@@@ -3395,7 -3400,8 +3395,8 @@@ static void vmx_load_mmu_pgd(struct kvm
                        update_guest_cr3 = false;
                vmx_ept_load_pdptrs(vcpu);
        } else {
-               guest_cr3 = root_hpa | kvm_get_active_pcid(vcpu);
+               guest_cr3 = root_hpa | kvm_get_active_pcid(vcpu) |
+                           kvm_get_active_cr3_lam_bits(vcpu);
        }
  
        if (update_guest_cr3)
@@@ -4828,10 -4834,7 +4829,10 @@@ static void __vmx_vcpu_reset(struct kvm
        vmx->nested.posted_intr_nv = -1;
        vmx->nested.vmxon_ptr = INVALID_GPA;
        vmx->nested.current_vmptr = INVALID_GPA;
 +
 +#ifdef CONFIG_KVM_HYPERV
        vmx->nested.hv_evmcs_vmptr = EVMPTR_INVALID;
 +#endif
  
        vcpu->arch.microcode_version = 0x100000000ULL;
        vmx->msr_ia32_feature_control_valid_bits = FEAT_CTL_LOCKED;
@@@ -5780,7 -5783,7 +5781,7 @@@ static int handle_ept_violation(struct 
         * would also use advanced VM-exit information for EPT violations to
         * reconstruct the page fault error code.
         */
-       if (unlikely(allow_smaller_maxphyaddr && kvm_vcpu_is_illegal_gpa(vcpu, gpa)))
+       if (unlikely(allow_smaller_maxphyaddr && !kvm_vcpu_is_legal_gpa(vcpu, gpa)))
                return kvm_emulate_instruction(vcpu, 0);
  
        return kvm_mmu_page_fault(vcpu, gpa, error_code, NULL, 0);
@@@ -7671,6 -7674,9 +7672,9 @@@ static void nested_vmx_cr_fixed1_bits_u
        cr4_fixed1_update(X86_CR4_UMIP,       ecx, feature_bit(UMIP));
        cr4_fixed1_update(X86_CR4_LA57,       ecx, feature_bit(LA57));
  
+       entry = kvm_find_cpuid_entry_index(vcpu, 0x7, 1);
+       cr4_fixed1_update(X86_CR4_LAM_SUP,    eax, feature_bit(LAM));
  #undef cr4_fixed1_update
  }
  
@@@ -7757,6 -7763,7 +7761,7 @@@ static void vmx_vcpu_after_set_cpuid(st
                kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_XSAVES);
  
        kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_VMX);
+       kvm_governed_feature_check_and_set(vcpu, X86_FEATURE_LAM);
  
        vmx_setup_uret_msrs(vmx);
  
@@@ -8203,6 -8210,50 +8208,50 @@@ static void vmx_vm_destroy(struct kvm *
        free_pages((unsigned long)kvm_vmx->pid_table, vmx_get_pid_table_order(kvm));
  }
  
+ /*
+  * Note, the SDM states that the linear address is masked *after* the modified
+  * canonicality check, whereas KVM masks (untags) the address and then performs
+  * a "normal" canonicality check.  Functionally, the two methods are identical,
+  * and when the masking occurs relative to the canonicality check isn't visible
+  * to software, i.e. KVM's behavior doesn't violate the SDM.
+  */
+ gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags)
+ {
+       int lam_bit;
+       unsigned long cr3_bits;
+       if (flags & (X86EMUL_F_FETCH | X86EMUL_F_IMPLICIT | X86EMUL_F_INVLPG))
+               return gva;
+       if (!is_64_bit_mode(vcpu))
+               return gva;
+       /*
+        * Bit 63 determines if the address should be treated as user address
+        * or a supervisor address.
+        */
+       if (!(gva & BIT_ULL(63))) {
+               cr3_bits = kvm_get_active_cr3_lam_bits(vcpu);
+               if (!(cr3_bits & (X86_CR3_LAM_U57 | X86_CR3_LAM_U48)))
+                       return gva;
+               /* LAM_U48 is ignored if LAM_U57 is set. */
+               lam_bit = cr3_bits & X86_CR3_LAM_U57 ? 56 : 47;
+       } else {
+               if (!kvm_is_cr4_bit_set(vcpu, X86_CR4_LAM_SUP))
+                       return gva;
+               lam_bit = kvm_is_cr4_bit_set(vcpu, X86_CR4_LA57) ? 56 : 47;
+       }
+       /*
+        * Untag the address by sign-extending the lam_bit, but NOT to bit 63.
+        * Bit 63 is retained from the raw virtual address so that untagging
+        * doesn't change a user access to a supervisor access, and vice versa.
+        */
+       return (sign_extend64(gva, lam_bit) & ~BIT_ULL(63)) | (gva & BIT_ULL(63));
+ }
  static struct kvm_x86_ops vmx_x86_ops __initdata = {
        .name = KBUILD_MODNAME,
  
        .complete_emulated_msr = kvm_complete_insn_gp,
  
        .vcpu_deliver_sipi_vector = kvm_vcpu_deliver_sipi_vector,
+       .get_untagged_addr = vmx_get_untagged_addr,
  };
  
  static unsigned int vmx_handle_intel_pt_intr(void)
diff --combined arch/x86/kvm/vmx/vmx.h
index 8fe6eb2b4a34c41225ad55fc611dc3776fee9ef7,45cee1a8bc0a413bd95f01bb24caa036ae8ada64..e3b0985bb74a1f4d57be41cbb0d283abbc476625
@@@ -241,11 -241,9 +241,11 @@@ struct nested_vmx 
                bool guest_mode;
        } smm;
  
 +#ifdef CONFIG_KVM_HYPERV
        gpa_t hv_evmcs_vmptr;
        struct kvm_host_map hv_evmcs_map;
        struct hv_enlightened_vmcs *hv_evmcs;
 +#endif
  };
  
  struct vcpu_vmx {
@@@ -422,6 -420,8 +422,8 @@@ void vmx_enable_intercept_for_msr(struc
  u64 vmx_get_l2_tsc_offset(struct kvm_vcpu *vcpu);
  u64 vmx_get_l2_tsc_multiplier(struct kvm_vcpu *vcpu);
  
+ gva_t vmx_get_untagged_addr(struct kvm_vcpu *vcpu, gva_t gva, unsigned int flags);
  static inline void vmx_set_intercept_for_msr(struct kvm_vcpu *vcpu, u32 msr,
                                             int type, bool value)
  {
@@@ -747,4 -747,14 +749,4 @@@ static inline bool vmx_can_use_ipiv(str
        return  lapic_in_kernel(vcpu) && enable_ipiv;
  }
  
 -static inline bool guest_cpuid_has_evmcs(struct kvm_vcpu *vcpu)
 -{
 -      /*
 -       * eVMCS is exposed to the guest if Hyper-V is enabled in CPUID and
 -       * eVMCS has been explicitly enabled by userspace.
 -       */
 -      return vcpu->arch.hyperv_enabled &&
 -             to_vmx(vcpu)->nested.enlightened_vmcs_enabled;
 -}
 -
  #endif /* __KVM_X86_VMX_H */
diff --combined arch/x86/kvm/x86.c
index 242a8417ef227a4867ebd2b7ae6479d28c8c4a94,ecfe97aa35c2a6c4a414542cabd19f06068628a2..0366eca119d70f1089ff27e4bbf00a23aa04f090
@@@ -1284,7 -1284,7 +1284,7 @@@ int kvm_set_cr3(struct kvm_vcpu *vcpu, 
         * stuff CR3, e.g. for RSM emulation, and there is no guarantee that
         * the current vCPU mode is accurate.
         */
-       if (kvm_vcpu_is_illegal_gpa(vcpu, cr3))
+       if (!kvm_vcpu_is_legal_cr3(vcpu, cr3))
                return 1;
  
        if (is_pae_paging(vcpu) && !load_pdptrs(vcpu, cr3))
@@@ -1504,8 -1504,6 +1504,8 @@@ 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_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,
@@@ -2513,29 -2510,26 +2513,29 @@@ static inline int gtod_is_based_on_tsc(
  }
  #endif
  
 -static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
 +static void kvm_track_tsc_matching(struct kvm_vcpu *vcpu, bool new_generation)
  {
  #ifdef CONFIG_X86_64
 -      bool vcpus_matched;
        struct kvm_arch *ka = &vcpu->kvm->arch;
        struct pvclock_gtod_data *gtod = &pvclock_gtod_data;
  
 -      vcpus_matched = (ka->nr_vcpus_matched_tsc + 1 ==
 -                       atomic_read(&vcpu->kvm->online_vcpus));
 +      /*
 +       * To use the masterclock, the host clocksource must be based on TSC
 +       * and all vCPUs must have matching TSCs.  Note, the count for matching
 +       * vCPUs doesn't include the reference vCPU, hence "+1".
 +       */
 +      bool use_master_clock = (ka->nr_vcpus_matched_tsc + 1 ==
 +                               atomic_read(&vcpu->kvm->online_vcpus)) &&
 +                              gtod_is_based_on_tsc(gtod->clock.vclock_mode);
  
        /*
 -       * Once the masterclock is enabled, always perform request in
 -       * order to update it.
 -       *
 -       * In order to enable masterclock, the host clocksource must be TSC
 -       * and the vcpus need to have matched TSCs.  When that happens,
 -       * perform request to enable masterclock.
 +       * Request a masterclock update if the masterclock needs to be toggled
 +       * on/off, or when starting a new generation and the masterclock is
 +       * enabled (compute_guest_tsc() requires the masterclock snapshot to be
 +       * taken _after_ the new generation is created).
         */
 -      if (ka->use_master_clock ||
 -          (gtod_is_based_on_tsc(gtod->clock.vclock_mode) && vcpus_matched))
 +      if ((ka->use_master_clock && new_generation) ||
 +          (ka->use_master_clock != use_master_clock))
                kvm_make_request(KVM_REQ_MASTERCLOCK_UPDATE, vcpu);
  
        trace_kvm_track_tsc(vcpu->vcpu_id, ka->nr_vcpus_matched_tsc,
@@@ -2712,7 -2706,7 +2712,7 @@@ static void __kvm_synchronize_tsc(struc
        vcpu->arch.this_tsc_nsec = kvm->arch.cur_tsc_nsec;
        vcpu->arch.this_tsc_write = kvm->arch.cur_tsc_write;
  
 -      kvm_track_tsc_matching(vcpu);
 +      kvm_track_tsc_matching(vcpu, !matched);
  }
  
  static void kvm_synchronize_tsc(struct kvm_vcpu *vcpu, u64 *user_value)
@@@ -4026,7 -4020,6 +4026,7 @@@ int kvm_set_msr_common(struct kvm_vcpu 
                 * 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_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.
@@@ -4385,7 -4377,6 +4385,7 @@@ int kvm_get_msr_common(struct kvm_vcpu 
                 */
                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:
                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
@@@ -4537,7 -4527,6 +4537,7 @@@ static inline bool kvm_can_mwait_in_gue
                boot_cpu_has(X86_FEATURE_ARAT);
  }
  
 +#ifdef CONFIG_KVM_HYPERV
  static int kvm_ioctl_get_supported_hv_cpuid(struct kvm_vcpu *vcpu,
                                            struct kvm_cpuid2 __user *cpuid_arg)
  {
  
        return 0;
  }
 +#endif
  
  static bool kvm_is_vm_type_supported(unsigned long type)
  {
@@@ -4592,11 -4580,9 +4592,11 @@@ int kvm_vm_ioctl_check_extension(struc
        case KVM_CAP_PIT_STATE2:
        case KVM_CAP_SET_IDENTITY_MAP_ADDR:
        case KVM_CAP_VCPU_EVENTS:
 +#ifdef CONFIG_KVM_HYPERV
        case KVM_CAP_HYPERV:
        case KVM_CAP_HYPERV_VAPIC:
        case KVM_CAP_HYPERV_SPIN:
 +      case KVM_CAP_HYPERV_TIME:
        case KVM_CAP_HYPERV_SYNIC:
        case KVM_CAP_HYPERV_SYNIC2:
        case KVM_CAP_HYPERV_VP_INDEX:
        case KVM_CAP_HYPERV_CPUID:
        case KVM_CAP_HYPERV_ENFORCE_CPUID:
        case KVM_CAP_SYS_HYPERV_CPUID:
 +#endif
        case KVM_CAP_PCI_SEGMENT:
        case KVM_CAP_DEBUGREGS:
        case KVM_CAP_X86_ROBUST_SINGLESTEP:
        case KVM_CAP_GET_TSC_KHZ:
        case KVM_CAP_KVMCLOCK_CTRL:
        case KVM_CAP_READONLY_MEM:
 -      case KVM_CAP_HYPERV_TIME:
        case KVM_CAP_IOAPIC_POLARITY_IGNORED:
        case KVM_CAP_TSC_DEADLINE_TIMER:
        case KVM_CAP_DISABLE_QUIRKS:
                r = kvm_x86_ops.nested_ops->get_state ?
                        kvm_x86_ops.nested_ops->get_state(NULL, NULL, 0) : 0;
                break;
 +#ifdef CONFIG_KVM_HYPERV
        case KVM_CAP_HYPERV_DIRECT_TLBFLUSH:
                r = kvm_x86_ops.enable_l2_tlb_flush != NULL;
                break;
        case KVM_CAP_HYPERV_ENLIGHTENED_VMCS:
                r = kvm_x86_ops.nested_ops->enable_evmcs != NULL;
                break;
 +#endif
        case KVM_CAP_SMALLER_MAXPHYADDR:
                r = (int) allow_smaller_maxphyaddr;
                break;
@@@ -4900,11 -4884,9 +4900,11 @@@ long kvm_arch_dev_ioctl(struct file *fi
        case KVM_GET_MSRS:
                r = msr_io(NULL, argp, do_get_msr_feature, 1);
                break;
 +#ifdef CONFIG_KVM_HYPERV
        case KVM_GET_SUPPORTED_HV_CPUID:
                r = kvm_ioctl_get_supported_hv_cpuid(NULL, argp);
                break;
 +#endif
        case KVM_GET_DEVICE_ATTR: {
                struct kvm_device_attr attr;
                r = -EFAULT;
@@@ -5549,8 -5531,8 +5549,8 @@@ static void kvm_vcpu_ioctl_x86_get_xsav
  static void kvm_vcpu_ioctl_x86_get_xsave(struct kvm_vcpu *vcpu,
                                         struct kvm_xsave *guest_xsave)
  {
 -      return kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region,
 -                                           sizeof(guest_xsave->region));
 +      kvm_vcpu_ioctl_x86_get_xsave2(vcpu, (void *)guest_xsave->region,
 +                                    sizeof(guest_xsave->region));
  }
  
  static int kvm_vcpu_ioctl_x86_set_xsave(struct kvm_vcpu *vcpu,
@@@ -5730,11 -5712,14 +5730,11 @@@ static int kvm_vcpu_ioctl_device_attr(s
  static int kvm_vcpu_ioctl_enable_cap(struct kvm_vcpu *vcpu,
                                     struct kvm_enable_cap *cap)
  {
 -      int r;
 -      uint16_t vmcs_version;
 -      void __user *user_ptr;
 -
        if (cap->flags)
                return -EINVAL;
  
        switch (cap->cap) {
 +#ifdef CONFIG_KVM_HYPERV
        case KVM_CAP_HYPERV_SYNIC2:
                if (cap->args[0])
                        return -EINVAL;
                return kvm_hv_activate_synic(vcpu, cap->cap ==
                                             KVM_CAP_HYPERV_SYNIC2);
        case KVM_CAP_HYPERV_ENLIGHTENED_VMCS:
 -              if (!kvm_x86_ops.nested_ops->enable_evmcs)
 -                      return -ENOTTY;
 -              r = kvm_x86_ops.nested_ops->enable_evmcs(vcpu, &vmcs_version);
 -              if (!r) {
 -                      user_ptr = (void __user *)(uintptr_t)cap->args[0];
 -                      if (copy_to_user(user_ptr, &vmcs_version,
 -                                       sizeof(vmcs_version)))
 -                              r = -EFAULT;
 +              {
 +                      int r;
 +                      uint16_t vmcs_version;
 +                      void __user *user_ptr;
 +
 +                      if (!kvm_x86_ops.nested_ops->enable_evmcs)
 +                              return -ENOTTY;
 +                      r = kvm_x86_ops.nested_ops->enable_evmcs(vcpu, &vmcs_version);
 +                      if (!r) {
 +                              user_ptr = (void __user *)(uintptr_t)cap->args[0];
 +                              if (copy_to_user(user_ptr, &vmcs_version,
 +                                               sizeof(vmcs_version)))
 +                                      r = -EFAULT;
 +                      }
 +                      return r;
                }
 -              return r;
        case KVM_CAP_HYPERV_DIRECT_TLBFLUSH:
                if (!kvm_x86_ops.enable_l2_tlb_flush)
                        return -ENOTTY;
  
        case KVM_CAP_HYPERV_ENFORCE_CPUID:
                return kvm_hv_set_enforce_cpuid(vcpu, cap->args[0]);
 +#endif
  
        case KVM_CAP_ENFORCE_PV_FEATURE_CPUID:
                vcpu->arch.pv_cpuid.enforce = cap->args[0];
@@@ -6163,11 -6141,9 +6163,11 @@@ long kvm_arch_vcpu_ioctl(struct file *f
                srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
        }
 +#ifdef CONFIG_KVM_HYPERV
        case KVM_GET_SUPPORTED_HV_CPUID:
                r = kvm_ioctl_get_supported_hv_cpuid(vcpu, argp);
                break;
 +#endif
  #ifdef CONFIG_KVM_XEN
        case KVM_XEN_VCPU_GET_ATTR: {
                struct kvm_xen_vcpu_attr xva;
@@@ -7225,7 -7201,6 +7225,7 @@@ set_pit2_out
                r = static_call(kvm_x86_mem_enc_unregister_region)(kvm, &region);
                break;
        }
 +#ifdef CONFIG_KVM_HYPERV
        case KVM_HYPERV_EVENTFD: {
                struct kvm_hyperv_eventfd hvevfd;
  
                r = kvm_vm_ioctl_hv_eventfd(kvm, &hvevfd);
                break;
        }
 +#endif
        case KVM_SET_PMU_EVENT_FILTER:
                r = kvm_vm_ioctl_set_pmu_event_filter(kvm, argp);
                break;
@@@ -8471,6 -8445,15 +8471,15 @@@ static void emulator_vm_bugged(struct x
                kvm_vm_bugged(kvm);
  }
  
+ static gva_t emulator_get_untagged_addr(struct x86_emulate_ctxt *ctxt,
+                                       gva_t addr, unsigned int flags)
+ {
+       if (!kvm_x86_ops.get_untagged_addr)
+               return addr;
+       return static_call(kvm_x86_get_untagged_addr)(emul_to_vcpu(ctxt), addr, flags);
+ }
  static const struct x86_emulate_ops emulate_ops = {
        .vm_bugged           = emulator_vm_bugged,
        .read_gpr            = emulator_read_gpr,
        .leave_smm           = emulator_leave_smm,
        .triple_fault        = emulator_triple_fault,
        .set_xcr             = emulator_set_xcr,
+       .get_untagged_addr   = emulator_get_untagged_addr,
  };
  
  static void toggle_interruptibility(struct kvm_vcpu *vcpu, u32 mask)
@@@ -10614,20 -10598,19 +10624,20 @@@ static void vcpu_scan_ioapic(struct kvm
  
  static void vcpu_load_eoi_exitmap(struct kvm_vcpu *vcpu)
  {
 -      u64 eoi_exit_bitmap[4];
 -
        if (!kvm_apic_hw_enabled(vcpu->arch.apic))
                return;
  
 +#ifdef CONFIG_KVM_HYPERV
        if (to_hv_vcpu(vcpu)) {
 +              u64 eoi_exit_bitmap[4];
 +
                bitmap_or((ulong *)eoi_exit_bitmap,
                          vcpu->arch.ioapic_handled_vectors,
                          to_hv_synic(vcpu)->vec_bitmap, 256);
                static_call_cond(kvm_x86_load_eoi_exitmap)(vcpu, eoi_exit_bitmap);
                return;
        }
 -
 +#endif
        static_call_cond(kvm_x86_load_eoi_exitmap)(
                vcpu, (u64 *)vcpu->arch.ioapic_handled_vectors);
  }
@@@ -10718,11 -10701,9 +10728,11 @@@ static int vcpu_enter_guest(struct kvm_
                 * the flushes are considered "remote" and not "local" because
                 * the requests can be initiated from other vCPUs.
                 */
 +#ifdef CONFIG_KVM_HYPERV
                if (kvm_check_request(KVM_REQ_HV_TLB_FLUSH, vcpu) &&
                    kvm_hv_vcpu_flush_tlb(vcpu))
                        kvm_vcpu_flush_tlb_guest(vcpu);
 +#endif
  
                if (kvm_check_request(KVM_REQ_REPORT_TPR_ACCESS, vcpu)) {
                        vcpu->run->exit_reason = KVM_EXIT_TPR_ACCESS;
                        vcpu_load_eoi_exitmap(vcpu);
                if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
                        kvm_vcpu_reload_apic_access_page(vcpu);
 +#ifdef CONFIG_KVM_HYPERV
                if (kvm_check_request(KVM_REQ_HV_CRASH, vcpu)) {
                        vcpu->run->exit_reason = KVM_EXIT_SYSTEM_EVENT;
                        vcpu->run->system_event.type = KVM_SYSTEM_EVENT_CRASH;
                 */
                if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
                        kvm_hv_process_stimers(vcpu);
 +#endif
                if (kvm_check_request(KVM_REQ_APICV_UPDATE, vcpu))
                        kvm_vcpu_update_apicv(vcpu);
                if (kvm_check_request(KVM_REQ_APF_READY, vcpu))
@@@ -11643,7 -11622,7 +11653,7 @@@ static bool kvm_is_valid_sregs(struct k
                 */
                if (!(sregs->cr4 & X86_CR4_PAE) || !(sregs->efer & EFER_LMA))
                        return false;
-               if (kvm_vcpu_is_illegal_gpa(vcpu, sregs->cr3))
+               if (!kvm_vcpu_is_legal_cr3(vcpu, sregs->cr3))
                        return false;
        } else {
                /*
@@@ -12252,6 -12231,7 +12262,6 @@@ void kvm_vcpu_reset(struct kvm_vcpu *vc
        }
  
        if (!init_event) {
 -              kvm_pmu_reset(vcpu);
                vcpu->arch.smbase = 0x30000;
  
                vcpu->arch.msr_misc_features_enables = 0;
@@@ -12468,9 -12448,7 +12478,9 @@@ void kvm_arch_sched_in(struct kvm_vcpu 
  
  void kvm_arch_free_vm(struct kvm *kvm)
  {
 -      kfree(to_kvm_hv(kvm)->hv_pa_pg);
 +#if IS_ENABLED(CONFIG_HYPERV)
 +      kfree(kvm->arch.hv_pa_pg);
 +#endif
        __kvm_arch_free_vm(kvm);
  }
  
@@@ -13083,10 -13061,7 +13093,10 @@@ bool kvm_arch_vcpu_in_kernel(struct kvm
        if (vcpu->arch.guest_state_protected)
                return true;
  
 -      return vcpu->arch.preempted_in_kernel;
 +      if (vcpu != kvm_get_running_vcpu())
 +              return vcpu->arch.preempted_in_kernel;
 +
 +      return static_call(kvm_x86_get_cpl)(vcpu) == 0;
  }
  
  unsigned long kvm_arch_vcpu_get_ip(struct kvm_vcpu *vcpu)
@@@ -13588,6 -13563,10 +13598,10 @@@ int kvm_handle_invpcid(struct kvm_vcpu 
  
        switch (type) {
        case INVPCID_TYPE_INDIV_ADDR:
+               /*
+                * LAM doesn't apply to addresses that are inputs to TLB
+                * invalidation.
+                */
                if ((!pcid_enabled && (operand.pcid != 0)) ||
                    is_noncanonical_address(operand.gla, vcpu)) {
                        kvm_inject_gp(vcpu, 0);
This page took 0.134578 seconds and 4 git commands to generate.