aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kvm/e500_tlb.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kvm/e500_tlb.c')
-rw-r--r--arch/powerpc/kvm/e500_tlb.c267
1 files changed, 189 insertions, 78 deletions
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c
index b976d8025e5..59221bb1e00 100644
--- a/arch/powerpc/kvm/e500_tlb.c
+++ b/arch/powerpc/kvm/e500_tlb.c
@@ -12,6 +12,7 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/kernel.h>
15#include <linux/types.h> 16#include <linux/types.h>
16#include <linux/slab.h> 17#include <linux/slab.h>
17#include <linux/string.h> 18#include <linux/string.h>
@@ -26,7 +27,7 @@
26#include "trace.h" 27#include "trace.h"
27#include "timing.h" 28#include "timing.h"
28 29
29#define to_htlb1_esel(esel) (tlb1_entry_num - (esel) - 1) 30#define to_htlb1_esel(esel) (host_tlb_params[1].entries - (esel) - 1)
30 31
31struct id { 32struct id {
32 unsigned long val; 33 unsigned long val;
@@ -63,7 +64,7 @@ static DEFINE_PER_CPU(struct pcpu_id_table, pcpu_sids);
63 * The valid range of shadow ID is [1..255] */ 64 * The valid range of shadow ID is [1..255] */
64static DEFINE_PER_CPU(unsigned long, pcpu_last_used_sid); 65static DEFINE_PER_CPU(unsigned long, pcpu_last_used_sid);
65 66
66static unsigned int tlb1_entry_num; 67static struct kvmppc_e500_tlb_params host_tlb_params[E500_TLB_NUM];
67 68
68/* 69/*
69 * Allocate a free shadow id and setup a valid sid mapping in given entry. 70 * Allocate a free shadow id and setup a valid sid mapping in given entry.
@@ -237,7 +238,7 @@ void kvmppc_dump_tlbs(struct kvm_vcpu *vcpu)
237 } 238 }
238} 239}
239 240
240static inline unsigned int tlb0_get_next_victim( 241static inline unsigned int gtlb0_get_next_victim(
241 struct kvmppc_vcpu_e500 *vcpu_e500) 242 struct kvmppc_vcpu_e500 *vcpu_e500)
242{ 243{
243 unsigned int victim; 244 unsigned int victim;
@@ -252,7 +253,7 @@ static inline unsigned int tlb0_get_next_victim(
252static inline unsigned int tlb1_max_shadow_size(void) 253static inline unsigned int tlb1_max_shadow_size(void)
253{ 254{
254 /* reserve one entry for magic page */ 255 /* reserve one entry for magic page */
255 return tlb1_entry_num - tlbcam_index - 1; 256 return host_tlb_params[1].entries - tlbcam_index - 1;
256} 257}
257 258
258static inline int tlbe_is_writable(struct tlbe *tlbe) 259static inline int tlbe_is_writable(struct tlbe *tlbe)
@@ -302,13 +303,12 @@ static inline void __write_host_tlbe(struct tlbe *stlbe, uint32_t mas0)
302 local_irq_restore(flags); 303 local_irq_restore(flags);
303} 304}
304 305
306/* esel is index into set, not whole array */
305static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500, 307static inline void write_host_tlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
306 int tlbsel, int esel, struct tlbe *stlbe) 308 int tlbsel, int esel, struct tlbe *stlbe)
307{ 309{
308 if (tlbsel == 0) { 310 if (tlbsel == 0) {
309 __write_host_tlbe(stlbe, 311 __write_host_tlbe(stlbe, MAS0_TLBSEL(0) | MAS0_ESEL(esel));
310 MAS0_TLBSEL(0) |
311 MAS0_ESEL(esel & (KVM_E500_TLB0_WAY_NUM - 1)));
312 } else { 312 } else {
313 __write_host_tlbe(stlbe, 313 __write_host_tlbe(stlbe,
314 MAS0_TLBSEL(1) | 314 MAS0_TLBSEL(1) |
@@ -355,8 +355,8 @@ void kvmppc_e500_tlb_put(struct kvm_vcpu *vcpu)
355{ 355{
356} 356}
357 357
358static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, 358static void inval_gtlbe_on_host(struct kvmppc_vcpu_e500 *vcpu_e500,
359 int tlbsel, int esel) 359 int tlbsel, int esel)
360{ 360{
361 struct tlbe *gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel]; 361 struct tlbe *gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel];
362 struct vcpu_id_table *idt = vcpu_e500->idt; 362 struct vcpu_id_table *idt = vcpu_e500->idt;
@@ -412,18 +412,53 @@ static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500,
412 preempt_enable(); 412 preempt_enable();
413} 413}
414 414
415static int tlb0_set_base(gva_t addr, int sets, int ways)
416{
417 int set_base;
418
419 set_base = (addr >> PAGE_SHIFT) & (sets - 1);
420 set_base *= ways;
421
422 return set_base;
423}
424
425static int gtlb0_set_base(struct kvmppc_vcpu_e500 *vcpu_e500, gva_t addr)
426{
427 int sets = KVM_E500_TLB0_SIZE / KVM_E500_TLB0_WAY_NUM;
428
429 return tlb0_set_base(addr, sets, KVM_E500_TLB0_WAY_NUM);
430}
431
432static int htlb0_set_base(gva_t addr)
433{
434 return tlb0_set_base(addr, host_tlb_params[0].sets,
435 host_tlb_params[0].ways);
436}
437
438static unsigned int get_tlb_esel(struct kvmppc_vcpu_e500 *vcpu_e500, int tlbsel)
439{
440 unsigned int esel = get_tlb_esel_bit(vcpu_e500);
441
442 if (tlbsel == 0) {
443 esel &= KVM_E500_TLB0_WAY_NUM_MASK;
444 esel += gtlb0_set_base(vcpu_e500, vcpu_e500->mas2);
445 } else {
446 esel &= vcpu_e500->gtlb_size[tlbsel] - 1;
447 }
448
449 return esel;
450}
451
415/* Search the guest TLB for a matching entry. */ 452/* Search the guest TLB for a matching entry. */
416static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500, 453static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500,
417 gva_t eaddr, int tlbsel, unsigned int pid, int as) 454 gva_t eaddr, int tlbsel, unsigned int pid, int as)
418{ 455{
419 int size = vcpu_e500->gtlb_size[tlbsel]; 456 int size = vcpu_e500->gtlb_size[tlbsel];
420 int set_base; 457 unsigned int set_base;
421 int i; 458 int i;
422 459
423 if (tlbsel == 0) { 460 if (tlbsel == 0) {
424 int mask = size / KVM_E500_TLB0_WAY_NUM - 1; 461 set_base = gtlb0_set_base(vcpu_e500, eaddr);
425 set_base = (eaddr >> PAGE_SHIFT) & mask;
426 set_base *= KVM_E500_TLB0_WAY_NUM;
427 size = KVM_E500_TLB0_WAY_NUM; 462 size = KVM_E500_TLB0_WAY_NUM;
428 } else { 463 } else {
429 set_base = 0; 464 set_base = 0;
@@ -455,29 +490,55 @@ static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500,
455 return -1; 490 return -1;
456} 491}
457 492
458static inline void kvmppc_e500_priv_setup(struct tlbe_priv *priv, 493static inline void kvmppc_e500_ref_setup(struct tlbe_ref *ref,
459 struct tlbe *gtlbe, 494 struct tlbe *gtlbe,
460 pfn_t pfn) 495 pfn_t pfn)
461{ 496{
462 priv->pfn = pfn; 497 ref->pfn = pfn;
463 priv->flags = E500_TLB_VALID; 498 ref->flags = E500_TLB_VALID;
464 499
465 if (tlbe_is_writable(gtlbe)) 500 if (tlbe_is_writable(gtlbe))
466 priv->flags |= E500_TLB_DIRTY; 501 ref->flags |= E500_TLB_DIRTY;
467} 502}
468 503
469static inline void kvmppc_e500_priv_release(struct tlbe_priv *priv) 504static inline void kvmppc_e500_ref_release(struct tlbe_ref *ref)
470{ 505{
471 if (priv->flags & E500_TLB_VALID) { 506 if (ref->flags & E500_TLB_VALID) {
472 if (priv->flags & E500_TLB_DIRTY) 507 if (ref->flags & E500_TLB_DIRTY)
473 kvm_release_pfn_dirty(priv->pfn); 508 kvm_release_pfn_dirty(ref->pfn);
474 else 509 else
475 kvm_release_pfn_clean(priv->pfn); 510 kvm_release_pfn_clean(ref->pfn);
511
512 ref->flags = 0;
513 }
514}
515
516static void clear_tlb_privs(struct kvmppc_vcpu_e500 *vcpu_e500)
517{
518 int tlbsel = 0;
519 int i;
476 520
477 priv->flags = 0; 521 for (i = 0; i < vcpu_e500->gtlb_size[tlbsel]; i++) {
522 struct tlbe_ref *ref =
523 &vcpu_e500->gtlb_priv[tlbsel][i].ref;
524 kvmppc_e500_ref_release(ref);
478 } 525 }
479} 526}
480 527
528static void clear_tlb_refs(struct kvmppc_vcpu_e500 *vcpu_e500)
529{
530 int stlbsel = 1;
531 int i;
532
533 for (i = 0; i < host_tlb_params[stlbsel].entries; i++) {
534 struct tlbe_ref *ref =
535 &vcpu_e500->tlb_refs[stlbsel][i];
536 kvmppc_e500_ref_release(ref);
537 }
538
539 clear_tlb_privs(vcpu_e500);
540}
541
481static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu, 542static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
482 unsigned int eaddr, int as) 543 unsigned int eaddr, int as)
483{ 544{
@@ -487,7 +548,7 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
487 548
488 /* since we only have two TLBs, only lower bit is used. */ 549 /* since we only have two TLBs, only lower bit is used. */
489 tlbsel = (vcpu_e500->mas4 >> 28) & 0x1; 550 tlbsel = (vcpu_e500->mas4 >> 28) & 0x1;
490 victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0; 551 victim = (tlbsel == 0) ? gtlb0_get_next_victim(vcpu_e500) : 0;
491 pidsel = (vcpu_e500->mas4 >> 16) & 0xf; 552 pidsel = (vcpu_e500->mas4 >> 16) & 0xf;
492 tsized = (vcpu_e500->mas4 >> 7) & 0x1f; 553 tsized = (vcpu_e500->mas4 >> 7) & 0x1f;
493 554
@@ -508,10 +569,12 @@ static inline void kvmppc_e500_deliver_tlb_miss(struct kvm_vcpu *vcpu,
508/* TID must be supplied by the caller */ 569/* TID must be supplied by the caller */
509static inline void kvmppc_e500_setup_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500, 570static inline void kvmppc_e500_setup_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
510 struct tlbe *gtlbe, int tsize, 571 struct tlbe *gtlbe, int tsize,
511 struct tlbe_priv *priv, 572 struct tlbe_ref *ref,
512 u64 gvaddr, struct tlbe *stlbe) 573 u64 gvaddr, struct tlbe *stlbe)
513{ 574{
514 pfn_t pfn = priv->pfn; 575 pfn_t pfn = ref->pfn;
576
577 BUG_ON(!(ref->flags & E500_TLB_VALID));
515 578
516 /* Force TS=1 IPROT=0 for all guest mappings. */ 579 /* Force TS=1 IPROT=0 for all guest mappings. */
517 stlbe->mas1 = MAS1_TSIZE(tsize) | MAS1_TS | MAS1_VALID; 580 stlbe->mas1 = MAS1_TSIZE(tsize) | MAS1_TS | MAS1_VALID;
@@ -524,16 +587,15 @@ static inline void kvmppc_e500_setup_stlbe(struct kvmppc_vcpu_e500 *vcpu_e500,
524 stlbe->mas7 = (pfn >> (32 - PAGE_SHIFT)) & MAS7_RPN; 587 stlbe->mas7 = (pfn >> (32 - PAGE_SHIFT)) & MAS7_RPN;
525} 588}
526 589
527 590/* sesel is an index into the entire array, not just the set */
528static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500, 591static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
529 u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe, int tlbsel, int esel, 592 u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe, int tlbsel, int sesel,
530 struct tlbe *stlbe) 593 struct tlbe *stlbe, struct tlbe_ref *ref)
531{ 594{
532 struct kvm_memory_slot *slot; 595 struct kvm_memory_slot *slot;
533 unsigned long pfn, hva; 596 unsigned long pfn, hva;
534 int pfnmap = 0; 597 int pfnmap = 0;
535 int tsize = BOOK3E_PAGESZ_4K; 598 int tsize = BOOK3E_PAGESZ_4K;
536 struct tlbe_priv *priv;
537 599
538 /* 600 /*
539 * Translate guest physical to true physical, acquiring 601 * Translate guest physical to true physical, acquiring
@@ -629,12 +691,11 @@ static inline void kvmppc_e500_shadow_map(struct kvmppc_vcpu_e500 *vcpu_e500,
629 } 691 }
630 } 692 }
631 693
632 /* Drop old priv and setup new one. */ 694 /* Drop old ref and setup new one. */
633 priv = &vcpu_e500->gtlb_priv[tlbsel][esel]; 695 kvmppc_e500_ref_release(ref);
634 kvmppc_e500_priv_release(priv); 696 kvmppc_e500_ref_setup(ref, gtlbe, pfn);
635 kvmppc_e500_priv_setup(priv, gtlbe, pfn);
636 697
637 kvmppc_e500_setup_stlbe(vcpu_e500, gtlbe, tsize, priv, gvaddr, stlbe); 698 kvmppc_e500_setup_stlbe(vcpu_e500, gtlbe, tsize, ref, gvaddr, stlbe);
638} 699}
639 700
640/* XXX only map the one-one case, for now use TLB0 */ 701/* XXX only map the one-one case, for now use TLB0 */
@@ -642,14 +703,22 @@ static int kvmppc_e500_tlb0_map(struct kvmppc_vcpu_e500 *vcpu_e500,
642 int esel, struct tlbe *stlbe) 703 int esel, struct tlbe *stlbe)
643{ 704{
644 struct tlbe *gtlbe; 705 struct tlbe *gtlbe;
706 struct tlbe_ref *ref;
707 int sesel = esel & (host_tlb_params[0].ways - 1);
708 int sesel_base;
709 gva_t ea;
645 710
646 gtlbe = &vcpu_e500->gtlb_arch[0][esel]; 711 gtlbe = &vcpu_e500->gtlb_arch[0][esel];
712 ref = &vcpu_e500->gtlb_priv[0][esel].ref;
713
714 ea = get_tlb_eaddr(gtlbe);
715 sesel_base = htlb0_set_base(ea);
647 716
648 kvmppc_e500_shadow_map(vcpu_e500, get_tlb_eaddr(gtlbe), 717 kvmppc_e500_shadow_map(vcpu_e500, get_tlb_eaddr(gtlbe),
649 get_tlb_raddr(gtlbe) >> PAGE_SHIFT, 718 get_tlb_raddr(gtlbe) >> PAGE_SHIFT,
650 gtlbe, 0, esel, stlbe); 719 gtlbe, 0, sesel_base + sesel, stlbe, ref);
651 720
652 return esel; 721 return sesel;
653} 722}
654 723
655/* Caller must ensure that the specified guest TLB entry is safe to insert into 724/* Caller must ensure that the specified guest TLB entry is safe to insert into
@@ -658,14 +727,17 @@ static int kvmppc_e500_tlb0_map(struct kvmppc_vcpu_e500 *vcpu_e500,
658static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500, 727static int kvmppc_e500_tlb1_map(struct kvmppc_vcpu_e500 *vcpu_e500,
659 u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe, struct tlbe *stlbe) 728 u64 gvaddr, gfn_t gfn, struct tlbe *gtlbe, struct tlbe *stlbe)
660{ 729{
730 struct tlbe_ref *ref;
661 unsigned int victim; 731 unsigned int victim;
662 732
663 victim = vcpu_e500->gtlb_nv[1]++; 733 victim = vcpu_e500->host_tlb1_nv++;
664 734
665 if (unlikely(vcpu_e500->gtlb_nv[1] >= tlb1_max_shadow_size())) 735 if (unlikely(vcpu_e500->host_tlb1_nv >= tlb1_max_shadow_size()))
666 vcpu_e500->gtlb_nv[1] = 0; 736 vcpu_e500->host_tlb1_nv = 0;
667 737
668 kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1, victim, stlbe); 738 ref = &vcpu_e500->tlb_refs[1][victim];
739 kvmppc_e500_shadow_map(vcpu_e500, gvaddr, gfn, gtlbe, 1,
740 victim, stlbe, ref);
669 741
670 return victim; 742 return victim;
671} 743}
@@ -792,7 +864,7 @@ int kvmppc_e500_emul_tlbsx(struct kvm_vcpu *vcpu, int rb)
792 864
793 /* since we only have two TLBs, only lower bit is used. */ 865 /* since we only have two TLBs, only lower bit is used. */
794 tlbsel = vcpu_e500->mas4 >> 28 & 0x1; 866 tlbsel = vcpu_e500->mas4 >> 28 & 0x1;
795 victim = (tlbsel == 0) ? tlb0_get_next_victim(vcpu_e500) : 0; 867 victim = (tlbsel == 0) ? gtlb0_get_next_victim(vcpu_e500) : 0;
796 868
797 vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim) 869 vcpu_e500->mas0 = MAS0_TLBSEL(tlbsel) | MAS0_ESEL(victim)
798 | MAS0_NV(vcpu_e500->gtlb_nv[tlbsel]); 870 | MAS0_NV(vcpu_e500->gtlb_nv[tlbsel]);
@@ -839,7 +911,7 @@ int kvmppc_e500_emul_tlbwe(struct kvm_vcpu *vcpu)
839 gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel]; 911 gtlbe = &vcpu_e500->gtlb_arch[tlbsel][esel];
840 912
841 if (get_tlb_v(gtlbe)) 913 if (get_tlb_v(gtlbe))
842 kvmppc_e500_stlbe_invalidate(vcpu_e500, tlbsel, esel); 914 inval_gtlbe_on_host(vcpu_e500, tlbsel, esel);
843 915
844 gtlbe->mas1 = vcpu_e500->mas1; 916 gtlbe->mas1 = vcpu_e500->mas1;
845 gtlbe->mas2 = vcpu_e500->mas2; 917 gtlbe->mas2 = vcpu_e500->mas2;
@@ -950,11 +1022,11 @@ void kvmppc_mmu_map(struct kvm_vcpu *vcpu, u64 eaddr, gpa_t gpaddr,
950 switch (tlbsel) { 1022 switch (tlbsel) {
951 case 0: 1023 case 0:
952 stlbsel = 0; 1024 stlbsel = 0;
953 sesel = esel; 1025 sesel = esel & (host_tlb_params[0].ways - 1);
954 priv = &vcpu_e500->gtlb_priv[stlbsel][sesel]; 1026 priv = &vcpu_e500->gtlb_priv[tlbsel][esel];
955 1027
956 kvmppc_e500_setup_stlbe(vcpu_e500, gtlbe, BOOK3E_PAGESZ_4K, 1028 kvmppc_e500_setup_stlbe(vcpu_e500, gtlbe, BOOK3E_PAGESZ_4K,
957 priv, eaddr, &stlbe); 1029 &priv->ref, eaddr, &stlbe);
958 break; 1030 break;
959 1031
960 case 1: { 1032 case 1: {
@@ -1020,32 +1092,76 @@ void kvmppc_e500_tlb_setup(struct kvmppc_vcpu_e500 *vcpu_e500)
1020 1092
1021int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500) 1093int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
1022{ 1094{
1023 tlb1_entry_num = mfspr(SPRN_TLB1CFG) & 0xFFF; 1095 host_tlb_params[0].entries = mfspr(SPRN_TLB0CFG) & TLBnCFG_N_ENTRY;
1096 host_tlb_params[1].entries = mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY;
1097
1098 /*
1099 * This should never happen on real e500 hardware, but is
1100 * architecturally possible -- e.g. in some weird nested
1101 * virtualization case.
1102 */
1103 if (host_tlb_params[0].entries == 0 ||
1104 host_tlb_params[1].entries == 0) {
1105 pr_err("%s: need to know host tlb size\n", __func__);
1106 return -ENODEV;
1107 }
1108
1109 host_tlb_params[0].ways = (mfspr(SPRN_TLB0CFG) & TLBnCFG_ASSOC) >>
1110 TLBnCFG_ASSOC_SHIFT;
1111 host_tlb_params[1].ways = host_tlb_params[1].entries;
1112
1113 if (!is_power_of_2(host_tlb_params[0].entries) ||
1114 !is_power_of_2(host_tlb_params[0].ways) ||
1115 host_tlb_params[0].entries < host_tlb_params[0].ways ||
1116 host_tlb_params[0].ways == 0) {
1117 pr_err("%s: bad tlb0 host config: %u entries %u ways\n",
1118 __func__, host_tlb_params[0].entries,
1119 host_tlb_params[0].ways);
1120 return -ENODEV;
1121 }
1122
1123 host_tlb_params[0].sets =
1124 host_tlb_params[0].entries / host_tlb_params[0].ways;
1125 host_tlb_params[1].sets = 1;
1024 1126
1025 vcpu_e500->gtlb_size[0] = KVM_E500_TLB0_SIZE; 1127 vcpu_e500->gtlb_size[0] = KVM_E500_TLB0_SIZE;
1026 vcpu_e500->gtlb_arch[0] = 1128 vcpu_e500->gtlb_arch[0] =
1027 kzalloc(sizeof(struct tlbe) * KVM_E500_TLB0_SIZE, GFP_KERNEL); 1129 kzalloc(sizeof(struct tlbe) * KVM_E500_TLB0_SIZE, GFP_KERNEL);
1028 if (vcpu_e500->gtlb_arch[0] == NULL) 1130 if (vcpu_e500->gtlb_arch[0] == NULL)
1029 goto err_out; 1131 goto err;
1030 1132
1031 vcpu_e500->gtlb_size[1] = KVM_E500_TLB1_SIZE; 1133 vcpu_e500->gtlb_size[1] = KVM_E500_TLB1_SIZE;
1032 vcpu_e500->gtlb_arch[1] = 1134 vcpu_e500->gtlb_arch[1] =
1033 kzalloc(sizeof(struct tlbe) * KVM_E500_TLB1_SIZE, GFP_KERNEL); 1135 kzalloc(sizeof(struct tlbe) * KVM_E500_TLB1_SIZE, GFP_KERNEL);
1034 if (vcpu_e500->gtlb_arch[1] == NULL) 1136 if (vcpu_e500->gtlb_arch[1] == NULL)
1035 goto err_out_guest0; 1137 goto err;
1036 1138
1037 vcpu_e500->gtlb_priv[0] = (struct tlbe_priv *) 1139 vcpu_e500->tlb_refs[0] =
1038 kzalloc(sizeof(struct tlbe_priv) * KVM_E500_TLB0_SIZE, GFP_KERNEL); 1140 kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[0].entries,
1039 if (vcpu_e500->gtlb_priv[0] == NULL) 1141 GFP_KERNEL);
1040 goto err_out_guest1; 1142 if (!vcpu_e500->tlb_refs[0])
1041 vcpu_e500->gtlb_priv[1] = (struct tlbe_priv *) 1143 goto err;
1042 kzalloc(sizeof(struct tlbe_priv) * KVM_E500_TLB1_SIZE, GFP_KERNEL); 1144
1043 1145 vcpu_e500->tlb_refs[1] =
1044 if (vcpu_e500->gtlb_priv[1] == NULL) 1146 kzalloc(sizeof(struct tlbe_ref) * host_tlb_params[1].entries,
1045 goto err_out_priv0; 1147 GFP_KERNEL);
1148 if (!vcpu_e500->tlb_refs[1])
1149 goto err;
1150
1151 vcpu_e500->gtlb_priv[0] =
1152 kzalloc(sizeof(struct tlbe_ref) * vcpu_e500->gtlb_size[0],
1153 GFP_KERNEL);
1154 if (!vcpu_e500->gtlb_priv[0])
1155 goto err;
1156
1157 vcpu_e500->gtlb_priv[1] =
1158 kzalloc(sizeof(struct tlbe_ref) * vcpu_e500->gtlb_size[1],
1159 GFP_KERNEL);
1160 if (!vcpu_e500->gtlb_priv[1])
1161 goto err;
1046 1162
1047 if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL) 1163 if (kvmppc_e500_id_table_alloc(vcpu_e500) == NULL)
1048 goto err_out_priv1; 1164 goto err;
1049 1165
1050 /* Init TLB configuration register */ 1166 /* Init TLB configuration register */
1051 vcpu_e500->tlb0cfg = mfspr(SPRN_TLB0CFG) & ~0xfffUL; 1167 vcpu_e500->tlb0cfg = mfspr(SPRN_TLB0CFG) & ~0xfffUL;
@@ -1055,31 +1171,26 @@ int kvmppc_e500_tlb_init(struct kvmppc_vcpu_e500 *vcpu_e500)
1055 1171
1056 return 0; 1172 return 0;
1057 1173
1058err_out_priv1: 1174err:
1059 kfree(vcpu_e500->gtlb_priv[1]); 1175 kfree(vcpu_e500->tlb_refs[0]);
1060err_out_priv0: 1176 kfree(vcpu_e500->tlb_refs[1]);
1061 kfree(vcpu_e500->gtlb_priv[0]); 1177 kfree(vcpu_e500->gtlb_priv[0]);
1062err_out_guest1: 1178 kfree(vcpu_e500->gtlb_priv[1]);
1063 kfree(vcpu_e500->gtlb_arch[1]);
1064err_out_guest0:
1065 kfree(vcpu_e500->gtlb_arch[0]); 1179 kfree(vcpu_e500->gtlb_arch[0]);
1066err_out: 1180 kfree(vcpu_e500->gtlb_arch[1]);
1067 return -1; 1181 return -1;
1068} 1182}
1069 1183
1070void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500) 1184void kvmppc_e500_tlb_uninit(struct kvmppc_vcpu_e500 *vcpu_e500)
1071{ 1185{
1072 int stlbsel, i; 1186 clear_tlb_refs(vcpu_e500);
1073
1074 /* release all privs */
1075 for (stlbsel = 0; stlbsel < 2; stlbsel++)
1076 for (i = 0; i < vcpu_e500->gtlb_size[stlbsel]; i++) {
1077 struct tlbe_priv *priv =
1078 &vcpu_e500->gtlb_priv[stlbsel][i];
1079 kvmppc_e500_priv_release(priv);
1080 }
1081 1187
1082 kvmppc_e500_id_table_free(vcpu_e500); 1188 kvmppc_e500_id_table_free(vcpu_e500);
1189
1190 kfree(vcpu_e500->tlb_refs[0]);
1191 kfree(vcpu_e500->tlb_refs[1]);
1192 kfree(vcpu_e500->gtlb_priv[0]);
1193 kfree(vcpu_e500->gtlb_priv[1]);
1083 kfree(vcpu_e500->gtlb_arch[1]); 1194 kfree(vcpu_e500->gtlb_arch[1]);
1084 kfree(vcpu_e500->gtlb_arch[0]); 1195 kfree(vcpu_e500->gtlb_arch[0]);
1085} 1196}