Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b1022fbd authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Benjamin Herrenschmidt
Browse files

powerpc: Decode the pte-lp-encoding bits correctly.



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: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Acked-by: default avatarPaul Mackerras <paulus@samba.org>
Signed-off-by: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
parent 74f227b2
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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);
+19 −14
Original line number Diff line number Diff line
@@ -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) */
@@ -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)
@@ -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;
}
@@ -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;
}

/*
+1 −1
Original line number Diff line number Diff line
@@ -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 */
+7 −1
Original line number Diff line number Diff line
@@ -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)++;
}

+12 −6
Original line number Diff line number Diff line
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
Loading