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

Commit 7e381c0f authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Michael Ellerman
Browse files

powerpc/mm/radix: Add mmu context handling callback for radix

parent d2adba3f
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -37,10 +37,14 @@ extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm);
extern void set_context(unsigned long id, pgd_t *pgd);

#ifdef CONFIG_PPC_BOOK3S_64
extern void radix__switch_mmu_context(struct mm_struct *prev,
				     struct mm_struct *next);
static inline void switch_mmu_context(struct mm_struct *prev,
				      struct mm_struct *next,
				      struct task_struct *tsk)
{
	if (radix_enabled())
		return radix__switch_mmu_context(prev, next);
	return switch_slb(tsk, next);
}

+35 −8
Original line number Diff line number Diff line
@@ -58,6 +58,17 @@ int __init_new_context(void)
	return index;
}
EXPORT_SYMBOL_GPL(__init_new_context);
static int radix__init_new_context(struct mm_struct *mm, int index)
{
	unsigned long rts_field;

	/*
	 * set the process table entry,
	 */
	rts_field = 3ull << PPC_BITLSHIFT(2);
	process_tb[index].prtb0 = cpu_to_be64(rts_field | __pa(mm->pgd) | RADIX_PGD_INDEX_SIZE);
	return 0;
}

int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
{
@@ -67,6 +78,10 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
	if (index < 0)
		return index;

	if (radix_enabled()) {
		radix__init_new_context(mm, index);
	} else {

		/* The old code would re-promote on fork, we don't do that
		 * when using slices as it could cause problem promoting slices
		 * that have been forced down to 4K
@@ -74,6 +89,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
		if (slice_mm_new_context(mm))
			slice_set_user_psize(mm, mmu_virtual_psize);
		subpage_prot_init_new_context(mm);
	}
	mm->context.id = index;
#ifdef CONFIG_PPC_ICSWX
	mm->context.cop_lockp = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
@@ -144,8 +160,19 @@ void destroy_context(struct mm_struct *mm)
	mm->context.cop_lockp = NULL;
#endif /* CONFIG_PPC_ICSWX */

	if (radix_enabled())
		process_tb[mm->context.id].prtb1 = 0;
	else
		subpage_prot_free(mm);
	destroy_pagetable_page(mm);
	__destroy_context(mm->context.id);
	subpage_prot_free(mm);
	mm->context.id = MMU_NO_CONTEXT;
}

#ifdef CONFIG_PPC_RADIX_MMU
void radix__switch_mmu_context(struct mm_struct *prev, struct mm_struct *next)
{
	mtspr(SPRN_PID, next->context.id);
	asm volatile("isync": : :"memory");
}
#endif