Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 15 Jul 2021 18:56:07 +0000 (11:56 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 15 Jul 2021 18:56:07 +0000 (11:56 -0700)
Pull kvm fixes from Paolo Bonzini:

 - Allow again loading KVM on 32-bit non-PAE builds

 - Fixes for host SMIs on AMD

 - Fixes for guest SMIs on AMD

 - Fixes for selftests on s390 and ARM

 - Fix memory leak

 - Enforce no-instrumentation area on vmentry when hardware breakpoints
   are in use.

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (25 commits)
  KVM: selftests: smm_test: Test SMM enter from L2
  KVM: nSVM: Restore nested control upon leaving SMM
  KVM: nSVM: Fix L1 state corruption upon return from SMM
  KVM: nSVM: Introduce svm_copy_vmrun_state()
  KVM: nSVM: Check that VM_HSAVE_PA MSR was set before VMRUN
  KVM: nSVM: Check the value written to MSR_VM_HSAVE_PA
  KVM: SVM: Fix sev_pin_memory() error checks in SEV migration utilities
  KVM: SVM: Return -EFAULT if copy_to_user() for SEV mig packet header fails
  KVM: SVM: add module param to control the #SMI interception
  KVM: SVM: remove INIT intercept handler
  KVM: SVM: #SMI interception must not skip the instruction
  KVM: VMX: Remove vmx_msr_index from vmx.h
  KVM: X86: Disable hardware breakpoints unconditionally before kvm_x86->run()
  KVM: selftests: Address extra memslot parameters in vm_vaddr_alloc
  kvm: debugfs: fix memory leak in kvm_create_vm_debugfs
  KVM: x86/pmu: Clear anythread deprecated bit when 0xa leaf is unsupported on the SVM
  KVM: mmio: Fix use-after-free Read in kvm_vm_ioctl_unregister_coalesced_mmio
  KVM: SVM: Revert clearing of C-bit on GPA in #NPF handler
  KVM: x86/mmu: Do not apply HPA (memory encryption) mask to GPAs
  KVM: x86: Use kernel's x86_phys_bits to handle reduced MAXPHYADDR
  ...

1  2 
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/svm/sev.c
arch/x86/kvm/x86.c
virt/kvm/kvm_main.c

diff --combined arch/x86/kvm/mmu/mmu.c
@@@ -53,6 -53,8 +53,8 @@@
  #include <asm/kvm_page_track.h>
  #include "trace.h"
  
+ #include "paging.h"
  extern bool itlb_multihit_kvm_mitigation;
  
  int __read_mostly nx_huge_pages = -1;
@@@ -2450,7 -2452,7 +2452,7 @@@ static int make_mmu_pages_available(str
         * page is available, while the caller may end up allocating as many as
         * four pages, e.g. for PAE roots or for 5-level paging.  Temporarily
         * exceeding the (arbitrary by default) limit will not harm the host,
 -       * being too agressive may unnecessarily kill the guest, and getting an
 +       * being too aggressive may unnecessarily kill the guest, and getting an
         * exact count is far more trouble than it's worth, especially in the
         * page fault paths.
         */
diff --combined arch/x86/kvm/svm/sev.c
@@@ -19,7 -19,6 +19,7 @@@
  #include <linux/trace_events.h>
  #include <asm/fpu/internal.h>
  
 +#include <asm/pkru.h>
  #include <asm/trapnr.h>
  
  #include "x86.h"
@@@ -1272,8 -1271,8 +1272,8 @@@ static int sev_send_update_data(struct 
        /* Pin guest memory */
        guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
                                    PAGE_SIZE, &n, 0);
-       if (!guest_page)
-               return -EFAULT;
+       if (IS_ERR(guest_page))
+               return PTR_ERR(guest_page);
  
        /* allocate memory for header and transport buffer */
        ret = -ENOMEM;
        }
  
        /* Copy packet header to userspace. */
-       ret = copy_to_user((void __user *)(uintptr_t)params.hdr_uaddr, hdr,
-                               params.hdr_len);
+       if (copy_to_user((void __user *)(uintptr_t)params.hdr_uaddr, hdr,
+                        params.hdr_len))
+               ret = -EFAULT;
  
  e_free_trans_data:
        kfree(trans_data);
@@@ -1463,11 -1463,12 +1464,12 @@@ static int sev_receive_update_data(stru
        data.trans_len = params.trans_len;
  
        /* Pin guest memory */
-       ret = -EFAULT;
        guest_page = sev_pin_memory(kvm, params.guest_uaddr & PAGE_MASK,
                                    PAGE_SIZE, &n, 0);
-       if (!guest_page)
+       if (IS_ERR(guest_page)) {
+               ret = PTR_ERR(guest_page);
                goto e_free_trans;
+       }
  
        /* The RECEIVE_UPDATE_DATA command requires C-bit to be always set. */
        data.guest_address = (page_to_pfn(guest_page[0]) << PAGE_SHIFT) + offset;
diff --combined arch/x86/kvm/x86.c
@@@ -66,7 -66,6 +66,7 @@@
  #include <asm/msr.h>
  #include <asm/desc.h>
  #include <asm/mce.h>
 +#include <asm/pkru.h>
  #include <linux/kernel_stat.h>
  #include <asm/fpu/internal.h> /* Ugh! */
  #include <asm/pvclock.h>
@@@ -940,7 -939,7 +940,7 @@@ void kvm_load_guest_xsave_state(struct 
            (kvm_read_cr4_bits(vcpu, X86_CR4_PKE) ||
             (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU)) &&
            vcpu->arch.pkru != vcpu->arch.host_pkru)
 -              __write_pkru(vcpu->arch.pkru);
 +              write_pkru(vcpu->arch.pkru);
  }
  EXPORT_SYMBOL_GPL(kvm_load_guest_xsave_state);
  
@@@ -954,7 -953,7 +954,7 @@@ void kvm_load_host_xsave_state(struct k
             (vcpu->arch.xcr0 & XFEATURE_MASK_PKRU))) {
                vcpu->arch.pkru = rdpkru();
                if (vcpu->arch.pkru != vcpu->arch.host_pkru)
 -                      __write_pkru(vcpu->arch.host_pkru);
 +                      write_pkru(vcpu->arch.host_pkru);
        }
  
        if (kvm_read_cr4_bits(vcpu, X86_CR4_OSXSAVE)) {
@@@ -4705,21 -4704,20 +4705,21 @@@ static void fill_xsave(u8 *dest, struc
         */
        valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
        while (valid) {
 +              u32 size, offset, ecx, edx;
                u64 xfeature_mask = valid & -valid;
                int xfeature_nr = fls64(xfeature_mask) - 1;
 -              void *src = get_xsave_addr(xsave, xfeature_nr);
 -
 -              if (src) {
 -                      u32 size, offset, ecx, edx;
 -                      cpuid_count(XSTATE_CPUID, xfeature_nr,
 -                                  &size, &offset, &ecx, &edx);
 -                      if (xfeature_nr == XFEATURE_PKRU)
 -                              memcpy(dest + offset, &vcpu->arch.pkru,
 -                                     sizeof(vcpu->arch.pkru));
 -                      else
 -                              memcpy(dest + offset, src, size);
 +              void *src;
 +
 +              cpuid_count(XSTATE_CPUID, xfeature_nr,
 +                          &size, &offset, &ecx, &edx);
  
 +              if (xfeature_nr == XFEATURE_PKRU) {
 +                      memcpy(dest + offset, &vcpu->arch.pkru,
 +                             sizeof(vcpu->arch.pkru));
 +              } else {
 +                      src = get_xsave_addr(xsave, xfeature_nr);
 +                      if (src)
 +                              memcpy(dest + offset, src, size);
                }
  
                valid -= xfeature_mask;
@@@ -4749,20 -4747,18 +4749,20 @@@ static void load_xsave(struct kvm_vcpu 
         */
        valid = xstate_bv & ~XFEATURE_MASK_FPSSE;
        while (valid) {
 +              u32 size, offset, ecx, edx;
                u64 xfeature_mask = valid & -valid;
                int xfeature_nr = fls64(xfeature_mask) - 1;
 -              void *dest = get_xsave_addr(xsave, xfeature_nr);
 -
 -              if (dest) {
 -                      u32 size, offset, ecx, edx;
 -                      cpuid_count(XSTATE_CPUID, xfeature_nr,
 -                                  &size, &offset, &ecx, &edx);
 -                      if (xfeature_nr == XFEATURE_PKRU)
 -                              memcpy(&vcpu->arch.pkru, src + offset,
 -                                     sizeof(vcpu->arch.pkru));
 -                      else
 +
 +              cpuid_count(XSTATE_CPUID, xfeature_nr,
 +                          &size, &offset, &ecx, &edx);
 +
 +              if (xfeature_nr == XFEATURE_PKRU) {
 +                      memcpy(&vcpu->arch.pkru, src + offset,
 +                             sizeof(vcpu->arch.pkru));
 +              } else {
 +                      void *dest = get_xsave_addr(xsave, xfeature_nr);
 +
 +                      if (dest)
                                memcpy(dest, src + offset, size);
                }
  
@@@ -9601,6 -9597,8 +9601,8 @@@ static int vcpu_enter_guest(struct kvm_
                set_debugreg(vcpu->arch.eff_db[3], 3);
                set_debugreg(vcpu->arch.dr6, 6);
                vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
+       } else if (unlikely(hw_breakpoint_active())) {
+               set_debugreg(0, 7);
        }
  
        for (;;) {
@@@ -9889,7 -9887,7 +9891,7 @@@ static void kvm_save_current_fpu(struc
                memcpy(&fpu->state, &current->thread.fpu.state,
                       fpu_kernel_xstate_size);
        else
 -              copy_fpregs_to_fpstate(fpu);
 +              save_fpregs_to_fpstate(fpu);
  }
  
  /* Swap (qemu) user FPU context for the guest FPU context. */
@@@ -9905,7 -9903,7 +9907,7 @@@ static void kvm_load_guest_fpu(struct k
         */
        if (vcpu->arch.guest_fpu)
                /* PKRU is separately restored in kvm_x86_ops.run. */
 -              __copy_kernel_to_fpregs(&vcpu->arch.guest_fpu->state,
 +              __restore_fpregs_from_fpstate(&vcpu->arch.guest_fpu->state,
                                        ~XFEATURE_MASK_PKRU);
  
        fpregs_mark_activate();
@@@ -9926,7 -9924,7 +9928,7 @@@ static void kvm_put_guest_fpu(struct kv
        if (vcpu->arch.guest_fpu)
                kvm_save_current_fpu(vcpu->arch.guest_fpu);
  
 -      copy_kernel_to_fpregs(&vcpu->arch.user_fpu->state);
 +      restore_fpregs_from_fpstate(&vcpu->arch.user_fpu->state);
  
        fpregs_mark_activate();
        fpregs_unlock();
@@@ -10985,9 -10983,6 +10987,6 @@@ int kvm_arch_hardware_setup(void *opaqu
        int r;
  
        rdmsrl_safe(MSR_EFER, &host_efer);
-       if (WARN_ON_ONCE(boot_cpu_has(X86_FEATURE_NX) &&
-                        !(host_efer & EFER_NX)))
-               return -EIO;
  
        if (boot_cpu_has(X86_FEATURE_XSAVES))
                rdmsrl(MSR_IA32_XSS, host_xss);
diff --combined virt/kvm/kvm_main.c
@@@ -935,7 -935,7 +935,7 @@@ static int kvm_create_vm_debugfs(struc
                stat_data->kvm = kvm;
                stat_data->desc = pdesc;
                stat_data->kind = KVM_STAT_VCPU;
-               kvm->debugfs_stat_data[i] = stat_data;
+               kvm->debugfs_stat_data[i + kvm_vm_stats_header.num_desc] = stat_data;
                debugfs_create_file(pdesc->name, kvm_stats_debugfs_mode(pdesc),
                                    kvm->debugfs_dentry, stat_data,
                                    &stat_fops_per_vm);
@@@ -2290,7 -2290,7 +2290,7 @@@ static kvm_pfn_t hva_to_pfn(unsigned lo
        }
  
  retry:
 -      vma = find_vma_intersection(current->mm, addr, addr + 1);
 +      vma = vma_lookup(current->mm, addr);
  
        if (vma == NULL)
                pfn = KVM_PFN_ERR_FAULT;
@@@ -5264,7 -5264,7 +5264,7 @@@ static void kvm_sched_out(struct preemp
  {
        struct kvm_vcpu *vcpu = preempt_notifier_to_vcpu(pn);
  
 -      if (current->state == TASK_RUNNING) {
 +      if (current->on_rq) {
                WRITE_ONCE(vcpu->preempted, true);
                WRITE_ONCE(vcpu->ready, true);
        }