@@ -536,6 +536,8 @@ void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
int __must_check vcpu_load(struct kvm_vcpu *vcpu);
void vcpu_put(struct kvm_vcpu *vcpu);
+void kvm_vcpu_run_adjust_pid(struct kvm_vcpu *vcpu);
+
#ifdef __KVM_HAVE_IOAPIC
void kvm_arch_post_irq_ack_notifier_list_update(struct kvm *kvm);
void kvm_arch_post_irq_routing_update(struct kvm *kvm);
@@ -2504,6 +2504,22 @@ static int kvm_vcpu_ioctl_set_sigmask(struct kvm_vcpu *vcpu, sigset_t *sigset)
return 0;
}
+void kvm_vcpu_run_adjust_pid(struct kvm_vcpu *vcpu)
+{
+ struct pid *oldpid;
+
+ oldpid = rcu_access_pointer(vcpu->pid);
+ if (unlikely(oldpid != current->pids[PIDTYPE_PID].pid)) {
+ /* The thread running this VCPU changed. */
+ struct pid *newpid = get_task_pid(current, PIDTYPE_PID);
+
+ rcu_assign_pointer(vcpu->pid, newpid);
+ if (oldpid)
+ synchronize_rcu();
+ put_pid(oldpid);
+ }
+}
+
static long kvm_vcpu_ioctl(struct file *filp,
unsigned int ioctl, unsigned long arg)
{
@@ -2530,23 +2546,13 @@ static long kvm_vcpu_ioctl(struct file *filp,
switch (ioctl) {
case KVM_RUN: {
- struct pid *oldpid;
r = -EINVAL;
if (arg)
goto out;
r = vcpu_load(vcpu);
if (r)
goto out;
- oldpid = rcu_access_pointer(vcpu->pid);
- if (unlikely(oldpid != current->pids[PIDTYPE_PID].pid)) {
- /* The thread running this VCPU changed. */
- struct pid *newpid = get_task_pid(current, PIDTYPE_PID);
-
- rcu_assign_pointer(vcpu->pid, newpid);
- if (oldpid)
- synchronize_rcu();
- put_pid(oldpid);
- }
+ kvm_vcpu_run_adjust_pid(vcpu);
r = kvm_arch_vcpu_ioctl_run(vcpu, vcpu->run);
vcpu_put(vcpu);
trace_kvm_userspace_exit(vcpu->run->exit_reason, r);
Every time userspace calls KVM_RUM, we check if another thread started running the VCPU, and in that case, we adjust the vcpu->pid field to the new thread. We obviously only want to perform this logic once we hold the vcpu->mutex and are actually going to run the VCPU. As we are about to move the vcpu_load() call into the architecture-specific implementation of the ioctl, we first factor the pid adjustment logic out in its own function which each architecture can call later on. Signed-off-by: Christoffer Dall <christoffer.dall@linaro.org> --- include/linux/kvm_host.h | 2 ++ virt/kvm/kvm_main.c | 28 +++++++++++++++++----------- 2 files changed, 19 insertions(+), 11 deletions(-)