Commit 5524a27d authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Benjamin Herrenschmidt

powerpc/mm: Convert virtual address to vpn

This patch convert different functions to take virtual page number
instead of virtual address. Virtual page number is virtual address
shifted right by VPN_SHIFT (12) bits. This enable us to have an
address range of upto 76 bits.
Reviewed-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent dcda287a
...@@ -59,7 +59,7 @@ struct hpte_cache { ...@@ -59,7 +59,7 @@ struct hpte_cache {
struct hlist_node list_vpte; struct hlist_node list_vpte;
struct hlist_node list_vpte_long; struct hlist_node list_vpte_long;
struct rcu_head rcu_head; struct rcu_head rcu_head;
u64 host_va; u64 host_vpn;
u64 pfn; u64 pfn;
ulong slot; ulong slot;
struct kvmppc_pte pte; struct kvmppc_pte pte;
......
...@@ -34,19 +34,19 @@ struct machdep_calls { ...@@ -34,19 +34,19 @@ struct machdep_calls {
char *name; char *name;
#ifdef CONFIG_PPC64 #ifdef CONFIG_PPC64
void (*hpte_invalidate)(unsigned long slot, void (*hpte_invalidate)(unsigned long slot,
unsigned long va, unsigned long vpn,
int psize, int ssize, int psize, int ssize,
int local); int local);
long (*hpte_updatepp)(unsigned long slot, long (*hpte_updatepp)(unsigned long slot,
unsigned long newpp, unsigned long newpp,
unsigned long va, unsigned long vpn,
int psize, int ssize, int psize, int ssize,
int local); int local);
void (*hpte_updateboltedpp)(unsigned long newpp, void (*hpte_updateboltedpp)(unsigned long newpp,
unsigned long ea, unsigned long ea,
int psize, int ssize); int psize, int ssize);
long (*hpte_insert)(unsigned long hpte_group, long (*hpte_insert)(unsigned long hpte_group,
unsigned long va, unsigned long vpn,
unsigned long prpn, unsigned long prpn,
unsigned long rflags, unsigned long rflags,
unsigned long vflags, unsigned long vflags,
......
...@@ -154,9 +154,25 @@ struct mmu_psize_def ...@@ -154,9 +154,25 @@ struct mmu_psize_def
#define MMU_SEGSIZE_256M 0 #define MMU_SEGSIZE_256M 0
#define MMU_SEGSIZE_1T 1 #define MMU_SEGSIZE_1T 1
/*
* encode page number shift.
* in order to fit the 78 bit va in a 64 bit variable we shift the va by
* 12 bits. This enable us to address upto 76 bit va.
* For hpt hash from a va we can ignore the page size bits of va and for
* hpte encoding we ignore up to 23 bits of va. So ignoring lower 12 bits ensure
* we work in all cases including 4k page size.
*/
#define VPN_SHIFT 12
#ifndef __ASSEMBLY__ #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 * The current system page and segment sizes
*/ */
...@@ -180,18 +196,39 @@ extern unsigned long tce_alloc_start, tce_alloc_end; ...@@ -180,18 +196,39 @@ extern unsigned long tce_alloc_start, tce_alloc_end;
extern int mmu_ci_restrictions; extern int mmu_ci_restrictions;
/* /*
* This function sets the AVPN and L fields of the HPTE appropriately * This computes the AVPN and B fields of the first dword of a HPTE,
* for the page size * 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_v(unsigned long va, int psize, static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize,
int ssize) int ssize)
{ {
unsigned long v; unsigned long v;
v = (va >> 23) & ~(mmu_psize_defs[psize].avpnm); /*
* 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 = (vpn >> (23 - VPN_SHIFT)) & ~(mmu_psize_defs[psize].avpnm);
v <<= HPTE_V_AVPN_SHIFT; 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
*/
static inline unsigned long hpte_encode_v(unsigned long vpn,
int psize, int ssize)
{
unsigned long v;
v = hpte_encode_avpn(vpn, psize, ssize);
if (psize != MMU_PAGE_4K) if (psize != MMU_PAGE_4K)
v |= HPTE_V_LARGE; v |= HPTE_V_LARGE;
v |= ((unsigned long) ssize) << HPTE_V_SSIZE_SHIFT;
return v; return v;
} }
...@@ -216,30 +253,37 @@ static inline unsigned long hpte_encode_r(unsigned long pa, int psize) ...@@ -216,30 +253,37 @@ static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
} }
/* /*
* Build a VA given VSID, EA and segment size * Build a VPN_SHIFT bit shifted va given VSID, EA and segment size.
*/ */
static inline unsigned long hpt_va(unsigned long ea, unsigned long vsid, static inline unsigned long hpt_vpn(unsigned long ea,
int ssize) unsigned long vsid, int ssize)
{ {
if (ssize == MMU_SEGSIZE_256M) unsigned long mask;
return (vsid << 28) | (ea & 0xfffffffUL); int s_shift = segment_shift(ssize);
return (vsid << 40) | (ea & 0xffffffffffUL);
mask = (1ul << (s_shift - VPN_SHIFT)) - 1;
return (vsid << (s_shift - VPN_SHIFT)) | ((ea >> VPN_SHIFT) & mask);
} }
/* /*
* This hashes a virtual address * This hashes a virtual address
*/ */
static inline unsigned long hpt_hash(unsigned long vpn,
static inline unsigned long hpt_hash(unsigned long va, unsigned int shift, unsigned int shift, int ssize)
int ssize)
{ {
int mask;
unsigned long hash, vsid; unsigned long hash, vsid;
/* VPN_SHIFT can be atmost 12 */
if (ssize == MMU_SEGSIZE_256M) { if (ssize == MMU_SEGSIZE_256M) {
hash = (va >> 28) ^ ((va & 0x0fffffffUL) >> shift); mask = (1ul << (SID_SHIFT - VPN_SHIFT)) - 1;
hash = (vpn >> (SID_SHIFT - VPN_SHIFT)) ^
((vpn & mask) >> (shift - VPN_SHIFT));
} else { } else {
vsid = va >> 40; mask = (1ul << (SID_SHIFT_1T - VPN_SHIFT)) - 1;
hash = vsid ^ (vsid << 25) ^ ((va & 0xffffffffffUL) >> shift); vsid = vpn >> (SID_SHIFT_1T - VPN_SHIFT);
hash = vsid ^ (vsid << 25) ^
((vpn & mask) >> (shift - VPN_SHIFT)) ;
} }
return hash & 0x7fffffffffUL; return hash & 0x7fffffffffUL;
} }
......
...@@ -58,14 +58,16 @@ ...@@ -58,14 +58,16 @@
/* Trick: we set __end to va + 64k, which happens works for /* Trick: we set __end to va + 64k, which happens works for
* a 16M page as well as we want only one iteration * a 16M page as well as we want only one iteration
*/ */
#define pte_iterate_hashed_subpages(rpte, psize, va, index, shift) \ #define pte_iterate_hashed_subpages(rpte, psize, vpn, index, shift) \
do { \ do { \
unsigned long __end = va + PAGE_SIZE; \ unsigned long __end = vpn + (1UL << (PAGE_SHIFT - VPN_SHIFT)); \
unsigned __split = (psize == MMU_PAGE_4K || \ unsigned __split = (psize == MMU_PAGE_4K || \
psize == MMU_PAGE_64K_AP); \ psize == MMU_PAGE_64K_AP); \
shift = mmu_psize_defs[psize].shift; \ shift = mmu_psize_defs[psize].shift; \
for (index = 0; va < __end; index++, va += (1L << shift)) { \ for (index = 0; vpn < __end; index++, \
if (!__split || __rpte_sub_valid(rpte, index)) do { \ vpn += (1L << (shift - VPN_SHIFT))) { \
if (!__split || __rpte_sub_valid(rpte, index)) \
do {
#define pte_iterate_hashed_end() } while(0); } } while(0) #define pte_iterate_hashed_end() } while(0); } } while(0)
......
...@@ -95,7 +95,7 @@ struct ppc64_tlb_batch { ...@@ -95,7 +95,7 @@ struct ppc64_tlb_batch {
unsigned long index; unsigned long index;
struct mm_struct *mm; struct mm_struct *mm;
real_pte_t pte[PPC64_TLB_BATCH_NR]; real_pte_t pte[PPC64_TLB_BATCH_NR];
unsigned long vaddr[PPC64_TLB_BATCH_NR]; unsigned long vpn[PPC64_TLB_BATCH_NR];
unsigned int psize; unsigned int psize;
int ssize; int ssize;
}; };
...@@ -127,7 +127,7 @@ static inline void arch_leave_lazy_mmu_mode(void) ...@@ -127,7 +127,7 @@ static inline void arch_leave_lazy_mmu_mode(void)
#define arch_flush_lazy_mmu_mode() do {} while (0) #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(unsigned long vpn, real_pte_t pte, int psize,
int ssize, int local); int ssize, int local);
extern void flush_hash_range(unsigned long number, int local); extern void flush_hash_range(unsigned long number, int local);
......
...@@ -141,7 +141,7 @@ extern char etext[]; ...@@ -141,7 +141,7 @@ extern char etext[];
int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
{ {
pfn_t hpaddr; pfn_t hpaddr;
u64 va; u64 vpn;
u64 vsid; u64 vsid;
struct kvmppc_sid_map *map; struct kvmppc_sid_map *map;
volatile u32 *pteg; volatile u32 *pteg;
...@@ -173,7 +173,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) ...@@ -173,7 +173,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
BUG_ON(!map); BUG_ON(!map);
vsid = map->host_vsid; vsid = map->host_vsid;
va = (vsid << SID_SHIFT) | (eaddr & ~ESID_MASK); vpn = (vsid << (SID_SHIFT - VPN_SHIFT)) | ((eaddr & ~ESID_MASK) >> VPN_SHIFT)
next_pteg: next_pteg:
if (rr == 16) { if (rr == 16) {
...@@ -244,11 +244,11 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) ...@@ -244,11 +244,11 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n", dprintk_mmu("KVM: %c%c Map 0x%llx: [%lx] 0x%llx (0x%llx) -> %lx\n",
orig_pte->may_write ? 'w' : '-', orig_pte->may_write ? 'w' : '-',
orig_pte->may_execute ? 'x' : '-', orig_pte->may_execute ? 'x' : '-',
orig_pte->eaddr, (ulong)pteg, va, orig_pte->eaddr, (ulong)pteg, vpn,
orig_pte->vpage, hpaddr); orig_pte->vpage, hpaddr);
pte->slot = (ulong)&pteg[rr]; pte->slot = (ulong)&pteg[rr];
pte->host_va = va; pte->host_vpn = vpn;
pte->pte = *orig_pte; pte->pte = *orig_pte;
pte->pfn = hpaddr >> PAGE_SHIFT; pte->pfn = hpaddr >> PAGE_SHIFT;
......
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte) void kvmppc_mmu_invalidate_pte(struct kvm_vcpu *vcpu, struct hpte_cache *pte)
{ {
ppc_md.hpte_invalidate(pte->slot, pte->host_va, ppc_md.hpte_invalidate(pte->slot, pte->host_vpn,
MMU_PAGE_4K, MMU_SEGSIZE_256M, MMU_PAGE_4K, MMU_SEGSIZE_256M,
false); false);
} }
...@@ -80,8 +80,9 @@ static struct kvmppc_sid_map *find_sid_vsid(struct kvm_vcpu *vcpu, u64 gvsid) ...@@ -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) int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
{ {
unsigned long vpn;
pfn_t hpaddr; pfn_t hpaddr;
ulong hash, hpteg, va; ulong hash, hpteg;
u64 vsid; u64 vsid;
int ret; int ret;
int rflags = 0x192; int rflags = 0x192;
...@@ -117,7 +118,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) ...@@ -117,7 +118,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
} }
vsid = map->host_vsid; vsid = map->host_vsid;
va = hpt_va(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M); vpn = hpt_vpn(orig_pte->eaddr, vsid, MMU_SEGSIZE_256M);
if (!orig_pte->may_write) if (!orig_pte->may_write)
rflags |= HPTE_R_PP; rflags |= HPTE_R_PP;
...@@ -129,7 +130,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) ...@@ -129,7 +130,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
else else
kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT); kvmppc_mmu_flush_icache(hpaddr >> PAGE_SHIFT);
hash = hpt_hash(va, PTE_SIZE, MMU_SEGSIZE_256M); hash = hpt_hash(vpn, PTE_SIZE, MMU_SEGSIZE_256M);
map_again: map_again:
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
...@@ -141,7 +142,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) ...@@ -141,7 +142,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
goto out; goto out;
} }
ret = ppc_md.hpte_insert(hpteg, va, hpaddr, rflags, vflags, MMU_PAGE_4K, MMU_SEGSIZE_256M); ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
MMU_PAGE_4K, MMU_SEGSIZE_256M);
if (ret < 0) { if (ret < 0) {
/* If we couldn't map a primary PTE, try a secondary */ /* If we couldn't map a primary PTE, try a secondary */
...@@ -152,7 +154,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) ...@@ -152,7 +154,8 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
} else { } else {
struct hpte_cache *pte = kvmppc_mmu_hpte_cache_next(vcpu); struct hpte_cache *pte = kvmppc_mmu_hpte_cache_next(vcpu);
trace_kvm_book3s_64_mmu_map(rflags, hpteg, va, hpaddr, orig_pte); trace_kvm_book3s_64_mmu_map(rflags, hpteg,
vpn, hpaddr, orig_pte);
/* The ppc_md code may give us a secondary entry even though we /* The ppc_md code may give us a secondary entry even though we
asked for a primary. Fix up. */ asked for a primary. Fix up. */
...@@ -162,7 +165,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte) ...@@ -162,7 +165,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
} }
pte->slot = hpteg + (ret & 7); pte->slot = hpteg + (ret & 7);
pte->host_va = va; pte->host_vpn = vpn;
pte->pte = *orig_pte; pte->pte = *orig_pte;
pte->pfn = hpaddr >> PAGE_SHIFT; pte->pfn = hpaddr >> PAGE_SHIFT;
......
...@@ -189,7 +189,7 @@ TRACE_EVENT(kvm_book3s_mmu_map, ...@@ -189,7 +189,7 @@ TRACE_EVENT(kvm_book3s_mmu_map,
TP_ARGS(pte), TP_ARGS(pte),
TP_STRUCT__entry( TP_STRUCT__entry(
__field( u64, host_va ) __field( u64, host_vpn )
__field( u64, pfn ) __field( u64, pfn )
__field( ulong, eaddr ) __field( ulong, eaddr )
__field( u64, vpage ) __field( u64, vpage )
...@@ -198,7 +198,7 @@ TRACE_EVENT(kvm_book3s_mmu_map, ...@@ -198,7 +198,7 @@ TRACE_EVENT(kvm_book3s_mmu_map,
), ),
TP_fast_assign( TP_fast_assign(
__entry->host_va = pte->host_va; __entry->host_vpn = pte->host_vpn;
__entry->pfn = pte->pfn; __entry->pfn = pte->pfn;
__entry->eaddr = pte->pte.eaddr; __entry->eaddr = pte->pte.eaddr;
__entry->vpage = pte->pte.vpage; __entry->vpage = pte->pte.vpage;
...@@ -208,8 +208,8 @@ TRACE_EVENT(kvm_book3s_mmu_map, ...@@ -208,8 +208,8 @@ TRACE_EVENT(kvm_book3s_mmu_map,
(pte->pte.may_execute ? 0x1 : 0); (pte->pte.may_execute ? 0x1 : 0);
), ),
TP_printk("Map: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", TP_printk("Map: hvpn=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]",
__entry->host_va, __entry->pfn, __entry->eaddr, __entry->host_vpn, __entry->pfn, __entry->eaddr,
__entry->vpage, __entry->raddr, __entry->flags) __entry->vpage, __entry->raddr, __entry->flags)
); );
...@@ -218,7 +218,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate, ...@@ -218,7 +218,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate,
TP_ARGS(pte), TP_ARGS(pte),
TP_STRUCT__entry( TP_STRUCT__entry(
__field( u64, host_va ) __field( u64, host_vpn )
__field( u64, pfn ) __field( u64, pfn )
__field( ulong, eaddr ) __field( ulong, eaddr )
__field( u64, vpage ) __field( u64, vpage )
...@@ -227,7 +227,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate, ...@@ -227,7 +227,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate,
), ),
TP_fast_assign( TP_fast_assign(
__entry->host_va = pte->host_va; __entry->host_vpn = pte->host_vpn;
__entry->pfn = pte->pfn; __entry->pfn = pte->pfn;
__entry->eaddr = pte->pte.eaddr; __entry->eaddr = pte->pte.eaddr;
__entry->vpage = pte->pte.vpage; __entry->vpage = pte->pte.vpage;
...@@ -238,7 +238,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate, ...@@ -238,7 +238,7 @@ TRACE_EVENT(kvm_book3s_mmu_invalidate,
), ),
TP_printk("Flush: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]", TP_printk("Flush: hva=%llx pfn=%llx ea=%lx vp=%llx ra=%lx [%x]",
__entry->host_va, __entry->pfn, __entry->eaddr, __entry->host_vpn, __entry->pfn, __entry->eaddr,
__entry->vpage, __entry->raddr, __entry->flags) __entry->vpage, __entry->raddr, __entry->flags)
); );
......
...@@ -63,7 +63,7 @@ _GLOBAL(__hash_page_4K) ...@@ -63,7 +63,7 @@ _GLOBAL(__hash_page_4K)
/* Save non-volatile registers. /* Save non-volatile registers.
* r31 will hold "old PTE" * r31 will hold "old PTE"
* r30 is "new PTE" * r30 is "new PTE"
* r29 is "va" * r29 is vpn
* r28 is a hash value * r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?) * r27 is hashtab mask (maybe dynamic patched instead ?)
*/ */
...@@ -111,10 +111,10 @@ BEGIN_FTR_SECTION ...@@ -111,10 +111,10 @@ BEGIN_FTR_SECTION
cmpdi r9,0 /* check segment size */ cmpdi r9,0 /* check segment size */
bne 3f bne 3f
END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
/* Calc va and put it in r29 */ /* Calc vpn and put it in r29 */
rldicr r29,r5,28,63-28 sldi r29,r5,SID_SHIFT - VPN_SHIFT
rldicl r3,r3,0,36 rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r3,r29 or r29,r28,r29
/* Calculate hash value for primary slot and store it in r28 */ /* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
...@@ -122,14 +122,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -122,14 +122,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
xor r28,r5,r0 xor r28,r5,r0
b 4f b 4f
3: /* Calc VA and hash in r29 and r28 for 1T segment */ 3: /* Calc vpn and put it in r29 */
sldi r29,r5,40 /* vsid << 40 */ sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
clrldi r3,r3,24 /* ea & 0xffffffffff */ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
or r29,r28,r29
/*
* calculate hash value for primary slot and
* store it in r28 for 1T segment
*/
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */ clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
xor r28,r28,r5 xor r28,r28,r5
or r29,r3,r29 /* VA */
xor r28,r28,r0 /* hash */ xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */ /* Convert linux PTE bits into HW equivalents */
...@@ -185,7 +190,7 @@ htab_insert_pte: ...@@ -185,7 +190,7 @@ htab_insert_pte:
/* Call ppc_md.hpte_insert */ /* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
mr r4,r29 /* Retrieve va */ mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */ li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */ li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */ ld r9,STK_PARAM(R9)(r1) /* segment size */
...@@ -208,7 +213,7 @@ _GLOBAL(htab_call_hpte_insert1) ...@@ -208,7 +213,7 @@ _GLOBAL(htab_call_hpte_insert1)
/* Call ppc_md.hpte_insert */ /* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
mr r4,r29 /* Retrieve va */ mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */ li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */ ld r9,STK_PARAM(R9)(r1) /* segment size */
...@@ -278,7 +283,7 @@ htab_modify_pte: ...@@ -278,7 +283,7 @@ htab_modify_pte:
add r3,r0,r3 /* add slot idx */ add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */ /* Call ppc_md.hpte_updatepp */
mr r5,r29 /* va */ mr r5,r29 /* vpn */
li r6,MMU_PAGE_4K /* page size */ li r6,MMU_PAGE_4K /* page size */
ld r7,STK_PARAM(R9)(r1) /* segment size */ ld r7,STK_PARAM(R9)(r1) /* segment size */
ld r8,STK_PARAM(R8)(r1) /* get "local" param */ ld r8,STK_PARAM(R8)(r1) /* get "local" param */
...@@ -339,7 +344,7 @@ _GLOBAL(__hash_page_4K) ...@@ -339,7 +344,7 @@ _GLOBAL(__hash_page_4K)
/* Save non-volatile registers. /* Save non-volatile registers.
* r31 will hold "old PTE" * r31 will hold "old PTE"
* r30 is "new PTE" * r30 is "new PTE"
* r29 is "va" * r29 is vpn
* r28 is a hash value * r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?) * r27 is hashtab mask (maybe dynamic patched instead ?)
* r26 is the hidx mask * r26 is the hidx mask
...@@ -394,10 +399,14 @@ BEGIN_FTR_SECTION ...@@ -394,10 +399,14 @@ BEGIN_FTR_SECTION
cmpdi r9,0 /* check segment size */ cmpdi r9,0 /* check segment size */
bne 3f bne 3f
END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
/* Calc va and put it in r29 */ /* Calc vpn and put it in r29 */
rldicr r29,r5,28,63-28 /* r29 = (vsid << 28) */ sldi r29,r5,SID_SHIFT - VPN_SHIFT
rldicl r3,r3,0,36 /* r3 = (ea & 0x0fffffff) */ /*
or r29,r3,r29 /* r29 = va */ * clrldi r3,r3,64 - SID_SHIFT --> ea & 0xfffffff
* srdi r28,r3,VPN_SHIFT
*/
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r28,r29
/* Calculate hash value for primary slot and store it in r28 */ /* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
...@@ -405,14 +414,23 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -405,14 +414,23 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
xor r28,r5,r0 xor r28,r5,r0
b 4f b 4f
3: /* Calc VA and hash in r29 and r28 for 1T segment */ 3: /* Calc vpn and put it in r29 */
sldi r29,r5,40 /* vsid << 40 */ sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
clrldi r3,r3,24 /* ea & 0xffffffffff */ /*
* clrldi r3,r3,64 - SID_SHIFT_1T --> ea & 0xffffffffff
* srdi r28,r3,VPN_SHIFT
*/
rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
or r29,r28,r29
/*
* Calculate hash value for primary slot and
* store it in r28 for 1T segment
*/
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */ clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */ rldicl r0,r3,64-12,36 /* (ea >> 12) & 0xfffffff */
xor r28,r28,r5 xor r28,r28,r5
or r29,r3,r29 /* VA */
xor r28,r28,r0 /* hash */ xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */ /* Convert linux PTE bits into HW equivalents */
...@@ -488,7 +506,7 @@ htab_special_pfn: ...@@ -488,7 +506,7 @@ htab_special_pfn:
/* Call ppc_md.hpte_insert */ /* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
mr r4,r29 /* Retrieve va */ mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */ li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */ li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */ ld r9,STK_PARAM(R9)(r1) /* segment size */
...@@ -515,7 +533,7 @@ _GLOBAL(htab_call_hpte_insert1) ...@@ -515,7 +533,7 @@ _GLOBAL(htab_call_hpte_insert1)
/* Call ppc_md.hpte_insert */ /* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
mr r4,r29 /* Retrieve va */ mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */ li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */ ld r9,STK_PARAM(R9)(r1) /* segment size */
...@@ -547,7 +565,7 @@ _GLOBAL(htab_call_hpte_remove) ...@@ -547,7 +565,7 @@ _GLOBAL(htab_call_hpte_remove)
* useless now that the segment has been switched to 4k pages. * useless now that the segment has been switched to 4k pages.
*/ */
htab_inval_old_hpte: htab_inval_old_hpte:
mr r3,r29 /* virtual addr */ mr r3,r29 /* vpn */
mr r4,r31 /* PTE.pte */ mr r4,r31 /* PTE.pte */
li r5,0 /* PTE.hidx */ li r5,0 /* PTE.hidx */
li r6,MMU_PAGE_64K /* psize */ li r6,MMU_PAGE_64K /* psize */
...@@ -620,7 +638,7 @@ htab_modify_pte: ...@@ -620,7 +638,7 @@ htab_modify_pte:
add r3,r0,r3 /* add slot idx */ add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */ /* Call ppc_md.hpte_updatepp */
mr r5,r29 /* va */ mr r5,r29 /* vpn */
li r6,MMU_PAGE_4K /* page size */ li r6,MMU_PAGE_4K /* page size */
ld r7,STK_PARAM(R9)(r1) /* segment size */ ld r7,STK_PARAM(R9)(r1) /* segment size */
ld r8,STK_PARAM(R8)(r1) /* get "local" param */ ld r8,STK_PARAM(R8)(r1) /* get "local" param */
...@@ -676,7 +694,7 @@ _GLOBAL(__hash_page_64K) ...@@ -676,7 +694,7 @@ _GLOBAL(__hash_page_64K)
/* Save non-volatile registers. /* Save non-volatile registers.
* r31 will hold "old PTE" * r31 will hold "old PTE"
* r30 is "new PTE" * r30 is "new PTE"
* r29 is "va" * r29 is vpn
* r28 is a hash value * r28 is a hash value
* r27 is hashtab mask (maybe dynamic patched instead ?) * r27 is hashtab mask (maybe dynamic patched instead ?)
*/ */
...@@ -729,10 +747,10 @@ BEGIN_FTR_SECTION ...@@ -729,10 +747,10 @@ BEGIN_FTR_SECTION
cmpdi r9,0 /* check segment size */ cmpdi r9,0 /* check segment size */
bne 3f bne 3f
END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
/* Calc va and put it in r29 */ /* Calc vpn and put it in r29 */
rldicr r29,r5,28,63-28 sldi r29,r5,SID_SHIFT - VPN_SHIFT
rldicl r3,r3,0,36 rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT - VPN_SHIFT)
or r29,r3,r29 or r29,r28,r29
/* Calculate hash value for primary slot and store it in r28 */ /* Calculate hash value for primary slot and store it in r28 */
rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */ rldicl r5,r5,0,25 /* vsid & 0x0000007fffffffff */
...@@ -740,14 +758,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT) ...@@ -740,14 +758,19 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_1T_SEGMENT)
xor r28,r5,r0 xor r28,r5,r0
b 4f b 4f
3: /* Calc VA and hash in r29 and r28 for 1T segment */ 3: /* Calc vpn and put it in r29 */
sldi r29,r5,40 /* vsid << 40 */ sldi r29,r5,SID_SHIFT_1T - VPN_SHIFT
clrldi r3,r3,24 /* ea & 0xffffffffff */ rldicl r28,r3,64 - VPN_SHIFT,64 - (SID_SHIFT_1T - VPN_SHIFT)
or r29,r28,r29
/*
* calculate hash value for primary slot and
* store it in r28 for 1T segment
*/
rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */ rldic r28,r5,25,25 /* (vsid << 25) & 0x7fffffffff */
clrldi r5,r5,40 /* vsid & 0xffffff */ clrldi r5,r5,40 /* vsid & 0xffffff */
rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */ rldicl r0,r3,64-16,40 /* (ea >> 16) & 0xffffff */
xor r28,r28,r5 xor r28,r28,r5
or r29,r3,r29 /* VA */
xor r28,r28,r0 /* hash */ xor r28,r28,r0 /* hash */
/* Convert linux PTE bits into HW equivalents */ /* Convert linux PTE bits into HW equivalents */
...@@ -806,7 +829,7 @@ ht64_insert_pte: ...@@ -806,7 +829,7 @@ ht64_insert_pte:
/* Call ppc_md.hpte_insert */ /* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
mr r4,r29 /* Retrieve va */ mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */ li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_64K li r8,MMU_PAGE_64K
ld r9,STK_PARAM(R9)(r1) /* segment size */ ld r9,STK_PARAM(R9)(r1) /* segment size */
...@@ -829,7 +852,7 @@ _GLOBAL(ht64_call_hpte_insert1) ...@@ -829,7 +852,7 @@ _GLOBAL(ht64_call_hpte_insert1)
/* Call ppc_md.hpte_insert */ /* Call ppc_md.hpte_insert */
ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */ ld r6,STK_PARAM(R4)(r1) /* Retrieve new pp bits */
mr r4,r29 /* Retrieve va */ mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */ li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_64K li r8,MMU_PAGE_64K
ld r9,STK_PARAM(R9)(r1) /* segment size */ ld r9,STK_PARAM(R9)(r1) /* segment size */
...@@ -899,7 +922,7 @@ ht64_modify_pte: ...@@ -899,7 +922,7 @@ ht64_modify_pte:
add r3,r0,r3 /* add slot idx */ add r3,r0,r3 /* add slot idx */
/* Call ppc_md.hpte_updatepp */ /* Call ppc_md.hpte_updatepp */
mr r5,r29 /* va */ mr r5,r29 /* vpn */
li r6,MMU_PAGE_64K li r6,MMU_PAGE_64K
ld r7,STK_PARAM(R9)(r1) /* segment size */ ld r7,STK_PARAM(R9)(r1) /* segment size */
ld r8,STK_PARAM(R8)(r1) /* get "local" param */ ld r8,STK_PARAM(R8)(r1) /* get "local" param */
......
This diff is collapsed.
...@@ -191,18 +191,18 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, ...@@ -191,18 +191,18 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
vaddr += step, paddr += step) { vaddr += step, paddr += step) {
unsigned long hash, hpteg; unsigned long hash, hpteg;
unsigned long vsid = get_kernel_vsid(vaddr, ssize); unsigned long vsid = get_kernel_vsid(vaddr, ssize);
unsigned long va = hpt_va(vaddr, vsid, ssize); unsigned long vpn = hpt_vpn(vaddr, vsid, ssize);
unsigned long tprot = prot; unsigned long tprot = prot;
/* Make kernel text executable */ /* Make kernel text executable */
if (overlaps_kernel_text(vaddr, vaddr + step)) if (overlaps_kernel_text(vaddr, vaddr + step))
tprot &= ~HPTE_R_N; tprot &= ~HPTE_R_N;
hash = hpt_hash(va, shift, ssize); hash = hpt_hash(vpn, shift, ssize);
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
BUG_ON(!ppc_md.hpte_insert); BUG_ON(!ppc_md.hpte_insert);
ret = ppc_md.hpte_insert(hpteg, va, paddr, tprot, ret = ppc_md.hpte_insert(hpteg, vpn, paddr, tprot,
HPTE_V_BOLTED, psize, ssize); HPTE_V_BOLTED, psize, ssize);
if (ret < 0) if (ret < 0)
...@@ -1152,21 +1152,21 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, ...@@ -1152,21 +1152,21 @@ void hash_preload(struct mm_struct *mm, unsigned long ea,
/* WARNING: This is called from hash_low_64.S, if you change this prototype, /* WARNING: This is called from hash_low_64.S, if you change this prototype,
* do not forget to update the assembly call site ! * 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(unsigned long vpn, real_pte_t pte, int psize, int ssize,
int local) int local)
{ {
unsigned long hash, index, shift, hidx, slot; unsigned long hash, index, shift, hidx, slot;
DBG_LOW("flush_hash_page(va=%016lx)\n", va); DBG_LOW("flush_hash_page(vpn=%016lx)\n", vpn);
pte_iterate_hashed_subpages(pte, psize, va, index, shift) { pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
hash = hpt_hash(va, shift, ssize); hash = hpt_hash(vpn, shift, ssize);
hidx = __rpte_to_hidx(pte, index); hidx = __rpte_to_hidx(pte, index);
if (hidx & _PTEIDX_SECONDARY) if (hidx & _PTEIDX_SECONDARY)
hash = ~hash; hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX; slot += hidx & _PTEIDX_GROUP_IX;
DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx); DBG_LOW(" sub %ld: hash=%lx, hidx=%lx\n", index, slot, hidx);
ppc_md.hpte_invalidate(slot, va, psize, ssize, local); ppc_md.hpte_invalidate(slot, vpn, psize, ssize, local);
} pte_iterate_hashed_end(); } pte_iterate_hashed_end();
} }
...@@ -1180,7 +1180,7 @@ void flush_hash_range(unsigned long number, int local) ...@@ -1180,7 +1180,7 @@ void flush_hash_range(unsigned long number, int local)
&__get_cpu_var(ppc64_tlb_batch); &__get_cpu_var(ppc64_tlb_batch);
for (i = 0; i < number; i++) for (i = 0; i < number; i++)
flush_hash_page(batch->vaddr[i], batch->pte[i], flush_hash_page(batch->vpn[i], batch->pte[i],
batch->psize, batch->ssize, local); batch->psize, batch->ssize, local);
} }
} }
...@@ -1207,14 +1207,14 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi) ...@@ -1207,14 +1207,14 @@ static void kernel_map_linear_page(unsigned long vaddr, unsigned long lmi)
{ {
unsigned long hash, hpteg; unsigned long hash, hpteg;
unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize); unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize);
unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL); unsigned long mode = htab_convert_pte_flags(PAGE_KERNEL);
int ret; int ret;
hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize); hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);
ret = ppc_md.hpte_insert(hpteg, va, __pa(vaddr), ret = ppc_md.hpte_insert(hpteg, vpn, __pa(vaddr),
mode, HPTE_V_BOLTED, mode, HPTE_V_BOLTED,
mmu_linear_psize, mmu_kernel_ssize); mmu_linear_psize, mmu_kernel_ssize);
BUG_ON (ret < 0); BUG_ON (ret < 0);
...@@ -1228,9 +1228,9 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) ...@@ -1228,9 +1228,9 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
{ {
unsigned long hash, hidx, slot; unsigned long hash, hidx, slot;
unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize); unsigned long vsid = get_kernel_vsid(vaddr, mmu_kernel_ssize);
unsigned long va = hpt_va(vaddr, vsid, mmu_kernel_ssize); unsigned long vpn = hpt_vpn(vaddr, vsid, mmu_kernel_ssize);
hash = hpt_hash(va, PAGE_SHIFT, mmu_kernel_ssize); hash = hpt_hash(vpn, PAGE_SHIFT, mmu_kernel_ssize);
spin_lock(&linear_map_hash_lock); spin_lock(&linear_map_hash_lock);
BUG_ON(!(linear_map_hash_slots[lmi] & 0x80)); BUG_ON(!(linear_map_hash_slots[lmi] & 0x80));
hidx = linear_map_hash_slots[lmi] & 0x7f; hidx = linear_map_hash_slots[lmi] & 0x7f;
...@@ -1240,7 +1240,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi) ...@@ -1240,7 +1240,7 @@ static void kernel_unmap_linear_page(unsigned long vaddr, unsigned long lmi)
hash = ~hash; hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX; slot += hidx & _PTEIDX_GROUP_IX;
ppc_md.hpte_invalidate(slot, va, mmu_linear_psize, mmu_kernel_ssize, 0); ppc_md.hpte_invalidate(slot, vpn, mmu_linear_psize, mmu_kernel_ssize, 0);
} }
void kernel_map_pages(struct page *page, int numpages, int enable) void kernel_map_pages(struct page *page, int numpages, int enable)
......
...@@ -18,14 +18,15 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, ...@@ -18,14 +18,15 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
pte_t *ptep, unsigned long trap, int local, int ssize, pte_t *ptep, unsigned long trap, int local, int ssize,
unsigned int shift, unsigned int mmu_psize) unsigned int shift, unsigned int mmu_psize)
{ {
unsigned long vpn;
unsigned long old_pte, new_pte; unsigned long old_pte, new_pte;
unsigned long va, rflags, pa, sz; unsigned long rflags, pa, sz;
long slot; long slot;
BUG_ON(shift != mmu_psize_defs[mmu_psize].shift); BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
/* Search the Linux page table for a match with va */ /* Search the Linux page table for a match with va */
va = hpt_va(ea, vsid, ssize); vpn = hpt_vpn(ea, vsid, ssize);
/* At this point, we have a pte (old_pte) which can be used to build /* At this point, we have a pte (old_pte) which can be used to build
* or update an HPTE. There are 2 cases: * or update an HPTE. There are 2 cases:
...@@ -69,19 +70,19 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, ...@@ -69,19 +70,19 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
/* There MIGHT be an HPTE for this pte */ /* There MIGHT be an HPTE for this pte */
unsigned long hash, slot; unsigned long hash, slot;
hash = hpt_hash(va, shift, ssize); hash = hpt_hash(vpn, shift, ssize);
if (old_pte & _PAGE_F_SECOND) if (old_pte & _PAGE_F_SECOND)
hash = ~hash; hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += (old_pte & _PAGE_F_GIX) >> 12; slot += (old_pte & _PAGE_F_GIX) >> 12;
if (ppc_md.hpte_updatepp(slot, rflags, va, mmu_psize, if (ppc_md.hpte_updatepp(slot, rflags, vpn, mmu_psize,
ssize, local) == -1) ssize, local) == -1)
old_pte &= ~_PAGE_HPTEFLAGS; old_pte &= ~_PAGE_HPTEFLAGS;
} }
if (likely(!(old_pte & _PAGE_HASHPTE))) { if (likely(!(old_pte & _PAGE_HASHPTE))) {
unsigned long hash = hpt_hash(va, shift, ssize); unsigned long hash = hpt_hash(vpn, shift, ssize);
unsigned long hpte_group; unsigned long hpte_group;
pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT; pa = pte_pfn(__pte(old_pte)) << PAGE_SHIFT;
...@@ -101,14 +102,14 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, ...@@ -101,14 +102,14 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
_PAGE_COHERENT | _PAGE_GUARDED)); _PAGE_COHERENT | _PAGE_GUARDED));
/* Insert into the hash table, primary slot */ /* Insert into the hash table, primary slot */
slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, 0, slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags, 0,
mmu_psize, ssize); mmu_psize, ssize);
/* Primary is full, try the secondary */ /* Primary is full, try the secondary */
if (unlikely(slot == -1)) { if (unlikely(slot == -1)) {
hpte_group = ((~hash & htab_hash_mask) * hpte_group = ((~hash & htab_hash_mask) *
HPTES_PER_GROUP) & ~0x7UL; HPTES_PER_GROUP) & ~0x7UL;
slot = ppc_md.hpte_insert(hpte_group, va, pa, rflags, slot = ppc_md.hpte_insert(hpte_group, vpn, pa, rflags,
HPTE_V_SECONDARY, HPTE_V_SECONDARY,
mmu_psize, ssize); mmu_psize, ssize);
if (slot == -1) { if (slot == -1) {
......
...@@ -42,8 +42,9 @@ DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch); ...@@ -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, void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, unsigned long pte, int huge) pte_t *ptep, unsigned long pte, int huge)
{ {
unsigned long vpn;
struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch); struct ppc64_tlb_batch *batch = &get_cpu_var(ppc64_tlb_batch);
unsigned long vsid, vaddr; unsigned long vsid;
unsigned int psize; unsigned int psize;
int ssize; int ssize;
real_pte_t rpte; real_pte_t rpte;
...@@ -86,7 +87,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, ...@@ -86,7 +87,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
vsid = get_kernel_vsid(addr, mmu_kernel_ssize); vsid = get_kernel_vsid(addr, mmu_kernel_ssize);
ssize = mmu_kernel_ssize; ssize = mmu_kernel_ssize;
} }
vaddr = hpt_va(addr, vsid, ssize); vpn = hpt_vpn(addr, vsid, ssize);
rpte = __real_pte(__pte(pte), ptep); rpte = __real_pte(__pte(pte), ptep);
/* /*
...@@ -96,7 +97,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, ...@@ -96,7 +97,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
* and decide to use local invalidates instead... * and decide to use local invalidates instead...
*/ */
if (!batch->active) { if (!batch->active) {
flush_hash_page(vaddr, rpte, psize, ssize, 0); flush_hash_page(vpn, rpte, psize, ssize, 0);
put_cpu_var(ppc64_tlb_batch); put_cpu_var(ppc64_tlb_batch);
return; return;
} }
...@@ -122,7 +123,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr, ...@@ -122,7 +123,7 @@ void hpte_need_flush(struct mm_struct *mm, unsigned long addr,
batch->ssize = ssize; batch->ssize = ssize;
} }
batch->pte[i] = rpte; batch->pte[i] = rpte;
batch->vaddr[i] = vaddr; batch->vpn[i] = vpn;
batch->index = ++i; batch->index = ++i;
if (i >= PPC64_TLB_BATCH_NR) if (i >= PPC64_TLB_BATCH_NR)
__flush_tlb_pending(batch); __flush_tlb_pending(batch);
...@@ -146,7 +147,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch) ...@@ -146,7 +147,7 @@ void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
if (cpumask_equal(mm_cpumask(batch->mm), tmp)) if (cpumask_equal(mm_cpumask(batch->mm), tmp))
local = 1; local = 1;
if (i == 1) if (i == 1)
flush_hash_page(batch->vaddr[0], batch->pte[0], flush_hash_page(batch->vpn[0], batch->pte[0],
batch->psize, batch->ssize, local); batch->psize, batch->ssize, local);
else else
flush_hash_range(i, local); flush_hash_range(i, local);
......
...@@ -88,7 +88,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group) ...@@ -88,7 +88,7 @@ static inline unsigned int beat_read_mask(unsigned hpte_group)
} }
static long beat_lpar_hpte_insert(unsigned long hpte_group, static long beat_lpar_hpte_insert(unsigned long hpte_group,
unsigned long va, unsigned long pa, unsigned long vpn, unsigned long pa,
unsigned long rflags, unsigned long vflags, unsigned long rflags, unsigned long vflags,
int psize, int ssize) int psize, int ssize)
{ {
...@@ -103,7 +103,7 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group, ...@@ -103,7 +103,7 @@ static long beat_lpar_hpte_insert(unsigned long hpte_group,
"rflags=%lx, vflags=%lx, psize=%d)\n", "rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize); hpte_group, va, pa, rflags, vflags, psize);
hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) | hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) |
vflags | HPTE_V_VALID; vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags; hpte_r = hpte_encode_r(pa, psize) | rflags;
...@@ -184,14 +184,14 @@ static void beat_lpar_hptab_clear(void) ...@@ -184,14 +184,14 @@ static void beat_lpar_hptab_clear(void)
*/ */
static long beat_lpar_hpte_updatepp(unsigned long slot, static long beat_lpar_hpte_updatepp(unsigned long slot,
unsigned long newpp, unsigned long newpp,
unsigned long va, unsigned long vpn,
int psize, int ssize, int local) int psize, int ssize, int local)
{ {
unsigned long lpar_rc; unsigned long lpar_rc;
u64 dummy0, dummy1; u64 dummy0, dummy1;
unsigned long want_v; unsigned long want_v;
want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
DBG_LOW(" update: " DBG_LOW(" update: "
"avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ", "avpnv=%016lx, slot=%016lx, psize: %d, newpp %016lx ... ",
...@@ -220,15 +220,15 @@ static long beat_lpar_hpte_updatepp(unsigned long slot, ...@@ -220,15 +220,15 @@ static long beat_lpar_hpte_updatepp(unsigned long slot,
return 0; return 0;
} }
static long beat_lpar_hpte_find(unsigned long va, int psize) static long beat_lpar_hpte_find(unsigned long vpn, int psize)
{ {
unsigned long hash; unsigned long hash;
unsigned long i, j; unsigned long i, j;
long slot; long slot;
unsigned long want_v, hpte_v; unsigned long want_v, hpte_v;
hash = hpt_hash(va, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M); hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, MMU_SEGSIZE_256M);
want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
for (j = 0; j < 2; j++) { for (j = 0; j < 2; j++) {
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
...@@ -255,14 +255,15 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, ...@@ -255,14 +255,15 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
unsigned long ea, unsigned long ea,
int psize, int ssize) int psize, int ssize)
{ {
unsigned long lpar_rc, slot, vsid, va; unsigned long vpn;
unsigned long lpar_rc, slot, vsid;
u64 dummy0, dummy1; u64 dummy0, dummy1;
vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M); vsid = get_kernel_vsid(ea, MMU_SEGSIZE_256M);
va = hpt_va(ea, vsid, MMU_SEGSIZE_256M); vpn = hpt_vpn(ea, vsid, MMU_SEGSIZE_256M);
raw_spin_lock(&beat_htab_lock); raw_spin_lock(&beat_htab_lock);
slot = beat_lpar_hpte_find(va, psize); slot = beat_lpar_hpte_find(vpn, psize);
BUG_ON(slot == -1); BUG_ON(slot == -1);
lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7, lpar_rc = beat_write_htab_entry(0, slot, 0, newpp, 0, 7,
...@@ -272,7 +273,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp, ...@@ -272,7 +273,7 @@ static void beat_lpar_hpte_updateboltedpp(unsigned long newpp,
BUG_ON(lpar_rc != 0); 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, unsigned long vpn,
int psize, int ssize, int local) int psize, int ssize, int local)
{ {
unsigned long want_v; unsigned long want_v;
...@@ -282,7 +283,7 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va, ...@@ -282,7 +283,7 @@ static void beat_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n",
slot, va, psize, local); slot, va, psize, local);
want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
raw_spin_lock_irqsave(&beat_htab_lock, flags); raw_spin_lock_irqsave(&beat_htab_lock, flags);
dummy1 = beat_lpar_hpte_getword0(slot); dummy1 = beat_lpar_hpte_getword0(slot);
...@@ -311,7 +312,7 @@ void __init hpte_init_beat(void) ...@@ -311,7 +312,7 @@ void __init hpte_init_beat(void)
} }
static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
unsigned long va, unsigned long pa, unsigned long vpn, unsigned long pa,
unsigned long rflags, unsigned long vflags, unsigned long rflags, unsigned long vflags,
int psize, int ssize) int psize, int ssize)
{ {
...@@ -322,11 +323,11 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, ...@@ -322,11 +323,11 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
return -1; return -1;
if (!(vflags & HPTE_V_BOLTED)) if (!(vflags & HPTE_V_BOLTED))
DBG_LOW("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " DBG_LOW("hpte_insert(group=%lx, vpn=%016lx, pa=%016lx, "
"rflags=%lx, vflags=%lx, psize=%d)\n", "rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize); hpte_group, vpn, pa, rflags, vflags, psize);
hpte_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M) | hpte_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M) |
vflags | HPTE_V_VALID; vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags; hpte_r = hpte_encode_r(pa, psize) | rflags;
...@@ -364,14 +365,14 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group, ...@@ -364,14 +365,14 @@ static long beat_lpar_hpte_insert_v3(unsigned long hpte_group,
*/ */
static long beat_lpar_hpte_updatepp_v3(unsigned long slot, static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
unsigned long newpp, unsigned long newpp,
unsigned long va, unsigned long vpn,
int psize, int ssize, int local) int psize, int ssize, int local)
{ {
unsigned long lpar_rc; unsigned long lpar_rc;
unsigned long want_v; unsigned long want_v;
unsigned long pss; unsigned long pss;
want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
DBG_LOW(" update: " DBG_LOW(" update: "
...@@ -392,16 +393,16 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot, ...@@ -392,16 +393,16 @@ static long beat_lpar_hpte_updatepp_v3(unsigned long slot,
return 0; 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, unsigned long vpn,
int psize, int ssize, int local) int psize, int ssize, int local)
{ {
unsigned long want_v; unsigned long want_v;
unsigned long lpar_rc; unsigned long lpar_rc;
unsigned long pss; unsigned long pss;
DBG_LOW(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", DBG_LOW(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n",
slot, va, psize, local); slot, vpn, psize, local);
want_v = hpte_encode_v(va, psize, MMU_SEGSIZE_256M); want_v = hpte_encode_v(vpn, psize, MMU_SEGSIZE_256M);
pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc; pss = (psize == MMU_PAGE_4K) ? -1UL : mmu_psize_defs[psize].penc;
lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss); lpar_rc = beat_invalidate_htab_entry3(0, slot, want_v, pss);
......
...@@ -43,7 +43,7 @@ enum ps3_lpar_vas_id { ...@@ -43,7 +43,7 @@ enum ps3_lpar_vas_id {
static DEFINE_SPINLOCK(ps3_htab_lock); 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, unsigned long vpn,
unsigned long pa, unsigned long rflags, unsigned long vflags, unsigned long pa, unsigned long rflags, unsigned long vflags,
int psize, int ssize) int psize, int ssize)
{ {
...@@ -61,7 +61,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va, ...@@ -61,7 +61,7 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
*/ */
vflags &= ~HPTE_V_SECONDARY; vflags &= ~HPTE_V_SECONDARY;
hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID; hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags; hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags;
spin_lock_irqsave(&ps3_htab_lock, flags); spin_lock_irqsave(&ps3_htab_lock, flags);
...@@ -75,8 +75,8 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va, ...@@ -75,8 +75,8 @@ static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
if (result) { if (result) {
/* all entries bolted !*/ /* all entries bolted !*/
pr_info("%s:result=%d va=%lx pa=%lx ix=%lx v=%llx r=%llx\n", pr_info("%s:result=%d vpn=%lx pa=%lx ix=%lx v=%llx r=%llx\n",
__func__, result, va, pa, hpte_group, hpte_v, hpte_r); __func__, result, vpn, pa, hpte_group, hpte_v, hpte_r);
BUG(); BUG();
} }
...@@ -107,7 +107,7 @@ static long ps3_hpte_remove(unsigned long hpte_group) ...@@ -107,7 +107,7 @@ static long ps3_hpte_remove(unsigned long hpte_group)
} }
static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int psize, int ssize, int local) unsigned long vpn, int psize, int ssize, int local)
{ {
int result; int result;
u64 hpte_v, want_v, hpte_rs; u64 hpte_v, want_v, hpte_rs;
...@@ -115,7 +115,7 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, ...@@ -115,7 +115,7 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long flags; unsigned long flags;
long ret; long ret;
want_v = hpte_encode_v(va, psize, ssize); want_v = hpte_encode_v(vpn, psize, ssize);
spin_lock_irqsave(&ps3_htab_lock, flags); spin_lock_irqsave(&ps3_htab_lock, flags);
...@@ -125,8 +125,8 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp, ...@@ -125,8 +125,8 @@ static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
&hpte_rs); &hpte_rs);
if (result) { if (result) {
pr_info("%s: res=%d read va=%lx slot=%lx psize=%d\n", pr_info("%s: res=%d read vpn=%lx slot=%lx psize=%d\n",
__func__, result, va, slot, psize); __func__, result, vpn, slot, psize);
BUG(); BUG();
} }
...@@ -159,7 +159,7 @@ static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea, ...@@ -159,7 +159,7 @@ static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
panic("ps3_hpte_updateboltedpp() not implemented"); 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, unsigned long vpn,
int psize, int ssize, int local) int psize, int ssize, int local)
{ {
unsigned long flags; unsigned long flags;
...@@ -170,8 +170,8 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va, ...@@ -170,8 +170,8 @@ static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0); result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0);
if (result) { if (result) {
pr_info("%s: res=%d va=%lx slot=%lx psize=%d\n", pr_info("%s: res=%d vpn=%lx slot=%lx psize=%d\n",
__func__, result, va, slot, psize); __func__, result, vpn, slot, psize);
BUG(); BUG();
} }
......
...@@ -107,7 +107,7 @@ void vpa_init(int cpu) ...@@ -107,7 +107,7 @@ void vpa_init(int cpu)
} }
static long pSeries_lpar_hpte_insert(unsigned long hpte_group, static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long va, unsigned long pa, unsigned long vpn, unsigned long pa,
unsigned long rflags, unsigned long vflags, unsigned long rflags, unsigned long vflags,
int psize, int ssize) int psize, int ssize)
{ {
...@@ -117,11 +117,11 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group, ...@@ -117,11 +117,11 @@ static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
unsigned long hpte_v, hpte_r; unsigned long hpte_v, hpte_r;
if (!(vflags & HPTE_V_BOLTED)) if (!(vflags & HPTE_V_BOLTED))
pr_devel("hpte_insert(group=%lx, va=%016lx, pa=%016lx, " pr_devel("hpte_insert(group=%lx, vpn=%016lx, "
"rflags=%lx, vflags=%lx, psize=%d)\n", "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n",
hpte_group, va, pa, rflags, vflags, psize); hpte_group, vpn, pa, rflags, vflags, psize);
hpte_v = hpte_encode_v(va, psize, ssize) | vflags | HPTE_V_VALID; hpte_v = hpte_encode_v(vpn, psize, ssize) | vflags | HPTE_V_VALID;
hpte_r = hpte_encode_r(pa, psize) | rflags; hpte_r = hpte_encode_r(pa, psize) | rflags;
if (!(vflags & HPTE_V_BOLTED)) if (!(vflags & HPTE_V_BOLTED))
...@@ -225,22 +225,6 @@ static void pSeries_lpar_hptab_clear(void) ...@@ -225,22 +225,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(unsigned long va, int psize,
int ssize)
{
unsigned long v;
v = (va >> 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 * 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. * the low 3 bits of flags happen to line up. So no transform is needed.
...@@ -249,14 +233,14 @@ static inline unsigned long hpte_encode_avpn(unsigned long va, int psize, ...@@ -249,14 +233,14 @@ static inline unsigned long hpte_encode_avpn(unsigned long va, int psize,
*/ */
static long pSeries_lpar_hpte_updatepp(unsigned long slot, static long pSeries_lpar_hpte_updatepp(unsigned long slot,
unsigned long newpp, unsigned long newpp,
unsigned long va, unsigned long vpn,
int psize, int ssize, int local) int psize, int ssize, int local)
{ {
unsigned long lpar_rc; unsigned long lpar_rc;
unsigned long flags = (newpp & 7) | H_AVPN; unsigned long flags = (newpp & 7) | H_AVPN;
unsigned long want_v; unsigned long want_v;
want_v = hpte_encode_avpn(va, psize, ssize); want_v = hpte_encode_avpn(vpn, psize, ssize);
pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...", pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
want_v, slot, flags, psize); want_v, slot, flags, psize);
...@@ -294,15 +278,15 @@ static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot) ...@@ -294,15 +278,15 @@ static unsigned long pSeries_lpar_hpte_getword0(unsigned long slot)
return dword0; return dword0;
} }
static long pSeries_lpar_hpte_find(unsigned long va, int psize, int ssize) static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize)
{ {
unsigned long hash; unsigned long hash;
unsigned long i; unsigned long i;
long slot; long slot;
unsigned long want_v, hpte_v; unsigned long want_v, hpte_v;
hash = hpt_hash(va, mmu_psize_defs[psize].shift, ssize); hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
want_v = hpte_encode_avpn(va, psize, ssize); want_v = hpte_encode_avpn(vpn, psize, ssize);
/* Bolted entries are always in the primary group */ /* Bolted entries are always in the primary group */
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
...@@ -322,12 +306,13 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, ...@@ -322,12 +306,13 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
unsigned long ea, unsigned long ea,
int psize, int ssize) int psize, int ssize)
{ {
unsigned long lpar_rc, slot, vsid, va, flags; unsigned long vpn;
unsigned long lpar_rc, slot, vsid, flags;
vsid = get_kernel_vsid(ea, ssize); vsid = get_kernel_vsid(ea, ssize);
va = hpt_va(ea, vsid, ssize); vpn = hpt_vpn(ea, vsid, ssize);
slot = pSeries_lpar_hpte_find(va, psize, ssize); slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
BUG_ON(slot == -1); BUG_ON(slot == -1);
flags = newpp & 7; flags = newpp & 7;
...@@ -336,17 +321,17 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp, ...@@ -336,17 +321,17 @@ static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
BUG_ON(lpar_rc != H_SUCCESS); 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, unsigned long vpn,
int psize, int ssize, int local) int psize, int ssize, int local)
{ {
unsigned long want_v; unsigned long want_v;
unsigned long lpar_rc; unsigned long lpar_rc;
unsigned long dummy1, dummy2; unsigned long dummy1, dummy2;
pr_devel(" inval : slot=%lx, va=%016lx, psize: %d, local: %d\n", pr_devel(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n",
slot, va, psize, local); slot, vpn, psize, local);
want_v = hpte_encode_avpn(va, psize, ssize); want_v = hpte_encode_avpn(vpn, psize, ssize);
lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2); lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2);
if (lpar_rc == H_NOT_FOUND) if (lpar_rc == H_NOT_FOUND)
return; return;
...@@ -357,15 +342,16 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, ...@@ -357,15 +342,16 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
static void pSeries_lpar_hpte_removebolted(unsigned long ea, static void pSeries_lpar_hpte_removebolted(unsigned long ea,
int psize, int ssize) int psize, int ssize)
{ {
unsigned long slot, vsid, va; unsigned long vpn;
unsigned long slot, vsid;
vsid = get_kernel_vsid(ea, ssize); vsid = get_kernel_vsid(ea, ssize);
va = hpt_va(ea, vsid, ssize); vpn = hpt_vpn(ea, vsid, ssize);
slot = pSeries_lpar_hpte_find(va, psize, ssize); slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
BUG_ON(slot == -1); BUG_ON(slot == -1);
pSeries_lpar_hpte_invalidate(slot, va, psize, ssize, 0); pSeries_lpar_hpte_invalidate(slot, vpn, psize, ssize, 0);
} }
/* Flag bits for H_BULK_REMOVE */ /* Flag bits for H_BULK_REMOVE */
...@@ -381,12 +367,12 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea, ...@@ -381,12 +367,12 @@ static void pSeries_lpar_hpte_removebolted(unsigned long ea,
*/ */
static void pSeries_lpar_flush_hash_range(unsigned long number, int local) static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
{ {
unsigned long vpn;
unsigned long i, pix, rc; unsigned long i, pix, rc;
unsigned long flags = 0; unsigned long flags = 0;
struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE); int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
unsigned long param[9]; unsigned long param[9];
unsigned long va;
unsigned long hash, index, shift, hidx, slot; unsigned long hash, index, shift, hidx, slot;
real_pte_t pte; real_pte_t pte;
int psize, ssize; int psize, ssize;
...@@ -398,21 +384,21 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) ...@@ -398,21 +384,21 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
ssize = batch->ssize; ssize = batch->ssize;
pix = 0; pix = 0;
for (i = 0; i < number; i++) { for (i = 0; i < number; i++) {
va = batch->vaddr[i]; vpn = batch->vpn[i];
pte = batch->pte[i]; pte = batch->pte[i];
pte_iterate_hashed_subpages(pte, psize, va, index, shift) { pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
hash = hpt_hash(va, shift, ssize); hash = hpt_hash(vpn, shift, ssize);
hidx = __rpte_to_hidx(pte, index); hidx = __rpte_to_hidx(pte, index);
if (hidx & _PTEIDX_SECONDARY) if (hidx & _PTEIDX_SECONDARY)
hash = ~hash; hash = ~hash;
slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
slot += hidx & _PTEIDX_GROUP_IX; slot += hidx & _PTEIDX_GROUP_IX;
if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) { if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
pSeries_lpar_hpte_invalidate(slot, va, psize, pSeries_lpar_hpte_invalidate(slot, vpn, psize,
ssize, local); ssize, local);
} else { } else {
param[pix] = HBR_REQUEST | HBR_AVPN | slot; param[pix] = HBR_REQUEST | HBR_AVPN | slot;
param[pix+1] = hpte_encode_avpn(va, psize, param[pix+1] = hpte_encode_avpn(vpn, psize,
ssize); ssize);
pix += 2; pix += 2;
if (pix == 8) { if (pix == 8) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment