diff options
Diffstat (limited to 'virt/kvm/async_pf.c')
-rw-r--r-- | virt/kvm/async_pf.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c index 65da997b4..db9668869 100644 --- a/virt/kvm/async_pf.c +++ b/virt/kvm/async_pf.c @@ -79,7 +79,13 @@ static void async_pf_execute(struct work_struct *work) might_sleep(); - get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL); + /* + * This work is run asynchromously to the task which owns + * mm and might be done in another context, so we must + * use FOLL_REMOTE. + */ + __get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL, FOLL_REMOTE); + kvm_async_page_present_sync(vcpu, apf); spin_lock(&vcpu->async_pf.lock); @@ -109,8 +115,8 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) /* cancel outstanding work queue item */ while (!list_empty(&vcpu->async_pf.queue)) { struct kvm_async_pf *work = - list_entry(vcpu->async_pf.queue.next, - typeof(*work), queue); + list_first_entry(&vcpu->async_pf.queue, + typeof(*work), queue); list_del(&work->queue); #ifdef CONFIG_KVM_ASYNC_PF_SYNC @@ -127,8 +133,8 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) spin_lock(&vcpu->async_pf.lock); while (!list_empty(&vcpu->async_pf.done)) { struct kvm_async_pf *work = - list_entry(vcpu->async_pf.done.next, - typeof(*work), link); + list_first_entry(&vcpu->async_pf.done, + typeof(*work), link); list_del(&work->link); kmem_cache_free(async_pf_cache, work); } |