drm/i915/gvt: Fix life cycle reference on KVM mm
authorZhenyu Wang <zhenyuw@linux.intel.com>
Fri, 31 Aug 2018 02:58:52 +0000 (10:58 +0800)
committerZhenyu Wang <zhenyuw@linux.intel.com>
Tue, 4 Sep 2018 06:55:23 +0000 (14:55 +0800)
Handle guest mm access life cycle properly with mmget()/mmput().
As noted by Linus, use_mm() depends on valid live page table but
KVM's mmgrab() doesn't guarantee that. As vGPU usage depends on
guest VM life cycle, need to make sure to use mmget()/mmput() to
guarantee VM address access.

v3: fix build

v2: v1 caused a weird dependence issue which failed for vfio
device release, which result invalid mdev vgpu and kvm state
without proper release taken. This trys to put right reference
around VM address space access instead.

Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Zhi Wang <zhi.a.wang@intel.com>
Reviewed-by: Zhi Wang <zhi.a.wang@intel.com>
Signed-off-by: Zhenyu Wang <zhenyuw@linux.intel.com>
drivers/gpu/drm/i915/gvt/kvmgt.c

index a45f46d..c7afee3 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/device.h>
 #include <linux/mm.h>
 #include <linux/mmu_context.h>
+#include <linux/sched/mm.h>
 #include <linux/types.h>
 #include <linux/list.h>
 #include <linux/rbtree.h>
@@ -1792,16 +1793,21 @@ static int kvmgt_rw_gpa(unsigned long handle, unsigned long gpa,
        info = (struct kvmgt_guest_info *)handle;
        kvm = info->kvm;
 
-       if (kthread)
+       if (kthread) {
+               if (!mmget_not_zero(kvm->mm))
+                       return -EFAULT;
                use_mm(kvm->mm);
+       }
 
        idx = srcu_read_lock(&kvm->srcu);
        ret = write ? kvm_write_guest(kvm, gpa, buf, len) :
                      kvm_read_guest(kvm, gpa, buf, len);
        srcu_read_unlock(&kvm->srcu, idx);
 
-       if (kthread)
+       if (kthread) {
                unuse_mm(kvm->mm);
+               mmput(kvm->mm);
+       }
 
        return ret;
 }