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/mips | |
| 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/mips')
| -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]; |
