diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-23 12:18:08 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-23 12:18:08 -0400 |
commit | 72dd4e7980bf584fa11db4f00e38d5cf956a8856 (patch) | |
tree | fed8bc25883a01dc2e4916fe90a58f07b26ed93b /arch | |
parent | b4d3ba3346f092b9185da991414775281ceacaac (diff) | |
parent | 6d17c0d1e8a66f5508082cb0fecb8afb7e9a21e4 (diff) |
Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm bugfixes from Gleb Natapov.
* git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM/MIPS32: Wrap calls to gfn_to_pfn() with srcu_read_lock/unlock()
KVM/MIPS32: Move include/asm/kvm.h => include/uapi/asm/kvm.h since it is a user visible API.
KVM: take over co-maintainership from Marcelo, fix MAINTAINERS entry
Diffstat (limited to 'arch')
-rw-r--r-- | arch/mips/include/uapi/asm/kvm.h (renamed from arch/mips/include/asm/kvm.h) | 0 | ||||
-rw-r--r-- | arch/mips/kvm/kvm_tlb.c | 35 |
2 files changed, 26 insertions, 9 deletions
diff --git a/arch/mips/include/asm/kvm.h b/arch/mips/include/uapi/asm/kvm.h index 85789eacbf18..85789eacbf18 100644 --- a/arch/mips/include/asm/kvm.h +++ b/arch/mips/include/uapi/asm/kvm.h | |||
diff --git a/arch/mips/kvm/kvm_tlb.c b/arch/mips/kvm/kvm_tlb.c index e3f0d9b8b6c5..c777dd36d4a8 100644 --- a/arch/mips/kvm/kvm_tlb.c +++ b/arch/mips/kvm/kvm_tlb.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/kvm_host.h> | 19 | #include <linux/kvm_host.h> |
20 | #include <linux/srcu.h> | ||
21 | |||
20 | 22 | ||
21 | #include <asm/cpu.h> | 23 | #include <asm/cpu.h> |
22 | #include <asm/bootinfo.h> | 24 | #include <asm/bootinfo.h> |
@@ -169,21 +171,27 @@ void kvm_mips_dump_shadow_tlbs(struct kvm_vcpu *vcpu) | |||
169 | } | 171 | } |
170 | } | 172 | } |
171 | 173 | ||
172 | static void kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) | 174 | static int kvm_mips_map_page(struct kvm *kvm, gfn_t gfn) |
173 | { | 175 | { |
176 | int srcu_idx, err = 0; | ||
174 | pfn_t pfn; | 177 | pfn_t pfn; |
175 | 178 | ||
176 | if (kvm->arch.guest_pmap[gfn] != KVM_INVALID_PAGE) | 179 | if (kvm->arch.guest_pmap[gfn] != KVM_INVALID_PAGE) |
177 | return; | 180 | return 0; |
178 | 181 | ||
182 | srcu_idx = srcu_read_lock(&kvm->srcu); | ||
179 | pfn = kvm_mips_gfn_to_pfn(kvm, gfn); | 183 | pfn = kvm_mips_gfn_to_pfn(kvm, gfn); |
180 | 184 | ||
181 | if (kvm_mips_is_error_pfn(pfn)) { | 185 | if (kvm_mips_is_error_pfn(pfn)) { |
182 | panic("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn); | 186 | kvm_err("Couldn't get pfn for gfn %#" PRIx64 "!\n", gfn); |
187 | err = -EFAULT; | ||
188 | goto out; | ||
183 | } | 189 | } |
184 | 190 | ||
185 | kvm->arch.guest_pmap[gfn] = pfn; | 191 | kvm->arch.guest_pmap[gfn] = pfn; |
186 | return; | 192 | out: |
193 | srcu_read_unlock(&kvm->srcu, srcu_idx); | ||
194 | return err; | ||
187 | } | 195 | } |
188 | 196 | ||
189 | /* Translate guest KSEG0 addresses to Host PA */ | 197 | /* Translate guest KSEG0 addresses to Host PA */ |
@@ -207,7 +215,10 @@ unsigned long kvm_mips_translate_guest_kseg0_to_hpa(struct kvm_vcpu *vcpu, | |||
207 | gva); | 215 | gva); |
208 | return KVM_INVALID_PAGE; | 216 | return KVM_INVALID_PAGE; |
209 | } | 217 | } |
210 | kvm_mips_map_page(vcpu->kvm, gfn); | 218 | |
219 | if (kvm_mips_map_page(vcpu->kvm, gfn) < 0) | ||
220 | return KVM_INVALID_ADDR; | ||
221 | |||
211 | return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset; | 222 | return (kvm->arch.guest_pmap[gfn] << PAGE_SHIFT) + offset; |
212 | } | 223 | } |
213 | 224 | ||
@@ -310,8 +321,11 @@ int kvm_mips_handle_kseg0_tlb_fault(unsigned long badvaddr, | |||
310 | even = !(gfn & 0x1); | 321 | even = !(gfn & 0x1); |
311 | vaddr = badvaddr & (PAGE_MASK << 1); | 322 | vaddr = badvaddr & (PAGE_MASK << 1); |
312 | 323 | ||
313 | kvm_mips_map_page(vcpu->kvm, gfn); | 324 | if (kvm_mips_map_page(vcpu->kvm, gfn) < 0) |
314 | kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1); | 325 | return -1; |
326 | |||
327 | if (kvm_mips_map_page(vcpu->kvm, gfn ^ 0x1) < 0) | ||
328 | return -1; | ||
315 | 329 | ||
316 | if (even) { | 330 | if (even) { |
317 | pfn0 = kvm->arch.guest_pmap[gfn]; | 331 | pfn0 = kvm->arch.guest_pmap[gfn]; |
@@ -389,8 +403,11 @@ kvm_mips_handle_mapped_seg_tlb_fault(struct kvm_vcpu *vcpu, | |||
389 | pfn0 = 0; | 403 | pfn0 = 0; |
390 | pfn1 = 0; | 404 | pfn1 = 0; |
391 | } else { | 405 | } else { |
392 | kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT); | 406 | if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT) < 0) |
393 | kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT); | 407 | return -1; |
408 | |||
409 | if (kvm_mips_map_page(kvm, mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT) < 0) | ||
410 | return -1; | ||
394 | 411 | ||
395 | pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT]; | 412 | pfn0 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo0) >> PAGE_SHIFT]; |
396 | pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT]; | 413 | pfn1 = kvm->arch.guest_pmap[mips3_tlbpfn_to_paddr(tlb->tlb_lo1) >> PAGE_SHIFT]; |