diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-09 14:14:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-09 14:14:13 -0400 |
commit | 63f4711aec01586e92c26da08a24bff0b8d16aa2 (patch) | |
tree | 1e15b5a5820e60357274472d9d7ce6f97e808322 /arch | |
parent | 6a5beacca8681fb6602649dd8cf5ba50a90befb3 (diff) | |
parent | 331b646d60b0c3885208e1e02bd9f40319953efc (diff) |
Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Avi Kivity:
"Two asynchronous page fault fixes (one guest, one host), a powerpc
page refcount fix, and an ia64 build fix."
* git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: ia64: fix build due to typo
KVM: PPC: Book3S HV: Fix refcounting of hugepages
KVM: Do not take reference to mm during async #PF
KVM: ensure async PF event wakes up vcpu from halt
Diffstat (limited to 'arch')
-rw-r--r-- | arch/ia64/kvm/kvm-ia64.c | 2 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_64_mmu_hv.c | 22 | ||||
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/kvm.c | 9 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 1 |
5 files changed, 16 insertions, 20 deletions
diff --git a/arch/ia64/kvm/kvm-ia64.c b/arch/ia64/kvm/kvm-ia64.c index f5104b7c52cd..463fb3bbe11e 100644 --- a/arch/ia64/kvm/kvm-ia64.c +++ b/arch/ia64/kvm/kvm-ia64.c | |||
@@ -1174,7 +1174,7 @@ out: | |||
1174 | 1174 | ||
1175 | bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) | 1175 | bool kvm_vcpu_compatible(struct kvm_vcpu *vcpu) |
1176 | { | 1176 | { |
1177 | return irqchip_in_kernel(vcpu->kcm) == (vcpu->arch.apic != NULL); | 1177 | return irqchip_in_kernel(vcpu->kvm) == (vcpu->arch.apic != NULL); |
1178 | } | 1178 | } |
1179 | 1179 | ||
1180 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) | 1180 | int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) |
diff --git a/arch/powerpc/kvm/book3s_64_mmu_hv.c b/arch/powerpc/kvm/book3s_64_mmu_hv.c index ddc485a529f2..c3beaeef3f60 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_hv.c +++ b/arch/powerpc/kvm/book3s_64_mmu_hv.c | |||
@@ -258,6 +258,8 @@ static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn, | |||
258 | !(memslot->userspace_addr & (s - 1))) { | 258 | !(memslot->userspace_addr & (s - 1))) { |
259 | start &= ~(s - 1); | 259 | start &= ~(s - 1); |
260 | pgsize = s; | 260 | pgsize = s; |
261 | get_page(hpage); | ||
262 | put_page(page); | ||
261 | page = hpage; | 263 | page = hpage; |
262 | } | 264 | } |
263 | } | 265 | } |
@@ -281,11 +283,8 @@ static long kvmppc_get_guest_page(struct kvm *kvm, unsigned long gfn, | |||
281 | err = 0; | 283 | err = 0; |
282 | 284 | ||
283 | out: | 285 | out: |
284 | if (got) { | 286 | if (got) |
285 | if (PageHuge(page)) | ||
286 | page = compound_head(page); | ||
287 | put_page(page); | 287 | put_page(page); |
288 | } | ||
289 | return err; | 288 | return err; |
290 | 289 | ||
291 | up_err: | 290 | up_err: |
@@ -678,8 +677,15 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu, | |||
678 | SetPageDirty(page); | 677 | SetPageDirty(page); |
679 | 678 | ||
680 | out_put: | 679 | out_put: |
681 | if (page) | 680 | if (page) { |
682 | put_page(page); | 681 | /* |
682 | * We drop pages[0] here, not page because page might | ||
683 | * have been set to the head page of a compound, but | ||
684 | * we have to drop the reference on the correct tail | ||
685 | * page to match the get inside gup() | ||
686 | */ | ||
687 | put_page(pages[0]); | ||
688 | } | ||
683 | return ret; | 689 | return ret; |
684 | 690 | ||
685 | out_unlock: | 691 | out_unlock: |
@@ -979,6 +985,7 @@ void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa, | |||
979 | pa = *physp; | 985 | pa = *physp; |
980 | } | 986 | } |
981 | page = pfn_to_page(pa >> PAGE_SHIFT); | 987 | page = pfn_to_page(pa >> PAGE_SHIFT); |
988 | get_page(page); | ||
982 | } else { | 989 | } else { |
983 | hva = gfn_to_hva_memslot(memslot, gfn); | 990 | hva = gfn_to_hva_memslot(memslot, gfn); |
984 | npages = get_user_pages_fast(hva, 1, 1, pages); | 991 | npages = get_user_pages_fast(hva, 1, 1, pages); |
@@ -991,8 +998,6 @@ void *kvmppc_pin_guest_page(struct kvm *kvm, unsigned long gpa, | |||
991 | page = compound_head(page); | 998 | page = compound_head(page); |
992 | psize <<= compound_order(page); | 999 | psize <<= compound_order(page); |
993 | } | 1000 | } |
994 | if (!kvm->arch.using_mmu_notifiers) | ||
995 | get_page(page); | ||
996 | offset = gpa & (psize - 1); | 1001 | offset = gpa & (psize - 1); |
997 | if (nb_ret) | 1002 | if (nb_ret) |
998 | *nb_ret = psize - offset; | 1003 | *nb_ret = psize - offset; |
@@ -1003,7 +1008,6 @@ void kvmppc_unpin_guest_page(struct kvm *kvm, void *va) | |||
1003 | { | 1008 | { |
1004 | struct page *page = virt_to_page(va); | 1009 | struct page *page = virt_to_page(va); |
1005 | 1010 | ||
1006 | page = compound_head(page); | ||
1007 | put_page(page); | 1011 | put_page(page); |
1008 | } | 1012 | } |
1009 | 1013 | ||
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 01294a5099dd..108d1f580177 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c | |||
@@ -1192,8 +1192,6 @@ static void unpin_slot(struct kvm *kvm, int slot_id) | |||
1192 | continue; | 1192 | continue; |
1193 | pfn = physp[j] >> PAGE_SHIFT; | 1193 | pfn = physp[j] >> PAGE_SHIFT; |
1194 | page = pfn_to_page(pfn); | 1194 | page = pfn_to_page(pfn); |
1195 | if (PageHuge(page)) | ||
1196 | page = compound_head(page); | ||
1197 | SetPageDirty(page); | 1195 | SetPageDirty(page); |
1198 | put_page(page); | 1196 | put_page(page); |
1199 | } | 1197 | } |
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c index b8ba6e4a27e4..e554e5ad2fe8 100644 --- a/arch/x86/kernel/kvm.c +++ b/arch/x86/kernel/kvm.c | |||
@@ -79,7 +79,6 @@ struct kvm_task_sleep_node { | |||
79 | u32 token; | 79 | u32 token; |
80 | int cpu; | 80 | int cpu; |
81 | bool halted; | 81 | bool halted; |
82 | struct mm_struct *mm; | ||
83 | }; | 82 | }; |
84 | 83 | ||
85 | static struct kvm_task_sleep_head { | 84 | static struct kvm_task_sleep_head { |
@@ -126,9 +125,7 @@ void kvm_async_pf_task_wait(u32 token) | |||
126 | 125 | ||
127 | n.token = token; | 126 | n.token = token; |
128 | n.cpu = smp_processor_id(); | 127 | n.cpu = smp_processor_id(); |
129 | n.mm = current->active_mm; | ||
130 | n.halted = idle || preempt_count() > 1; | 128 | n.halted = idle || preempt_count() > 1; |
131 | atomic_inc(&n.mm->mm_count); | ||
132 | init_waitqueue_head(&n.wq); | 129 | init_waitqueue_head(&n.wq); |
133 | hlist_add_head(&n.link, &b->list); | 130 | hlist_add_head(&n.link, &b->list); |
134 | spin_unlock(&b->lock); | 131 | spin_unlock(&b->lock); |
@@ -161,9 +158,6 @@ EXPORT_SYMBOL_GPL(kvm_async_pf_task_wait); | |||
161 | static void apf_task_wake_one(struct kvm_task_sleep_node *n) | 158 | static void apf_task_wake_one(struct kvm_task_sleep_node *n) |
162 | { | 159 | { |
163 | hlist_del_init(&n->link); | 160 | hlist_del_init(&n->link); |
164 | if (!n->mm) | ||
165 | return; | ||
166 | mmdrop(n->mm); | ||
167 | if (n->halted) | 161 | if (n->halted) |
168 | smp_send_reschedule(n->cpu); | 162 | smp_send_reschedule(n->cpu); |
169 | else if (waitqueue_active(&n->wq)) | 163 | else if (waitqueue_active(&n->wq)) |
@@ -207,7 +201,7 @@ again: | |||
207 | * async PF was not yet handled. | 201 | * async PF was not yet handled. |
208 | * Add dummy entry for the token. | 202 | * Add dummy entry for the token. |
209 | */ | 203 | */ |
210 | n = kmalloc(sizeof(*n), GFP_ATOMIC); | 204 | n = kzalloc(sizeof(*n), GFP_ATOMIC); |
211 | if (!n) { | 205 | if (!n) { |
212 | /* | 206 | /* |
213 | * Allocation failed! Busy wait while other cpu | 207 | * Allocation failed! Busy wait while other cpu |
@@ -219,7 +213,6 @@ again: | |||
219 | } | 213 | } |
220 | n->token = token; | 214 | n->token = token; |
221 | n->cpu = smp_processor_id(); | 215 | n->cpu = smp_processor_id(); |
222 | n->mm = NULL; | ||
223 | init_waitqueue_head(&n->wq); | 216 | init_waitqueue_head(&n->wq); |
224 | hlist_add_head(&n->link, &b->list); | 217 | hlist_add_head(&n->link, &b->list); |
225 | } else | 218 | } else |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 91a5e989abcf..185a2b823a2d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -6581,6 +6581,7 @@ void kvm_arch_async_page_present(struct kvm_vcpu *vcpu, | |||
6581 | kvm_inject_page_fault(vcpu, &fault); | 6581 | kvm_inject_page_fault(vcpu, &fault); |
6582 | } | 6582 | } |
6583 | vcpu->arch.apf.halted = false; | 6583 | vcpu->arch.apf.halted = false; |
6584 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; | ||
6584 | } | 6585 | } |
6585 | 6586 | ||
6586 | bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu) | 6587 | bool kvm_arch_can_inject_async_page_present(struct kvm_vcpu *vcpu) |