diff options
author | Scott Wood <scottwood@freescale.com> | 2011-06-14 18:35:20 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2011-07-12 13:16:40 +0300 |
commit | 1aee47a0276f75a371e13a936a48f64eb5d3ec1b (patch) | |
tree | a8fa2c437a7a562b61b8a028e3d8c78a422d2e1f /arch/powerpc/kvm/e500_tlb.c | |
parent | dd9ebf1f94354b010f2ac7a98bf69168636cb08e (diff) |
KVM: PPC: e500: Don't search over the entire TLB0.
Only look in the 4 entries that could possibly contain the
entry we're looking for.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
Diffstat (limited to 'arch/powerpc/kvm/e500_tlb.c')
-rw-r--r-- | arch/powerpc/kvm/e500_tlb.c | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/arch/powerpc/kvm/e500_tlb.c b/arch/powerpc/kvm/e500_tlb.c index ea394571bbb6..13c432ea2fa8 100644 --- a/arch/powerpc/kvm/e500_tlb.c +++ b/arch/powerpc/kvm/e500_tlb.c @@ -418,11 +418,21 @@ static void kvmppc_e500_stlbe_invalidate(struct kvmppc_vcpu_e500 *vcpu_e500, static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500, gva_t eaddr, int tlbsel, unsigned int pid, int as) { + int size = vcpu_e500->gtlb_size[tlbsel]; + int set_base; int i; - /* XXX Replace loop with fancy data structures. */ - for (i = 0; i < vcpu_e500->gtlb_size[tlbsel]; i++) { - struct tlbe *tlbe = &vcpu_e500->gtlb_arch[tlbsel][i]; + if (tlbsel == 0) { + int mask = size / KVM_E500_TLB0_WAY_NUM - 1; + set_base = (eaddr >> PAGE_SHIFT) & mask; + set_base *= KVM_E500_TLB0_WAY_NUM; + size = KVM_E500_TLB0_WAY_NUM; + } else { + set_base = 0; + } + + for (i = 0; i < size; i++) { + struct tlbe *tlbe = &vcpu_e500->gtlb_arch[tlbsel][set_base + i]; unsigned int tid; if (eaddr < get_tlb_eaddr(tlbe)) @@ -441,7 +451,7 @@ static int kvmppc_e500_tlb_index(struct kvmppc_vcpu_e500 *vcpu_e500, if (get_tlb_ts(tlbe) != as && as != -1) continue; - return i; + return set_base + i; } return -1; |