diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-09 12:24:36 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2008-02-09 12:24:40 -0500 |
commit | 5a216a20837c5f5fa1ca4b8ae8991ffd96b08e6f (patch) | |
tree | dde54e28497e920fa460cc95dadb6b38f1b2dbe0 /include/asm-s390/tlb.h | |
parent | 146e4b3c8b92071b18f0b2e6f47165bad4f9e825 (diff) |
[S390] Add four level page tables for CONFIG_64BIT=y.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'include/asm-s390/tlb.h')
-rw-r--r-- | include/asm-s390/tlb.h | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h index ecac75ec6cb0..9b2ddb7aac49 100644 --- a/include/asm-s390/tlb.h +++ b/include/asm-s390/tlb.h | |||
@@ -38,7 +38,7 @@ struct mmu_gather { | |||
38 | struct mm_struct *mm; | 38 | struct mm_struct *mm; |
39 | unsigned int fullmm; | 39 | unsigned int fullmm; |
40 | unsigned int nr_ptes; | 40 | unsigned int nr_ptes; |
41 | unsigned int nr_pmds; | 41 | unsigned int nr_pxds; |
42 | void *array[TLB_NR_PTRS]; | 42 | void *array[TLB_NR_PTRS]; |
43 | }; | 43 | }; |
44 | 44 | ||
@@ -53,7 +53,7 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, | |||
53 | tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || | 53 | tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || |
54 | (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); | 54 | (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); |
55 | tlb->nr_ptes = 0; | 55 | tlb->nr_ptes = 0; |
56 | tlb->nr_pmds = TLB_NR_PTRS; | 56 | tlb->nr_pxds = TLB_NR_PTRS; |
57 | if (tlb->fullmm) | 57 | if (tlb->fullmm) |
58 | __tlb_flush_mm(mm); | 58 | __tlb_flush_mm(mm); |
59 | return tlb; | 59 | return tlb; |
@@ -62,12 +62,13 @@ static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, | |||
62 | static inline void tlb_flush_mmu(struct mmu_gather *tlb, | 62 | static inline void tlb_flush_mmu(struct mmu_gather *tlb, |
63 | unsigned long start, unsigned long end) | 63 | unsigned long start, unsigned long end) |
64 | { | 64 | { |
65 | if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pmds < TLB_NR_PTRS)) | 65 | if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) |
66 | __tlb_flush_mm(tlb->mm); | 66 | __tlb_flush_mm(tlb->mm); |
67 | while (tlb->nr_ptes > 0) | 67 | while (tlb->nr_ptes > 0) |
68 | pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); | 68 | pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); |
69 | while (tlb->nr_pmds < TLB_NR_PTRS) | 69 | while (tlb->nr_pxds < TLB_NR_PTRS) |
70 | pmd_free(tlb->mm, (pmd_t *) tlb->array[tlb->nr_pmds++]); | 70 | /* pgd_free frees the pointer as region or segment table */ |
71 | pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]); | ||
71 | } | 72 | } |
72 | 73 | ||
73 | static inline void tlb_finish_mmu(struct mmu_gather *tlb, | 74 | static inline void tlb_finish_mmu(struct mmu_gather *tlb, |
@@ -99,7 +100,7 @@ static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) | |||
99 | { | 100 | { |
100 | if (!tlb->fullmm) { | 101 | if (!tlb->fullmm) { |
101 | tlb->array[tlb->nr_ptes++] = pte; | 102 | tlb->array[tlb->nr_ptes++] = pte; |
102 | if (tlb->nr_ptes >= tlb->nr_pmds) | 103 | if (tlb->nr_ptes >= tlb->nr_pxds) |
103 | tlb_flush_mmu(tlb, 0, 0); | 104 | tlb_flush_mmu(tlb, 0, 0); |
104 | } else | 105 | } else |
105 | pte_free(tlb->mm, pte); | 106 | pte_free(tlb->mm, pte); |
@@ -113,15 +114,29 @@ static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) | |||
113 | { | 114 | { |
114 | #ifdef __s390x__ | 115 | #ifdef __s390x__ |
115 | if (!tlb->fullmm) { | 116 | if (!tlb->fullmm) { |
116 | tlb->array[--tlb->nr_pmds] = (struct page *) pmd; | 117 | tlb->array[--tlb->nr_pxds] = pmd; |
117 | if (tlb->nr_ptes >= tlb->nr_pmds) | 118 | if (tlb->nr_ptes >= tlb->nr_pxds) |
118 | tlb_flush_mmu(tlb, 0, 0); | 119 | tlb_flush_mmu(tlb, 0, 0); |
119 | } else | 120 | } else |
120 | pmd_free(tlb->mm, pmd); | 121 | pmd_free(tlb->mm, pmd); |
121 | #endif | 122 | #endif |
122 | } | 123 | } |
123 | 124 | ||
124 | #define pud_free_tlb(tlb, pud) do { } while (0) | 125 | /* |
126 | * pud_free_tlb frees a pud table and clears the CRSTE for the | ||
127 | * region third table entry from the tlb. | ||
128 | */ | ||
129 | static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) | ||
130 | { | ||
131 | #ifdef __s390x__ | ||
132 | if (!tlb->fullmm) { | ||
133 | tlb->array[--tlb->nr_pxds] = pud; | ||
134 | if (tlb->nr_ptes >= tlb->nr_pxds) | ||
135 | tlb_flush_mmu(tlb, 0, 0); | ||
136 | } else | ||
137 | pud_free(tlb->mm, pud); | ||
138 | #endif | ||
139 | } | ||
125 | 140 | ||
126 | #define tlb_start_vma(tlb, vma) do { } while (0) | 141 | #define tlb_start_vma(tlb, vma) do { } while (0) |
127 | #define tlb_end_vma(tlb, vma) do { } while (0) | 142 | #define tlb_end_vma(tlb, vma) do { } while (0) |