Skip to content

Commit

Permalink
[S390] make page table walking more robust
Browse files Browse the repository at this point in the history
Make page table walking on s390 more robust. The current code requires
that the pgd/pud/pmd/pte loop is only done for address ranges that are
below the end address of the last vma of the address space. But this
is not always true, e.g. the generic page table walker does not guarantee
this. Change TASK_SIZE/TASK_SIZE_OF to reflect the current size of the
address space. This makes the generic page table walker happy but it
breaks the upgrade of a 3 level page table to a 4 level page table.
To make the upgrade work again another fix is required.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Martin Schwidefsky committed Mar 18, 2009
1 parent 2887fc5 commit f481bfa
Show file tree
Hide file tree
Showing 3 changed files with 6 additions and 5 deletions.
5 changes: 2 additions & 3 deletions arch/s390/include/asm/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ extern void print_cpu_info(struct cpuinfo_S390 *);
extern int get_cpu_capability(unsigned int *);

/*
* User space process size: 2GB for 31 bit, 4TB for 64 bit.
* User space process size: 2GB for 31 bit, 4TB or 8PT for 64 bit.
*/
#ifndef __s390x__

Expand All @@ -70,8 +70,7 @@ extern int get_cpu_capability(unsigned int *);

#else /* __s390x__ */

#define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \
(1UL << 31) : (1UL << 53))
#define TASK_SIZE_OF(tsk) ((tsk)->mm->context.asce_limit)
#define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \
(1UL << 30) : (1UL << 41))
#define TASK_SIZE TASK_SIZE_OF(current)
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/mm/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
* Leave an at least ~128 MB hole.
*/
#define MIN_GAP (128*1024*1024)
#define MAX_GAP (TASK_SIZE/6*5)
#define MAX_GAP (STACK_TOP/6*5)

static inline unsigned long mmap_base(void)
{
Expand All @@ -46,7 +46,7 @@ static inline unsigned long mmap_base(void)
else if (gap > MAX_GAP)
gap = MAX_GAP;

return TASK_SIZE - (gap & PAGE_MASK);
return STACK_TOP - (gap & PAGE_MASK);
}

static inline int mmap_is_legacy(void)
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/mm/pgtable.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ int crst_table_upgrade(struct mm_struct *mm, unsigned long limit)
crst_table_init(table, entry);
pgd_populate(mm, (pgd_t *) table, (pud_t *) pgd);
mm->pgd = (pgd_t *) table;
mm->task_size = mm->context.asce_limit;
table = NULL;
}
spin_unlock(&mm->page_table_lock);
Expand Down Expand Up @@ -154,6 +155,7 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
BUG();
}
mm->pgd = (pgd_t *) (pgd_val(*pgd) & _REGION_ENTRY_ORIGIN);
mm->task_size = mm->context.asce_limit;
crst_table_free(mm, (unsigned long *) pgd);
}
update_mm(mm, current);
Expand Down

0 comments on commit f481bfa

Please sign in to comment.