Commit fb790377 authored by Christophe Leroy's avatar Christophe Leroy Committed by Madhavan Srinivasan
Browse files

powerpc/32s: Fix segments setup when TASK_SIZE is not a multiple of 256M



For book3s/32 it is assumed that TASK_SIZE is a multiple of 256 Mbytes,
but Kconfig allows any value for TASK_SIZE.

In all relevant calculations, align TASK_SIZE to the upper 256 Mbytes
boundary.

Also use ASM_CONST() in the definition of TASK_SIZE to ensure it is
seen as an unsigned constant.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarMadhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/8928d906079e156c59794c41e826a684eaaaebb4.1766574657.git.chleroy@kernel.org
parent 704f4300
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -192,12 +192,15 @@ extern s32 patch__hash_page_B, patch__hash_page_C;
extern s32 patch__flush_hash_A0, patch__flush_hash_A1, patch__flush_hash_A2;
extern s32 patch__flush_hash_B;

#include <linux/sizes.h>
#include <linux/align.h>

#include <asm/reg.h>
#include <asm/task_size_32.h>

static __always_inline void update_user_segment(u32 n, u32 val)
{
	if (n << 28 < TASK_SIZE)
	if (n << 28 < ALIGN(TASK_SIZE, SZ_256M))
		mtsr(val + n * 0x111, n << 28);
}

+1 −1
Original line number Diff line number Diff line
@@ -6,7 +6,7 @@
#error User TASK_SIZE overlaps with KERNEL_START address
#endif

#define TASK_SIZE (CONFIG_TASK_SIZE)
#define TASK_SIZE ASM_CONST(CONFIG_TASK_SIZE)

/*
 * This decides where the kernel will search for a free chunk of vm space during
+1 −1
Original line number Diff line number Diff line
@@ -331,7 +331,7 @@ int main(void)

#ifndef CONFIG_PPC64
	DEFINE(TASK_SIZE, TASK_SIZE);
	DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
	DEFINE(NUM_USER_SEGMENTS, ALIGN(TASK_SIZE, SZ_256M) >> 28);
#endif /* ! CONFIG_PPC64 */

	/* datapage offsets for use by vdso */
+3 −3
Original line number Diff line number Diff line
@@ -420,7 +420,7 @@ InstructionTLBMiss:
	lwz	r2,0(r2)		/* get pmd entry */
#ifdef CONFIG_EXECMEM
	rlwinm	r3, r0, 4, 0xf
	subi	r3, r3, (TASK_SIZE >> 28) & 0xf
	subi	r3, r3, NUM_USER_SEGMENTS
#endif
	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
	beq-	InstructionAddressInvalid	/* return if no mapping */
@@ -475,7 +475,7 @@ DataLoadTLBMiss:
	lwz	r2,0(r1)		/* get pmd entry */
	rlwinm	r3, r0, 4, 0xf
	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
	subi	r3, r3, (TASK_SIZE >> 28) & 0xf
	subi	r3, r3, NUM_USER_SEGMENTS
	beq-	2f			/* bail if no mapping */
1:	rlwimi	r2,r0,22,20,29		/* insert next 10 bits of address */
	lwz	r2,0(r2)		/* get linux-style pte */
@@ -554,7 +554,7 @@ DataStoreTLBMiss:
	lwz	r2,0(r1)		/* get pmd entry */
	rlwinm	r3, r0, 4, 0xf
	rlwinm.	r2,r2,0,0,19		/* extract address of pte page */
	subi	r3, r3, (TASK_SIZE >> 28) & 0xf
	subi	r3, r3, NUM_USER_SEGMENTS
	beq-	2f			/* bail if no mapping */
1:
	rlwimi	r2,r0,22,20,29		/* insert next 10 bits of address */
+1 −1
Original line number Diff line number Diff line
@@ -225,7 +225,7 @@ int mmu_mark_initmem_nx(void)

	BUILD_BUG_ON(ALIGN_DOWN(MODULES_VADDR, SZ_256M) < TASK_SIZE);

	for (i = TASK_SIZE >> 28; i < 16; i++) {
	for (i = ALIGN(TASK_SIZE, SZ_256M) >> 28; i < 16; i++) {
		/* Do not set NX on VM space for modules */
		if (is_module_segment(i << 28))
			continue;
Loading