From 6252d702c5311ce916caf75ed82e5c8245171c92 Mon Sep 17 00:00:00 2001 From: Martin Schwidefsky Date: Sat, 9 Feb 2008 18:24:37 +0100 Subject: [S390] dynamic page tables. Add support for different number of page table levels dependent on the highest address used for a process. This will cause a 31 bit process to use a two level page table instead of the four level page table that is the default after the pud has been introduced. Likewise a normal 64 bit process will use three levels instead of four. Only if a process runs out of the 4 tera bytes which can be addressed with a three level page table the fourth level is dynamically added. Then the process can use up to 8 peta byte. Signed-off-by: Martin Schwidefsky --- include/asm-s390/tlb.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/asm-s390/tlb.h') diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h index 9b2ddb7aac4..3d8a96d39d9 100644 --- a/include/asm-s390/tlb.h +++ b/include/asm-s390/tlb.h @@ -109,10 +109,15 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) /* * pmd_free_tlb frees a pmd table and clears the CRSTE for the * segment table entry from the tlb. + * If the mm uses a two level page table the single pmd is freed + * as the pgd. pmd_free_tlb checks the asce_limit against 2GB + * to avoid the double free of the pmd in this case. */ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) { #ifdef __s390x__ + if (tlb->mm->context.asce_limit <= (1UL << 31)) + return; if (!tlb->fullmm) { tlb->array[--tlb->nr_pxds] = pmd; if (tlb->nr_ptes >= tlb->nr_pxds) @@ -125,10 +130,15 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) /* * pud_free_tlb frees a pud table and clears the CRSTE for the * region third table entry from the tlb. + * If the mm uses a three level page table the single pud is freed + * as the pgd. pud_free_tlb checks the asce_limit against 4TB + * to avoid the double free of the pud in this case. */ static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) { #ifdef __s390x__ + if (tlb->mm->context.asce_limit <= (1UL << 42)) + return; if (!tlb->fullmm) { tlb->array[--tlb->nr_pxds] = pud; if (tlb->nr_ptes >= tlb->nr_pxds) -- cgit v1.2.3