Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: PPC: Book3S HV: Add helpers for lock/unlock hpte

This adds helper routines for locking and unlocking HPTEs, and uses
them in the rest of the code. We don't change any locking rules in
this patch.

Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Signed-off-by: Alexander Graf <agraf@suse.de>

authored by

Aneesh Kumar K.V and committed by
Alexander Graf
a4bd6eb0 31037eca

+33 -31
+14
arch/powerpc/include/asm/kvm_book3s_64.h
··· 85 85 return old == 0; 86 86 } 87 87 88 + static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v) 89 + { 90 + hpte_v &= ~HPTE_V_HVLOCK; 91 + asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); 92 + hpte[0] = cpu_to_be64(hpte_v); 93 + } 94 + 95 + /* Without barrier */ 96 + static inline void __unlock_hpte(__be64 *hpte, unsigned long hpte_v) 97 + { 98 + hpte_v &= ~HPTE_V_HVLOCK; 99 + hpte[0] = cpu_to_be64(hpte_v); 100 + } 101 + 88 102 static inline int __hpte_actual_psize(unsigned int lp, int psize) 89 103 { 90 104 int i, shift;
+10 -15
arch/powerpc/kvm/book3s_64_mmu_hv.c
··· 338 338 v = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK; 339 339 gr = kvm->arch.revmap[index].guest_rpte; 340 340 341 - /* Unlock the HPTE */ 342 - asm volatile("lwsync" : : : "memory"); 343 - hptep[0] = cpu_to_be64(v); 341 + unlock_hpte(hptep, v); 344 342 preempt_enable(); 345 343 346 344 gpte->eaddr = eaddr; ··· 467 469 hpte[0] = be64_to_cpu(hptep[0]) & ~HPTE_V_HVLOCK; 468 470 hpte[1] = be64_to_cpu(hptep[1]); 469 471 hpte[2] = r = rev->guest_rpte; 470 - asm volatile("lwsync" : : : "memory"); 471 - hptep[0] = cpu_to_be64(hpte[0]); 472 + unlock_hpte(hptep, hpte[0]); 472 473 preempt_enable(); 473 474 474 475 if (hpte[0] != vcpu->arch.pgfault_hpte[0] || ··· 618 621 619 622 hptep[1] = cpu_to_be64(r); 620 623 eieio(); 621 - hptep[0] = cpu_to_be64(hpte[0]); 624 + __unlock_hpte(hptep, hpte[0]); 622 625 asm volatile("ptesync" : : : "memory"); 623 626 preempt_enable(); 624 627 if (page && hpte_is_writable(r)) ··· 639 642 return ret; 640 643 641 644 out_unlock: 642 - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); 645 + __unlock_hpte(hptep, be64_to_cpu(hptep[0])); 643 646 preempt_enable(); 644 647 goto out_put; 645 648 } ··· 768 771 } 769 772 } 770 773 unlock_rmap(rmapp); 771 - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); 774 + __unlock_hpte(hptep, be64_to_cpu(hptep[0])); 772 775 } 773 776 return 0; 774 777 } ··· 854 857 } 855 858 ret = 1; 856 859 } 857 - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); 860 + __unlock_hpte(hptep, be64_to_cpu(hptep[0])); 858 861 } while ((i = j) != head); 859 862 860 863 unlock_rmap(rmapp); ··· 971 974 972 975 /* Now check and modify the HPTE */ 973 976 if (!(hptep[0] & cpu_to_be64(HPTE_V_VALID))) { 974 - /* unlock and continue */ 975 - hptep[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); 977 + __unlock_hpte(hptep, be64_to_cpu(hptep[0])); 976 978 continue; 977 979 } 978 980 ··· 992 996 npages_dirty = n; 993 997 eieio(); 994 998 } 995 - v &= ~(HPTE_V_ABSENT | HPTE_V_HVLOCK); 999 + v &= ~HPTE_V_ABSENT; 996 1000 v |= HPTE_V_VALID; 997 - hptep[0] = cpu_to_be64(v); 1001 + __unlock_hpte(hptep, v); 998 1002 } while ((i = j) != head); 999 1003 1000 1004 unlock_rmap(rmapp); ··· 1214 1218 r &= ~HPTE_GR_MODIFIED; 1215 1219 revp->guest_rpte = r; 1216 1220 } 1217 - asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); 1218 - hptp[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); 1221 + unlock_hpte(hptp, be64_to_cpu(hptp[0])); 1219 1222 preempt_enable(); 1220 1223 if (!(valid == want_valid && (first_pass || dirty))) 1221 1224 ok = 0;
+9 -16
arch/powerpc/kvm/book3s_hv_rm_mmu.c
··· 150 150 return kvmppc_read_update_linux_pte(ptep, writing, hugepage_shift); 151 151 } 152 152 153 - static inline void unlock_hpte(__be64 *hpte, unsigned long hpte_v) 154 - { 155 - asm volatile(PPC_RELEASE_BARRIER "" : : : "memory"); 156 - hpte[0] = cpu_to_be64(hpte_v); 157 - } 158 - 159 153 long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags, 160 154 long pte_index, unsigned long pteh, unsigned long ptel, 161 155 pgd_t *pgdir, bool realmode, unsigned long *pte_idx_ret) ··· 265 271 u64 pte; 266 272 while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) 267 273 cpu_relax(); 268 - pte = be64_to_cpu(*hpte); 274 + pte = be64_to_cpu(hpte[0]); 269 275 if (!(pte & (HPTE_V_VALID | HPTE_V_ABSENT))) 270 276 break; 271 - *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK); 277 + __unlock_hpte(hpte, pte); 272 278 hpte += 2; 273 279 } 274 280 if (i == 8) ··· 284 290 285 291 while (!try_lock_hpte(hpte, HPTE_V_HVLOCK)) 286 292 cpu_relax(); 287 - pte = be64_to_cpu(*hpte); 293 + pte = be64_to_cpu(hpte[0]); 288 294 if (pte & (HPTE_V_VALID | HPTE_V_ABSENT)) { 289 - *hpte &= ~cpu_to_be64(HPTE_V_HVLOCK); 295 + __unlock_hpte(hpte, pte); 290 296 return H_PTEG_FULL; 291 297 } 292 298 } ··· 325 331 326 332 /* Write the first HPTE dword, unlocking the HPTE and making it valid */ 327 333 eieio(); 328 - hpte[0] = cpu_to_be64(pteh); 334 + __unlock_hpte(hpte, pteh); 329 335 asm volatile("ptesync" : : : "memory"); 330 336 331 337 *pte_idx_ret = pte_index; ··· 406 412 if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || 407 413 ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn) || 408 414 ((flags & H_ANDCOND) && (pte & avpn) != 0)) { 409 - hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); 415 + __unlock_hpte(hpte, pte); 410 416 return H_NOT_FOUND; 411 417 } 412 418 ··· 542 548 be64_to_cpu(hp[0]), be64_to_cpu(hp[1])); 543 549 rcbits = rev->guest_rpte & (HPTE_R_R|HPTE_R_C); 544 550 args[j] |= rcbits << (56 - 5); 545 - hp[0] = 0; 551 + __unlock_hpte(hp, 0); 546 552 } 547 553 } 548 554 ··· 568 574 pte = be64_to_cpu(hpte[0]); 569 575 if ((pte & (HPTE_V_ABSENT | HPTE_V_VALID)) == 0 || 570 576 ((flags & H_AVPN) && (pte & ~0x7fUL) != avpn)) { 571 - hpte[0] &= ~cpu_to_be64(HPTE_V_HVLOCK); 577 + __unlock_hpte(hpte, pte); 572 578 return H_NOT_FOUND; 573 579 } 574 580 ··· 749 755 /* Return with the HPTE still locked */ 750 756 return (hash << 3) + (i >> 1); 751 757 752 - /* Unlock and move on */ 753 - hpte[i] = cpu_to_be64(v); 758 + __unlock_hpte(&hpte[i], v); 754 759 } 755 760 756 761 if (val & HPTE_V_SECONDARY)