Re: [PATCH 1/2] KVM: PPC: Book3S HV: Correct tlbie usage

2013-07-17 Thread Aneesh Kumar K.V
Paul Mackerras pau...@samba.org writes:

 This corrects the usage of the tlbie (TLB invalidate entry) instruction
 in HV KVM.  The tlbie instruction changed between PPC970 and POWER7.
 On the PPC970, the bit to select large vs. small page is in the instruction,
 not in the RB register value.  This changes the code to use the correct
 form on PPC970.

I guess we need a similar fix for __tlbiel ?


 On POWER7 we were calculating the AVAL (Abbreviated Virtual Address, Lower)
 field of the RB value incorrectly for 64k pages.  This fixes it.

 Since we now have several cases to handle for the tlbie instruction, this
 factors out the code to do a sequence of tlbies into a new function,
 do_tlbies(), and calls that from the various places where the code was
 doing tlbie instructions inline.  It also makes kvmppc_h_bulk_remove()
 use the same global_invalidates() function for determining whether to do
 local or global TLB invalidations as is used in other places, for
 consistency, and also to make sure that kvm-arch.need_tlb_flush gets
 updated properly.

 Signed-off-by: Paul Mackerras pau...@samba.org
 Cc: sta...@vger.kernel.org
 ---
  arch/powerpc/include/asm/kvm_book3s_64.h |   2 +-
  arch/powerpc/kvm/book3s_hv_rm_mmu.c  | 139 
 ++-
  2 files changed, 82 insertions(+), 59 deletions(-)

 diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h 
 b/arch/powerpc/include/asm/kvm_book3s_64.h
 index 9c1ff33..dc6b84a 100644
 --- a/arch/powerpc/include/asm/kvm_book3s_64.h
 +++ b/arch/powerpc/include/asm/kvm_book3s_64.h
 @@ -100,7 +100,7 @@ static inline unsigned long compute_tlbie_rb(unsigned 
 long v, unsigned long r,
   /* (masks depend on page size) */
   rb |= 0x1000;   /* page encoding in LP field */
   rb |= (va_low  0x7f)  16; /* 7b of VA in AVA/LP 
 field */
 - rb |= (va_low  0xfe);  /* AVAL field (P7 doesn't seem 
 to care) */
 + rb |= ((va_low  4)  0xf0);   /* AVAL field
 (P7 doesn't seem to care) */


Can you explain this more ? Why shift by 4 ? and what about the three
bits ('e' part of 0xfe) ? 

   }
   } else {
   /* 4kB page */
 diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c 
 b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
 index 6dcbb49..105b00f 100644
 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
 +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
 @@ -385,6 +385,80 @@ static inline int try_lock_tlbie(unsigned int *lock)
   return old == 0;
  }
  

-aneesh

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/2] KVM: PPC: Book3S HV: Correct tlbie usage

2013-07-10 Thread Alexander Graf

On 08.07.2013, at 12:08, Paul Mackerras wrote:

 This corrects the usage of the tlbie (TLB invalidate entry) instruction
 in HV KVM.  The tlbie instruction changed between PPC970 and POWER7.
 On the PPC970, the bit to select large vs. small page is in the instruction,
 not in the RB register value.  This changes the code to use the correct
 form on PPC970.
 
 On POWER7 we were calculating the AVAL (Abbreviated Virtual Address, Lower)
 field of the RB value incorrectly for 64k pages.  This fixes it.
 
 Since we now have several cases to handle for the tlbie instruction, this
 factors out the code to do a sequence of tlbies into a new function,
 do_tlbies(), and calls that from the various places where the code was
 doing tlbie instructions inline.  It also makes kvmppc_h_bulk_remove()
 use the same global_invalidates() function for determining whether to do
 local or global TLB invalidations as is used in other places, for
 consistency, and also to make sure that kvm-arch.need_tlb_flush gets
 updated properly.
 
 Signed-off-by: Paul Mackerras pau...@samba.org
 Cc: sta...@vger.kernel.org

Thanks, applied both to kvm-ppc-queue.


Alex

--
To unsubscribe from this list: send the line unsubscribe kvm-ppc in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/2] KVM: PPC: Book3S HV: Correct tlbie usage

2013-07-08 Thread Paul Mackerras
This corrects the usage of the tlbie (TLB invalidate entry) instruction
in HV KVM.  The tlbie instruction changed between PPC970 and POWER7.
On the PPC970, the bit to select large vs. small page is in the instruction,
not in the RB register value.  This changes the code to use the correct
form on PPC970.

On POWER7 we were calculating the AVAL (Abbreviated Virtual Address, Lower)
field of the RB value incorrectly for 64k pages.  This fixes it.

Since we now have several cases to handle for the tlbie instruction, this
factors out the code to do a sequence of tlbies into a new function,
do_tlbies(), and calls that from the various places where the code was
doing tlbie instructions inline.  It also makes kvmppc_h_bulk_remove()
use the same global_invalidates() function for determining whether to do
local or global TLB invalidations as is used in other places, for
consistency, and also to make sure that kvm-arch.need_tlb_flush gets
updated properly.

Signed-off-by: Paul Mackerras pau...@samba.org
Cc: sta...@vger.kernel.org
---
 arch/powerpc/include/asm/kvm_book3s_64.h |   2 +-
 arch/powerpc/kvm/book3s_hv_rm_mmu.c  | 139 ++-
 2 files changed, 82 insertions(+), 59 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s_64.h 
b/arch/powerpc/include/asm/kvm_book3s_64.h
index 9c1ff33..dc6b84a 100644
--- a/arch/powerpc/include/asm/kvm_book3s_64.h
+++ b/arch/powerpc/include/asm/kvm_book3s_64.h
@@ -100,7 +100,7 @@ static inline unsigned long compute_tlbie_rb(unsigned long 
v, unsigned long r,
/* (masks depend on page size) */
rb |= 0x1000;   /* page encoding in LP field */
rb |= (va_low  0x7f)  16; /* 7b of VA in AVA/LP 
field */
-   rb |= (va_low  0xfe);  /* AVAL field (P7 doesn't seem 
to care) */
+   rb |= ((va_low  4)  0xf0);   /* AVAL field (P7 
doesn't seem to care) */
}
} else {
/* 4kB page */
diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c 
b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
index 6dcbb49..105b00f 100644
--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
@@ -385,6 +385,80 @@ static inline int try_lock_tlbie(unsigned int *lock)
return old == 0;
 }
 
+/*
+ * tlbie/tlbiel is a bit different on the PPC970 compared to later
+ * processors such as POWER7; the large page bit is in the instruction
+ * not RB, and the top 16 bits and the bottom 12 bits of the VA
+ * in RB must be 0.
+ */
+static void do_tlbies_970(struct kvm *kvm, unsigned long *rbvalues,
+ long npages, int global, bool need_sync)
+{
+   long i;
+
+   if (global) {
+   while (!try_lock_tlbie(kvm-arch.tlbie_lock))
+   cpu_relax();
+   if (need_sync)
+   asm volatile(ptesync : : : memory);
+   for (i = 0; i  npages; ++i) {
+   unsigned long rb = rbvalues[i];
+
+   if (rb  1) /* large page */
+   asm volatile(tlbie %0,1 : :
+r (rb  0xf000ul));
+   else
+   asm volatile(tlbie %0,0 : :
+r (rb  0xf000ul));
+   }
+   asm volatile(eieio; tlbsync; ptesync : : : memory);
+   kvm-arch.tlbie_lock = 0;
+   } else {
+   if (need_sync)
+   asm volatile(ptesync : : : memory);
+   for (i = 0; i  npages; ++i) {
+   unsigned long rb = rbvalues[i];
+
+   if (rb  1) /* large page */
+   asm volatile(tlbiel %0,1 : :
+r (rb  0xf000ul));
+   else
+   asm volatile(tlbiel %0,0 : :
+r (rb  0xf000ul));
+   }
+   asm volatile(ptesync : : : memory);
+   }
+}
+
+static void do_tlbies(struct kvm *kvm, unsigned long *rbvalues,
+ long npages, int global, bool need_sync)
+{
+   long i;
+
+   if (cpu_has_feature(CPU_FTR_ARCH_201)) {
+   /* PPC970 tlbie instruction is a bit different */
+   do_tlbies_970(kvm, rbvalues, npages, global, need_sync);
+   return;
+   }
+   if (global) {
+   while (!try_lock_tlbie(kvm-arch.tlbie_lock))
+   cpu_relax();
+   if (need_sync)
+   asm volatile(ptesync : : : memory);
+   for (i = 0; i  npages; ++i)
+   asm volatile(PPC_TLBIE(%1,%0) : :
+r (rbvalues[i]), r (kvm-arch.lpid));
+   asm volatile(eieio; tlbsync; ptesync