aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/book3s.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/book3s.c')
-rw-r--r--arch/powerpc/kvm/book3s.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c
index 0ed5376df82..eee97b5a740 100644
--- a/arch/powerpc/kvm/book3s.c
+++ b/arch/powerpc/kvm/book3s.c
@@ -419,6 +419,25 @@ void kvmppc_set_pvr(struct kvm_vcpu *vcpu, u32 pvr)
419 } 419 }
420} 420}
421 421
422pfn_t kvmppc_gfn_to_pfn(struct kvm_vcpu *vcpu, gfn_t gfn)
423{
424 ulong mp_pa = vcpu->arch.magic_page_pa;
425
426 /* Magic page override */
427 if (unlikely(mp_pa) &&
428 unlikely(((gfn << PAGE_SHIFT) & KVM_PAM) ==
429 ((mp_pa & PAGE_MASK) & KVM_PAM))) {
430 ulong shared_page = ((ulong)vcpu->arch.shared) & PAGE_MASK;
431 pfn_t pfn;
432
433 pfn = (pfn_t)virt_to_phys((void*)shared_page) >> PAGE_SHIFT;
434 get_page(pfn_to_page(pfn));
435 return pfn;
436 }
437
438 return gfn_to_pfn(vcpu->kvm, gfn);
439}
440
422/* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To 441/* Book3s_32 CPUs always have 32 bytes cache line size, which Linux assumes. To
423 * make Book3s_32 Linux work on Book3s_64, we have to make sure we trap dcbz to 442 * make Book3s_32 Linux work on Book3s_64, we have to make sure we trap dcbz to
424 * emulate 32 bytes dcbz length. 443 * emulate 32 bytes dcbz length.
@@ -554,6 +573,13 @@ mmio:
554 573
555static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn) 574static int kvmppc_visible_gfn(struct kvm_vcpu *vcpu, gfn_t gfn)
556{ 575{
576 ulong mp_pa = vcpu->arch.magic_page_pa;
577
578 if (unlikely(mp_pa) &&
579 unlikely((mp_pa & KVM_PAM) >> PAGE_SHIFT == gfn)) {
580 return 1;
581 }
582
557 return kvm_is_visible_gfn(vcpu->kvm, gfn); 583 return kvm_is_visible_gfn(vcpu->kvm, gfn);
558} 584}
559 585
@@ -1257,6 +1283,7 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
1257 struct kvmppc_vcpu_book3s *vcpu_book3s; 1283 struct kvmppc_vcpu_book3s *vcpu_book3s;
1258 struct kvm_vcpu *vcpu; 1284 struct kvm_vcpu *vcpu;
1259 int err = -ENOMEM; 1285 int err = -ENOMEM;
1286 unsigned long p;
1260 1287
1261 vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s)); 1288 vcpu_book3s = vmalloc(sizeof(struct kvmppc_vcpu_book3s));
1262 if (!vcpu_book3s) 1289 if (!vcpu_book3s)
@@ -1274,8 +1301,10 @@ struct kvm_vcpu *kvmppc_core_vcpu_create(struct kvm *kvm, unsigned int id)
1274 if (err) 1301 if (err)
1275 goto free_shadow_vcpu; 1302 goto free_shadow_vcpu;
1276 1303
1277 vcpu->arch.shared = (void*)__get_free_page(GFP_KERNEL|__GFP_ZERO); 1304 p = __get_free_page(GFP_KERNEL|__GFP_ZERO);
1278 if (!vcpu->arch.shared) 1305 /* the real shared page fills the last 4k of our page */
1306 vcpu->arch.shared = (void*)(p + PAGE_SIZE - 4096);
1307 if (!p)
1279 goto uninit_vcpu; 1308 goto uninit_vcpu;
1280 1309
1281 vcpu->arch.host_retip = kvm_return_point; 1310 vcpu->arch.host_retip = kvm_return_point;
@@ -1322,7 +1351,7 @@ void kvmppc_core_vcpu_free(struct kvm_vcpu *vcpu)
1322{ 1351{
1323 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu); 1352 struct kvmppc_vcpu_book3s *vcpu_book3s = to_book3s(vcpu);
1324 1353
1325 free_page((unsigned long)vcpu->arch.shared); 1354 free_page((unsigned long)vcpu->arch.shared & PAGE_MASK);
1326 kvm_vcpu_uninit(vcpu); 1355 kvm_vcpu_uninit(vcpu);
1327 kfree(vcpu_book3s->shadow_vcpu); 1356 kfree(vcpu_book3s->shadow_vcpu);
1328 vfree(vcpu_book3s); 1357 vfree(vcpu_book3s);