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

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

Signed-off-by: default avatarAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent d2adba3f
...@@ -37,10 +37,14 @@ extern void switch_slb(struct task_struct *tsk, struct mm_struct *mm); ...@@ -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); extern void set_context(unsigned long id, pgd_t *pgd);
#ifdef CONFIG_PPC_BOOK3S_64 #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, static inline void switch_mmu_context(struct mm_struct *prev,
struct mm_struct *next, struct mm_struct *next,
struct task_struct *tsk) struct task_struct *tsk)
{ {
if (radix_enabled())
return radix__switch_mmu_context(prev, next);
return switch_slb(tsk, next); return switch_slb(tsk, next);
} }
......
...@@ -58,6 +58,17 @@ int __init_new_context(void) ...@@ -58,6 +58,17 @@ int __init_new_context(void)
return index; return index;
} }
EXPORT_SYMBOL_GPL(__init_new_context); 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) 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) ...@@ -67,6 +78,10 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
if (index < 0) if (index < 0)
return index; 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 /* The old code would re-promote on fork, we don't do that
* when using slices as it could cause problem promoting slices * when using slices as it could cause problem promoting slices
* that have been forced down to 4K * that have been forced down to 4K
...@@ -74,6 +89,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) ...@@ -74,6 +89,7 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
if (slice_mm_new_context(mm)) if (slice_mm_new_context(mm))
slice_set_user_psize(mm, mmu_virtual_psize); slice_set_user_psize(mm, mmu_virtual_psize);
subpage_prot_init_new_context(mm); subpage_prot_init_new_context(mm);
}
mm->context.id = index; mm->context.id = index;
#ifdef CONFIG_PPC_ICSWX #ifdef CONFIG_PPC_ICSWX
mm->context.cop_lockp = kmalloc(sizeof(spinlock_t), GFP_KERNEL); mm->context.cop_lockp = kmalloc(sizeof(spinlock_t), GFP_KERNEL);
...@@ -144,8 +160,19 @@ void destroy_context(struct mm_struct *mm) ...@@ -144,8 +160,19 @@ void destroy_context(struct mm_struct *mm)
mm->context.cop_lockp = NULL; mm->context.cop_lockp = NULL;
#endif /* CONFIG_PPC_ICSWX */ #endif /* CONFIG_PPC_ICSWX */
if (radix_enabled())
process_tb[mm->context.id].prtb1 = 0;
else
subpage_prot_free(mm);
destroy_pagetable_page(mm); destroy_pagetable_page(mm);
__destroy_context(mm->context.id); __destroy_context(mm->context.id);
subpage_prot_free(mm);
mm->context.id = MMU_NO_CONTEXT; 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment