KVM: mark vcpu->pid pointer as rcu protected

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>
This commit is contained in:
Christian Borntraeger 2017-07-06 14:44:28 +02:00
parent 1372324b32
commit 0e4524a5d3
2 changed files with 12 additions and 5 deletions

View File

@ -234,7 +234,7 @@ struct kvm_vcpu {
int guest_fpu_loaded, guest_xcr0_loaded; int guest_fpu_loaded, guest_xcr0_loaded;
struct swait_queue_head wq; struct swait_queue_head wq;
struct pid *pid; struct pid __rcu *pid;
int sigset_active; int sigset_active;
sigset_t sigset; sigset_t sigset;
struct kvm_vcpu_stat stat; struct kvm_vcpu_stat stat;

View File

@ -293,7 +293,12 @@ EXPORT_SYMBOL_GPL(kvm_vcpu_init);
void kvm_vcpu_uninit(struct kvm_vcpu *vcpu) 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); kvm_arch_vcpu_uninit(vcpu);
free_page((unsigned long)vcpu->run); free_page((unsigned long)vcpu->run);
} }
@ -2551,13 +2556,14 @@ static long kvm_vcpu_ioctl(struct file *filp,
if (r) if (r)
return r; return r;
switch (ioctl) { switch (ioctl) {
case KVM_RUN: case KVM_RUN: {
struct pid *oldpid;
r = -EINVAL; r = -EINVAL;
if (arg) if (arg)
goto out; 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. */ /* The thread running this VCPU changed. */
struct pid *oldpid = vcpu->pid;
struct pid *newpid = get_task_pid(current, PIDTYPE_PID); struct pid *newpid = get_task_pid(current, PIDTYPE_PID);
rcu_assign_pointer(vcpu->pid, newpid); 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); r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);
trace_kvm_userspace_exit(vcpu->run->exit_reason, r); trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
break; break;
}
case KVM_GET_REGS: { case KVM_GET_REGS: {
struct kvm_regs *kvm_regs; struct kvm_regs *kvm_regs;