forked from luck/tmp_suning_uos_patched
s390/mm: cleanup init_new_context() callback
The set of values asce_limit may be assigned with is TASK_SIZE_MAX, _REGION1_SIZE, _REGION2_SIZE and 0 as a special case if the callback was called from execve(). Do VM_BUG_ON() if asce_limit is something else. Save few CPU cycles by removing unnecessary asce_limit re-assignment in case of 3-level task and redundant PGD entry type reconstruction. Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com> Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
This commit is contained in:
parent
f75556081a
commit
1058c163dc
|
@ -18,6 +18,8 @@
|
|||
static inline int init_new_context(struct task_struct *tsk,
|
||||
struct mm_struct *mm)
|
||||
{
|
||||
unsigned long asce_type, init_entry;
|
||||
|
||||
spin_lock_init(&mm->context.lock);
|
||||
INIT_LIST_HEAD(&mm->context.pgtable_list);
|
||||
INIT_LIST_HEAD(&mm->context.gmap_list);
|
||||
|
@ -35,29 +37,34 @@ static inline int init_new_context(struct task_struct *tsk,
|
|||
mm->context.allow_gmap_hpage_1m = 0;
|
||||
#endif
|
||||
switch (mm->context.asce_limit) {
|
||||
case _REGION2_SIZE:
|
||||
default:
|
||||
/*
|
||||
* forked 3-level task, fall through to set new asce with new
|
||||
* mm->pgd
|
||||
* context created by exec, the value of asce_limit can
|
||||
* only be zero in this case
|
||||
*/
|
||||
case 0:
|
||||
/* context created by exec, set asce limit to 4TB */
|
||||
VM_BUG_ON(mm->context.asce_limit);
|
||||
/* continue as 3-level task */
|
||||
mm->context.asce_limit = _REGION2_SIZE;
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION3;
|
||||
fallthrough;
|
||||
case _REGION2_SIZE:
|
||||
/* forked 3-level task */
|
||||
init_entry = _REGION3_ENTRY_EMPTY;
|
||||
asce_type = _ASCE_TYPE_REGION3;
|
||||
break;
|
||||
case TASK_SIZE_MAX:
|
||||
/* forked 5-level task, set new asce with new_mm->pgd */
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION1;
|
||||
/* forked 5-level task */
|
||||
init_entry = _REGION1_ENTRY_EMPTY;
|
||||
asce_type = _ASCE_TYPE_REGION1;
|
||||
break;
|
||||
case _REGION1_SIZE:
|
||||
/* forked 4-level task, set new asce with new mm->pgd */
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | _ASCE_TYPE_REGION2;
|
||||
/* forked 4-level task */
|
||||
init_entry = _REGION2_ENTRY_EMPTY;
|
||||
asce_type = _ASCE_TYPE_REGION2;
|
||||
break;
|
||||
}
|
||||
crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm));
|
||||
mm->context.asce = __pa(mm->pgd) | _ASCE_TABLE_LENGTH |
|
||||
_ASCE_USER_BITS | asce_type;
|
||||
crst_table_init((unsigned long *) mm->pgd, init_entry);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -34,17 +34,6 @@ static inline void crst_table_init(unsigned long *crst, unsigned long entry)
|
|||
memset64((u64 *)crst, entry, _CRST_ENTRIES);
|
||||
}
|
||||
|
||||
static inline unsigned long pgd_entry_type(struct mm_struct *mm)
|
||||
{
|
||||
if (mm_pmd_folded(mm))
|
||||
return _SEGMENT_ENTRY_EMPTY;
|
||||
if (mm_pud_folded(mm))
|
||||
return _REGION3_ENTRY_EMPTY;
|
||||
if (mm_p4d_folded(mm))
|
||||
return _REGION2_ENTRY_EMPTY;
|
||||
return _REGION1_ENTRY_EMPTY;
|
||||
}
|
||||
|
||||
int crst_table_upgrade(struct mm_struct *mm, unsigned long limit);
|
||||
|
||||
static inline unsigned long check_asce_limit(struct mm_struct *mm, unsigned long addr,
|
||||
|
|
Loading…
Reference in New Issue
Block a user