linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64
@ 2012-06-29 14:17 Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 1/9] arch/powerpc: Use hpt_va to compute virtual address Aneesh Kumar K.V
                   ` (8 more replies)
  0 siblings, 9 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev

Hi,

This patchset include patches for supporting 64TB with ppc64. I haven't booted
this on hardware with 64TB memory yet. But they boot fine on real hardware with
less memory. Changes extend VSID bits to 38 bits for a 256MB segment
and 26 bits for 1TB segments. 

The patches are not for inclusion. I have few "Verify" tags in the patches for
which I would like closer review.

Thanks,
-aneesh

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH -V1 1/9] arch/powerpc: Use hpt_va to compute virtual address
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct Aneesh Kumar K.V
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

Don't open code the same

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/platforms/cell/beat_htab.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index 943c9d3..b83077e 100644
--- a/arch/powerpc/platforms/cell/beat_htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
@@ -259,7 +259,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
 	u64 dummy0, dummy1;
 
 	vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
-	va = (vsid << 28) | (ea & 0x0fffffff);
+	va = hpt_va(ea, vsid, MMU_SEGSIZE_256M);
 
 	raw_spin_lock(&beat_htab_lock);
 	slot = beat_lpar_hpte_find(va, psize);
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 1/9] arch/powerpc: Use hpt_va to compute virtual address Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 17:44   ` Cody P Schafer
  2012-06-29 21:43   ` Benjamin Herrenschmidt
  2012-06-29 14:17 ` [PATCH -V1 3/9] arch/powerpc: Simplify hpte_decode Aneesh Kumar K.V
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

This is in preparation to the conversion of 64 bit powerpc virtual address
to the max 78 bits. Later patch will switch struct virt_addr to a struct
of virtual segment id and segment offset.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/kvm_book3s.h   |    2 +-
 arch/powerpc/include/asm/machdep.h      |    6 +--
 arch/powerpc/include/asm/mmu-hash64.h   |   24 ++++++----
 arch/powerpc/include/asm/tlbflush.h     |    4 +-
 arch/powerpc/kvm/book3s_64_mmu_host.c   |    3 +-
 arch/powerpc/mm/hash_native_64.c        |   76 +++++++++++++++++--------------
 arch/powerpc/mm/hash_utils_64.c         |   12 ++---
 arch/powerpc/mm/hugetlbpage-hash64.c    |    3 +-
 arch/powerpc/mm/tlb_hash64.c            |    3 +-
 arch/powerpc/platforms/cell/beat_htab.c |   17 +++----
 arch/powerpc/platforms/ps3/htab.c       |    6 +--
 arch/powerpc/platforms/pseries/lpar.c   |   30 ++++++------
 12 files changed, 103 insertions(+), 83 deletions(-)

diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
index fd07f43..374b75d 100644
--- a/arch/powerpc/include/asm/kvm_book3s.h
+++ b/arch/powerpc/include/asm/kvm_book3s.h
@@ -59,7 +59,7 @@ struct hpte_cache {
 	struct hlist_node list_vpte;
 	struct hlist_node list_vpte_long;
 	struct rcu_head rcu_head;
-	u64 host_va;
+	struct virt_addr host_va;
 	u64 pfn;
 	ulong slot;
 	struct kvmppc_pte pte;
diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index 42ce570..b34d0a9 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -34,19 +34,19 @@ struct machdep_calls {
 	char		*name;
 #ifdef CONFIG_PPC64
 	void            (*hpte_invalidate)(unsigned long slot,
-					   unsigned long va,
+					   struct virt_addr va,
 					   int psize, int ssize,
 					   int local);
 	long		(*hpte_updatepp)(unsigned long slot, 
 					 unsigned long newpp, 
-					 unsigned long va,
+					 struct virt_addr va,
 					 int psize, int ssize,
 					 int local);
 	void            (*hpte_updateboltedpp)(unsigned long newpp, 
 					       unsigned long ea,
 					       int psize, int ssize);
 	long		(*hpte_insert)(unsigned long hpte_group,
-				       unsigned long va,
+				       struct virt_addr va,
 				       unsigned long prpn,
 				       unsigned long rflags,
 				       unsigned long vflags,
diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 1c65a59..5ff936b 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -143,6 +143,10 @@ struct mmu_psize_def
 	unsigned long	sllp;	/* SLB L||LP (exact mask to use in slbmte) */
 };
 
+struct virt_addr {
+	unsigned long addr;
+};
+
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -183,11 +187,11 @@ extern int mmu_ci_restrictions;
  * This function sets the AVPN and L fields of the HPTE  appropriately
  * for the page size
  */
-static inline unsigned long hpte_encode_v(unsigned long va, int psize,
+static inline unsigned long hpte_encode_v(struct virt_addr va, int psize,
 					  int ssize)
 {
 	unsigned long v;
-	v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
+	v = (va.addr >> 23) & ~(mmu_psize_defs[psize].avpnm);
 	v <<= HPTE_V_AVPN_SHIFT;
 	if (psize != MMU_PAGE_4K)
 		v |= HPTE_V_LARGE;
@@ -218,28 +222,30 @@ static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
 /*
  * Build a VA given VSID, EA and segment size
  */
-static inline unsigned long hpt_va(unsigned long ea, unsigned long vsid,
+static inline struct virt_addr hpt_va(unsigned long ea, unsigned long vsid,
 				   int ssize)
 {
+	struct virt_addr va;
 	if (ssize == MMU_SEGSIZE_256M)
-		return (vsid << 28) | (ea & 0xfffffffUL);
-	return (vsid << 40) | (ea & 0xffffffffffUL);
+		va.addr = (vsid << 28) | (ea & 0xfffffffUL);
+	va.addr = (vsid << 40) | (ea & 0xffffffffffUL);
+	return va;
 }
 
 /*
  * This hashes a virtual address
  */
 
-static inline unsigned long hpt_hash(unsigned long va, unsigned int shift,
+static inline unsigned long hpt_hash(struct virt_addr va, unsigned int shift,
 				     int ssize)
 {
 	unsigned long hash, vsid;
 
 	if (ssize == MMU_SEGSIZE_256M) {
-		hash = (va >> 28) ^ ((va & 0x0fffffffUL) >> shift);
+		hash = (va.addr >> 28) ^ ((va.addr & 0x0fffffffUL) >> shift);
 	} else {
-		vsid = va >> 40;
-		hash = vsid ^ (vsid << 25) ^ ((va & 0xffffffffffUL) >> shift);
+		vsid = va.addr >> 40;
+		hash = vsid ^ (vsid << 25) ^ ((va.addr & 0xffffffffffUL) >> shift);
 	}
 	return hash & 0x7fffffffffUL;
 }
diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
index 81143fc..2c8ad50 100644
--- a/arch/powerpc/include/asm/tlbflush.h
+++ b/arch/powerpc/include/asm/tlbflush.h
@@ -95,7 +95,7 @@ struct ppc64_tlb_batch {
 	unsigned long		index;
 	struct mm_struct	*mm;
 	real_pte_t		pte[PPC64_TLB_BATCH_NR];
-	unsigned long		vaddr[PPC64_TLB_BATCH_NR];
+	struct virt_addr	vaddr[PPC64_TLB_BATCH_NR];
 	unsigned int		psize;
 	int			ssize;
 };
@@ -127,7 +127,7 @@ static inline void arch_leave_lazy_mmu_mode(void)
 #define arch_flush_lazy_mmu_mode()      do {} while (0)
 
 
-extern void flush_hash_page(unsigned long va, real_pte_t pte, int psize,
+extern void flush_hash_page(struct virt_addr va, real_pte_t pte, int psize,
 			    int ssize, int local);
 extern void flush_hash_range(unsigned long number, int local);
 
diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
index 10fc8ec..933b117 100644
--- a/arch/powerpc/kvm/book3s_64_mmu_host.c
+++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
@@ -80,8 +80,9 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid)
 
 int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
 {
+	struct virt_addr va;
 	pfn_t hpaddr;
-	ulong hash, hpteg, va;
+	ulong hash, hpteg;
 	u64 vsid;
 	int ret;
 	int rflags = 0x192;
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 90039bc..cab3892 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -39,62 +39,67 @@
 
 DEFINE_RAW_SPINLOCK(native_tlbie_lock);
 
-static inline void __tlbie(unsigned long va, int psize, int ssize)
+/* Verify docs says 14 .. 14+i bits */
+static inline void __tlbie(struct virt_addr va, int psize, int ssize)
 {
+	unsigned long vaddr = va.addr;
 	unsigned int penc;
 
+	vaddr &= ~(0xffffULL << 48);
+
 	/* clear top 16 bits, non SLS segment */
-	va &= ~(0xffffULL << 48);
+	vaddr &= ~(0xffffULL << 48);
 
 	switch (psize) {
 	case MMU_PAGE_4K:
-		va &= ~0xffful;
-		va |= ssize << 8;
+		vaddr &= ~0xffful;
+		vaddr |= ssize << 8;
 		asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
-			     : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
+			     : : "r" (vaddr), "r"(0), "i" (CPU_FTR_ARCH_206)
 			     : "memory");
 		break;
 	default:
 		penc = mmu_psize_defs[psize].penc;
-		va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
-		va |= penc << 12;
-		va |= ssize << 8;
-		va |= 1; /* L */
+		vaddr &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
+		vaddr |= penc << 12;
+		vaddr |= ssize << 8;
+		vaddr |= 1; /* L */
 		asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2)
-			     : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
+			     : : "r" (vaddr), "r"(0), "i" (CPU_FTR_ARCH_206)
 			     : "memory");
 		break;
 	}
 }
 
-static inline void __tlbiel(unsigned long va, int psize, int ssize)
+/* Verify docs says 14 .. 14+i bits */
+static inline void __tlbiel(struct virt_addr va, int psize, int ssize)
 {
+	unsigned long vaddr = va.addr;
 	unsigned int penc;
 
-	/* clear top 16 bits, non SLS segment */
-	va &= ~(0xffffULL << 48);
+	vaddr &= ~(0xffffULL << 48);
 
 	switch (psize) {
 	case MMU_PAGE_4K:
-		va &= ~0xffful;
-		va |= ssize << 8;
+		vaddr &= ~0xffful;
+		vaddr |= ssize << 8;
 		asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)"
-			     : : "r"(va) : "memory");
+			     : : "r"(vaddr) : "memory");
 		break;
 	default:
 		penc = mmu_psize_defs[psize].penc;
-		va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
-		va |= penc << 12;
-		va |= ssize << 8;
-		va |= 1; /* L */
+		vaddr &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
+		vaddr |= penc << 12;
+		vaddr |= ssize << 8;
+		vaddr |= 1; /* L */
 		asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
-			     : : "r"(va) : "memory");
+			     : : "r"(vaddr) : "memory");
 		break;
 	}
 
 }
 
-static inline void tlbie(unsigned long va, int psize, int ssize, int local)
+static inline void tlbie(struct virt_addr va, int psize, int ssize, int local)
 {
 	unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL);
 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
@@ -134,7 +139,7 @@ static inline void native_unlock_hpte(struct hash_pte *hptep)
 	clear_bit_unlock(HPTE_LOCK_BIT, word);
 }
 
-static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
+static long native_hpte_insert(unsigned long hpte_group, struct virt_addr va,
 			unsigned long pa, unsigned long rflags,
 			unsigned long vflags, int psize, int ssize)
 {
@@ -225,7 +230,7 @@ static long native_hpte_remove(unsigned long hpte_group)
 }
 
 static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
-				 unsigned long va, int psize, int ssize,
+				 struct virt_addr va, int psize, int ssize,
 				 int local)
 {
 	struct hash_pte *hptep = htab_address + slot;
@@ -259,7 +264,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 	return ret;
 }
 
-static long native_hpte_find(unsigned long va, int psize, int ssize)
+static long native_hpte_find(struct virt_addr va, int psize, int ssize)
 {
 	struct hash_pte *hptep;
 	unsigned long hash;
@@ -295,7 +300,8 @@ static long native_hpte_find(unsigned long va, int psize, int ssize)
 static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
 				       int psize, int ssize)
 {
-	unsigned long vsid, va;
+	struct virt_addr va;
+	unsigned long vsid;
 	long slot;
 	struct hash_pte *hptep;
 
@@ -315,7 +321,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
 	tlbie(va, psize, ssize, 0);
 }
 
-static void native_hpte_invalidate(unsigned long slot, unsigned long va,
+static void native_hpte_invalidate(unsigned long slot, struct virt_addr va,
 				   int psize, int ssize, int local)
 {
 	struct hash_pte *hptep = htab_address + slot;
@@ -349,7 +355,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
 #define LP_MASK(i)	((0xFF >> (i)) << LP_SHIFT)
 
 static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
-			int *psize, int *ssize, unsigned long *va)
+			int *psize, int *ssize, struct virt_addr *va)
 {
 	unsigned long hpte_r = hpte->r;
 	unsigned long hpte_v = hpte->v;
@@ -403,7 +409,7 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
 		avpn |= (vpi << mmu_psize_defs[size].shift);
 	}
 
-	*va = avpn;
+	va->addr = avpn;
 	*psize = size;
 	*ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
 }
@@ -418,9 +424,10 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
  */
 static void native_hpte_clear(void)
 {
+	struct virt_addr va;
 	unsigned long slot, slots, flags;
 	struct hash_pte *hptep = htab_address;
-	unsigned long hpte_v, va;
+	unsigned long hpte_v;
 	unsigned long pteg_count;
 	int psize, ssize;
 
@@ -465,7 +472,8 @@ static void native_hpte_clear(void)
  */
 static void native_flush_hash_range(unsigned long number, int local)
 {
-	unsigned long va, hash, index, hidx, shift, slot;
+	struct virt_addr va;
+	unsigned long hash, index, hidx, shift, slot;
 	struct hash_pte *hptep;
 	unsigned long hpte_v;
 	unsigned long want_v;
@@ -482,7 +490,7 @@ static void native_flush_hash_range(unsigned long number, int local)
 		va = batch->vaddr[i];
 		pte = batch->pte[i];
 
-		pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
+		pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
 			hash = hpt_hash(va, shift, ssize);
 			hidx = __rpte_to_hidx(pte, index);
 			if (hidx & _PTEIDX_SECONDARY)
@@ -508,7 +516,7 @@ static void native_flush_hash_range(unsigned long number, int local)
 			va = batch->vaddr[i];
 			pte = batch->pte[i];
 
-			pte_iterate_hashed_subpages(pte, psize, va, index,
+			pte_iterate_hashed_subpages(pte, psize, va.addr, index,
 						    shift) {
 				__tlbiel(va, psize, ssize);
 			} pte_iterate_hashed_end();
@@ -525,7 +533,7 @@ static void native_flush_hash_range(unsigned long number, int local)
 			va = batch->vaddr[i];
 			pte = batch->pte[i];
 
-			pte_iterate_hashed_subpages(pte, psize, va, index,
+			pte_iterate_hashed_subpages(pte, psize, va.addr, index,
 						    shift) {
 				__tlbie(va, psize, ssize);
 			} pte_iterate_hashed_end();
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 377e5cb..2429d53 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -192,7 +192,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
 	     vaddr += step, paddr += step) {
 		unsigned long hash, hpteg;
 		unsigned long vsid = get_kernel_vsid(vaddr, ssize);
-		unsigned long va = hpt_va(vaddr, vsid, ssize);
+		struct virt_addr va = hpt_va(vaddr, vsid, ssize);
 		unsigned long tprot = prot;
 
 		/* Make kernel text executable */
@@ -1153,13 +1153,13 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
 /* WARNING: This is called from hash_low_64.S, if you change this prototype,
  *          do not forget to update the assembly call site !
  */
-void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
+void flush_hash_page(struct virt_addr va, real_pte_t pte, int psize, int ssize,
 		     int local)
 {
 	unsigned long hash, index, shift, hidx, slot;
 
-	DBG_LOW("flush_hash_page(va=%016lx)\n", va);
-	pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
+	DBG_LOW("flush_hash_page(va=%016lx)\n", va.addr);
+	pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
 		hash = hpt_hash(va, shift, ssize);
 		hidx = __rpte_to_hidx(pte, index);
 		if (hidx & _PTEIDX_SECONDARY)
@@ -1208,7 +1208,7 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
 {
 	unsigned long hash, hpteg;
 	unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
-	unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
+	struct virt_addr va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
 	unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL);
 	int ret;
 
@@ -1229,7 +1229,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
 {
 	unsigned long hash, hidx, slot;
 	unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
-	unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
+	struct virt_addr va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
 
 	hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize);
 	spin_lock(&linear_map_hash_lock);
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
index cc5c273..47b4ed0 100644
--- a/arch/powerpc/mm/hugetlbpage-hash64.c
+++ b/arch/powerpc/mm/hugetlbpage-hash64.c
@@ -18,8 +18,9 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
 		     pte_t *ptep, unsigned long trap, int local, int ssize,
 		     unsigned int shift, unsigned int mmu_psize)
 {
+	struct virt_addr va;
 	unsigned long old_pte, new_pte;
-	unsigned long va, rflags, pa, sz;
+	unsigned long rflags, pa, sz;
 	long slot;
 
 	BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
index 31f1820..b830466 100644
--- a/arch/powerpc/mm/tlb_hash64.c
+++ b/arch/powerpc/mm/tlb_hash64.c
@@ -42,8 +42,9 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
 void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
 		     pte_t *ptep, unsigned long pte, int huge)
 {
+	struct virt_addr vaddr;
 	struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
-	unsigned long vsid, vaddr;
+	unsigned long vsid;
 	unsigned int psize;
 	int ssize;
 	real_pte_t rpte;
diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
index b83077e..a2dfc22 100644
--- a/arch/powerpc/platforms/cell/beat_htab.c
+++ b/arch/powerpc/platforms/cell/beat_htab.c
@@ -88,7 +88,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group)
 }
 
 static long beat_lpar_hpte_insert(unsigned long hpte_group,
-				  unsigned long va, unsigned long pa,
+				  struct virt_addr va, unsigned long pa,
 				  unsigned long rflags, unsigned long vflags,
 				  int psize, int ssize)
 {
@@ -184,7 +184,7 @@ static void beat_lpar_hptab_clear(void)
  */
 static long beat_lpar_hpte_updatepp(unsigned long slot,
 				    unsigned long newpp,
-				    unsigned long va,
+				    struct virt_addr va,
 				    int psize, int ssize, int local)
 {
 	unsigned long lpar_rc;
@@ -220,7 +220,7 @@ static long beat_lpar_hpte_updatepp(unsigned long slot,
 	return 0;
 }
 
-static long beat_lpar_hpte_find(unsigned long va, int psize)
+static long beat_lpar_hpte_find(struct virt_addr va, int psize)
 {
 	unsigned long hash;
 	unsigned long i, j;
@@ -255,7 +255,8 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
 					  unsigned long ea,
 					  int psize, int ssize)
 {
-	unsigned long lpar_rc, slot, vsid, va;
+	struct virt_addr va;
+	unsigned long lpar_rc, slot, vsid;
 	u64 dummy0, dummy1;
 
 	vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
@@ -272,7 +273,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
 	BUG_ON(lpar_rc != 0);
 }
 
-static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
+static void beat_lpar_hpte_invalidate(unsigned long slot, struct virt_addr va,
 					 int psize, int ssize, int local)
 {
 	unsigned long want_v;
@@ -311,7 +312,7 @@ void __init hpte_init_beat(void)
 }
 
 static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
-				  unsigned long va, unsigned long pa,
+				  struct virt_addr va, unsigned long pa,
 				  unsigned long rflags, unsigned long vflags,
 				  int psize, int ssize)
 {
@@ -364,7 +365,7 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
  */
 static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
 				    unsigned long newpp,
-				    unsigned long va,
+				    struct virt_addr va,
 				    int psize, int ssize, int local)
 {
 	unsigned long lpar_rc;
@@ -392,7 +393,7 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
 	return 0;
 }
 
-static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va,
+static void beat_lpar_hpte_invalidate_v3(unsigned long slot, struct virt_addr va,
 					 int psize, int ssize, int local)
 {
 	unsigned long want_v;
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index 3124cf7..6e27576 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -43,7 +43,7 @@ enum ps3_lpar_vas_id {
 
 static DEFINE_SPINLOCK(ps3_htab_lock);
 
-static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
+static long ps3_hpte_insert(unsigned long hpte_group, struct virt_addr va,
 	unsigned long pa, unsigned long rflags, unsigned long vflags,
 	int psize, int ssize)
 {
@@ -107,7 +107,7 @@ static long ps3_hpte_remove(unsigned long hpte_group)
 }
 
 static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
-	unsigned long va, int psize, int ssize, int local)
+	struct virt_addr va, int psize, int ssize, int local)
 {
 	int result;
 	u64 hpte_v, want_v, hpte_rs;
@@ -159,7 +159,7 @@ static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
 	panic("ps3_hpte_updateboltedpp() not implemented");
 }
 
-static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
+static void ps3_hpte_invalidate(unsigned long slot, struct virt_addr va,
 	int psize, int ssize, int local)
 {
 	unsigned long flags;
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 5f3ef87..b4e9641 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -108,9 +108,9 @@ void vpa_init(int cpu)
 }
 
 static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
- 			      unsigned long va, unsigned long pa,
- 			      unsigned long rflags, unsigned long vflags,
-			      int psize, int ssize)
+				     struct virt_addr va, unsigned long pa,
+				     unsigned long rflags, unsigned long vflags,
+				     int psize, int ssize)
 {
 	unsigned long lpar_rc;
 	unsigned long flags;
@@ -120,7 +120,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 	if (!(vflags & HPTE_V_BOLTED))
 		pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
 			 "rflags=%lx, vflags=%lx, psize=%d)\n",
-			 hpte_group, va, pa, rflags, vflags, psize);
+			 hpte_group, va.addr, pa, rflags, vflags, psize);
 
 	hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID;
 	hpte_r = hpte_encode_r(pa, psize) | rflags;
@@ -231,12 +231,12 @@ static void pSeries_lpar_hptab_clear(void)
  * for use when we want to match an existing PTE.  The bottom 7 bits
  * of the returned value are zero.
  */
-static inline unsigned long hpte_encode_avpn(unsigned long va, int psize,
+static inline unsigned long hpte_encode_avpn(struct virt_addr va, int psize,
 					     int ssize)
 {
 	unsigned long v;
 
-	v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
+	v = (va.addr >> 23) & ~(mmu_psize_defs[psize].avpnm);
 	v <<= HPTE_V_AVPN_SHIFT;
 	v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
 	return v;
@@ -250,7 +250,7 @@ static inline unsigned long hpte_encode_avpn(unsigned long va, int psize,
  */
 static long pSeries_lpar_hpte_updatepp(unsigned long slot,
 				       unsigned long newpp,
-				       unsigned long va,
+				       struct virt_addr va,
 				       int psize, int ssize, int local)
 {
 	unsigned long lpar_rc;
@@ -295,7 +295,7 @@ static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
 	return dword0;
 }
 
-static long pSeries_lpar_hpte_find(unsigned long va, int psize, int ssize)
+static long pSeries_lpar_hpte_find(struct virt_addr va, int psize, int ssize)
 {
 	unsigned long hash;
 	unsigned long i;
@@ -323,7 +323,8 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
 					     unsigned long ea,
 					     int psize, int ssize)
 {
-	unsigned long lpar_rc, slot, vsid, va, flags;
+	struct virt_addr va;
+	unsigned long lpar_rc, slot, vsid, flags;
 
 	vsid = get_kernel_vsid(ea, ssize);
 	va = hpt_va(ea, vsid, ssize);
@@ -337,7 +338,7 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
 	BUG_ON(lpar_rc != H_SUCCESS);
 }
 
-static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
+static void pSeries_lpar_hpte_invalidate(unsigned long slot, struct virt_addr va,
 					 int psize, int ssize, int local)
 {
 	unsigned long want_v;
@@ -345,7 +346,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
 	unsigned long dummy1, dummy2;
 
 	pr_devel("    inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
-		 slot, va, psize, local);
+		 slot, va.addr, psize, local);
 
 	want_v = hpte_encode_avpn(va, psize, ssize);
 	lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2);
@@ -358,7 +359,8 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
 static void pSeries_lpar_hpte_removebolted(unsigned long ea,
 					   int psize, int ssize)
 {
-	unsigned long slot, vsid, va;
+	struct virt_addr va;
+	unsigned long slot, vsid;
 
 	vsid = get_kernel_vsid(ea, ssize);
 	va = hpt_va(ea, vsid, ssize);
@@ -382,12 +384,12 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea,
  */
 static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
 {
+	struct virt_addr va;
 	unsigned long i, pix, rc;
 	unsigned long flags = 0;
 	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
 	unsigned long param[9];
-	unsigned long va;
 	unsigned long hash, index, shift, hidx, slot;
 	real_pte_t pte;
 	int psize, ssize;
@@ -401,7 +403,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
 	for (i = 0; i < number; i++) {
 		va = batch->vaddr[i];
 		pte = batch->pte[i];
-		pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
+		pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
 			hash = hpt_hash(va, shift, ssize);
 			hidx = __rpte_to_hidx(pte, index);
 			if (hidx & _PTEIDX_SECONDARY)
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 3/9] arch/powerpc: Simplify hpte_decode
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 1/9] arch/powerpc: Use hpt_va to compute virtual address Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 4/9] arch/powerpc: Use vsid and segment offset to represent virtual address Aneesh Kumar K.V
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

This patch simplify hpte_decode for easy switching of virtual address to
vsid and segment offset combination in the later patch

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/mm/hash_native_64.c |   51 ++++++++++++++++++++++----------------
 1 file changed, 30 insertions(+), 21 deletions(-)

diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index cab3892..76c2574 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -357,9 +357,10 @@ static void native_hpte_invalidate(unsigned long slot, struct virt_addr va,
 static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
 			int *psize, int *ssize, struct virt_addr *va)
 {
+	unsigned long avpn, pteg, vpi;
 	unsigned long hpte_r = hpte->r;
 	unsigned long hpte_v = hpte->v;
-	unsigned long avpn;
+	unsigned long vsid, seg_off;
 	int i, size, shift, penc;
 
 	if (!(hpte_v & HPTE_V_LARGE))
@@ -386,32 +387,40 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
 	}
 
 	/* This works for all page sizes, and for 256M and 1T segments */
+	*ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
 	shift = mmu_psize_defs[size].shift;
-	avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm) << 23;
-
-	if (shift < 23) {
-		unsigned long vpi, vsid, pteg;
 
-		pteg = slot / HPTES_PER_GROUP;
-		if (hpte_v & HPTE_V_SECONDARY)
-			pteg = ~pteg;
-		switch (hpte_v >> HPTE_V_SSIZE_SHIFT) {
-		case MMU_SEGSIZE_256M:
-			vpi = ((avpn >> 28) ^ pteg) & htab_hash_mask;
-			break;
-		case MMU_SEGSIZE_1T:
-			vsid = avpn >> 40;
+	avpn = (HPTE_V_AVPN_VAL(hpte_v) & ~mmu_psize_defs[size].avpnm);
+	pteg = slot / HPTES_PER_GROUP;
+	if (hpte_v & HPTE_V_SECONDARY)
+		pteg = ~pteg;
+
+	switch (*ssize) {
+	case MMU_SEGSIZE_256M:
+		/* We only have 28 - 23 bits of seg_off in avpn */
+		seg_off = (avpn & 0x1f) << 23;
+		vsid    =  avpn >> 5;
+		/* We can find more bits from the pteg value */
+		if (shift < 23) {
+			vpi = (vsid ^ pteg) & htab_hash_mask;
+			seg_off |= vpi << shift;
+		}
+		va->addr = vsid << 28 | seg_off;
+	case MMU_SEGSIZE_1T:
+		/* We only have 40 - 23 bits of seg_off in avpn */
+		seg_off = (avpn & 0x1ffff) << 23;
+		vsid    = avpn >> 17;
+		if (shift < 23) {
 			vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask;
-			break;
-		default:
-			avpn = vpi = size = 0;
+			seg_off |= vpi << shift;
 		}
-		avpn |= (vpi << mmu_psize_defs[size].shift);
+		va->addr = vsid << 40 | seg_off;
+	default:
+		seg_off = 0;
+		vsid    = 0;
+		va->addr = 0;
 	}
-
-	va->addr = avpn;
 	*psize = size;
-	*ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
 }
 
 /*
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 4/9] arch/powerpc: Use vsid and segment offset to represent virtual address
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
                   ` (2 preceding siblings ...)
  2012-06-29 14:17 ` [PATCH -V1 3/9] arch/powerpc: Simplify hpte_decode Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 21:45   ` Benjamin Herrenschmidt
  2012-06-29 14:17 ` [PATCH -V1 5/9] arch/powerpc: Make KERN_VIRT_SIZE not dependend on PGTABLE_RANGE Aneesh Kumar K.V
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

This patch enables us to have 78 bit virtual address.

With 1TB segments we use 40 bits of virtual adress as segment offset and
the remaining 24 bits (of the current 64 bit virtual address) are used
to index the virtual segment. Out of the 24 bits we currently use 19 bits
for user context and that leave us with only 4 bits for effective segment
ID. In-order to support more than 16TB of memory we would require more than
4 ESID bits. This patch splits the virtual address to two unsigned long
components, vsid and segment offset thereby allowing us to support 78 bit
virtual address.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/mmu-hash64.h |   62 ++++++++---
 arch/powerpc/mm/hash_low_64.S         |  191 ++++++++++++++++++---------------
 arch/powerpc/mm/hash_native_64.c      |   36 ++++---
 arch/powerpc/mm/hash_utils_64.c       |    6 +-
 arch/powerpc/platforms/ps3/htab.c     |   13 +--
 arch/powerpc/platforms/pseries/lpar.c |   29 ++---
 6 files changed, 192 insertions(+), 145 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 5ff936b..e48c66b 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -143,8 +143,10 @@ struct mmu_psize_def
 	unsigned long	sllp;	/* SLB L||LP (exact mask to use in slbmte) */
 };
 
+/* 78 bit power virtual address */
 struct virt_addr {
-	unsigned long addr;
+	unsigned long vsid;
+	unsigned long seg_off;
 };
 
 #endif /* __ASSEMBLY__ */
@@ -161,6 +163,13 @@ struct virt_addr {
 
 #ifndef __ASSEMBLY__
 
+static inline int segment_shift(int ssize)
+{
+	if (ssize == MMU_SEGSIZE_256M)
+		return SID_SHIFT;
+	return SID_SHIFT_1T;
+}
+
 /*
  * The current system page and segment sizes
  */
@@ -184,6 +193,32 @@ extern unsigned long tce_alloc_start, tce_alloc_end;
 extern int mmu_ci_restrictions;
 
 /*
+ * This computes the AVPN and B fields of the first dword of a HPTE,
+ * for use when we want to match an existing PTE.  The bottom 7 bits
+ * of the returned value are zero.
+ */
+static inline unsigned long hpte_encode_avpn(struct virt_addr va, int psize,
+					     int ssize)
+{
+	unsigned long v;
+
+	/*
+	 * The AVA field omits the low-order 23 bits of the 78 bits VA.
+	 * These bits are not needed in the PTE, because the
+	 * low-order b of these bits are part of the byte offset
+	 * into the virtual page and, if b < 23, the high-order
+	 * 23-b of these bits are always used in selecting the
+	 * PTEGs to be searched
+	 */
+	v = va.seg_off >> 23;
+	v |= va.vsid << (segment_shift(ssize) - 23);
+	v &= ~(mmu_psize_defs[psize].avpnm);
+	v <<= HPTE_V_AVPN_SHIFT;
+	v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
+	return v;
+}
+
+/*
  * This function sets the AVPN and L fields of the HPTE  appropriately
  * for the page size
  */
@@ -191,11 +226,9 @@ static inline unsigned long hpte_encode_v(struct virt_addr va, int psize,
 					  int ssize)
 {
 	unsigned long v;
-	v = (va.addr >> 23) & ~(mmu_psize_defs[psize].avpnm);
-	v <<= HPTE_V_AVPN_SHIFT;
+	v = hpte_encode_avpn(va, psize, ssize);
 	if (psize != MMU_PAGE_4K)
 		v |= HPTE_V_LARGE;
-	v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
 	return v;
 }
 
@@ -222,30 +255,31 @@ static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
 /*
  * Build a VA given VSID, EA and segment size
  */
-static inline struct virt_addr hpt_va(unsigned long ea, unsigned long vsid,
-				   int ssize)
+static inline struct virt_addr hpt_va(unsigned long ea, unsigned long vsid, int ssize)
 {
 	struct virt_addr va;
+
+	va.vsid    = vsid;
 	if (ssize == MMU_SEGSIZE_256M)
-		va.addr = (vsid << 28) | (ea & 0xfffffffUL);
-	va.addr = (vsid << 40) | (ea & 0xffffffffffUL);
+		va.seg_off = ea & 0xfffffffUL;
+	else
+		va.seg_off = ea & 0xffffffffffUL;
 	return va;
 }
 
 /*
  * This hashes a virtual address
  */
-
-static inline unsigned long hpt_hash(struct virt_addr va, unsigned int shift,
-				     int ssize)
+/* Verify */
+static inline unsigned long hpt_hash(struct virt_addr va, unsigned int shift, int ssize)
 {
 	unsigned long hash, vsid;
 
 	if (ssize == MMU_SEGSIZE_256M) {
-		hash = (va.addr >> 28) ^ ((va.addr & 0x0fffffffUL) >> shift);
+		hash = (va.vsid & 0x0000007fffffffff) ^ (va.seg_off >> shift);
 	} else {
-		vsid = va.addr >> 40;
-		hash = vsid ^ (vsid << 25) ^ ((va.addr & 0xffffffffffUL) >> shift);
+		vsid = va.vsid;
+		hash = vsid ^ (vsid << 25) ^ (va.seg_off >> shift);
 	}
 	return hash & 0x7fffffffffUL;
 }
diff --git a/arch/powerpc/mm/hash_low_64.S b/arch/powerpc/mm/hash_low_64.S
index a242b5d..cf66a0a 100644
--- a/arch/powerpc/mm/hash_low_64.S
+++ b/arch/powerpc/mm/hash_low_64.S
@@ -71,10 +71,12 @@ _GLOBAL(__hash_page_4K)
 	/* Save non-volatile registers.
 	 * r31 will hold "old PTE"
 	 * r30 is "new PTE"
-	 * r29 is "va"
+	 * r29 is vsid
 	 * r28 is a hash value
 	 * r27 is hashtab mask (maybe dynamic patched instead ?)
+	 * r26 is seg_off
 	 */
+	std	r26,STK_REG(r26)(r1)
 	std	r27,STK_REG(r27)(r1)
 	std	r28,STK_REG(r28)(r1)
 	std	r29,STK_REG(r29)(r1)
@@ -119,10 +121,9 @@ BEGIN_FTR_SECTION
 	cmpdi	r9,0			/* check segment size */
 	bne	3f
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
-	/* Calc va and put it in r29 */
-	rldicr	r29,r5,28,63-28
-	rldicl	r3,r3,0,36
-	or	r29,r3,r29
+	/* r29 is virtual address and r26 is seg_off */
+	mr	r29,r5			/* vsid */
+	rldicl	r26,r3,0,36		/* ea & 0x000000000fffffffUL */
 
 	/* Calculate hash value for primary slot and store it in r28 */
 	rldicl	r5,r5,0,25		/* vsid & 0x0000007fffffffff */
@@ -130,14 +131,17 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	xor	r28,r5,r0
 	b	4f
 
-3:	/* Calc VA and hash in r29 and r28 for 1T segment */
-	sldi	r29,r5,40		/* vsid << 40 */
-	clrldi	r3,r3,24		/* ea & 0xffffffffff */
+3:	/* r29 is virtual address and r26 is seg_off */
+	mr	r29,r5			/* vsid */
+	rldicl	r26,r3,0,24		/* ea & 0xffffffffff */
+	/*
+	 * calculate hash value for primary slot and
+	 * store it in r28 for 1T segment
+	 */
 	rldic	r28,r5,25,25		/* (vsid << 25) & 0x7fffffffff */
 	clrldi	r5,r5,40		/* vsid & 0xffffff */
 	rldicl	r0,r3,64-12,36		/* (ea >> 12) & 0xfffffff */
 	xor	r28,r28,r5
-	or	r29,r3,r29		/* VA */
 	xor	r28,r28,r0		/* hash */
 
 	/* Convert linux PTE bits into HW equivalents */
@@ -183,20 +187,21 @@ htab_insert_pte:
 	andc	r30,r30,r0
 	ori	r30,r30,_PAGE_HASHPTE
 
-	/* physical address r5 */
-	rldicl	r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
-	sldi	r5,r5,PAGE_SHIFT
+	/* physical address r6 */
+	rldicl	r6,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+	sldi	r6,r6,PAGE_SHIFT
 
 	/* Calculate primary group hash */
 	and	r0,r28,r27
 	rldicr	r3,r0,3,63-3		/* r3 = (hash & mask) << 3 */
 
 	/* Call ppc_md.hpte_insert */
-	ld	r6,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
-	mr	r4,r29			/* Retrieve va */
-	li	r7,0			/* !bolted, !secondary */
-	li	r8,MMU_PAGE_4K		/* page size */
-	ld	r9,STK_PARM(r9)(r1)	/* segment size */
+	ld	r7,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
+	mr	r4,r29			/* Retrieve vsid */
+	mr	r5,r26			/* seg_off */
+	li	r8,0			/* !bolted, !secondary */
+	li	r9,MMU_PAGE_4K		/* page size */
+	ld	r10,STK_PARM(r9)(r1)	/* segment size */
 _GLOBAL(htab_call_hpte_insert1)
 	bl	.			/* Patched by htab_finish_init() */
 	cmpdi	0,r3,0
@@ -206,20 +211,21 @@ _GLOBAL(htab_call_hpte_insert1)
 
 	/* Now try secondary slot */
 	
-	/* physical address r5 */
-	rldicl	r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
-	sldi	r5,r5,PAGE_SHIFT
+	/* physical address r6 */
+	rldicl	r6,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+	sldi	r6,r6,PAGE_SHIFT
 
 	/* Calculate secondary group hash */
 	andc	r0,r27,r28
 	rldicr	r3,r0,3,63-3	/* r0 = (~hash & mask) << 3 */
 	
 	/* Call ppc_md.hpte_insert */
-	ld	r6,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
-	mr	r4,r29			/* Retrieve va */
-	li	r7,HPTE_V_SECONDARY	/* !bolted, secondary */
-	li	r8,MMU_PAGE_4K		/* page size */
-	ld	r9,STK_PARM(r9)(r1)	/* segment size */
+	ld	r7,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
+	mr	r4,r29			/* Retrieve vsid */
+	mr	r5,r26			/* seg_off */
+	li	r8,HPTE_V_SECONDARY	/* !bolted, secondary */
+	li	r9,MMU_PAGE_4K		/* page size */
+	ld	r10,STK_PARM(r9)(r1)	/* segment size */
 _GLOBAL(htab_call_hpte_insert2)
 	bl	.			/* Patched by htab_finish_init() */
 	cmpdi	0,r3,0
@@ -286,13 +292,13 @@ htab_modify_pte:
 	add	r3,r0,r3	/* add slot idx */
 
 	/* Call ppc_md.hpte_updatepp */
-	mr	r5,r29			/* va */
-	li	r6,MMU_PAGE_4K		/* page size */
-	ld	r7,STK_PARM(r9)(r1)	/* segment size */
-	ld	r8,STK_PARM(r8)(r1)	/* get "local" param */
+	mr	r5,r29			/* vsid */
+	mr	r6,r26			/* seg off */
+	li	r7,MMU_PAGE_4K		/* page size */
+	ld	r8,STK_PARM(r9)(r1)	/* segment size */
+	ld	r9,STK_PARM(r8)(r1)	/* get "local" param */
 _GLOBAL(htab_call_hpte_updatepp)
 	bl	.			/* Patched by htab_finish_init() */
-
 	/* if we failed because typically the HPTE wasn't really here
 	 * we try an insertion. 
 	 */
@@ -347,12 +353,14 @@ _GLOBAL(__hash_page_4K)
 	/* Save non-volatile registers.
 	 * r31 will hold "old PTE"
 	 * r30 is "new PTE"
-	 * r29 is "va"
+	 * r29 is vsid
 	 * r28 is a hash value
 	 * r27 is hashtab mask (maybe dynamic patched instead ?)
 	 * r26 is the hidx mask
 	 * r25 is the index in combo page
+	 * r24 is seg_off
 	 */
+	std	r24,STK_REG(r24)(r1)
 	std	r25,STK_REG(r25)(r1)
 	std	r26,STK_REG(r26)(r1)
 	std	r27,STK_REG(r27)(r1)
@@ -402,10 +410,9 @@ BEGIN_FTR_SECTION
 	cmpdi	r9,0			/* check segment size */
 	bne	3f
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
-	/* Calc va and put it in r29 */
-	rldicr	r29,r5,28,63-28		/* r29 = (vsid << 28) */
-	rldicl	r3,r3,0,36		/* r3 = (ea & 0x0fffffff) */
-	or	r29,r3,r29		/* r29 = va */
+	/* r29 is virtual address and r24 is seg_off */
+	mr	r29,r5			/* vsid */
+	rldicl	r24,r3,0,36		/* ea & 0x000000000fffffffUL */
 
 	/* Calculate hash value for primary slot and store it in r28 */
 	rldicl	r5,r5,0,25		/* vsid & 0x0000007fffffffff */
@@ -413,14 +420,17 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	xor	r28,r5,r0
 	b	4f
 
-3:	/* Calc VA and hash in r29 and r28 for 1T segment */
-	sldi	r29,r5,40		/* vsid << 40 */
-	clrldi	r3,r3,24		/* ea & 0xffffffffff */
+3:	/* r29 is virtual address and r24 is seg_off */
+	mr	r29,r5			/* vsid */
+	rldicl	r24,r3,0,24		/* ea & 0xffffffffff */
+	/*
+	 * Calculate hash value for primary slot and
+	 * store it in r28  for 1T segment
+	 */
 	rldic	r28,r5,25,25		/* (vsid << 25) & 0x7fffffffff */
 	clrldi	r5,r5,40		/* vsid & 0xffffff */
 	rldicl	r0,r3,64-12,36		/* (ea >> 12) & 0xfffffff */
 	xor	r28,r28,r5
-	or	r29,r3,r29		/* VA */
 	xor	r28,r28,r0		/* hash */
 
 	/* Convert linux PTE bits into HW equivalents */
@@ -481,25 +491,26 @@ END_FTR_SECTION(CPU_FTR_NOEXECUTE|CPU_FTR_COHERENT_ICACHE, CPU_FTR_NOEXECUTE)
 	bne	htab_modify_pte
 
 htab_insert_pte:
-	/* real page number in r5, PTE RPN value + index */
+	/* real page number in r6, PTE RPN value + index */
 	andis.	r0,r31,_PAGE_4K_PFN@h
 	srdi	r5,r31,PTE_RPN_SHIFT
 	bne-	htab_special_pfn
 	sldi	r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
 	add	r5,r5,r25
 htab_special_pfn:
-	sldi	r5,r5,HW_PAGE_SHIFT
+	sldi	r6,r5,HW_PAGE_SHIFT
 
 	/* Calculate primary group hash */
 	and	r0,r28,r27
 	rldicr	r3,r0,3,63-3		/* r0 = (hash & mask) << 3 */
 
 	/* Call ppc_md.hpte_insert */
-	ld	r6,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
-	mr	r4,r29			/* Retrieve va */
-	li	r7,0			/* !bolted, !secondary */
-	li	r8,MMU_PAGE_4K		/* page size */
-	ld	r9,STK_PARM(r9)(r1)	/* segment size */
+	ld	r7,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
+	mr	r4,r29			/* Retrieve vsid */
+	mr      r5,r24			/* seg off */
+	li	r8,0			/* !bolted, !secondary */
+	li	r9,MMU_PAGE_4K		/* page size */
+	ld	r10,STK_PARM(r9)(r1)	/* segment size */
 _GLOBAL(htab_call_hpte_insert1)
 	bl	.			/* patched by htab_finish_init() */
 	cmpdi	0,r3,0
@@ -515,18 +526,19 @@ _GLOBAL(htab_call_hpte_insert1)
 	bne-	3f
 	sldi	r5,r5,PAGE_SHIFT-HW_PAGE_SHIFT
 	add	r5,r5,r25
-3:	sldi	r5,r5,HW_PAGE_SHIFT
+3:	sldi	r6,r5,HW_PAGE_SHIFT
 
 	/* Calculate secondary group hash */
 	andc	r0,r27,r28
 	rldicr	r3,r0,3,63-3		/* r0 = (~hash & mask) << 3 */
 
 	/* Call ppc_md.hpte_insert */
-	ld	r6,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
-	mr	r4,r29			/* Retrieve va */
-	li	r7,HPTE_V_SECONDARY	/* !bolted, secondary */
-	li	r8,MMU_PAGE_4K		/* page size */
-	ld	r9,STK_PARM(r9)(r1)	/* segment size */
+	ld	r7,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
+	mr	r4,r29			/* Retrieve vsid */
+	mr      r5,r24			/* seg off */
+	li	r8,HPTE_V_SECONDARY	/* !bolted, secondary */
+	li	r9,MMU_PAGE_4K		/* page size */
+	ld	r10,STK_PARM(r9)(r1)	/* segment size */
 _GLOBAL(htab_call_hpte_insert2)
 	bl	.			/* patched by htab_finish_init() */
 	cmpdi	0,r3,0
@@ -628,13 +640,13 @@ htab_modify_pte:
 	add	r3,r0,r3	/* add slot idx */
 
 	/* Call ppc_md.hpte_updatepp */
-	mr	r5,r29			/* va */
-	li	r6,MMU_PAGE_4K		/* page size */
-	ld	r7,STK_PARM(r9)(r1)	/* segment size */
-	ld	r8,STK_PARM(r8)(r1)	/* get "local" param */
+	mr	r5,r29			/* vsid */
+	mr      r6,r24			/* seg off */
+	li	r7,MMU_PAGE_4K		/* page size */
+	ld	r8,STK_PARM(r9)(r1)	/* segment size */
+	ld	r9,STK_PARM(r8)(r1)	/* get "local" param */
 _GLOBAL(htab_call_hpte_updatepp)
 	bl	.			/* patched by htab_finish_init() */
-
 	/* if we failed because typically the HPTE wasn't really here
 	 * we try an insertion.
 	 */
@@ -684,10 +696,12 @@ _GLOBAL(__hash_page_64K)
 	/* Save non-volatile registers.
 	 * r31 will hold "old PTE"
 	 * r30 is "new PTE"
-	 * r29 is "va"
+	 * r29 is vsid
 	 * r28 is a hash value
 	 * r27 is hashtab mask (maybe dynamic patched instead ?)
+	 * r26 is seg off
 	 */
+	std	r26,STK_REG(r26)(r1)
 	std	r27,STK_REG(r27)(r1)
 	std	r28,STK_REG(r28)(r1)
 	std	r29,STK_REG(r29)(r1)
@@ -737,10 +751,9 @@ BEGIN_FTR_SECTION
 	cmpdi	r9,0			/* check segment size */
 	bne	3f
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
-	/* Calc va and put it in r29 */
-	rldicr	r29,r5,28,63-28
-	rldicl	r3,r3,0,36
-	or	r29,r3,r29
+	/* r29 is virtual address and r26 is seg_off */
+	mr	r29,r5			/* vsid */
+	rldicl	r26,r3,0,36		/* ea & 0x000000000fffffffUL */
 
 	/* Calculate hash value for primary slot and store it in r28 */
 	rldicl	r5,r5,0,25		/* vsid & 0x0000007fffffffff */
@@ -748,14 +761,17 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
 	xor	r28,r5,r0
 	b	4f
 
-3:	/* Calc VA and hash in r29 and r28 for 1T segment */
-	sldi	r29,r5,40		/* vsid << 40 */
-	clrldi	r3,r3,24		/* ea & 0xffffffffff */
+3:	/* r29 is virtual address and r26 is seg_off */
+	mr	r29,r5			/* vsid */
+	rldicl	r26,r3,0,24		/* ea & 0xffffffffff */
+	/*
+	 * calculate hash value for primary slot and
+	 * store it in r28 for 1T segment
+	 */
 	rldic	r28,r5,25,25		/* (vsid << 25) & 0x7fffffffff */
 	clrldi	r5,r5,40		/* vsid & 0xffffff */
 	rldicl	r0,r3,64-16,40		/* (ea >> 16) & 0xffffff */
 	xor	r28,r28,r5
-	or	r29,r3,r29		/* VA */
 	xor	r28,r28,r0		/* hash */
 
 	/* Convert linux PTE bits into HW equivalents */
@@ -804,20 +820,21 @@ ht64_insert_pte:
 #else
 	ori	r30,r30,_PAGE_HASHPTE
 #endif
-	/* Phyical address in r5 */
-	rldicl	r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
-	sldi	r5,r5,PAGE_SHIFT
+	/* Phyical address in r6 */
+	rldicl	r6,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+	sldi	r6,r6,PAGE_SHIFT
 
 	/* Calculate primary group hash */
 	and	r0,r28,r27
 	rldicr	r3,r0,3,63-3	/* r0 = (hash & mask) << 3 */
 
 	/* Call ppc_md.hpte_insert */
-	ld	r6,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
-	mr	r4,r29			/* Retrieve va */
-	li	r7,0			/* !bolted, !secondary */
-	li	r8,MMU_PAGE_64K
-	ld	r9,STK_PARM(r9)(r1)	/* segment size */
+	ld	r7,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
+	mr	r4,r29			/* Retrieve vsid */
+	mr	r5,r26			/* seg_off */
+	li	r8,0			/* !bolted, !secondary */
+	li	r9,MMU_PAGE_64K
+	ld	r10,STK_PARM(r9)(r1)	/* segment size */
 _GLOBAL(ht64_call_hpte_insert1)
 	bl	.			/* patched by htab_finish_init() */
 	cmpdi	0,r3,0
@@ -827,20 +844,21 @@ _GLOBAL(ht64_call_hpte_insert1)
 
 	/* Now try secondary slot */
 
-	/* Phyical address in r5 */
-	rldicl	r5,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
-	sldi	r5,r5,PAGE_SHIFT
+	/* Phyical address in r6 */
+	rldicl	r6,r31,64-PTE_RPN_SHIFT,PTE_RPN_SHIFT
+	sldi	r6,r6,PAGE_SHIFT
 
 	/* Calculate secondary group hash */
 	andc	r0,r27,r28
 	rldicr	r3,r0,3,63-3	/* r0 = (~hash & mask) << 3 */
 
 	/* Call ppc_md.hpte_insert */
-	ld	r6,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
-	mr	r4,r29			/* Retrieve va */
-	li	r7,HPTE_V_SECONDARY	/* !bolted, secondary */
-	li	r8,MMU_PAGE_64K
-	ld	r9,STK_PARM(r9)(r1)	/* segment size */
+	ld	r7,STK_PARM(r4)(r1)	/* Retrieve new pp bits */
+	mr	r4,r29			/* Retrieve vsid */
+	mr	r5,r26			/* seg_off */
+	li	r8,HPTE_V_SECONDARY	/* !bolted, secondary */
+	li	r9,MMU_PAGE_64K
+	ld	r10,STK_PARM(r9)(r1)	/* segment size */
 _GLOBAL(ht64_call_hpte_insert2)
 	bl	.			/* patched by htab_finish_init() */
 	cmpdi	0,r3,0
@@ -907,10 +925,11 @@ ht64_modify_pte:
 	add	r3,r0,r3	/* add slot idx */
 
 	/* Call ppc_md.hpte_updatepp */
-	mr	r5,r29			/* va */
-	li	r6,MMU_PAGE_64K
-	ld	r7,STK_PARM(r9)(r1)	/* segment size */
-	ld	r8,STK_PARM(r8)(r1)	/* get "local" param */
+	mr	r5,r29			/* vsid */
+	mr	r6,r26			/* seg off */
+	li	r7,MMU_PAGE_64K
+	ld	r8,STK_PARM(r9)(r1)	/* segment size */
+	ld	r9,STK_PARM(r8)(r1)	/* get "local" param */
 _GLOBAL(ht64_call_hpte_updatepp)
 	bl	.			/* patched by htab_finish_init() */
 
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index 76c2574..d65b63c 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -42,10 +42,12 @@ DEFINE_RAW_SPINLOCK(native_tlbie_lock);
 /* Verify docs says 14 .. 14+i bits */
 static inline void __tlbie(struct virt_addr va, int psize, int ssize)
 {
-	unsigned long vaddr = va.addr;
+	unsigned long vaddr;
 	unsigned int penc;
 
-	vaddr &= ~(0xffffULL << 48);
+	/* We need only lower 48 bit of va, non SLS segment */
+	vaddr = va.vsid << segment_shift(ssize);
+	vaddr |= va.seg_off;
 
 	/* clear top 16 bits, non SLS segment */
 	vaddr &= ~(0xffffULL << 48);
@@ -74,9 +76,13 @@ static inline void __tlbie(struct virt_addr va, int psize, int ssize)
 /* Verify docs says 14 .. 14+i bits */
 static inline void __tlbiel(struct virt_addr va, int psize, int ssize)
 {
-	unsigned long vaddr = va.addr;
+	unsigned long vaddr;
 	unsigned int penc;
 
+	/* We need only lower 48 bit of va, non SLS segment */
+	vaddr = va.vsid << segment_shift(ssize);
+	vaddr |= va.seg_off;
+
 	vaddr &= ~(0xffffULL << 48);
 
 	switch (psize) {
@@ -148,9 +154,9 @@ static long native_hpte_insert(unsigned long hpte_group, struct virt_addr va,
 	int i;
 
 	if (!(vflags & HPTE_V_BOLTED)) {
-		DBG_LOW("    insert(group=%lx, va=%016lx, pa=%016lx,"
-			" rflags=%lx, vflags=%lx, psize=%d)\n",
-			hpte_group, va, pa, rflags, vflags, psize);
+		DBG_LOW("    insert(group=%lx, vsid=%016lx, seg_off=%016lx, pa=%016lx,"
+			" rflags=%lx, vflags=%lx, psize=%d)\n", hpte_group,
+			va.vsid, va.seg_off, pa, rflags, vflags, psize);
 	}
 
 	for (i = 0; i < HPTES_PER_GROUP; i++) {
@@ -239,8 +245,9 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
 
 	want_v = hpte_encode_v(va, psize, ssize);
 
-	DBG_LOW("    update(va=%016lx, avpnv=%016lx, hash=%016lx, newpp=%x)",
-		va, want_v & HPTE_V_AVPN, slot, newpp);
+	DBG_LOW("    update(vsid=%016lx, seg_off=%016lx, avpnv=%016lx, "
+		"hash=%016lx, newpp=%lx)", va.vsid, va.seg_off,
+		want_v & HPTE_V_AVPN, slot, newpp);
 
 	native_lock_hpte(hptep);
 
@@ -331,7 +338,7 @@ static void native_hpte_invalidate(unsigned long slot, struct virt_addr va,
 
 	local_irq_save(flags);
 
-	DBG_LOW("    invalidate(va=%016lx, hash: %x)\n", va, slot);
+	DBG_LOW("    invalidate(va=%016lx, seg=%016lx, hash: %lx)\n", va.vsid, va.seg_off, slot);
 
 	want_v = hpte_encode_v(va, psize, ssize);
 	native_lock_hpte(hptep);
@@ -405,7 +412,6 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
 			vpi = (vsid ^ pteg) & htab_hash_mask;
 			seg_off |= vpi << shift;
 		}
-		va->addr = vsid << 28 | seg_off;
 	case MMU_SEGSIZE_1T:
 		/* We only have 40 - 23 bits of seg_off in avpn */
 		seg_off = (avpn & 0x1ffff) << 23;
@@ -414,12 +420,12 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
 			vpi = (vsid ^ (vsid << 25) ^ pteg) & htab_hash_mask;
 			seg_off |= vpi << shift;
 		}
-		va->addr = vsid << 40 | seg_off;
 	default:
 		seg_off = 0;
 		vsid    = 0;
-		va->addr = 0;
 	}
+	va->vsid = vsid;
+	va->seg_off = seg_off;
 	*psize = size;
 }
 
@@ -499,7 +505,7 @@ static void native_flush_hash_range(unsigned long number, int local)
 		va = batch->vaddr[i];
 		pte = batch->pte[i];
 
-		pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
+		pte_iterate_hashed_subpages(pte, psize, va.seg_off, index, shift) {
 			hash = hpt_hash(va, shift, ssize);
 			hidx = __rpte_to_hidx(pte, index);
 			if (hidx & _PTEIDX_SECONDARY)
@@ -525,7 +531,7 @@ static void native_flush_hash_range(unsigned long number, int local)
 			va = batch->vaddr[i];
 			pte = batch->pte[i];
 
-			pte_iterate_hashed_subpages(pte, psize, va.addr, index,
+			pte_iterate_hashed_subpages(pte, psize, va.seg_off, index,
 						    shift) {
 				__tlbiel(va, psize, ssize);
 			} pte_iterate_hashed_end();
@@ -542,7 +548,7 @@ static void native_flush_hash_range(unsigned long number, int local)
 			va = batch->vaddr[i];
 			pte = batch->pte[i];
 
-			pte_iterate_hashed_subpages(pte, psize, va.addr, index,
+			pte_iterate_hashed_subpages(pte, psize, va.seg_off, index,
 						    shift) {
 				__tlbie(va, psize, ssize);
 			} pte_iterate_hashed_end();
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 2429d53..8b5d3c2 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -1158,8 +1158,10 @@ void flush_hash_page(struct virt_addr va, real_pte_t pte, int psize, int ssize,
 {
 	unsigned long hash, index, shift, hidx, slot;
 
-	DBG_LOW("flush_hash_page(va=%016lx)\n", va.addr);
-	pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
+	DBG_LOW("flush_hash_page(vsid=%016lx seg_off=%016lx)\n",
+		va.vsid, va.seg_off);
+	/* since we won't cross segments, use seg_off for iteration */
+	pte_iterate_hashed_subpages(pte, psize, va.seg_off, index, shift) {
 		hash = hpt_hash(va, shift, ssize);
 		hidx = __rpte_to_hidx(pte, index);
 		if (hidx & _PTEIDX_SECONDARY)
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
index 6e27576..4aa969d 100644
--- a/arch/powerpc/platforms/ps3/htab.c
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -75,8 +75,9 @@ static long ps3_hpte_insert(unsigned long hpte_group, struct virt_addr va,
 
 	if (result) {
 		/* all entries bolted !*/
-		pr_info("%s:result=%d va=%lx pa=%lx ix=%lx v=%llx r=%llx\n",
-			__func__, result, va, pa, hpte_group, hpte_v, hpte_r);
+		pr_info("%s:result=%d vsid=%lx seg_off=%lx pa=%lx ix=%lx "
+			"v=%llx r=%llx\n", __func__, result, va.vsid,
+			va.seg_off, pa, hpte_group, hpte_v, hpte_r);
 		BUG();
 	}
 
@@ -125,8 +126,8 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
 				       &hpte_rs);
 
 	if (result) {
-		pr_info("%s: res=%d read va=%lx slot=%lx psize=%d\n",
-			__func__, result, va, slot, psize);
+		pr_info("%s: res=%d read vsid=%lx seg_off=%lx slot=%lx psize=%d\n",
+			__func__, result, va.vsid, va.seg_off, slot, psize);
 		BUG();
 	}
 
@@ -170,8 +171,8 @@ static void ps3_hpte_invalidate(unsigned long slot, struct virt_addr va,
 	result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0);
 
 	if (result) {
-		pr_info("%s: res=%d va=%lx slot=%lx psize=%d\n",
-			__func__, result, va, slot, psize);
+		pr_info("%s: res=%d vsid=%lx seg_off=%lx slot=%lx psize=%d\n",
+			__func__, result, va.vsid, va.seg_off, slot, psize);
 		BUG();
 	}
 
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index b4e9641..4c0848f 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -118,9 +118,10 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 	unsigned long hpte_v, hpte_r;
 
 	if (!(vflags & HPTE_V_BOLTED))
-		pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
-			 "rflags=%lx, vflags=%lx, psize=%d)\n",
-			 hpte_group, va.addr, pa, rflags, vflags, psize);
+		pr_devel("hpte_insert(group=%lx, vsid=%016lx, segoff=%016lx, "
+			 "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n",
+			 hpte_group, va.vsid, va.seg_off,
+			 pa, rflags, vflags, psize);
 
 	hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID;
 	hpte_r = hpte_encode_r(pa, psize) | rflags;
@@ -227,22 +228,6 @@ static void pSeries_lpar_hptab_clear(void)
 }
 
 /*
- * This computes the AVPN and B fields of the first dword of a HPTE,
- * for use when we want to match an existing PTE.  The bottom 7 bits
- * of the returned value are zero.
- */
-static inline unsigned long hpte_encode_avpn(struct virt_addr va, int psize,
-					     int ssize)
-{
-	unsigned long v;
-
-	v = (va.addr >> 23) & ~(mmu_psize_defs[psize].avpnm);
-	v <<= HPTE_V_AVPN_SHIFT;
-	v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
-	return v;
-}
-
-/*
  * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
  * the low 3 bits of flags happen to line up.  So no transform is needed.
  * We can probably optimize here and assume the high bits of newpp are
@@ -345,8 +330,8 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, struct virt_addr va
 	unsigned long lpar_rc;
 	unsigned long dummy1, dummy2;
 
-	pr_devel("    inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
-		 slot, va.addr, psize, local);
+	pr_devel("    inval : slot=%lx, vsid=%016lx, seg_off=%016lx, psize: %d, local: %d\n",
+		 slot, va.vsid, va.seg_off, psize, local);
 
 	want_v = hpte_encode_avpn(va, psize, ssize);
 	lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2);
@@ -403,7 +388,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
 	for (i = 0; i < number; i++) {
 		va = batch->vaddr[i];
 		pte = batch->pte[i];
-		pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
+		pte_iterate_hashed_subpages(pte, psize, va.seg_off, index, shift) {
 			hash = hpt_hash(va, shift, ssize);
 			hidx = __rpte_to_hidx(pte, index);
 			if (hidx & _PTEIDX_SECONDARY)
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 5/9] arch/powerpc: Make KERN_VIRT_SIZE not dependend on PGTABLE_RANGE
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
                   ` (3 preceding siblings ...)
  2012-06-29 14:17 ` [PATCH -V1 4/9] arch/powerpc: Use vsid and segment offset to represent virtual address Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 6/9] arch/powerpc: Increase the slice range to 64TB Aneesh Kumar K.V
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

As we keep increasing PGTABLE_RANGE we need not increase the virual
map area for kernel.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/pgtable-ppc64.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index c420561..8af1cf2 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -41,7 +41,7 @@
 #else
 #define KERN_VIRT_START ASM_CONST(0xD000000000000000)
 #endif
-#define KERN_VIRT_SIZE	PGTABLE_RANGE
+#define KERN_VIRT_SIZE	ASM_CONST(0x0000100000000000)
 
 /*
  * The vmalloc space starts at the beginning of that region, and
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 6/9] arch/powerpc: Increase the slice range to 64TB
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
                   ` (4 preceding siblings ...)
  2012-06-29 14:17 ` [PATCH -V1 5/9] arch/powerpc: Make KERN_VIRT_SIZE not dependend on PGTABLE_RANGE Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 7/9] arch/powerpc: Use 50 bits of VSID in slbmte Aneesh Kumar K.V
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

This patch makes the high psizes mask as an unsigned char array
so that we can have more than 16TB. Currently we support upto
64TB

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/mmu-hash64.h |    7 ++-
 arch/powerpc/include/asm/page_64.h    |    7 ++-
 arch/powerpc/mm/hash_utils_64.c       |   15 +++---
 arch/powerpc/mm/slb_low.S             |   35 ++++++++----
 arch/powerpc/mm/slice.c               |   95 +++++++++++++++++++++------------
 5 files changed, 109 insertions(+), 50 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index e48c66b..47ddfa1 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -456,7 +456,12 @@ typedef struct {
 
 #ifdef CONFIG_PPC_MM_SLICES
 	u64 low_slices_psize;	/* SLB page size encodings */
-	u64 high_slices_psize;  /* 4 bits per slice for now */
+	/*
+	 * FIXME!! it should be derived from PGTABLE_RANGE
+	 * Right now we support 64TB and 4 bits for each
+	 * 1TB slice we need 32 bytes for 64TB.
+	 */
+	unsigned char high_slices_psize[32];  /* 4 bits per slice for now */
 #else
 	u16 sllp;		/* SLB page size encoding */
 #endif
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index fed85e6..8806e87 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -82,7 +82,12 @@ extern u64 ppc64_pft_size;
 
 struct slice_mask {
 	u16 low_slices;
-	u16 high_slices;
+	/*
+	 * FIXME!!
+	 * This should be derived out of PGTABLE_RANGE. For the current
+	 * max 64TB, u64 should be ok.
+	 */
+	u64 high_slices;
 };
 
 struct mm_struct;
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 8b5d3c2..beace0b 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -804,16 +804,19 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
 #ifdef CONFIG_PPC_MM_SLICES
 unsigned int get_paca_psize(unsigned long addr)
 {
-	unsigned long index, slices;
+	u64 lpsizes;
+	unsigned char *hpsizes;
+	unsigned long index, mask_index;
 
 	if (addr < SLICE_LOW_TOP) {
-		slices = get_paca()->context.low_slices_psize;
+		lpsizes = get_paca()->context.low_slices_psize;
 		index = GET_LOW_SLICE_INDEX(addr);
-	} else {
-		slices = get_paca()->context.high_slices_psize;
-		index = GET_HIGH_SLICE_INDEX(addr);
+		return (lpsizes >> (index * 4)) & 0xF;
 	}
-	return (slices >> (index * 4)) & 0xF;
+	hpsizes = get_paca()->context.high_slices_psize;
+	index = GET_HIGH_SLICE_INDEX(addr) >> 1;
+	mask_index = GET_HIGH_SLICE_INDEX(addr) - (index << 1);
+	return (hpsizes[index] >> (mask_index * 4)) & 0xF;
 }
 
 #else
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index b9ee79ce..c355af6 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -108,17 +108,34 @@ END_MMU_FTR_SECTION_IFCLR(MMU_FTR_1T_SEGMENT)
 	 * between 4k and 64k standard page size
 	 */
 #ifdef CONFIG_PPC_MM_SLICES
+	/* r10 have esid */
 	cmpldi	r10,16
-
-	/* Get the slice index * 4 in r11 and matching slice size mask in r9 */
-	ld	r9,PACALOWSLICESPSIZE(r13)
-	sldi	r11,r10,2
+	/* below SLICE_LOW_TOP */
 	blt	5f
-	ld	r9,PACAHIGHSLICEPSIZE(r13)
-	srdi	r11,r10,(SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT - 2)
-	andi.	r11,r11,0x3c
-
-5:	/* Extract the psize and multiply to get an array offset */
+	/*
+	 * Handle hpsizes,
+	 * r9 is get_paca()->context.high_slices_psize[index], r11 is mask_index
+	 * We use r10 here, later we restore it to esid.
+	 * Can we use other register instead of r10 ?
+	 */
+	srdi    r10,r10,(SLICE_HIGH_SHIFT - SLICE_LOW_SHIFT) /* index */
+	srdi	r11,r10,1			/* r11 is array index */
+	addi	r9,r11,PACAHIGHSLICEPSIZE
+	lbzx	r9,r9,r13			/* r9 is hpsizes[r11] */
+	sldi    r11,r11,1
+	subf	r11,r11,r10	/* mask_index = index - (array_index << 1) */
+	srdi	r10,r3,28	/* restore r10 with esid */
+	b	6f
+5:
+	/*
+	 * Handle lpsizes
+	 * r9 is get_paca()->context.low_slices_psize, r11 is index
+	 */
+	ld	r9,PACALOWSLICESPSIZE(r13)
+	mr	r11,r10
+6:
+	sldi	r11,r11,2  /* index * 4 */
+	/* Extract the psize and multiply to get an array offset */
 	srd	r9,r9,r11
 	andi.	r9,r9,0xf
 	mulli	r9,r9,MMUPSIZEDEFSIZE
diff --git a/arch/powerpc/mm/slice.c b/arch/powerpc/mm/slice.c
index 73709f7..302a481 100644
--- a/arch/powerpc/mm/slice.c
+++ b/arch/powerpc/mm/slice.c
@@ -42,7 +42,7 @@ int _slice_debug = 1;
 
 static void slice_print_mask(const char *label, struct slice_mask mask)
 {
-	char	*p, buf[16 + 3 + 16 + 1];
+	char	*p, buf[16 + 3 + 64 + 1];
 	int	i;
 
 	if (!_slice_debug)
@@ -142,19 +142,24 @@ static struct slice_mask slice_mask_for_free(struct mm_struct *mm)
 
 static struct slice_mask slice_mask_for_size(struct mm_struct *mm, int psize)
 {
+	unsigned char *hpsizes;
+	int index, mask_index;
 	struct slice_mask ret = { 0, 0 };
 	unsigned long i;
-	u64 psizes;
+	u64 lpsizes;
 
-	psizes = mm->context.low_slices_psize;
+	lpsizes = mm->context.low_slices_psize;
 	for (i = 0; i < SLICE_NUM_LOW; i++)
-		if (((psizes >> (i * 4)) & 0xf) == psize)
+		if (((lpsizes >> (i * 4)) & 0xf) == psize)
 			ret.low_slices |= 1u << i;
 
-	psizes = mm->context.high_slices_psize;
-	for (i = 0; i < SLICE_NUM_HIGH; i++)
-		if (((psizes >> (i * 4)) & 0xf) == psize)
+	hpsizes = mm->context.high_slices_psize;
+	for (i = 0; i < SLICE_NUM_HIGH; i++) {
+		index = i >> 1;
+		mask_index = i - (index << 1);
+		if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == psize)
 			ret.high_slices |= 1u << i;
+	}
 
 	return ret;
 }
@@ -183,8 +188,10 @@ static void slice_flush_segments(void *parm)
 
 static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psize)
 {
+	int index, mask_index;
 	/* Write the new slice psize bits */
-	u64 lpsizes, hpsizes;
+	unsigned char *hpsizes;
+	u64 lpsizes;
 	unsigned long i, flags;
 
 	slice_dbg("slice_convert(mm=%p, psize=%d)\n", mm, psize);
@@ -201,14 +208,18 @@ static void slice_convert(struct mm_struct *mm, struct slice_mask mask, int psiz
 			lpsizes = (lpsizes & ~(0xful << (i * 4))) |
 				(((unsigned long)psize) << (i * 4));
 
+	/* Assign the value back */
+	mm->context.low_slices_psize = lpsizes;
+
 	hpsizes = mm->context.high_slices_psize;
-	for (i = 0; i < SLICE_NUM_HIGH; i++)
+	for (i = 0; i < SLICE_NUM_HIGH; i++) {
+		index = i >> 1;
+		mask_index = i - (index << 1);
 		if (mask.high_slices & (1u << i))
-			hpsizes = (hpsizes & ~(0xful << (i * 4))) |
-				(((unsigned long)psize) << (i * 4));
-
-	mm->context.low_slices_psize = lpsizes;
-	mm->context.high_slices_psize = hpsizes;
+			hpsizes[index] = (hpsizes[index] &
+					  ~(0xf << (mask_index * 4))) |
+				(((unsigned long)psize) << (mask_index * 4));
+	}
 
 	slice_dbg(" lsps=%lx, hsps=%lx\n",
 		  mm->context.low_slices_psize,
@@ -587,18 +598,19 @@ unsigned long arch_get_unmapped_area_topdown(struct file *filp,
 
 unsigned int get_slice_psize(struct mm_struct *mm, unsigned long addr)
 {
-	u64 psizes;
-	int index;
+	unsigned char *hpsizes;
+	int index, mask_index;
 
 	if (addr < SLICE_LOW_TOP) {
-		psizes = mm->context.low_slices_psize;
+		u64 lpsizes;
+		lpsizes = mm->context.low_slices_psize;
 		index = GET_LOW_SLICE_INDEX(addr);
-	} else {
-		psizes = mm->context.high_slices_psize;
-		index = GET_HIGH_SLICE_INDEX(addr);
+		return (lpsizes >> (index * 4)) & 0xf;
 	}
-
-	return (psizes >> (index * 4)) & 0xf;
+	hpsizes = mm->context.high_slices_psize;
+	index = GET_HIGH_SLICE_INDEX(addr) >> 1;
+	mask_index = GET_HIGH_SLICE_INDEX(addr) - (index << 1);
+	return (hpsizes[index] >> (mask_index * 4)) & 0xf;
 }
 EXPORT_SYMBOL_GPL(get_slice_psize);
 
@@ -618,7 +630,9 @@ EXPORT_SYMBOL_GPL(get_slice_psize);
  */
 void slice_set_user_psize(struct mm_struct *mm, unsigned int psize)
 {
-	unsigned long flags, lpsizes, hpsizes;
+	int index, mask_index;
+	unsigned char *hpsizes;
+	unsigned long flags, lpsizes;
 	unsigned int old_psize;
 	int i;
 
@@ -639,15 +653,21 @@ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize)
 		if (((lpsizes >> (i * 4)) & 0xf) == old_psize)
 			lpsizes = (lpsizes & ~(0xful << (i * 4))) |
 				(((unsigned long)psize) << (i * 4));
+	/* Assign the value back */
+	mm->context.low_slices_psize = lpsizes;
 
 	hpsizes = mm->context.high_slices_psize;
-	for (i = 0; i < SLICE_NUM_HIGH; i++)
-		if (((hpsizes >> (i * 4)) & 0xf) == old_psize)
-			hpsizes = (hpsizes & ~(0xful << (i * 4))) |
-				(((unsigned long)psize) << (i * 4));
+	for (i = 0; i < SLICE_NUM_HIGH; i++) {
+		index = i >> 1;
+		mask_index = i - (index << 1);
+		if (((hpsizes[index] >> (mask_index * 4)) & 0xf) == old_psize)
+			hpsizes[index] = (hpsizes[index] &
+					  ~(0xf << (mask_index * 4))) |
+				(((unsigned long)psize) << (mask_index * 4));
+	}
+
+
 
-	mm->context.low_slices_psize = lpsizes;
-	mm->context.high_slices_psize = hpsizes;
 
 	slice_dbg(" lsps=%lx, hsps=%lx\n",
 		  mm->context.low_slices_psize,
@@ -660,18 +680,27 @@ void slice_set_user_psize(struct mm_struct *mm, unsigned int psize)
 void slice_set_psize(struct mm_struct *mm, unsigned long address,
 		     unsigned int psize)
 {
+	unsigned char *hpsizes;
 	unsigned long i, flags;
-	u64 *p;
+	u64 *lpsizes;
 
 	spin_lock_irqsave(&slice_convert_lock, flags);
 	if (address < SLICE_LOW_TOP) {
 		i = GET_LOW_SLICE_INDEX(address);
-		p = &mm->context.low_slices_psize;
+		lpsizes = &mm->context.low_slices_psize;
+		*lpsizes = (*lpsizes & ~(0xful << (i * 4))) |
+			((unsigned long) psize << (i * 4));
 	} else {
+		int index, mask_index;
 		i = GET_HIGH_SLICE_INDEX(address);
-		p = &mm->context.high_slices_psize;
+		hpsizes = mm->context.high_slices_psize;
+		index = i >> 1;
+		mask_index = i - (index << 1);
+		hpsizes[index] = (hpsizes[index] &
+				  ~(0xf << (mask_index * 4))) |
+			(((unsigned long)psize) << (mask_index * 4));
 	}
-	*p = (*p & ~(0xful << (i * 4))) | ((unsigned long) psize << (i * 4));
+
 	spin_unlock_irqrestore(&slice_convert_lock, flags);
 
 #ifdef CONFIG_SPU_BASE
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 7/9] arch/powerpc: Use 50 bits of VSID in slbmte
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
                   ` (5 preceding siblings ...)
  2012-06-29 14:17 ` [PATCH -V1 6/9] arch/powerpc: Increase the slice range to 64TB Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 8/9] arch/powerpc: Use 32bit array for slb cache Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 9/9] arch/powerpc: Add 64TB support Aneesh Kumar K.V
  8 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

Increase the number of valid VSID bits in slbmte instruction.
We will use the new bits when we increase valid VSID bits.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/mm/slb_low.S |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index c355af6..c1fc81c 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -226,7 +226,7 @@ _GLOBAL(slb_allocate_user)
  */
 slb_finish_load:
 	ASM_VSID_SCRAMBLE(r10,r9,256M)
-	rldimi	r11,r10,SLB_VSID_SHIFT,16	/* combine VSID and flags */
+	rldimi	r11,r10,SLB_VSID_SHIFT,2	/* combine VSID and flags */
 
 	/* r3 = EA, r11 = VSID data */
 	/*
@@ -290,7 +290,7 @@ _GLOBAL(slb_compare_rr_to_size)
 slb_finish_load_1T:
 	srdi	r10,r10,40-28		/* get 1T ESID */
 	ASM_VSID_SCRAMBLE(r10,r9,1T)
-	rldimi	r11,r10,SLB_VSID_SHIFT_1T,16	/* combine VSID and flags */
+	rldimi	r11,r10,SLB_VSID_SHIFT_1T,2	/* combine VSID and flags */
 	li	r10,MMU_SEGSIZE_1T
 	rldimi	r11,r10,SLB_VSID_SSIZE_SHIFT,0	/* insert segment size */
 
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 8/9] arch/powerpc: Use 32bit array for slb cache
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
                   ` (6 preceding siblings ...)
  2012-06-29 14:17 ` [PATCH -V1 7/9] arch/powerpc: Use 50 bits of VSID in slbmte Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  2012-06-29 14:17 ` [PATCH -V1 9/9] arch/powerpc: Add 64TB support Aneesh Kumar K.V
  8 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

With larger vsid we need to track more bits of ESID in slb cache
for slb invalidate.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/paca.h |    2 +-
 arch/powerpc/mm/slb_low.S       |    8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h
index daf813f..3e7abba 100644
--- a/arch/powerpc/include/asm/paca.h
+++ b/arch/powerpc/include/asm/paca.h
@@ -100,7 +100,7 @@ struct paca_struct {
 	/* SLB related definitions */
 	u16 vmalloc_sllp;
 	u16 slb_cache_ptr;
-	u16 slb_cache[SLB_CACHE_ENTRIES];
+	u32 slb_cache[SLB_CACHE_ENTRIES];
 #endif /* CONFIG_PPC_STD_MMU_64 */
 
 #ifdef CONFIG_PPC_BOOK3E
diff --git a/arch/powerpc/mm/slb_low.S b/arch/powerpc/mm/slb_low.S
index c1fc81c..d522679 100644
--- a/arch/powerpc/mm/slb_low.S
+++ b/arch/powerpc/mm/slb_low.S
@@ -269,10 +269,10 @@ _GLOBAL(slb_compare_rr_to_size)
 	bge	1f
 
 	/* still room in the slb cache */
-	sldi	r11,r3,1		/* r11 = offset * sizeof(u16) */
-	rldicl	r10,r10,36,28		/* get low 16 bits of the ESID */
-	add	r11,r11,r13		/* r11 = (u16 *)paca + offset */
-	sth	r10,PACASLBCACHE(r11)	/* paca->slb_cache[offset] = esid */
+	sldi	r11,r3,2		/* r11 = offset * sizeof(u32) */
+	rldicl	r10,r10,36,28		/* get the 36 bits of the ESID */
+	add	r11,r11,r13		/* r11 = (u32 *)paca + offset */
+	stw	r10,PACASLBCACHE(r11)	/* paca->slb_cache[offset] = esid */
 	addi	r3,r3,1			/* offset++ */
 	b	2f
 1:					/* offset >= SLB_CACHE_ENTRIES */
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH -V1 9/9] arch/powerpc: Add 64TB support
  2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
                   ` (7 preceding siblings ...)
  2012-06-29 14:17 ` [PATCH -V1 8/9] arch/powerpc: Use 32bit array for slb cache Aneesh Kumar K.V
@ 2012-06-29 14:17 ` Aneesh Kumar K.V
  8 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-06-29 14:17 UTC (permalink / raw)
  To: benh, paulus, michael, anton; +Cc: linuxppc-dev, Aneesh Kumar K.V

From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>

Increase max addressable range to 64TB. This is not tested on
real hardware yet.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
---
 arch/powerpc/include/asm/mmu-hash64.h        |    8 ++++----
 arch/powerpc/include/asm/pgtable-ppc64-4k.h  |    2 +-
 arch/powerpc/include/asm/pgtable-ppc64-64k.h |    2 +-
 arch/powerpc/include/asm/processor.h         |    4 ++--
 arch/powerpc/include/asm/sparsemem.h         |    4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
index 47ddfa1..bf042ba 100644
--- a/arch/powerpc/include/asm/mmu-hash64.h
+++ b/arch/powerpc/include/asm/mmu-hash64.h
@@ -367,16 +367,16 @@ extern void slb_set_size(u16 size);
  */
 
 #define VSID_MULTIPLIER_256M	ASM_CONST(200730139)	/* 28-bit prime */
-#define VSID_BITS_256M		36
+#define VSID_BITS_256M		38
 #define VSID_MODULUS_256M	((1UL<<VSID_BITS_256M)-1)
 
 #define VSID_MULTIPLIER_1T	ASM_CONST(12538073)	/* 24-bit prime */
-#define VSID_BITS_1T		24
+#define VSID_BITS_1T		26
 #define VSID_MODULUS_1T		((1UL<<VSID_BITS_1T)-1)
 
 #define CONTEXT_BITS		19
-#define USER_ESID_BITS		16
-#define USER_ESID_BITS_1T	4
+#define USER_ESID_BITS		18
+#define USER_ESID_BITS_1T	6
 
 #define USER_VSID_RANGE	(1UL << (USER_ESID_BITS + SID_SHIFT))
 
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-4k.h b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
index 6eefdcf..b3eccf2 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64-4k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-4k.h
@@ -7,7 +7,7 @@
  */
 #define PTE_INDEX_SIZE  9
 #define PMD_INDEX_SIZE  7
-#define PUD_INDEX_SIZE  7
+#define PUD_INDEX_SIZE  9
 #define PGD_INDEX_SIZE  9
 
 #ifndef __ASSEMBLY__
diff --git a/arch/powerpc/include/asm/pgtable-ppc64-64k.h b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
index 90533dd..be4e287 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64-64k.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64-64k.h
@@ -7,7 +7,7 @@
 #define PTE_INDEX_SIZE  12
 #define PMD_INDEX_SIZE  12
 #define PUD_INDEX_SIZE	0
-#define PGD_INDEX_SIZE  4
+#define PGD_INDEX_SIZE  6
 
 #ifndef __ASSEMBLY__
 #define PTE_TABLE_SIZE	(sizeof(real_pte_t) << PTE_INDEX_SIZE)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index 8e2d037..426ed13 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -100,8 +100,8 @@ extern struct task_struct *last_task_used_spe;
 #endif
 
 #ifdef CONFIG_PPC64
-/* 64-bit user address space is 44-bits (16TB user VM) */
-#define TASK_SIZE_USER64 (0x0000100000000000UL)
+/* 64-bit user address space is 46-bits (64TB user VM) */
+#define TASK_SIZE_USER64 (0x0000400000000000UL)
 
 /* 
  * 32-bit user address space is 4GB - 1 page 
diff --git a/arch/powerpc/include/asm/sparsemem.h b/arch/powerpc/include/asm/sparsemem.h
index 0c5fa31..f6fc0ee 100644
--- a/arch/powerpc/include/asm/sparsemem.h
+++ b/arch/powerpc/include/asm/sparsemem.h
@@ -10,8 +10,8 @@
  */
 #define SECTION_SIZE_BITS       24
 
-#define MAX_PHYSADDR_BITS       44
-#define MAX_PHYSMEM_BITS        44
+#define MAX_PHYSADDR_BITS       46
+#define MAX_PHYSMEM_BITS        46
 
 #endif /* CONFIG_SPARSEMEM */
 
-- 
1.7.10

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct
  2012-06-29 14:17 ` [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct Aneesh Kumar K.V
@ 2012-06-29 17:44   ` Cody P Schafer
  2012-06-29 21:43   ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 14+ messages in thread
From: Cody P Schafer @ 2012-06-29 17:44 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: linuxppc-dev, paulus, anton

> diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
> index 1c65a59..5ff936b 100644
> --- a/arch/powerpc/include/asm/mmu-hash64.h
> +++ b/arch/powerpc/include/asm/mmu-hash64.h
> @@ -143,6 +143,10 @@ struct mmu_psize_def
>   	unsigned long	sllp;	/* SLB L||LP (exact mask to use in slbmte) */
>   };
>
> +struct virt_addr {
> +	unsigned long addr;
> +};
> +
>   #endif /* __ASSEMBLY__ */
>
>   /*


> @@ -1153,13 +1153,13 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
>   /* WARNING: This is called from hash_low_64.S, if you change this prototype,
>    *          do not forget to update the assembly call site !
>    */

I'd suggest having a similar warning next to the definition of struct 
virt_addr, as any changes to it mean we'll need to adjust hash_low_64.S

> -void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
> +void flush_hash_page(struct virt_addr va, real_pte_t pte, int psize, int ssize,
>   		     int local)
>   {
>   	unsigned long hash, index, shift, hidx, slot;
>
> -	DBG_LOW("flush_hash_page(va=%016lx)\n", va);
> -	pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
> +	DBG_LOW("flush_hash_page(va=%016lx)\n", va.addr);
> +	pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
>   		hash = hpt_hash(va, shift, ssize);
>   		hidx = __rpte_to_hidx(pte, index);
>   		if (hidx & _PTEIDX_SECONDARY)

--
Cody

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct
  2012-06-29 14:17 ` [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct Aneesh Kumar K.V
  2012-06-29 17:44   ` Cody P Schafer
@ 2012-06-29 21:43   ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2012-06-29 21:43 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: linuxppc-dev, paulus, anton

On Fri, 2012-06-29 at 19:47 +0530, Aneesh Kumar K.V wrote:
> From: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
> 
> This is in preparation to the conversion of 64 bit powerpc virtual address
> to the max 78 bits. Later patch will switch struct virt_addr to a struct
> of virtual segment id and segment offset.

I'm not to happy about that.

Mostly, the name of the structure. It's too "generic" and thus likely to
both collide and cause misunderstandings. Do we really need that
anyways ?

Can't we just replace our use of va's everywhere with vpn's instead and
just avoid the type change ?

Cheers,
Ben.

> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
> ---
>  arch/powerpc/include/asm/kvm_book3s.h   |    2 +-
>  arch/powerpc/include/asm/machdep.h      |    6 +--
>  arch/powerpc/include/asm/mmu-hash64.h   |   24 ++++++----
>  arch/powerpc/include/asm/tlbflush.h     |    4 +-
>  arch/powerpc/kvm/book3s_64_mmu_host.c   |    3 +-
>  arch/powerpc/mm/hash_native_64.c        |   76 +++++++++++++++++--------------
>  arch/powerpc/mm/hash_utils_64.c         |   12 ++---
>  arch/powerpc/mm/hugetlbpage-hash64.c    |    3 +-
>  arch/powerpc/mm/tlb_hash64.c            |    3 +-
>  arch/powerpc/platforms/cell/beat_htab.c |   17 +++----
>  arch/powerpc/platforms/ps3/htab.c       |    6 +--
>  arch/powerpc/platforms/pseries/lpar.c   |   30 ++++++------
>  12 files changed, 103 insertions(+), 83 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/kvm_book3s.h b/arch/powerpc/include/asm/kvm_book3s.h
> index fd07f43..374b75d 100644
> --- a/arch/powerpc/include/asm/kvm_book3s.h
> +++ b/arch/powerpc/include/asm/kvm_book3s.h
> @@ -59,7 +59,7 @@ struct hpte_cache {
>  	struct hlist_node list_vpte;
>  	struct hlist_node list_vpte_long;
>  	struct rcu_head rcu_head;
> -	u64 host_va;
> +	struct virt_addr host_va;
>  	u64 pfn;
>  	ulong slot;
>  	struct kvmppc_pte pte;
> diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
> index 42ce570..b34d0a9 100644
> --- a/arch/powerpc/include/asm/machdep.h
> +++ b/arch/powerpc/include/asm/machdep.h
> @@ -34,19 +34,19 @@ struct machdep_calls {
>  	char		*name;
>  #ifdef CONFIG_PPC64
>  	void            (*hpte_invalidate)(unsigned long slot,
> -					   unsigned long va,
> +					   struct virt_addr va,
>  					   int psize, int ssize,
>  					   int local);
>  	long		(*hpte_updatepp)(unsigned long slot, 
>  					 unsigned long newpp, 
> -					 unsigned long va,
> +					 struct virt_addr va,
>  					 int psize, int ssize,
>  					 int local);
>  	void            (*hpte_updateboltedpp)(unsigned long newpp, 
>  					       unsigned long ea,
>  					       int psize, int ssize);
>  	long		(*hpte_insert)(unsigned long hpte_group,
> -				       unsigned long va,
> +				       struct virt_addr va,
>  				       unsigned long prpn,
>  				       unsigned long rflags,
>  				       unsigned long vflags,
> diff --git a/arch/powerpc/include/asm/mmu-hash64.h b/arch/powerpc/include/asm/mmu-hash64.h
> index 1c65a59..5ff936b 100644
> --- a/arch/powerpc/include/asm/mmu-hash64.h
> +++ b/arch/powerpc/include/asm/mmu-hash64.h
> @@ -143,6 +143,10 @@ struct mmu_psize_def
>  	unsigned long	sllp;	/* SLB L||LP (exact mask to use in slbmte) */
>  };
>  
> +struct virt_addr {
> +	unsigned long addr;
> +};
> +
>  #endif /* __ASSEMBLY__ */
>  
>  /*
> @@ -183,11 +187,11 @@ extern int mmu_ci_restrictions;
>   * This function sets the AVPN and L fields of the HPTE  appropriately
>   * for the page size
>   */
> -static inline unsigned long hpte_encode_v(unsigned long va, int psize,
> +static inline unsigned long hpte_encode_v(struct virt_addr va, int psize,
>  					  int ssize)
>  {
>  	unsigned long v;
> -	v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
> +	v = (va.addr >> 23) & ~(mmu_psize_defs[psize].avpnm);
>  	v <<= HPTE_V_AVPN_SHIFT;
>  	if (psize != MMU_PAGE_4K)
>  		v |= HPTE_V_LARGE;
> @@ -218,28 +222,30 @@ static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
>  /*
>   * Build a VA given VSID, EA and segment size
>   */
> -static inline unsigned long hpt_va(unsigned long ea, unsigned long vsid,
> +static inline struct virt_addr hpt_va(unsigned long ea, unsigned long vsid,
>  				   int ssize)
>  {
> +	struct virt_addr va;
>  	if (ssize == MMU_SEGSIZE_256M)
> -		return (vsid << 28) | (ea & 0xfffffffUL);
> -	return (vsid << 40) | (ea & 0xffffffffffUL);
> +		va.addr = (vsid << 28) | (ea & 0xfffffffUL);
> +	va.addr = (vsid << 40) | (ea & 0xffffffffffUL);
> +	return va;
>  }
>  
>  /*
>   * This hashes a virtual address
>   */
>  
> -static inline unsigned long hpt_hash(unsigned long va, unsigned int shift,
> +static inline unsigned long hpt_hash(struct virt_addr va, unsigned int shift,
>  				     int ssize)
>  {
>  	unsigned long hash, vsid;
>  
>  	if (ssize == MMU_SEGSIZE_256M) {
> -		hash = (va >> 28) ^ ((va & 0x0fffffffUL) >> shift);
> +		hash = (va.addr >> 28) ^ ((va.addr & 0x0fffffffUL) >> shift);
>  	} else {
> -		vsid = va >> 40;
> -		hash = vsid ^ (vsid << 25) ^ ((va & 0xffffffffffUL) >> shift);
> +		vsid = va.addr >> 40;
> +		hash = vsid ^ (vsid << 25) ^ ((va.addr & 0xffffffffffUL) >> shift);
>  	}
>  	return hash & 0x7fffffffffUL;
>  }
> diff --git a/arch/powerpc/include/asm/tlbflush.h b/arch/powerpc/include/asm/tlbflush.h
> index 81143fc..2c8ad50 100644
> --- a/arch/powerpc/include/asm/tlbflush.h
> +++ b/arch/powerpc/include/asm/tlbflush.h
> @@ -95,7 +95,7 @@ struct ppc64_tlb_batch {
>  	unsigned long		index;
>  	struct mm_struct	*mm;
>  	real_pte_t		pte[PPC64_TLB_BATCH_NR];
> -	unsigned long		vaddr[PPC64_TLB_BATCH_NR];
> +	struct virt_addr	vaddr[PPC64_TLB_BATCH_NR];
>  	unsigned int		psize;
>  	int			ssize;
>  };
> @@ -127,7 +127,7 @@ static inline void arch_leave_lazy_mmu_mode(void)
>  #define arch_flush_lazy_mmu_mode()      do {} while (0)
>  
> 
> -extern void flush_hash_page(unsigned long va, real_pte_t pte, int psize,
> +extern void flush_hash_page(struct virt_addr va, real_pte_t pte, int psize,
>  			    int ssize, int local);
>  extern void flush_hash_range(unsigned long number, int local);
>  
> diff --git a/arch/powerpc/kvm/book3s_64_mmu_host.c b/arch/powerpc/kvm/book3s_64_mmu_host.c
> index 10fc8ec..933b117 100644
> --- a/arch/powerpc/kvm/book3s_64_mmu_host.c
> +++ b/arch/powerpc/kvm/book3s_64_mmu_host.c
> @@ -80,8 +80,9 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid)
>  
>  int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
>  {
> +	struct virt_addr va;
>  	pfn_t hpaddr;
> -	ulong hash, hpteg, va;
> +	ulong hash, hpteg;
>  	u64 vsid;
>  	int ret;
>  	int rflags = 0x192;
> diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
> index 90039bc..cab3892 100644
> --- a/arch/powerpc/mm/hash_native_64.c
> +++ b/arch/powerpc/mm/hash_native_64.c
> @@ -39,62 +39,67 @@
>  
>  DEFINE_RAW_SPINLOCK(native_tlbie_lock);
>  
> -static inline void __tlbie(unsigned long va, int psize, int ssize)
> +/* Verify docs says 14 .. 14+i bits */
> +static inline void __tlbie(struct virt_addr va, int psize, int ssize)
>  {
> +	unsigned long vaddr = va.addr;
>  	unsigned int penc;
>  
> +	vaddr &= ~(0xffffULL << 48);
> +
>  	/* clear top 16 bits, non SLS segment */
> -	va &= ~(0xffffULL << 48);
> +	vaddr &= ~(0xffffULL << 48);
>  
>  	switch (psize) {
>  	case MMU_PAGE_4K:
> -		va &= ~0xffful;
> -		va |= ssize << 8;
> +		vaddr &= ~0xffful;
> +		vaddr |= ssize << 8;
>  		asm volatile(ASM_FTR_IFCLR("tlbie %0,0", PPC_TLBIE(%1,%0), %2)
> -			     : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
> +			     : : "r" (vaddr), "r"(0), "i" (CPU_FTR_ARCH_206)
>  			     : "memory");
>  		break;
>  	default:
>  		penc = mmu_psize_defs[psize].penc;
> -		va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
> -		va |= penc << 12;
> -		va |= ssize << 8;
> -		va |= 1; /* L */
> +		vaddr &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
> +		vaddr |= penc << 12;
> +		vaddr |= ssize << 8;
> +		vaddr |= 1; /* L */
>  		asm volatile(ASM_FTR_IFCLR("tlbie %0,1", PPC_TLBIE(%1,%0), %2)
> -			     : : "r" (va), "r"(0), "i" (CPU_FTR_ARCH_206)
> +			     : : "r" (vaddr), "r"(0), "i" (CPU_FTR_ARCH_206)
>  			     : "memory");
>  		break;
>  	}
>  }
>  
> -static inline void __tlbiel(unsigned long va, int psize, int ssize)
> +/* Verify docs says 14 .. 14+i bits */
> +static inline void __tlbiel(struct virt_addr va, int psize, int ssize)
>  {
> +	unsigned long vaddr = va.addr;
>  	unsigned int penc;
>  
> -	/* clear top 16 bits, non SLS segment */
> -	va &= ~(0xffffULL << 48);
> +	vaddr &= ~(0xffffULL << 48);
>  
>  	switch (psize) {
>  	case MMU_PAGE_4K:
> -		va &= ~0xffful;
> -		va |= ssize << 8;
> +		vaddr &= ~0xffful;
> +		vaddr |= ssize << 8;
>  		asm volatile(".long 0x7c000224 | (%0 << 11) | (0 << 21)"
> -			     : : "r"(va) : "memory");
> +			     : : "r"(vaddr) : "memory");
>  		break;
>  	default:
>  		penc = mmu_psize_defs[psize].penc;
> -		va &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
> -		va |= penc << 12;
> -		va |= ssize << 8;
> -		va |= 1; /* L */
> +		vaddr &= ~((1ul << mmu_psize_defs[psize].shift) - 1);
> +		vaddr |= penc << 12;
> +		vaddr |= ssize << 8;
> +		vaddr |= 1; /* L */
>  		asm volatile(".long 0x7c000224 | (%0 << 11) | (1 << 21)"
> -			     : : "r"(va) : "memory");
> +			     : : "r"(vaddr) : "memory");
>  		break;
>  	}
>  
>  }
>  
> -static inline void tlbie(unsigned long va, int psize, int ssize, int local)
> +static inline void tlbie(struct virt_addr va, int psize, int ssize, int local)
>  {
>  	unsigned int use_local = local && mmu_has_feature(MMU_FTR_TLBIEL);
>  	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
> @@ -134,7 +139,7 @@ static inline void native_unlock_hpte(struct hash_pte *hptep)
>  	clear_bit_unlock(HPTE_LOCK_BIT, word);
>  }
>  
> -static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
> +static long native_hpte_insert(unsigned long hpte_group, struct virt_addr va,
>  			unsigned long pa, unsigned long rflags,
>  			unsigned long vflags, int psize, int ssize)
>  {
> @@ -225,7 +230,7 @@ static long native_hpte_remove(unsigned long hpte_group)
>  }
>  
>  static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
> -				 unsigned long va, int psize, int ssize,
> +				 struct virt_addr va, int psize, int ssize,
>  				 int local)
>  {
>  	struct hash_pte *hptep = htab_address + slot;
> @@ -259,7 +264,7 @@ static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,
>  	return ret;
>  }
>  
> -static long native_hpte_find(unsigned long va, int psize, int ssize)
> +static long native_hpte_find(struct virt_addr va, int psize, int ssize)
>  {
>  	struct hash_pte *hptep;
>  	unsigned long hash;
> @@ -295,7 +300,8 @@ static long native_hpte_find(unsigned long va, int psize, int ssize)
>  static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
>  				       int psize, int ssize)
>  {
> -	unsigned long vsid, va;
> +	struct virt_addr va;
> +	unsigned long vsid;
>  	long slot;
>  	struct hash_pte *hptep;
>  
> @@ -315,7 +321,7 @@ static void native_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
>  	tlbie(va, psize, ssize, 0);
>  }
>  
> -static void native_hpte_invalidate(unsigned long slot, unsigned long va,
> +static void native_hpte_invalidate(unsigned long slot, struct virt_addr va,
>  				   int psize, int ssize, int local)
>  {
>  	struct hash_pte *hptep = htab_address + slot;
> @@ -349,7 +355,7 @@ static void native_hpte_invalidate(unsigned long slot, unsigned long va,
>  #define LP_MASK(i)	((0xFF >> (i)) << LP_SHIFT)
>  
>  static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
> -			int *psize, int *ssize, unsigned long *va)
> +			int *psize, int *ssize, struct virt_addr *va)
>  {
>  	unsigned long hpte_r = hpte->r;
>  	unsigned long hpte_v = hpte->v;
> @@ -403,7 +409,7 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
>  		avpn |= (vpi << mmu_psize_defs[size].shift);
>  	}
>  
> -	*va = avpn;
> +	va->addr = avpn;
>  	*psize = size;
>  	*ssize = hpte_v >> HPTE_V_SSIZE_SHIFT;
>  }
> @@ -418,9 +424,10 @@ static void hpte_decode(struct hash_pte *hpte, unsigned long slot,
>   */
>  static void native_hpte_clear(void)
>  {
> +	struct virt_addr va;
>  	unsigned long slot, slots, flags;
>  	struct hash_pte *hptep = htab_address;
> -	unsigned long hpte_v, va;
> +	unsigned long hpte_v;
>  	unsigned long pteg_count;
>  	int psize, ssize;
>  
> @@ -465,7 +472,8 @@ static void native_hpte_clear(void)
>   */
>  static void native_flush_hash_range(unsigned long number, int local)
>  {
> -	unsigned long va, hash, index, hidx, shift, slot;
> +	struct virt_addr va;
> +	unsigned long hash, index, hidx, shift, slot;
>  	struct hash_pte *hptep;
>  	unsigned long hpte_v;
>  	unsigned long want_v;
> @@ -482,7 +490,7 @@ static void native_flush_hash_range(unsigned long number, int local)
>  		va = batch->vaddr[i];
>  		pte = batch->pte[i];
>  
> -		pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
> +		pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
>  			hash = hpt_hash(va, shift, ssize);
>  			hidx = __rpte_to_hidx(pte, index);
>  			if (hidx & _PTEIDX_SECONDARY)
> @@ -508,7 +516,7 @@ static void native_flush_hash_range(unsigned long number, int local)
>  			va = batch->vaddr[i];
>  			pte = batch->pte[i];
>  
> -			pte_iterate_hashed_subpages(pte, psize, va, index,
> +			pte_iterate_hashed_subpages(pte, psize, va.addr, index,
>  						    shift) {
>  				__tlbiel(va, psize, ssize);
>  			} pte_iterate_hashed_end();
> @@ -525,7 +533,7 @@ static void native_flush_hash_range(unsigned long number, int local)
>  			va = batch->vaddr[i];
>  			pte = batch->pte[i];
>  
> -			pte_iterate_hashed_subpages(pte, psize, va, index,
> +			pte_iterate_hashed_subpages(pte, psize, va.addr, index,
>  						    shift) {
>  				__tlbie(va, psize, ssize);
>  			} pte_iterate_hashed_end();
> diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
> index 377e5cb..2429d53 100644
> --- a/arch/powerpc/mm/hash_utils_64.c
> +++ b/arch/powerpc/mm/hash_utils_64.c
> @@ -192,7 +192,7 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
>  	     vaddr += step, paddr += step) {
>  		unsigned long hash, hpteg;
>  		unsigned long vsid = get_kernel_vsid(vaddr, ssize);
> -		unsigned long va = hpt_va(vaddr, vsid, ssize);
> +		struct virt_addr va = hpt_va(vaddr, vsid, ssize);
>  		unsigned long tprot = prot;
>  
>  		/* Make kernel text executable */
> @@ -1153,13 +1153,13 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
>  /* WARNING: This is called from hash_low_64.S, if you change this prototype,
>   *          do not forget to update the assembly call site !
>   */
> -void flush_hash_page(unsigned long va, real_pte_t pte, int psize, int ssize,
> +void flush_hash_page(struct virt_addr va, real_pte_t pte, int psize, int ssize,
>  		     int local)
>  {
>  	unsigned long hash, index, shift, hidx, slot;
>  
> -	DBG_LOW("flush_hash_page(va=%016lx)\n", va);
> -	pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
> +	DBG_LOW("flush_hash_page(va=%016lx)\n", va.addr);
> +	pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
>  		hash = hpt_hash(va, shift, ssize);
>  		hidx = __rpte_to_hidx(pte, index);
>  		if (hidx & _PTEIDX_SECONDARY)
> @@ -1208,7 +1208,7 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
>  {
>  	unsigned long hash, hpteg;
>  	unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
> -	unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
> +	struct virt_addr va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
>  	unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL);
>  	int ret;
>  
> @@ -1229,7 +1229,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
>  {
>  	unsigned long hash, hidx, slot;
>  	unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
> -	unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
> +	struct virt_addr va = hpt_va(vaddr, vsid, mmu_kernel_ssize);
>  
>  	hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize);
>  	spin_lock(&linear_map_hash_lock);
> diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c
> index cc5c273..47b4ed0 100644
> --- a/arch/powerpc/mm/hugetlbpage-hash64.c
> +++ b/arch/powerpc/mm/hugetlbpage-hash64.c
> @@ -18,8 +18,9 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
>  		     pte_t *ptep, unsigned long trap, int local, int ssize,
>  		     unsigned int shift, unsigned int mmu_psize)
>  {
> +	struct virt_addr va;
>  	unsigned long old_pte, new_pte;
> -	unsigned long va, rflags, pa, sz;
> +	unsigned long rflags, pa, sz;
>  	long slot;
>  
>  	BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
> diff --git a/arch/powerpc/mm/tlb_hash64.c b/arch/powerpc/mm/tlb_hash64.c
> index 31f1820..b830466 100644
> --- a/arch/powerpc/mm/tlb_hash64.c
> +++ b/arch/powerpc/mm/tlb_hash64.c
> @@ -42,8 +42,9 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
>  void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
>  		     pte_t *ptep, unsigned long pte, int huge)
>  {
> +	struct virt_addr vaddr;
>  	struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
> -	unsigned long vsid, vaddr;
> +	unsigned long vsid;
>  	unsigned int psize;
>  	int ssize;
>  	real_pte_t rpte;
> diff --git a/arch/powerpc/platforms/cell/beat_htab.c b/arch/powerpc/platforms/cell/beat_htab.c
> index b83077e..a2dfc22 100644
> --- a/arch/powerpc/platforms/cell/beat_htab.c
> +++ b/arch/powerpc/platforms/cell/beat_htab.c
> @@ -88,7 +88,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group)
>  }
>  
>  static long beat_lpar_hpte_insert(unsigned long hpte_group,
> -				  unsigned long va, unsigned long pa,
> +				  struct virt_addr va, unsigned long pa,
>  				  unsigned long rflags, unsigned long vflags,
>  				  int psize, int ssize)
>  {
> @@ -184,7 +184,7 @@ static void beat_lpar_hptab_clear(void)
>   */
>  static long beat_lpar_hpte_updatepp(unsigned long slot,
>  				    unsigned long newpp,
> -				    unsigned long va,
> +				    struct virt_addr va,
>  				    int psize, int ssize, int local)
>  {
>  	unsigned long lpar_rc;
> @@ -220,7 +220,7 @@ static long beat_lpar_hpte_updatepp(unsigned long slot,
>  	return 0;
>  }
>  
> -static long beat_lpar_hpte_find(unsigned long va, int psize)
> +static long beat_lpar_hpte_find(struct virt_addr va, int psize)
>  {
>  	unsigned long hash;
>  	unsigned long i, j;
> @@ -255,7 +255,8 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
>  					  unsigned long ea,
>  					  int psize, int ssize)
>  {
> -	unsigned long lpar_rc, slot, vsid, va;
> +	struct virt_addr va;
> +	unsigned long lpar_rc, slot, vsid;
>  	u64 dummy0, dummy1;
>  
>  	vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
> @@ -272,7 +273,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
>  	BUG_ON(lpar_rc != 0);
>  }
>  
> -static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
> +static void beat_lpar_hpte_invalidate(unsigned long slot, struct virt_addr va,
>  					 int psize, int ssize, int local)
>  {
>  	unsigned long want_v;
> @@ -311,7 +312,7 @@ void __init hpte_init_beat(void)
>  }
>  
>  static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
> -				  unsigned long va, unsigned long pa,
> +				  struct virt_addr va, unsigned long pa,
>  				  unsigned long rflags, unsigned long vflags,
>  				  int psize, int ssize)
>  {
> @@ -364,7 +365,7 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
>   */
>  static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
>  				    unsigned long newpp,
> -				    unsigned long va,
> +				    struct virt_addr va,
>  				    int psize, int ssize, int local)
>  {
>  	unsigned long lpar_rc;
> @@ -392,7 +393,7 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
>  	return 0;
>  }
>  
> -static void beat_lpar_hpte_invalidate_v3(unsigned long slot, unsigned long va,
> +static void beat_lpar_hpte_invalidate_v3(unsigned long slot, struct virt_addr va,
>  					 int psize, int ssize, int local)
>  {
>  	unsigned long want_v;
> diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
> index 3124cf7..6e27576 100644
> --- a/arch/powerpc/platforms/ps3/htab.c
> +++ b/arch/powerpc/platforms/ps3/htab.c
> @@ -43,7 +43,7 @@ enum ps3_lpar_vas_id {
>  
>  static DEFINE_SPINLOCK(ps3_htab_lock);
>  
> -static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
> +static long ps3_hpte_insert(unsigned long hpte_group, struct virt_addr va,
>  	unsigned long pa, unsigned long rflags, unsigned long vflags,
>  	int psize, int ssize)
>  {
> @@ -107,7 +107,7 @@ static long ps3_hpte_remove(unsigned long hpte_group)
>  }
>  
>  static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
> -	unsigned long va, int psize, int ssize, int local)
> +	struct virt_addr va, int psize, int ssize, int local)
>  {
>  	int result;
>  	u64 hpte_v, want_v, hpte_rs;
> @@ -159,7 +159,7 @@ static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
>  	panic("ps3_hpte_updateboltedpp() not implemented");
>  }
>  
> -static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
> +static void ps3_hpte_invalidate(unsigned long slot, struct virt_addr va,
>  	int psize, int ssize, int local)
>  {
>  	unsigned long flags;
> diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
> index 5f3ef87..b4e9641 100644
> --- a/arch/powerpc/platforms/pseries/lpar.c
> +++ b/arch/powerpc/platforms/pseries/lpar.c
> @@ -108,9 +108,9 @@ void vpa_init(int cpu)
>  }
>  
>  static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
> - 			      unsigned long va, unsigned long pa,
> - 			      unsigned long rflags, unsigned long vflags,
> -			      int psize, int ssize)
> +				     struct virt_addr va, unsigned long pa,
> +				     unsigned long rflags, unsigned long vflags,
> +				     int psize, int ssize)
>  {
>  	unsigned long lpar_rc;
>  	unsigned long flags;
> @@ -120,7 +120,7 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
>  	if (!(vflags & HPTE_V_BOLTED))
>  		pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, "
>  			 "rflags=%lx, vflags=%lx, psize=%d)\n",
> -			 hpte_group, va, pa, rflags, vflags, psize);
> +			 hpte_group, va.addr, pa, rflags, vflags, psize);
>  
>  	hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID;
>  	hpte_r = hpte_encode_r(pa, psize) | rflags;
> @@ -231,12 +231,12 @@ static void pSeries_lpar_hptab_clear(void)
>   * for use when we want to match an existing PTE.  The bottom 7 bits
>   * of the returned value are zero.
>   */
> -static inline unsigned long hpte_encode_avpn(unsigned long va, int psize,
> +static inline unsigned long hpte_encode_avpn(struct virt_addr va, int psize,
>  					     int ssize)
>  {
>  	unsigned long v;
>  
> -	v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm);
> +	v = (va.addr >> 23) & ~(mmu_psize_defs[psize].avpnm);
>  	v <<= HPTE_V_AVPN_SHIFT;
>  	v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
>  	return v;
> @@ -250,7 +250,7 @@ static inline unsigned long hpte_encode_avpn(unsigned long va, int psize,
>   */
>  static long pSeries_lpar_hpte_updatepp(unsigned long slot,
>  				       unsigned long newpp,
> -				       unsigned long va,
> +				       struct virt_addr va,
>  				       int psize, int ssize, int local)
>  {
>  	unsigned long lpar_rc;
> @@ -295,7 +295,7 @@ static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
>  	return dword0;
>  }
>  
> -static long pSeries_lpar_hpte_find(unsigned long va, int psize, int ssize)
> +static long pSeries_lpar_hpte_find(struct virt_addr va, int psize, int ssize)
>  {
>  	unsigned long hash;
>  	unsigned long i;
> @@ -323,7 +323,8 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
>  					     unsigned long ea,
>  					     int psize, int ssize)
>  {
> -	unsigned long lpar_rc, slot, vsid, va, flags;
> +	struct virt_addr va;
> +	unsigned long lpar_rc, slot, vsid, flags;
>  
>  	vsid = get_kernel_vsid(ea, ssize);
>  	va = hpt_va(ea, vsid, ssize);
> @@ -337,7 +338,7 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
>  	BUG_ON(lpar_rc != H_SUCCESS);
>  }
>  
> -static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
> +static void pSeries_lpar_hpte_invalidate(unsigned long slot, struct virt_addr va,
>  					 int psize, int ssize, int local)
>  {
>  	unsigned long want_v;
> @@ -345,7 +346,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
>  	unsigned long dummy1, dummy2;
>  
>  	pr_devel("    inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
> -		 slot, va, psize, local);
> +		 slot, va.addr, psize, local);
>  
>  	want_v = hpte_encode_avpn(va, psize, ssize);
>  	lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2);
> @@ -358,7 +359,8 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
>  static void pSeries_lpar_hpte_removebolted(unsigned long ea,
>  					   int psize, int ssize)
>  {
> -	unsigned long slot, vsid, va;
> +	struct virt_addr va;
> +	unsigned long slot, vsid;
>  
>  	vsid = get_kernel_vsid(ea, ssize);
>  	va = hpt_va(ea, vsid, ssize);
> @@ -382,12 +384,12 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea,
>   */
>  static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
>  {
> +	struct virt_addr va;
>  	unsigned long i, pix, rc;
>  	unsigned long flags = 0;
>  	struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
>  	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
>  	unsigned long param[9];
> -	unsigned long va;
>  	unsigned long hash, index, shift, hidx, slot;
>  	real_pte_t pte;
>  	int psize, ssize;
> @@ -401,7 +403,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
>  	for (i = 0; i < number; i++) {
>  		va = batch->vaddr[i];
>  		pte = batch->pte[i];
> -		pte_iterate_hashed_subpages(pte, psize, va, index, shift) {
> +		pte_iterate_hashed_subpages(pte, psize, va.addr, index, shift) {
>  			hash = hpt_hash(va, shift, ssize);
>  			hidx = __rpte_to_hidx(pte, index);
>  			if (hidx & _PTEIDX_SECONDARY)

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH -V1 4/9] arch/powerpc: Use vsid and segment offset to represent virtual address
  2012-06-29 14:17 ` [PATCH -V1 4/9] arch/powerpc: Use vsid and segment offset to represent virtual address Aneesh Kumar K.V
@ 2012-06-29 21:45   ` Benjamin Herrenschmidt
  2012-07-01  7:53     ` Aneesh Kumar K.V
  0 siblings, 1 reply; 14+ messages in thread
From: Benjamin Herrenschmidt @ 2012-06-29 21:45 UTC (permalink / raw)
  To: Aneesh Kumar K.V; +Cc: linuxppc-dev, paulus, anton

On Fri, 2012-06-29 at 19:47 +0530, Aneesh Kumar K.V wrote:
>  
> +/* 78 bit power virtual address */
>  struct virt_addr {
> -       unsigned long addr;
> +       unsigned long vsid;
> +       unsigned long seg_off;
>  };

Do we really need to do that ? It's really nasty...

We are trying to add only a few bits, we get 12 for free by just using a
page number (4k based always, not PAGE_SHIFT based btw) no ? That should
get us going for a while....

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH -V1 4/9] arch/powerpc: Use vsid and segment offset to represent virtual address
  2012-06-29 21:45   ` Benjamin Herrenschmidt
@ 2012-07-01  7:53     ` Aneesh Kumar K.V
  0 siblings, 0 replies; 14+ messages in thread
From: Aneesh Kumar K.V @ 2012-07-01  7:53 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: paulus, linuxppc-dev, anton

Benjamin Herrenschmidt <benh@kernel.crashing.org> writes:

> On Fri, 2012-06-29 at 19:47 +0530, Aneesh Kumar K.V wrote:
>>  
>> +/* 78 bit power virtual address */
>>  struct virt_addr {
>> -       unsigned long addr;
>> +       unsigned long vsid;
>> +       unsigned long seg_off;
>>  };
>
> Do we really need to do that ? It's really nasty...
>
> We are trying to add only a few bits, we get 12 for free by just using a
> page number (4k based always, not PAGE_SHIFT based btw) no ? That should
> get us going for a while....
>

Ok, will update to vpn in the next iteration.

Thanks
-aneesh

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2012-07-01  7:53 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-29 14:17 [PATCH -V1 0/9] arch/powerpc: Add 64TB support to ppc64 Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 1/9] arch/powerpc: Use hpt_va to compute virtual address Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 2/9] arch/powerpc: Convert virtual address to a struct Aneesh Kumar K.V
2012-06-29 17:44   ` Cody P Schafer
2012-06-29 21:43   ` Benjamin Herrenschmidt
2012-06-29 14:17 ` [PATCH -V1 3/9] arch/powerpc: Simplify hpte_decode Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 4/9] arch/powerpc: Use vsid and segment offset to represent virtual address Aneesh Kumar K.V
2012-06-29 21:45   ` Benjamin Herrenschmidt
2012-07-01  7:53     ` Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 5/9] arch/powerpc: Make KERN_VIRT_SIZE not dependend on PGTABLE_RANGE Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 6/9] arch/powerpc: Increase the slice range to 64TB Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 7/9] arch/powerpc: Use 50 bits of VSID in slbmte Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 8/9] arch/powerpc: Use 32bit array for slb cache Aneesh Kumar K.V
2012-06-29 14:17 ` [PATCH -V1 9/9] arch/powerpc: Add 64TB support Aneesh Kumar K.V

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).