KVM: mark vcpu->pid pointer as rcu protected
authorChristian Borntraeger <borntraeger@de.ibm.com>
Thu, 6 Jul 2017 12:44:28 +0000 (14:44 +0200)
committerChristian Borntraeger <borntraeger@de.ibm.com>
Fri, 7 Jul 2017 11:00:19 +0000 (13:00 +0200)
We do use rcu to protect the pid pointer. Mark it as such and
adopt all code to use the proper access methods.

This was detected by sparse.
"virt/kvm/kvm_main.c:2248:15: error: incompatible types in comparison
expression (different address spaces)"

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
include/linux/kvm_host.h
virt/kvm/kvm_main.c

index 0b50e7b35ed4135f81a3332331132aa0b1fc1c18..bcd37b855c66763995d85e5f9ca80f48b3b1a8e4 100644 (file)
@@ -234,7 +234,7 @@ struct kvm_vcpu {
 
        int guest_fpu_loaded, guest_xcr0_loaded;
        struct swait_queue_head wq;
-       struct pid *pid;
+       struct pid __rcu *pid;
        int sigset_active;
        sigset_t sigset;
        struct kvm_vcpu_stat stat;
index 19f0ecb9b93e23501af3f5c21e2c971cebfd3c6a..fc2d58312fd521f6bbcd49e2dbe86569d1569615 100644 (file)
@@ -293,7 +293,12 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_init);
 
 void kvm_vcpu_uninit(struct kvm_vcpu *vcpu)
 {
-       put_pid(vcpu->pid);
+       /*
+        * no need for rcu_read_lock as VCPU_RUN is the only place that
+        * will change the vcpu->pid pointer and on uninit all file
+        * descriptors are already gone.
+        */
+       put_pid(rcu_dereference_protected(vcpu->pid, 1));
        kvm_arch_vcpu_uninit(vcpu);
        free_page((unsigned long)vcpu->run);
 }
@@ -2551,13 +2556,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
        if (r)
                return r;
        switch (ioctl) {
-       case KVM_RUN:
+       case KVM_RUN: {
+               struct pid *oldpid;
                r = -EINVAL;
                if (arg)
                        goto out;
-               if (unlikely(vcpu->pid != current->pids[PIDTYPE_PID].pid)) {
+               oldpid = rcu_access_pointer(vcpu->pid);
+               if (unlikely(oldpid != current->pids[PIDTYPE_PID].pid)) {
                        /* The thread running this VCPU changed. */
-                       struct pid *oldpid = vcpu->pid;
                        struct pid *newpid = get_task_pid(current, PIDTYPE_PID);
 
                        rcu_assign_pointer(vcpu->pid, newpid);
@@ -2568,6 +2574,7 @@ static long kvm_vcpu_ioctl(struct file *filp,
                r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);
                trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
                break;
+       }
        case KVM_GET_REGS: {
                struct kvm_regs *kvm_regs;