Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5a216a20 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

[S390] Add four level page tables for CONFIG_64BIT=y.

parent 146e4b3c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -112,8 +112,8 @@ void __init paging_init(void)
	init_mm.pgd = swapper_pg_dir;
	S390_lowcore.kernel_asce = __pa(init_mm.pgd) & PAGE_MASK;
#ifdef CONFIG_64BIT
	S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION3 | _ASCE_TABLE_LENGTH;
	pgd_type = _REGION3_ENTRY_EMPTY;
	S390_lowcore.kernel_asce |= _ASCE_TYPE_REGION2 | _ASCE_TABLE_LENGTH;
	pgd_type = _REGION2_ENTRY_EMPTY;
#else
	S390_lowcore.kernel_asce |= _ASCE_TABLE_LENGTH;
	pgd_type = _SEGMENT_ENTRY_EMPTY;
+13 −1
Original line number Diff line number Diff line
@@ -69,7 +69,19 @@ static void __ref *vmem_alloc_pages(unsigned int order)
	return alloc_bootmem_pages((1 << order) * PAGE_SIZE);
}

#define vmem_pud_alloc()	({ BUG(); ((pud_t *) NULL); })
static inline pud_t *vmem_pud_alloc(void)
{
	pud_t *pud = NULL;

#ifdef CONFIG_64BIT
	pud = vmem_alloc_pages(2);
	if (!pud)
		return NULL;
	pud_val(*pud) = _REGION3_ENTRY_EMPTY;
	memcpy(pud + 1, pud, (PTRS_PER_PUD - 1)*sizeof(pud_t));
#endif
	return pud;
}

static inline pmd_t *vmem_pmd_alloc(void)
{
+1 −8
Original line number Diff line number Diff line
@@ -138,14 +138,7 @@ typedef s390_regs elf_gregset_t;
   use of this is to invoke "./ld.so someprog" to test out a new version of
   the loader.  We need to make sure that it is out of the way of the program
   that it will "exec", and that there is sufficient room for the brk.  */

#ifndef __s390x__
#define ELF_ET_DYN_BASE         ((TASK_SIZE & 0x80000000) \
                                ? TASK_SIZE / 3 * 2 \
                                : 2 * TASK_SIZE / 3)
#else /* __s390x__ */
#define ELF_ET_DYN_BASE		(TASK_SIZE / 3 * 2)
#endif /* __s390x__ */

/* Wow, the "main" arch needs arch dependent functions too.. :) */

+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ static inline int init_new_context(struct task_struct *tsk,
{
	mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS;
#ifdef CONFIG_64BIT
	mm->context.asce_bits |= _ASCE_TYPE_REGION3;
	mm->context.asce_bits |= _ASCE_TYPE_REGION2;
#endif
	mm->context.noexec = s390_noexec;
	return 0;
+24 −5
Original line number Diff line number Diff line
@@ -73,11 +73,17 @@ static inline unsigned long pgd_entry_type(struct mm_struct *mm)

static inline unsigned long pgd_entry_type(struct mm_struct *mm)
{
	return _REGION3_ENTRY_EMPTY;
	return _REGION2_ENTRY_EMPTY;
}

#define pud_alloc_one(mm,address)		({ BUG(); ((pud_t *)2); })
#define pud_free(mm, x)				do { } while (0)
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address)
{
	unsigned long *table = crst_table_alloc(mm, mm->context.noexec);
	if (table)
		crst_table_init(table, _REGION3_ENTRY_EMPTY);
	return (pud_t *) table;
}
#define pud_free(mm, pud) crst_table_free(mm, (unsigned long *) pud)

static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
{
@@ -88,8 +94,21 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
}
#define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd)

#define pgd_populate(mm, pgd, pud)		BUG()
#define pgd_populate_kernel(mm, pgd, pud)	BUG()
static inline void pgd_populate_kernel(struct mm_struct *mm,
				       pgd_t *pgd, pud_t *pud)
{
	pgd_val(*pgd) = _REGION2_ENTRY | __pa(pud);
}

static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
{
	pgd_t *shadow_pgd = get_shadow_table(pgd);
	pud_t *shadow_pud = get_shadow_table(pud);

	if (shadow_pgd && shadow_pud)
		pgd_populate_kernel(mm, shadow_pgd, shadow_pud);
	pgd_populate_kernel(mm, pgd, pud);
}

static inline void pud_populate_kernel(struct mm_struct *mm,
				       pud_t *pud, pmd_t *pmd)
Loading