.. | .. |
---|
2 | 2 | #ifndef _ASM_POWERPC_BOOK3S_64_MMU_H_ |
---|
3 | 3 | #define _ASM_POWERPC_BOOK3S_64_MMU_H_ |
---|
4 | 4 | |
---|
| 5 | +#include <asm/page.h> |
---|
| 6 | + |
---|
5 | 7 | #ifndef __ASSEMBLY__ |
---|
6 | 8 | /* |
---|
7 | 9 | * Page size definition |
---|
.. | .. |
---|
23 | 25 | }; |
---|
24 | 26 | }; |
---|
25 | 27 | extern struct mmu_psize_def mmu_psize_defs[MMU_PAGE_COUNT]; |
---|
26 | | - |
---|
27 | 28 | #endif /* __ASSEMBLY__ */ |
---|
28 | 29 | |
---|
29 | 30 | /* 64-bit classic hash table MMU */ |
---|
.. | .. |
---|
66 | 67 | /* Base PID to allocate from */ |
---|
67 | 68 | extern unsigned int mmu_base_pid; |
---|
68 | 69 | |
---|
| 70 | +/* |
---|
| 71 | + * memory block size used with radix translation. |
---|
| 72 | + */ |
---|
| 73 | +extern unsigned long __ro_after_init radix_mem_block_size; |
---|
| 74 | + |
---|
69 | 75 | #define PRTB_SIZE_SHIFT (mmu_pid_bits + 4) |
---|
70 | 76 | #define PRTB_ENTRIES (1ul << mmu_pid_bits) |
---|
71 | 77 | |
---|
.. | .. |
---|
80 | 86 | /* Maximum possible number of NPUs in a system. */ |
---|
81 | 87 | #define NV_MAX_NPUS 8 |
---|
82 | 88 | |
---|
83 | | -/* |
---|
84 | | - * One bit per slice. We have lower slices which cover 256MB segments |
---|
85 | | - * upto 4G range. That gets us 16 low slices. For the rest we track slices |
---|
86 | | - * in 1TB size. |
---|
87 | | - */ |
---|
88 | | -struct slice_mask { |
---|
89 | | - u64 low_slices; |
---|
90 | | - DECLARE_BITMAP(high_slices, SLICE_NUM_HIGH); |
---|
91 | | -}; |
---|
92 | | - |
---|
93 | 89 | typedef struct { |
---|
94 | 90 | union { |
---|
95 | 91 | /* |
---|
.. | .. |
---|
103 | 99 | mm_context_id_t id; |
---|
104 | 100 | mm_context_id_t extended_id[TASK_SIZE_USER64/TASK_CONTEXT_SIZE]; |
---|
105 | 101 | }; |
---|
106 | | - u16 user_psize; /* page size index */ |
---|
107 | 102 | |
---|
108 | 103 | /* Number of bits in the mm_cpumask */ |
---|
109 | 104 | atomic_t active_cpus; |
---|
.. | .. |
---|
111 | 106 | /* Number of users of the external (Nest) MMU */ |
---|
112 | 107 | atomic_t copros; |
---|
113 | 108 | |
---|
114 | | - /* NPU NMMU context */ |
---|
115 | | - struct npu_context *npu_context; |
---|
| 109 | + /* Number of user space windows opened in process mm_context */ |
---|
| 110 | + atomic_t vas_windows; |
---|
116 | 111 | |
---|
117 | | -#ifdef CONFIG_PPC_MM_SLICES |
---|
118 | | - /* SLB page size encodings*/ |
---|
119 | | - unsigned char low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE]; |
---|
120 | | - unsigned char high_slices_psize[SLICE_ARRAY_SIZE]; |
---|
121 | | - unsigned long slb_addr_limit; |
---|
122 | | -# ifdef CONFIG_PPC_64K_PAGES |
---|
123 | | - struct slice_mask mask_64k; |
---|
124 | | -# endif |
---|
125 | | - struct slice_mask mask_4k; |
---|
126 | | -# ifdef CONFIG_HUGETLB_PAGE |
---|
127 | | - struct slice_mask mask_16m; |
---|
128 | | - struct slice_mask mask_16g; |
---|
129 | | -# endif |
---|
130 | | -#else |
---|
131 | | - u16 sllp; /* SLB page size encoding */ |
---|
132 | | -#endif |
---|
| 112 | + struct hash_mm_context *hash_context; |
---|
| 113 | + |
---|
133 | 114 | unsigned long vdso_base; |
---|
134 | | -#ifdef CONFIG_PPC_SUBPAGE_PROT |
---|
135 | | - struct subpage_prot_table spt; |
---|
136 | | -#endif /* CONFIG_PPC_SUBPAGE_PROT */ |
---|
137 | 115 | /* |
---|
138 | 116 | * pagetable fragment support |
---|
139 | 117 | */ |
---|
.. | .. |
---|
154 | 132 | #endif |
---|
155 | 133 | } mm_context_t; |
---|
156 | 134 | |
---|
| 135 | +static inline u16 mm_ctx_user_psize(mm_context_t *ctx) |
---|
| 136 | +{ |
---|
| 137 | + return ctx->hash_context->user_psize; |
---|
| 138 | +} |
---|
| 139 | + |
---|
| 140 | +static inline void mm_ctx_set_user_psize(mm_context_t *ctx, u16 user_psize) |
---|
| 141 | +{ |
---|
| 142 | + ctx->hash_context->user_psize = user_psize; |
---|
| 143 | +} |
---|
| 144 | + |
---|
| 145 | +static inline unsigned char *mm_ctx_low_slices(mm_context_t *ctx) |
---|
| 146 | +{ |
---|
| 147 | + return ctx->hash_context->low_slices_psize; |
---|
| 148 | +} |
---|
| 149 | + |
---|
| 150 | +static inline unsigned char *mm_ctx_high_slices(mm_context_t *ctx) |
---|
| 151 | +{ |
---|
| 152 | + return ctx->hash_context->high_slices_psize; |
---|
| 153 | +} |
---|
| 154 | + |
---|
| 155 | +static inline unsigned long mm_ctx_slb_addr_limit(mm_context_t *ctx) |
---|
| 156 | +{ |
---|
| 157 | + return ctx->hash_context->slb_addr_limit; |
---|
| 158 | +} |
---|
| 159 | + |
---|
| 160 | +static inline void mm_ctx_set_slb_addr_limit(mm_context_t *ctx, unsigned long limit) |
---|
| 161 | +{ |
---|
| 162 | + ctx->hash_context->slb_addr_limit = limit; |
---|
| 163 | +} |
---|
| 164 | + |
---|
| 165 | +static inline struct slice_mask *slice_mask_for_size(mm_context_t *ctx, int psize) |
---|
| 166 | +{ |
---|
| 167 | +#ifdef CONFIG_PPC_64K_PAGES |
---|
| 168 | + if (psize == MMU_PAGE_64K) |
---|
| 169 | + return &ctx->hash_context->mask_64k; |
---|
| 170 | +#endif |
---|
| 171 | +#ifdef CONFIG_HUGETLB_PAGE |
---|
| 172 | + if (psize == MMU_PAGE_16M) |
---|
| 173 | + return &ctx->hash_context->mask_16m; |
---|
| 174 | + if (psize == MMU_PAGE_16G) |
---|
| 175 | + return &ctx->hash_context->mask_16g; |
---|
| 176 | +#endif |
---|
| 177 | + BUG_ON(psize != MMU_PAGE_4K); |
---|
| 178 | + |
---|
| 179 | + return &ctx->hash_context->mask_4k; |
---|
| 180 | +} |
---|
| 181 | + |
---|
| 182 | +#ifdef CONFIG_PPC_SUBPAGE_PROT |
---|
| 183 | +static inline struct subpage_prot_table *mm_ctx_subpage_prot(mm_context_t *ctx) |
---|
| 184 | +{ |
---|
| 185 | + return ctx->hash_context->spt; |
---|
| 186 | +} |
---|
| 187 | +#endif |
---|
| 188 | + |
---|
157 | 189 | /* |
---|
158 | 190 | * The current system page and segment sizes |
---|
159 | 191 | */ |
---|
.. | .. |
---|
167 | 199 | void mmu_early_init_devtree(void); |
---|
168 | 200 | void hash__early_init_devtree(void); |
---|
169 | 201 | void radix__early_init_devtree(void); |
---|
170 | | -extern void radix_init_native(void); |
---|
| 202 | +#ifdef CONFIG_PPC_MEM_KEYS |
---|
| 203 | +void pkey_early_init_devtree(void); |
---|
| 204 | +#else |
---|
| 205 | +static inline void pkey_early_init_devtree(void) {} |
---|
| 206 | +#endif |
---|
| 207 | + |
---|
171 | 208 | extern void hash__early_init_mmu(void); |
---|
172 | 209 | extern void radix__early_init_mmu(void); |
---|
173 | | -static inline void early_init_mmu(void) |
---|
| 210 | +static inline void __init early_init_mmu(void) |
---|
174 | 211 | { |
---|
175 | 212 | if (radix_enabled()) |
---|
176 | 213 | return radix__early_init_mmu(); |
---|
.. | .. |
---|
187 | 224 | |
---|
188 | 225 | extern void hash__setup_initial_memory_limit(phys_addr_t first_memblock_base, |
---|
189 | 226 | phys_addr_t first_memblock_size); |
---|
190 | | -extern void radix__setup_initial_memory_limit(phys_addr_t first_memblock_base, |
---|
191 | | - phys_addr_t first_memblock_size); |
---|
192 | 227 | static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base, |
---|
193 | 228 | phys_addr_t first_memblock_size) |
---|
194 | 229 | { |
---|
195 | | - if (early_radix_enabled()) |
---|
196 | | - return radix__setup_initial_memory_limit(first_memblock_base, |
---|
197 | | - first_memblock_size); |
---|
| 230 | + /* |
---|
| 231 | + * Hash has more strict restrictions. At this point we don't |
---|
| 232 | + * know which translations we will pick. Hence go with hash |
---|
| 233 | + * restrictions. |
---|
| 234 | + */ |
---|
198 | 235 | return hash__setup_initial_memory_limit(first_memblock_base, |
---|
199 | 236 | first_memblock_size); |
---|
200 | 237 | } |
---|
201 | | - |
---|
202 | | -extern int (*register_process_table)(unsigned long base, unsigned long page_size, |
---|
203 | | - unsigned long tbl_size); |
---|
204 | 238 | |
---|
205 | 239 | #ifdef CONFIG_PPC_PSERIES |
---|
206 | 240 | extern void radix_init_pseries(void); |
---|
.. | .. |
---|
208 | 242 | static inline void radix_init_pseries(void) { }; |
---|
209 | 243 | #endif |
---|
210 | 244 | |
---|
211 | | -static inline int get_ea_context(mm_context_t *ctx, unsigned long ea) |
---|
| 245 | +#ifdef CONFIG_HOTPLUG_CPU |
---|
| 246 | +#define arch_clear_mm_cpumask_cpu(cpu, mm) \ |
---|
| 247 | + do { \ |
---|
| 248 | + if (cpumask_test_cpu(cpu, mm_cpumask(mm))) { \ |
---|
| 249 | + atomic_dec(&(mm)->context.active_cpus); \ |
---|
| 250 | + cpumask_clear_cpu(cpu, mm_cpumask(mm)); \ |
---|
| 251 | + } \ |
---|
| 252 | + } while (0) |
---|
| 253 | + |
---|
| 254 | +void cleanup_cpu_mmu_context(void); |
---|
| 255 | +#endif |
---|
| 256 | + |
---|
| 257 | +static inline int get_user_context(mm_context_t *ctx, unsigned long ea) |
---|
212 | 258 | { |
---|
213 | 259 | int index = ea >> MAX_EA_BITS_PER_CONTEXT; |
---|
214 | 260 | |
---|
.. | .. |
---|
223 | 269 | static inline unsigned long get_user_vsid(mm_context_t *ctx, |
---|
224 | 270 | unsigned long ea, int ssize) |
---|
225 | 271 | { |
---|
226 | | - unsigned long context = get_ea_context(ctx, ea); |
---|
| 272 | + unsigned long context = get_user_context(ctx, ea); |
---|
227 | 273 | |
---|
228 | 274 | return get_vsid(context, ea, ssize); |
---|
229 | 275 | } |
---|