Skip to content

Commit

Permalink
powerpc: Decode the pte-lp-encoding bits correctly.
Browse files Browse the repository at this point in the history
We look at both the segment base page size and actual page size and store
the pte-lp-encodings in an array per base page size.

We also update all relevant functions to take actual page size argument
so that we can use the correct PTE LP encoding in HPTE. This should also
get the basic Multiple Page Size per Segment (MPSS) support. This is needed
to enable THP on ppc64.

[Fixed PR KVM build --BenH]

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
  • Loading branch information
Aneesh Kumar K.V authored and Benjamin Herrenschmidt committed Apr 30, 2013
1 parent 74f227b commit b1022fb
Show file tree
Hide file tree
Showing 10 changed files with 234 additions and 118 deletions.
3 changes: 2 additions & 1 deletion arch/powerpc/include/asm/machdep.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ struct machdep_calls {
unsigned long prpn,
unsigned long rflags,
unsigned long vflags,
int psize, int ssize);
int psize, int apsize,
int ssize);
long (*hpte_remove)(unsigned long hpte_group);
void (*hpte_removebolted)(unsigned long ea,
int psize, int ssize);
Expand Down
33 changes: 19 additions & 14 deletions arch/powerpc/include/asm/mmu-hash64.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ extern unsigned long htab_hash_mask;
struct mmu_psize_def
{
unsigned int shift; /* number of bits */
unsigned int penc; /* HPTE encoding */
int penc[MMU_PAGE_COUNT]; /* HPTE encoding */
unsigned int tlbiel; /* tlbiel supported for that page size */
unsigned long avpnm; /* bits to mask out in AVPN in the HPTE */
unsigned long sllp; /* SLB L||LP (exact mask to use in slbmte) */
Expand Down Expand Up @@ -200,6 +200,13 @@ static inline unsigned int mmu_psize_to_shift(unsigned int mmu_psize)
*/
#define VPN_SHIFT 12

/*
* HPTE Large Page (LP) details
*/
#define LP_SHIFT 12
#define LP_BITS 8
#define LP_MASK(i) ((0xFF >> (i)) << LP_SHIFT)

#ifndef __ASSEMBLY__

static inline int segment_shift(int ssize)
Expand Down Expand Up @@ -255,14 +262,14 @@ static inline unsigned long hpte_encode_avpn(unsigned long vpn, int psize,

/*
* This function sets the AVPN and L fields of the HPTE appropriately
* for the page size
* using the base page size and actual page size.
*/
static inline unsigned long hpte_encode_v(unsigned long vpn,
int psize, int ssize)
static inline unsigned long hpte_encode_v(unsigned long vpn, int base_psize,
int actual_psize, int ssize)
{
unsigned long v;
v = hpte_encode_avpn(vpn, psize, ssize);
if (psize != MMU_PAGE_4K)
v = hpte_encode_avpn(vpn, base_psize, ssize);
if (actual_psize != MMU_PAGE_4K)
v |= HPTE_V_LARGE;
return v;
}
Expand All @@ -272,19 +279,17 @@ static inline unsigned long hpte_encode_v(unsigned long vpn,
* for the page size. We assume the pa is already "clean" that is properly
* aligned for the requested page size
*/
static inline unsigned long hpte_encode_r(unsigned long pa, int psize)
static inline unsigned long hpte_encode_r(unsigned long pa, int base_psize,
int actual_psize)
{
unsigned long r;

/* A 4K page needs no special encoding */
if (psize == MMU_PAGE_4K)
if (actual_psize == MMU_PAGE_4K)
return pa & HPTE_R_RPN;
else {
unsigned int penc = mmu_psize_defs[psize].penc;
unsigned int shift = mmu_psize_defs[psize].shift;
return (pa & ~((1ul << shift) - 1)) | (penc << 12);
unsigned int penc = mmu_psize_defs[base_psize].penc[actual_psize];
unsigned int shift = mmu_psize_defs[actual_psize].shift;
return (pa & ~((1ul << shift) - 1)) | (penc << LP_SHIFT);
}
return r;
}

/*
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kvm/book3s_64_mmu_host.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ int kvmppc_mmu_map_page(struct kvm_vcpu *vcpu, struct kvmppc_pte *orig_pte)
}

ret = ppc_md.hpte_insert(hpteg, vpn, hpaddr, rflags, vflags,
MMU_PAGE_4K, MMU_SEGSIZE_256M);
MMU_PAGE_4K, MMU_PAGE_4K, MMU_SEGSIZE_256M);

if (ret < 0) {
/* If we couldn't map a primary PTE, try a secondary */
Expand Down
8 changes: 7 additions & 1 deletion arch/powerpc/kvm/book3s_hv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1515,7 +1515,13 @@ static void kvmppc_add_seg_page_size(struct kvm_ppc_one_seg_page_size **sps,
(*sps)->page_shift = def->shift;
(*sps)->slb_enc = def->sllp;
(*sps)->enc[0].page_shift = def->shift;
(*sps)->enc[0].pte_enc = def->penc;
/*
* Only return base page encoding. We don't want to return
* all the supporting pte_enc, because our H_ENTER doesn't
* support MPSS yet. Once they do, we can start passing all
* support pte_enc here
*/
(*sps)->enc[0].pte_enc = def->penc[linux_psize];
(*sps)++;
}

Expand Down
18 changes: 12 additions & 6 deletions arch/powerpc/mm/hash_low_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,8 @@ htab_insert_pte:
mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
li r9,MMU_PAGE_4K /* actual page size */
ld r10,STK_PARAM(R9)(r1) /* segment size */
_GLOBAL(htab_call_hpte_insert1)
bl . /* Patched by htab_finish_init() */
cmpdi 0,r3,0
Expand All @@ -219,7 +220,8 @@ _GLOBAL(htab_call_hpte_insert1)
mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
li r9,MMU_PAGE_4K /* actual page size */
ld r10,STK_PARAM(R9)(r1) /* segment size */
_GLOBAL(htab_call_hpte_insert2)
bl . /* Patched by htab_finish_init() */
cmpdi 0,r3,0
Expand Down Expand Up @@ -515,7 +517,8 @@ htab_special_pfn:
mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
li r9,MMU_PAGE_4K /* actual page size */
ld r10,STK_PARAM(R9)(r1) /* segment size */
_GLOBAL(htab_call_hpte_insert1)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
Expand All @@ -542,7 +545,8 @@ _GLOBAL(htab_call_hpte_insert1)
mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_4K /* page size */
ld r9,STK_PARAM(R9)(r1) /* segment size */
li r9,MMU_PAGE_4K /* actual page size */
ld r10,STK_PARAM(R9)(r1) /* segment size */
_GLOBAL(htab_call_hpte_insert2)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
Expand Down Expand Up @@ -840,7 +844,8 @@ ht64_insert_pte:
mr r4,r29 /* Retrieve vpn */
li r7,0 /* !bolted, !secondary */
li r8,MMU_PAGE_64K
ld r9,STK_PARAM(R9)(r1) /* segment size */
li r9,MMU_PAGE_64K /* actual page size */
ld r10,STK_PARAM(R9)(r1) /* segment size */
_GLOBAL(ht64_call_hpte_insert1)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
Expand All @@ -863,7 +868,8 @@ _GLOBAL(ht64_call_hpte_insert1)
mr r4,r29 /* Retrieve vpn */
li r7,HPTE_V_SECONDARY /* !bolted, secondary */
li r8,MMU_PAGE_64K
ld r9,STK_PARAM(R9)(r1) /* segment size */
li r9,MMU_PAGE_64K /* actual page size */
ld r10,STK_PARAM(R9)(r1) /* segment size */
_GLOBAL(ht64_call_hpte_insert2)
bl . /* patched by htab_finish_init() */
cmpdi 0,r3,0
Expand Down
Loading

0 comments on commit b1022fb

Please sign in to comment.