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

Commit 15472423 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc/mm/slice: Allow up to 64 low slices



While the implementation of the "slices" address space allows
a significant amount of high slices, it limits the number of
low slices to 16 due to the use of a single u64 low_slices_psize
element in struct mm_context_t

On the 8xx, the minimum slice size is the size of the area
covered by a single PMD entry, ie 4M in 4K pages mode and 64M in
16K pages mode. This means we could have at least 64 slices.

In order to override this limitation, this patch switches the
handling of low_slices_psize to char array as done already for
high_slices_psize.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Reviewed-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent aa0ab02b
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -91,7 +91,8 @@ typedef struct {
	struct npu_context *npu_context;

#ifdef CONFIG_PPC_MM_SLICES
	u64 low_slices_psize;	/* SLB page size encodings */
	 /* SLB page size encodings*/
	unsigned char low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE];
	unsigned char high_slices_psize[SLICE_ARRAY_SIZE];
	unsigned long slb_addr_limit;
#else
+6 −1
Original line number Diff line number Diff line
@@ -186,6 +186,11 @@
#define M_APG2		0x00000040
#define M_APG3		0x00000060

#ifdef CONFIG_PPC_MM_SLICES
#include <asm/nohash/32/slice.h>
#define SLICE_ARRAY_SIZE	(1 << (32 - SLICE_LOW_SHIFT - 1))
#endif

#ifndef __ASSEMBLY__
typedef struct {
	unsigned int id;
@@ -193,7 +198,7 @@ typedef struct {
	unsigned long vdso_base;
#ifdef CONFIG_PPC_MM_SLICES
	u16 user_psize;		/* page size index */
	u64 low_slices_psize;	/* page size encodings */
	unsigned char low_slices_psize[SLICE_ARRAY_SIZE];
	unsigned char high_slices_psize[0];
	unsigned long slb_addr_limit;
#endif
+1 −1
Original line number Diff line number Diff line
@@ -141,7 +141,7 @@ struct paca_struct {
#ifdef CONFIG_PPC_BOOK3S
	mm_context_id_t mm_ctx_id;
#ifdef CONFIG_PPC_MM_SLICES
	u64 mm_ctx_low_slices_psize;
	unsigned char mm_ctx_low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE];
	unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE];
	unsigned long mm_ctx_slb_addr_limit;
#else
+2 −1
Original line number Diff line number Diff line
@@ -265,7 +265,8 @@ void copy_mm_to_paca(struct mm_struct *mm)
#ifdef CONFIG_PPC_MM_SLICES
	VM_BUG_ON(!mm->context.slb_addr_limit);
	get_paca()->mm_ctx_slb_addr_limit = mm->context.slb_addr_limit;
	get_paca()->mm_ctx_low_slices_psize = context->low_slices_psize;
	memcpy(&get_paca()->mm_ctx_low_slices_psize,
	       &context->low_slices_psize, sizeof(context->low_slices_psize));
	memcpy(&get_paca()->mm_ctx_high_slices_psize,
	       &context->high_slices_psize, TASK_SLICE_ARRAY_SZ(mm));
#else /* CONFIG_PPC_MM_SLICES */
+6 −7
Original line number Diff line number Diff line
@@ -1110,19 +1110,18 @@ unsigned int hash_page_do_lazy_icache(unsigned int pp, pte_t pte, int trap)
#ifdef CONFIG_PPC_MM_SLICES
static unsigned int get_paca_psize(unsigned long addr)
{
	u64 lpsizes;
	unsigned char *hpsizes;
	unsigned char *psizes;
	unsigned long index, mask_index;

	if (addr < SLICE_LOW_TOP) {
		lpsizes = get_paca()->mm_ctx_low_slices_psize;
		psizes = get_paca()->mm_ctx_low_slices_psize;
		index = GET_LOW_SLICE_INDEX(addr);
		return (lpsizes >> (index * 4)) & 0xF;
	}
	hpsizes = get_paca()->mm_ctx_high_slices_psize;
	} else {
		psizes = get_paca()->mm_ctx_high_slices_psize;
		index = GET_HIGH_SLICE_INDEX(addr);
	}
	mask_index = index & 0x1;
	return (hpsizes[index >> 1] >> (mask_index * 4)) & 0xF;
	return (psizes[index >> 1] >> (mask_index * 4)) & 0xF;
}

#else
Loading