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:
Alexander Gordeev 2020-03-19 13:44:50 +01:00 committed by Vasily Gorbik
parent f75556081a
commit 1058c163dc
2 changed files with 21 additions and 25 deletions

View File

@ -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;
}

View File

@ -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,