powerpc/mm/radix: Add mmu context handling callback for radix
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
d2adba3fd1
commit
7e381c0ff6
@ -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)
|
|||||||
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,13 +78,18 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm)
|
|||||||
if (index < 0)
|
if (index < 0)
|
||||||
return index;
|
return index;
|
||||||
|
|
||||||
/* The old code would re-promote on fork, we don't do that
|
if (radix_enabled()) {
|
||||||
* when using slices as it could cause problem promoting slices
|
radix__init_new_context(mm, index);
|
||||||
* that have been forced down to 4K
|
} else {
|
||||||
*/
|
|
||||||
if (slice_mm_new_context(mm))
|
/* The old code would re-promote on fork, we don't do that
|
||||||
slice_set_user_psize(mm, mmu_virtual_psize);
|
* when using slices as it could cause problem promoting slices
|
||||||
subpage_prot_init_new_context(mm);
|
* that have been forced down to 4K
|
||||||
|
*/
|
||||||
|
if (slice_mm_new_context(mm))
|
||||||
|
slice_set_user_psize(mm, mmu_virtual_psize);
|
||||||
|
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)
|
|||||||
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
|
||||||
|
Loading…
Reference in New Issue
Block a user