diff options
| -rw-r--r-- | arch/powerpc/platforms/pseries/lpar.c | 51 | ||||
| -rw-r--r-- | include/asm-powerpc/hvcall.h | 1 |
2 files changed, 47 insertions, 5 deletions
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 721436db3ef0..5a684fbd8f27 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c | |||
| @@ -502,23 +502,64 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va, | |||
| 502 | BUG_ON(lpar_rc != H_SUCCESS); | 502 | BUG_ON(lpar_rc != H_SUCCESS); |
| 503 | } | 503 | } |
| 504 | 504 | ||
| 505 | /* Flag bits for H_BULK_REMOVE */ | ||
| 506 | #define HBR_REQUEST 0x4000000000000000UL | ||
| 507 | #define HBR_RESPONSE 0x8000000000000000UL | ||
| 508 | #define HBR_END 0xc000000000000000UL | ||
| 509 | #define HBR_AVPN 0x0200000000000000UL | ||
| 510 | #define HBR_ANDCOND 0x0100000000000000UL | ||
| 511 | |||
| 505 | /* | 512 | /* |
| 506 | * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie | 513 | * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie |
| 507 | * lock. | 514 | * lock. |
| 508 | */ | 515 | */ |
| 509 | static void pSeries_lpar_flush_hash_range(unsigned long number, int local) | 516 | static void pSeries_lpar_flush_hash_range(unsigned long number, int local) |
| 510 | { | 517 | { |
| 511 | int i; | 518 | unsigned long i, pix, rc; |
| 512 | unsigned long flags = 0; | 519 | unsigned long flags; |
| 513 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); | 520 | struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch); |
| 514 | int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); | 521 | int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE); |
| 522 | unsigned long param[9]; | ||
| 523 | unsigned long va; | ||
| 524 | unsigned long hash, index, shift, hidx, slot; | ||
| 525 | real_pte_t pte; | ||
| 526 | int psize; | ||
| 515 | 527 | ||
| 516 | if (lock_tlbie) | 528 | if (lock_tlbie) |
| 517 | spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); | 529 | spin_lock_irqsave(&pSeries_lpar_tlbie_lock, flags); |
| 518 | 530 | ||
| 519 | for (i = 0; i < number; i++) | 531 | psize = batch->psize; |
| 520 | flush_hash_page(batch->vaddr[i], batch->pte[i], | 532 | pix = 0; |
| 521 | batch->psize, local); | 533 | for (i = 0; i < number; i++) { |
| 534 | va = batch->vaddr[i]; | ||
| 535 | pte = batch->pte[i]; | ||
| 536 | pte_iterate_hashed_subpages(pte, psize, va, index, shift) { | ||
| 537 | hash = hpt_hash(va, shift); | ||
| 538 | hidx = __rpte_to_hidx(pte, index); | ||
| 539 | if (hidx & _PTEIDX_SECONDARY) | ||
| 540 | hash = ~hash; | ||
| 541 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | ||
| 542 | slot += hidx & _PTEIDX_GROUP_IX; | ||
| 543 | param[pix] = HBR_REQUEST | HBR_AVPN | slot; | ||
| 544 | param[pix+1] = hpte_encode_v(va, psize) & HPTE_V_AVPN; | ||
| 545 | pix += 2; | ||
| 546 | if (pix == 8) { | ||
| 547 | rc = plpar_hcall9(H_BULK_REMOVE, param, | ||
| 548 | param[0], param[1], param[2], | ||
| 549 | param[3], param[4], param[5], | ||
| 550 | param[6], param[7]); | ||
| 551 | BUG_ON(rc != H_SUCCESS); | ||
| 552 | pix = 0; | ||
| 553 | } | ||
| 554 | } pte_iterate_hashed_end(); | ||
| 555 | } | ||
| 556 | if (pix) { | ||
| 557 | param[pix] = HBR_END; | ||
| 558 | rc = plpar_hcall9(H_BULK_REMOVE, param, param[0], param[1], | ||
| 559 | param[2], param[3], param[4], param[5], | ||
| 560 | param[6], param[7]); | ||
| 561 | BUG_ON(rc != H_SUCCESS); | ||
| 562 | } | ||
| 522 | 563 | ||
| 523 | if (lock_tlbie) | 564 | if (lock_tlbie) |
| 524 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); | 565 | spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); |
diff --git a/include/asm-powerpc/hvcall.h b/include/asm-powerpc/hvcall.h index 7a500732b671..60977806d2f4 100644 --- a/include/asm-powerpc/hvcall.h +++ b/include/asm-powerpc/hvcall.h | |||
| @@ -168,6 +168,7 @@ | |||
| 168 | #define H_FREE_LOGICAL_LAN 0x118 | 168 | #define H_FREE_LOGICAL_LAN 0x118 |
| 169 | #define H_ADD_LOGICAL_LAN_BUFFER 0x11C | 169 | #define H_ADD_LOGICAL_LAN_BUFFER 0x11C |
| 170 | #define H_SEND_LOGICAL_LAN 0x120 | 170 | #define H_SEND_LOGICAL_LAN 0x120 |
| 171 | #define H_BULK_REMOVE 0x124 | ||
| 171 | #define H_MULTICAST_CTRL 0x130 | 172 | #define H_MULTICAST_CTRL 0x130 |
| 172 | #define H_SET_XDABR 0x134 | 173 | #define H_SET_XDABR 0x134 |
| 173 | #define H_STUFF_TCE 0x138 | 174 | #define H_STUFF_TCE 0x138 |
