]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - arch/powerpc/platforms/pseries/lpar.c
powerpc/mm/radix: Use STD_MMU_64 to properly isolate hash related code
[mirror_ubuntu-jammy-kernel.git] / arch / powerpc / platforms / pseries / lpar.c
CommitLineData
1da177e4
LT
1/*
2 * pSeries_lpar.c
3 * Copyright (C) 2001 Todd Inglett, IBM Corporation
4 *
5 * pSeries LPAR support.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
f7ebf352
ME
22/* Enables debugging of low-level hash table routines - careful! */
23#undef DEBUG
1da177e4 24
1da177e4
LT
25#include <linux/kernel.h>
26#include <linux/dma-mapping.h>
463ce0e1 27#include <linux/console.h>
66b15db6 28#include <linux/export.h>
58995a9a 29#include <linux/jump_label.h>
1da177e4
LT
30#include <asm/processor.h>
31#include <asm/mmu.h>
32#include <asm/page.h>
33#include <asm/pgtable.h>
34#include <asm/machdep.h>
1da177e4 35#include <asm/mmu_context.h>
1da177e4
LT
36#include <asm/iommu.h>
37#include <asm/tlbflush.h>
38#include <asm/tlb.h>
39#include <asm/prom.h>
1da177e4 40#include <asm/cputable.h>
dcad47fc 41#include <asm/udbg.h>
2249ca9d 42#include <asm/smp.h>
c8cd093a 43#include <asm/trace.h>
f5339277 44#include <asm/firmware.h>
212bebb4 45#include <asm/plpar_wrappers.h>
c1caae3d 46#include <asm/kexec.h>
408cddd9 47#include <asm/fadump.h>
a1218720 48
21cf9133 49#include "pseries.h"
1da177e4 50
1a527286
AK
51/* Flag bits for H_BULK_REMOVE */
52#define HBR_REQUEST 0x4000000000000000UL
53#define HBR_RESPONSE 0x8000000000000000UL
54#define HBR_END 0xc000000000000000UL
55#define HBR_AVPN 0x0200000000000000UL
56#define HBR_ANDCOND 0x0100000000000000UL
57
1da177e4 58
b9377ffc 59/* in hvCall.S */
1da177e4 60EXPORT_SYMBOL(plpar_hcall);
b9377ffc 61EXPORT_SYMBOL(plpar_hcall9);
1da177e4 62EXPORT_SYMBOL(plpar_hcall_norets);
b9377ffc 63
1da177e4
LT
64void vpa_init(int cpu)
65{
66 int hwcpu = get_hard_smp_processor_id(cpu);
2f6093c8 67 unsigned long addr;
1da177e4 68 long ret;
cf9efce0
PM
69 struct paca_struct *pp;
70 struct dtl_entry *dtl;
233ccd0d 71
b89bdfb8
ME
72 /*
73 * The spec says it "may be problematic" if CPU x registers the VPA of
74 * CPU y. We should never do that, but wail if we ever do.
75 */
76 WARN_ON(cpu != smp_processor_id());
77
233ccd0d 78 if (cpu_has_feature(CPU_FTR_ALTIVEC))
8154c5d2 79 lppaca_of(cpu).vmxregs_in_use = 1;
233ccd0d 80
6e0b8bc9
ME
81 if (cpu_has_feature(CPU_FTR_ARCH_207S))
82 lppaca_of(cpu).ebb_regs_in_use = 1;
83
8154c5d2 84 addr = __pa(&lppaca_of(cpu));
2f6093c8 85 ret = register_vpa(hwcpu, addr);
1da177e4 86
2f6093c8 87 if (ret) {
711ef84e
AB
88 pr_err("WARNING: VPA registration for cpu %d (hw %d) of area "
89 "%lx failed with %ld\n", cpu, hwcpu, addr, ret);
2f6093c8
MN
90 return;
91 }
92 /*
93 * PAPR says this feature is SLB-Buffer but firmware never
94 * reports that. All SPLPAR support SLB shadow buffer.
95 */
1a8f6f97 96 addr = __pa(paca[cpu].slb_shadow_ptr);
2f6093c8
MN
97 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
98 ret = register_slb_shadow(hwcpu, addr);
99 if (ret)
711ef84e
AB
100 pr_err("WARNING: SLB shadow buffer registration for "
101 "cpu %d (hw %d) of area %lx failed with %ld\n",
102 cpu, hwcpu, addr, ret);
2f6093c8 103 }
cf9efce0
PM
104
105 /*
106 * Register dispatch trace log, if one has been allocated.
107 */
108 pp = &paca[cpu];
109 dtl = pp->dispatch_log;
110 if (dtl) {
111 pp->dtl_ridx = 0;
112 pp->dtl_curr = dtl;
113 lppaca_of(cpu).dtl_idx = 0;
114
115 /* hypervisor reads buffer length from this field */
7ffcf8ec 116 dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES);
cf9efce0
PM
117 ret = register_dtl(hwcpu, __pa(dtl));
118 if (ret)
711ef84e
AB
119 pr_err("WARNING: DTL registration of cpu %d (hw %d) "
120 "failed with %ld\n", smp_processor_id(),
121 hwcpu, ret);
cf9efce0
PM
122 lppaca_of(cpu).dtl_enable_mask = 2;
123 }
1da177e4
LT
124}
125
035223fb 126static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
5524a27d
AK
127 unsigned long vpn, unsigned long pa,
128 unsigned long rflags, unsigned long vflags,
b1022fbd 129 int psize, int apsize, int ssize)
1da177e4 130{
1da177e4
LT
131 unsigned long lpar_rc;
132 unsigned long flags;
133 unsigned long slot;
96e28449 134 unsigned long hpte_v, hpte_r;
1da177e4 135
3c726f8d 136 if (!(vflags & HPTE_V_BOLTED))
5524a27d
AK
137 pr_devel("hpte_insert(group=%lx, vpn=%016lx, "
138 "pa=%016lx, rflags=%lx, vflags=%lx, psize=%d)\n",
139 hpte_group, vpn, pa, rflags, vflags, psize);
3c726f8d 140
b1022fbd 141 hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID;
50de596d 142 hpte_r = hpte_encode_r(pa, psize, apsize, ssize) | rflags;
3c726f8d
BH
143
144 if (!(vflags & HPTE_V_BOLTED))
551a232c 145 pr_devel(" hpte_v=%016lx, hpte_r=%016lx\n", hpte_v, hpte_r);
3c726f8d 146
1da177e4
LT
147 /* Now fill in the actual HPTE */
148 /* Set CEC cookie to 0 */
149 /* Zero page = 0 */
150 /* I-cache Invalidate = 0 */
151 /* I-cache synchronize = 0 */
152 /* Exact = 0 */
153 flags = 0;
154
9ee820fa
BK
155 if (firmware_has_feature(FW_FEATURE_XCMO) && !(hpte_r & HPTE_R_N))
156 flags |= H_COALESCE_CAND;
1da177e4 157
b9377ffc 158 lpar_rc = plpar_pte_enter(flags, hpte_group, hpte_v, hpte_r, &slot);
706c8c93 159 if (unlikely(lpar_rc == H_PTEG_FULL)) {
3c726f8d 160 if (!(vflags & HPTE_V_BOLTED))
551a232c 161 pr_devel(" full\n");
1da177e4 162 return -1;
3c726f8d 163 }
1da177e4
LT
164
165 /*
166 * Since we try and ioremap PHBs we don't own, the pte insert
167 * will fail. However we must catch the failure in hash_page
168 * or we will loop forever, so return -2 in this case.
169 */
706c8c93 170 if (unlikely(lpar_rc != H_SUCCESS)) {
3c726f8d 171 if (!(vflags & HPTE_V_BOLTED))
4b8f63d9 172 pr_devel(" lpar err %ld\n", lpar_rc);
1da177e4 173 return -2;
3c726f8d
BH
174 }
175 if (!(vflags & HPTE_V_BOLTED))
551a232c 176 pr_devel(" -> slot: %lu\n", slot & 7);
1da177e4
LT
177
178 /* Because of iSeries, we have to pass down the secondary
179 * bucket bit here as well
180 */
96e28449 181 return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3);
1da177e4
LT
182}
183
184static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock);
185
186static long pSeries_lpar_hpte_remove(unsigned long hpte_group)
187{
188 unsigned long slot_offset;
189 unsigned long lpar_rc;
190 int i;
191 unsigned long dummy1, dummy2;
192
193 /* pick a random slot to start at */
194 slot_offset = mftb() & 0x7;
195
196 for (i = 0; i < HPTES_PER_GROUP; i++) {
197
198 /* don't remove a bolted entry */
199 lpar_rc = plpar_pte_remove(H_ANDCOND, hpte_group + slot_offset,
200 (0x1UL << 4), &dummy1, &dummy2);
706c8c93 201 if (lpar_rc == H_SUCCESS)
1da177e4 202 return i;
9fb26401
MW
203
204 /*
205 * The test for adjunct partition is performed before the
206 * ANDCOND test. H_RESOURCE may be returned, so we need to
207 * check for that as well.
208 */
209 BUG_ON(lpar_rc != H_NOT_FOUND && lpar_rc != H_RESOURCE);
1da177e4
LT
210
211 slot_offset++;
212 slot_offset &= 0x7;
213 }
214
215 return -1;
216}
217
218static void pSeries_lpar_hptab_clear(void)
219{
220 unsigned long size_bytes = 1UL << ppc64_pft_size;
221 unsigned long hpte_count = size_bytes >> 4;
d504bed6
MN
222 struct {
223 unsigned long pteh;
224 unsigned long ptel;
225 } ptes[4];
b7abc5c5 226 long lpar_rc;
bed9a315 227 unsigned long i, j;
d504bed6
MN
228
229 /* Read in batches of 4,
230 * invalidate only valid entries not in the VRMA
231 * hpte_count will be a multiple of 4
232 */
233 for (i = 0; i < hpte_count; i += 4) {
234 lpar_rc = plpar_pte_read_4_raw(0, i, (void *)ptes);
235 if (lpar_rc != H_SUCCESS)
236 continue;
237 for (j = 0; j < 4; j++){
238 if ((ptes[j].pteh & HPTE_V_VRMA_MASK) ==
239 HPTE_V_VRMA_MASK)
240 continue;
241 if (ptes[j].pteh & HPTE_V_VALID)
242 plpar_pte_remove_raw(0, i + j, 0,
243 &(ptes[j].pteh), &(ptes[j].ptel));
b7abc5c5
SS
244 }
245 }
e844b1ee
AB
246
247#ifdef __LITTLE_ENDIAN__
408cddd9
HB
248 /*
249 * Reset exceptions to big endian.
250 *
251 * FIXME this is a hack for kexec, we need to reset the exception
252 * endian before starting the new kernel and this is a convenient place
253 * to do it.
254 *
255 * This is also called on boot when a fadump happens. In that case we
256 * must not change the exception endian mode.
257 */
258 if (firmware_has_feature(FW_FEATURE_SET_MODE) && !is_fadump_active()) {
e844b1ee
AB
259 long rc;
260
261 rc = pseries_big_endian_exceptions();
262 /*
263 * At this point it is unlikely panic() will get anything
264 * out to the user, but at least this will stop us from
265 * continuing on further and creating an even more
266 * difficult to debug situation.
c1caae3d
HB
267 *
268 * There is a known problem when kdump'ing, if cpus are offline
269 * the above call will fail. Rather than panicking again, keep
270 * going and hope the kdump kernel is also little endian, which
271 * it usually is.
e844b1ee 272 */
c1caae3d 273 if (rc && !kdump_in_progress())
e844b1ee
AB
274 panic("Could not enable big endian exceptions");
275 }
276#endif
1da177e4
LT
277}
278
279/*
280 * NOTE: for updatepp ops we are fortunate that the linux "newpp" bits and
281 * the low 3 bits of flags happen to line up. So no transform is needed.
282 * We can probably optimize here and assume the high bits of newpp are
283 * already zero. For now I am paranoid.
284 */
3c726f8d
BH
285static long pSeries_lpar_hpte_updatepp(unsigned long slot,
286 unsigned long newpp,
5524a27d 287 unsigned long vpn,
db3d8534 288 int psize, int apsize,
aefa5688 289 int ssize, unsigned long inv_flags)
1da177e4
LT
290{
291 unsigned long lpar_rc;
292 unsigned long flags = (newpp & 7) | H_AVPN;
3c726f8d 293 unsigned long want_v;
1da177e4 294
5524a27d 295 want_v = hpte_encode_avpn(vpn, psize, ssize);
1da177e4 296
551a232c 297 pr_devel(" update: avpnv=%016lx, hash=%016lx, f=%lx, psize: %d ...",
f7ebf352 298 want_v, slot, flags, psize);
1da177e4 299
1189be65 300 lpar_rc = plpar_pte_protect(flags, slot, want_v);
3c726f8d 301
706c8c93 302 if (lpar_rc == H_NOT_FOUND) {
551a232c 303 pr_devel("not found !\n");
1da177e4 304 return -1;
3c726f8d
BH
305 }
306
551a232c 307 pr_devel("ok\n");
1da177e4 308
706c8c93 309 BUG_ON(lpar_rc != H_SUCCESS);
1da177e4
LT
310
311 return 0;
312}
313
4ad90c86 314static long __pSeries_lpar_hpte_find(unsigned long want_v, unsigned long hpte_group)
1da177e4 315{
4ad90c86
AK
316 long lpar_rc;
317 unsigned long i, j;
318 struct {
319 unsigned long pteh;
320 unsigned long ptel;
321 } ptes[4];
1da177e4 322
4ad90c86 323 for (i = 0; i < HPTES_PER_GROUP; i += 4, hpte_group += 4) {
1da177e4 324
4ad90c86
AK
325 lpar_rc = plpar_pte_read_4(0, hpte_group, (void *)ptes);
326 if (lpar_rc != H_SUCCESS)
327 continue;
1da177e4 328
4ad90c86
AK
329 for (j = 0; j < 4; j++) {
330 if (HPTE_V_COMPARE(ptes[j].pteh, want_v) &&
331 (ptes[j].pteh & HPTE_V_VALID))
332 return i + j;
333 }
334 }
1da177e4 335
4ad90c86 336 return -1;
1da177e4
LT
337}
338
5524a27d 339static long pSeries_lpar_hpte_find(unsigned long vpn, int psize, int ssize)
1da177e4 340{
1da177e4 341 long slot;
4ad90c86
AK
342 unsigned long hash;
343 unsigned long want_v;
344 unsigned long hpte_group;
1da177e4 345
5524a27d
AK
346 hash = hpt_hash(vpn, mmu_psize_defs[psize].shift, ssize);
347 want_v = hpte_encode_avpn(vpn, psize, ssize);
1189be65
PM
348
349 /* Bolted entries are always in the primary group */
4ad90c86
AK
350 hpte_group = (hash & htab_hash_mask) * HPTES_PER_GROUP;
351 slot = __pSeries_lpar_hpte_find(want_v, hpte_group);
352 if (slot < 0)
353 return -1;
354 return hpte_group + slot;
355}
1da177e4
LT
356
357static void pSeries_lpar_hpte_updateboltedpp(unsigned long newpp,
3c726f8d 358 unsigned long ea,
1189be65 359 int psize, int ssize)
1da177e4 360{
5524a27d
AK
361 unsigned long vpn;
362 unsigned long lpar_rc, slot, vsid, flags;
1da177e4 363
1189be65 364 vsid = get_kernel_vsid(ea, ssize);
5524a27d 365 vpn = hpt_vpn(ea, vsid, ssize);
1da177e4 366
5524a27d 367 slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
1da177e4
LT
368 BUG_ON(slot == -1);
369
370 flags = newpp & 7;
371 lpar_rc = plpar_pte_protect(flags, slot, 0);
372
706c8c93 373 BUG_ON(lpar_rc != H_SUCCESS);
1da177e4
LT
374}
375
5524a27d 376static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long vpn,
db3d8534
AK
377 int psize, int apsize,
378 int ssize, int local)
1da177e4 379{
3c726f8d 380 unsigned long want_v;
1da177e4
LT
381 unsigned long lpar_rc;
382 unsigned long dummy1, dummy2;
383
5524a27d
AK
384 pr_devel(" inval : slot=%lx, vpn=%016lx, psize: %d, local: %d\n",
385 slot, vpn, psize, local);
1da177e4 386
5524a27d 387 want_v = hpte_encode_avpn(vpn, psize, ssize);
1189be65 388 lpar_rc = plpar_pte_remove(H_AVPN, slot, want_v, &dummy1, &dummy2);
706c8c93 389 if (lpar_rc == H_NOT_FOUND)
1da177e4
LT
390 return;
391
706c8c93 392 BUG_ON(lpar_rc != H_SUCCESS);
1da177e4
LT
393}
394
e34aa03c 395#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1a527286
AK
396/*
397 * Limit iterations holding pSeries_lpar_tlbie_lock to 3. We also need
398 * to make sure that we avoid bouncing the hypervisor tlbie lock.
399 */
400#define PPC64_HUGE_HPTE_BATCH 12
401
402static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
403 unsigned long *vpn, int count,
404 int psize, int ssize)
405{
406 unsigned long param[8];
407 int i = 0, pix = 0, rc;
408 unsigned long flags = 0;
409 int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
410
411 if (lock_tlbie)
412 spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
413
414 for (i = 0; i < count; i++) {
415
416 if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
417 pSeries_lpar_hpte_invalidate(slot[i], vpn[i], psize, 0,
418 ssize, 0);
419 } else {
420 param[pix] = HBR_REQUEST | HBR_AVPN | slot[i];
421 param[pix+1] = hpte_encode_avpn(vpn[i], psize, ssize);
422 pix += 2;
423 if (pix == 8) {
424 rc = plpar_hcall9(H_BULK_REMOVE, param,
425 param[0], param[1], param[2],
426 param[3], param[4], param[5],
427 param[6], param[7]);
428 BUG_ON(rc != H_SUCCESS);
429 pix = 0;
430 }
431 }
432 }
433 if (pix) {
434 param[pix] = HBR_END;
435 rc = plpar_hcall9(H_BULK_REMOVE, param, param[0], param[1],
436 param[2], param[3], param[4], param[5],
437 param[6], param[7]);
438 BUG_ON(rc != H_SUCCESS);
439 }
440
441 if (lock_tlbie)
442 spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
443}
444
fa1f8ae8
AK
445static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
446 unsigned long addr,
447 unsigned char *hpte_slot_array,
d557b098 448 int psize, int ssize, int local)
1a527286 449{
fa1f8ae8 450 int i, index = 0;
1a527286
AK
451 unsigned long s_addr = addr;
452 unsigned int max_hpte_count, valid;
453 unsigned long vpn_array[PPC64_HUGE_HPTE_BATCH];
454 unsigned long slot_array[PPC64_HUGE_HPTE_BATCH];
fa1f8ae8 455 unsigned long shift, hidx, vpn = 0, hash, slot;
1a527286
AK
456
457 shift = mmu_psize_defs[psize].shift;
458 max_hpte_count = 1U << (PMD_SHIFT - shift);
459
460 for (i = 0; i < max_hpte_count; i++) {
461 valid = hpte_valid(hpte_slot_array, i);
462 if (!valid)
463 continue;
464 hidx = hpte_hash_index(hpte_slot_array, i);
465
466 /* get the vpn */
467 addr = s_addr + (i * (1ul << shift));
1a527286
AK
468 vpn = hpt_vpn(addr, vsid, ssize);
469 hash = hpt_hash(vpn, shift, ssize);
470 if (hidx & _PTEIDX_SECONDARY)
471 hash = ~hash;
472
473 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
474 slot += hidx & _PTEIDX_GROUP_IX;
475
476 slot_array[index] = slot;
477 vpn_array[index] = vpn;
478 if (index == PPC64_HUGE_HPTE_BATCH - 1) {
479 /*
480 * Now do a bluk invalidate
481 */
482 __pSeries_lpar_hugepage_invalidate(slot_array,
483 vpn_array,
484 PPC64_HUGE_HPTE_BATCH,
485 psize, ssize);
486 index = 0;
487 } else
488 index++;
489 }
490 if (index)
491 __pSeries_lpar_hugepage_invalidate(slot_array, vpn_array,
492 index, psize, ssize);
493}
e34aa03c
AK
494#else
495static void pSeries_lpar_hugepage_invalidate(unsigned long vsid,
496 unsigned long addr,
497 unsigned char *hpte_slot_array,
498 int psize, int ssize, int local)
499{
500 WARN(1, "%s called without THP support\n", __func__);
501}
502#endif
1a527286 503
27828f98
DG
504static int pSeries_lpar_hpte_removebolted(unsigned long ea,
505 int psize, int ssize)
f8c8803b 506{
5524a27d
AK
507 unsigned long vpn;
508 unsigned long slot, vsid;
f8c8803b
BP
509
510 vsid = get_kernel_vsid(ea, ssize);
5524a27d 511 vpn = hpt_vpn(ea, vsid, ssize);
f8c8803b 512
5524a27d 513 slot = pSeries_lpar_hpte_find(vpn, psize, ssize);
27828f98
DG
514 if (slot == -1)
515 return -ENOENT;
516
db3d8534
AK
517 /*
518 * lpar doesn't use the passed actual page size
519 */
520 pSeries_lpar_hpte_invalidate(slot, vpn, psize, 0, ssize, 0);
27828f98 521 return 0;
f8c8803b
BP
522}
523
1da177e4
LT
524/*
525 * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
526 * lock.
527 */
035223fb 528static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
1da177e4 529{
5524a27d 530 unsigned long vpn;
f03e64f2 531 unsigned long i, pix, rc;
12e86f92 532 unsigned long flags = 0;
69111bac 533 struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
44ae3ab3 534 int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
f03e64f2 535 unsigned long param[9];
f03e64f2
PM
536 unsigned long hash, index, shift, hidx, slot;
537 real_pte_t pte;
1189be65 538 int psize, ssize;
1da177e4
LT
539
540 if (lock_tlbie)
541 spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags);
542
f03e64f2 543 psize = batch->psize;
1189be65 544 ssize = batch->ssize;
f03e64f2
PM
545 pix = 0;
546 for (i = 0; i < number; i++) {
5524a27d 547 vpn = batch->vpn[i];
f03e64f2 548 pte = batch->pte[i];
5524a27d
AK
549 pte_iterate_hashed_subpages(pte, psize, vpn, index, shift) {
550 hash = hpt_hash(vpn, shift, ssize);
f03e64f2
PM
551 hidx = __rpte_to_hidx(pte, index);
552 if (hidx & _PTEIDX_SECONDARY)
553 hash = ~hash;
554 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;
555 slot += hidx & _PTEIDX_GROUP_IX;
12e86f92 556 if (!firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
db3d8534
AK
557 /*
558 * lpar doesn't use the passed actual page size
559 */
5524a27d 560 pSeries_lpar_hpte_invalidate(slot, vpn, psize,
db3d8534 561 0, ssize, local);
12e86f92
PM
562 } else {
563 param[pix] = HBR_REQUEST | HBR_AVPN | slot;
5524a27d 564 param[pix+1] = hpte_encode_avpn(vpn, psize,
1189be65 565 ssize);
12e86f92
PM
566 pix += 2;
567 if (pix == 8) {
568 rc = plpar_hcall9(H_BULK_REMOVE, param,
f03e64f2
PM
569 param[0], param[1], param[2],
570 param[3], param[4], param[5],
571 param[6], param[7]);
12e86f92
PM
572 BUG_ON(rc != H_SUCCESS);
573 pix = 0;
574 }
f03e64f2
PM
575 }
576 } pte_iterate_hashed_end();
577 }
578 if (pix) {
579 param[pix] = HBR_END;
580 rc = plpar_hcall9(H_BULK_REMOVE, param, param[0], param[1],
581 param[2], param[3], param[4], param[5],
582 param[6], param[7]);
583 BUG_ON(rc != H_SUCCESS);
584 }
1da177e4
LT
585
586 if (lock_tlbie)
587 spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
588}
589
4e89a2d8
WS
590static int __init disable_bulk_remove(char *str)
591{
592 if (strcmp(str, "off") == 0 &&
593 firmware_has_feature(FW_FEATURE_BULK_REMOVE)) {
594 printk(KERN_INFO "Disabling BULK_REMOVE firmware feature");
595 powerpc_firmware_features &= ~FW_FEATURE_BULK_REMOVE;
596 }
597 return 1;
598}
599
600__setup("bulk_remove=", disable_bulk_remove);
601
7d0daae4 602void __init hpte_init_lpar(void)
1da177e4
LT
603{
604 ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate;
605 ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp;
606 ppc_md.hpte_updateboltedpp = pSeries_lpar_hpte_updateboltedpp;
607 ppc_md.hpte_insert = pSeries_lpar_hpte_insert;
608 ppc_md.hpte_remove = pSeries_lpar_hpte_remove;
f8c8803b 609 ppc_md.hpte_removebolted = pSeries_lpar_hpte_removebolted;
1da177e4
LT
610 ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
611 ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear;
1a527286 612 ppc_md.hugepage_invalidate = pSeries_lpar_hugepage_invalidate;
1da177e4 613}
14f966e7
RJ
614
615#ifdef CONFIG_PPC_SMLPAR
616#define CMO_FREE_HINT_DEFAULT 1
617static int cmo_free_hint_flag = CMO_FREE_HINT_DEFAULT;
618
619static int __init cmo_free_hint(char *str)
620{
621 char *parm;
622 parm = strstrip(str);
623
624 if (strcasecmp(parm, "no") == 0 || strcasecmp(parm, "off") == 0) {
625 printk(KERN_INFO "cmo_free_hint: CMO free page hinting is not active.\n");
626 cmo_free_hint_flag = 0;
627 return 1;
628 }
629
630 cmo_free_hint_flag = 1;
631 printk(KERN_INFO "cmo_free_hint: CMO free page hinting is active.\n");
632
633 if (strcasecmp(parm, "yes") == 0 || strcasecmp(parm, "on") == 0)
634 return 1;
635
636 return 0;
637}
638
639__setup("cmo_free_hint=", cmo_free_hint);
640
641static void pSeries_set_page_state(struct page *page, int order,
642 unsigned long state)
643{
644 int i, j;
645 unsigned long cmo_page_sz, addr;
646
647 cmo_page_sz = cmo_get_page_size();
648 addr = __pa((unsigned long)page_address(page));
649
650 for (i = 0; i < (1 << order); i++, addr += PAGE_SIZE) {
651 for (j = 0; j < PAGE_SIZE; j += cmo_page_sz)
652 plpar_hcall_norets(H_PAGE_INIT, state, addr + j, 0);
653 }
654}
655
656void arch_free_page(struct page *page, int order)
657{
658 if (!cmo_free_hint_flag || !firmware_has_feature(FW_FEATURE_CMO))
659 return;
660
661 pSeries_set_page_state(page, order, H_PAGE_SET_UNUSED);
662}
663EXPORT_SYMBOL(arch_free_page);
664
665#endif
c8cd093a
AB
666
667#ifdef CONFIG_TRACEPOINTS
d4fe0965 668#ifdef HAVE_JUMP_LABEL
cc1adb5f
AB
669struct static_key hcall_tracepoint_key = STATIC_KEY_INIT;
670
671void hcall_tracepoint_regfunc(void)
672{
673 static_key_slow_inc(&hcall_tracepoint_key);
674}
675
676void hcall_tracepoint_unregfunc(void)
677{
678 static_key_slow_dec(&hcall_tracepoint_key);
679}
680#else
c8cd093a
AB
681/*
682 * We optimise our hcall path by placing hcall_tracepoint_refcount
683 * directly in the TOC so we can check if the hcall tracepoints are
684 * enabled via a single load.
685 */
686
687/* NB: reg/unreg are called while guarded with the tracepoints_mutex */
688extern long hcall_tracepoint_refcount;
689
690void hcall_tracepoint_regfunc(void)
691{
692 hcall_tracepoint_refcount++;
693}
694
695void hcall_tracepoint_unregfunc(void)
696{
697 hcall_tracepoint_refcount--;
698}
cc1adb5f
AB
699#endif
700
701/*
702 * Since the tracing code might execute hcalls we need to guard against
703 * recursion. One example of this are spinlocks calling H_YIELD on
704 * shared processor partitions.
705 */
706static DEFINE_PER_CPU(unsigned int, hcall_trace_depth);
707
c8cd093a 708
6f26353c 709void __trace_hcall_entry(unsigned long opcode, unsigned long *args)
c8cd093a 710{
57cdfdf8
AB
711 unsigned long flags;
712 unsigned int *depth;
713
a5ccfee0
AB
714 /*
715 * We cannot call tracepoints inside RCU idle regions which
716 * means we must not trace H_CEDE.
717 */
718 if (opcode == H_CEDE)
719 return;
720
57cdfdf8
AB
721 local_irq_save(flags);
722
69111bac 723 depth = this_cpu_ptr(&hcall_trace_depth);
57cdfdf8
AB
724
725 if (*depth)
726 goto out;
727
728 (*depth)++;
e4f387d8 729 preempt_disable();
6f26353c 730 trace_hcall_entry(opcode, args);
57cdfdf8
AB
731 (*depth)--;
732
733out:
734 local_irq_restore(flags);
c8cd093a
AB
735}
736
6f26353c
AB
737void __trace_hcall_exit(long opcode, unsigned long retval,
738 unsigned long *retbuf)
c8cd093a 739{
57cdfdf8
AB
740 unsigned long flags;
741 unsigned int *depth;
742
a5ccfee0
AB
743 if (opcode == H_CEDE)
744 return;
745
57cdfdf8
AB
746 local_irq_save(flags);
747
69111bac 748 depth = this_cpu_ptr(&hcall_trace_depth);
57cdfdf8
AB
749
750 if (*depth)
751 goto out;
752
753 (*depth)++;
6f26353c 754 trace_hcall_exit(opcode, retval, retbuf);
e4f387d8 755 preempt_enable();
57cdfdf8
AB
756 (*depth)--;
757
758out:
759 local_irq_restore(flags);
c8cd093a
AB
760}
761#endif
9ee820fa
BK
762
763/**
764 * h_get_mpp
765 * H_GET_MPP hcall returns info in 7 parms
766 */
767int h_get_mpp(struct hvcall_mpp_data *mpp_data)
768{
769 int rc;
770 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE];
771
772 rc = plpar_hcall9(H_GET_MPP, retbuf);
773
774 mpp_data->entitled_mem = retbuf[0];
775 mpp_data->mapped_mem = retbuf[1];
776
777 mpp_data->group_num = (retbuf[2] >> 2 * 8) & 0xffff;
778 mpp_data->pool_num = retbuf[2] & 0xffff;
779
780 mpp_data->mem_weight = (retbuf[3] >> 7 * 8) & 0xff;
781 mpp_data->unallocated_mem_weight = (retbuf[3] >> 6 * 8) & 0xff;
b0d436c7 782 mpp_data->unallocated_entitlement = retbuf[3] & 0xffffffffffffUL;
9ee820fa
BK
783
784 mpp_data->pool_size = retbuf[4];
785 mpp_data->loan_request = retbuf[5];
786 mpp_data->backing_mem = retbuf[6];
787
788 return rc;
789}
790EXPORT_SYMBOL(h_get_mpp);
791
792int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data)
793{
794 int rc;
795 unsigned long retbuf[PLPAR_HCALL9_BUFSIZE] = { 0 };
796
797 rc = plpar_hcall9(H_GET_MPP_X, retbuf);
798
799 mpp_x_data->coalesced_bytes = retbuf[0];
800 mpp_x_data->pool_coalesced_bytes = retbuf[1];
801 mpp_x_data->pool_purr_cycles = retbuf[2];
802 mpp_x_data->pool_spurr_cycles = retbuf[3];
803
804 return rc;
805}