diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-03 22:23:37 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2014-02-03 22:23:37 -0500 |
commit | f244d910ea2974d88efcc6d04594f25e22718f90 (patch) | |
tree | 7236a244a09fa76d73105df476d2f20a19066d70 /virt/kvm/async_pf.c | |
parent | 4f34d683e52271197e1ee17b7095e8ba27761ba6 (diff) | |
parent | 536336c21697551ceca44bdffb9f53e6cc5f2f20 (diff) |
Merge tag 'kvm-s390-20140130' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into HEAD
Two new features are added by this patch set:
- The floating interrupt controller (flic) that allows us to inject,
clear and inspect non-vcpu local interrupts. This also gives us an
opportunity to fix deficiencies in our existing interrupt definitions.
- Support for asynchronous page faults via the pfault mechanism. Testing
show significant guest performance improvements under host swap.
Diffstat (limited to 'virt/kvm/async_pf.c')
-rw-r--r-- | virt/kvm/async_pf.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/virt/kvm/async_pf.c b/virt/kvm/async_pf.c index 8631d9c14320..889aad022014 100644 --- a/virt/kvm/async_pf.c +++ b/virt/kvm/async_pf.c | |||
@@ -28,6 +28,21 @@ | |||
28 | #include "async_pf.h" | 28 | #include "async_pf.h" |
29 | #include <trace/events/kvm.h> | 29 | #include <trace/events/kvm.h> |
30 | 30 | ||
31 | static inline void kvm_async_page_present_sync(struct kvm_vcpu *vcpu, | ||
32 | struct kvm_async_pf *work) | ||
33 | { | ||
34 | #ifdef CONFIG_KVM_ASYNC_PF_SYNC | ||
35 | kvm_arch_async_page_present(vcpu, work); | ||
36 | #endif | ||
37 | } | ||
38 | static inline void kvm_async_page_present_async(struct kvm_vcpu *vcpu, | ||
39 | struct kvm_async_pf *work) | ||
40 | { | ||
41 | #ifndef CONFIG_KVM_ASYNC_PF_SYNC | ||
42 | kvm_arch_async_page_present(vcpu, work); | ||
43 | #endif | ||
44 | } | ||
45 | |||
31 | static struct kmem_cache *async_pf_cache; | 46 | static struct kmem_cache *async_pf_cache; |
32 | 47 | ||
33 | int kvm_async_pf_init(void) | 48 | int kvm_async_pf_init(void) |
@@ -69,6 +84,7 @@ static void async_pf_execute(struct work_struct *work) | |||
69 | down_read(&mm->mmap_sem); | 84 | down_read(&mm->mmap_sem); |
70 | get_user_pages(current, mm, addr, 1, 1, 0, NULL, NULL); | 85 | get_user_pages(current, mm, addr, 1, 1, 0, NULL, NULL); |
71 | up_read(&mm->mmap_sem); | 86 | up_read(&mm->mmap_sem); |
87 | kvm_async_page_present_sync(vcpu, apf); | ||
72 | unuse_mm(mm); | 88 | unuse_mm(mm); |
73 | 89 | ||
74 | spin_lock(&vcpu->async_pf.lock); | 90 | spin_lock(&vcpu->async_pf.lock); |
@@ -97,11 +113,16 @@ void kvm_clear_async_pf_completion_queue(struct kvm_vcpu *vcpu) | |||
97 | list_entry(vcpu->async_pf.queue.next, | 113 | list_entry(vcpu->async_pf.queue.next, |
98 | typeof(*work), queue); | 114 | typeof(*work), queue); |
99 | list_del(&work->queue); | 115 | list_del(&work->queue); |
116 | |||
117 | #ifdef CONFIG_KVM_ASYNC_PF_SYNC | ||
118 | flush_work(&work->work); | ||
119 | #else | ||
100 | if (cancel_work_sync(&work->work)) { | 120 | if (cancel_work_sync(&work->work)) { |
101 | mmdrop(work->mm); | 121 | mmdrop(work->mm); |
102 | kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */ | 122 | kvm_put_kvm(vcpu->kvm); /* == work->vcpu->kvm */ |
103 | kmem_cache_free(async_pf_cache, work); | 123 | kmem_cache_free(async_pf_cache, work); |
104 | } | 124 | } |
125 | #endif | ||
105 | } | 126 | } |
106 | 127 | ||
107 | spin_lock(&vcpu->async_pf.lock); | 128 | spin_lock(&vcpu->async_pf.lock); |
@@ -138,7 +159,7 @@ void kvm_check_async_pf_completion(struct kvm_vcpu *vcpu) | |||
138 | } | 159 | } |
139 | } | 160 | } |
140 | 161 | ||
141 | int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn, | 162 | int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, unsigned long hva, |
142 | struct kvm_arch_async_pf *arch) | 163 | struct kvm_arch_async_pf *arch) |
143 | { | 164 | { |
144 | struct kvm_async_pf *work; | 165 | struct kvm_async_pf *work; |
@@ -159,7 +180,7 @@ int kvm_setup_async_pf(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn, | |||
159 | work->wakeup_all = false; | 180 | work->wakeup_all = false; |
160 | work->vcpu = vcpu; | 181 | work->vcpu = vcpu; |
161 | work->gva = gva; | 182 | work->gva = gva; |
162 | work->addr = gfn_to_hva(vcpu->kvm, gfn); | 183 | work->addr = hva; |
163 | work->arch = *arch; | 184 | work->arch = *arch; |
164 | work->mm = current->mm; | 185 | work->mm = current->mm; |
165 | atomic_inc(&work->mm->mm_count); | 186 | atomic_inc(&work->mm->mm_count); |