powerpc/mm/thp: Return pte address if we find trans_splitting.
[firefly-linux-kernel-4.4.55.git] / arch / powerpc / include / asm / kvm_book3s_64.h
index 2d81e202bdccb7e2d06b128e727da0fc84c4f125..ce5610aa124c0ba17c577a6ece734e2b19f40fd9 100644 (file)
@@ -281,40 +281,37 @@ static inline int hpte_cache_flags_ok(unsigned long ptel, unsigned long io_type)
 
 /*
  * If it's present and writable, atomically set dirty and referenced bits and
- * return the PTE, otherwise return 0. If we find a transparent hugepage
- * and if it is marked splitting we return 0;
+ * return the PTE, otherwise return 0.
  */
-static inline pte_t kvmppc_read_update_linux_pte(pte_t *ptep, int writing,
-                                                unsigned int hugepage)
+static inline pte_t kvmppc_read_update_linux_pte(pte_t *ptep, int writing)
 {
        pte_t old_pte, new_pte = __pte(0);
 
        while (1) {
-               old_pte = pte_val(*ptep);
+               /*
+                * Make sure we don't reload from ptep
+                */
+               old_pte = READ_ONCE(*ptep);
                /*
                 * wait until _PAGE_BUSY is clear then set it atomically
                 */
-               if (unlikely(old_pte & _PAGE_BUSY)) {
+               if (unlikely(pte_val(old_pte) & _PAGE_BUSY)) {
                        cpu_relax();
                        continue;
                }
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
-               /* If hugepage and is trans splitting return None */
-               if (unlikely(hugepage &&
-                            pmd_trans_splitting(pte_pmd(old_pte))))
-                       return __pte(0);
-#endif
                /* If pte is not present return None */
-               if (unlikely(!(old_pte & _PAGE_PRESENT)))
+               if (unlikely(!(pte_val(old_pte) & _PAGE_PRESENT)))
                        return __pte(0);
 
                new_pte = pte_mkyoung(old_pte);
                if (writing && pte_write(old_pte))
                        new_pte = pte_mkdirty(new_pte);
 
-               if (old_pte == __cmpxchg_u64((unsigned long *)ptep, old_pte,
-                                            new_pte))
+               if (pte_val(old_pte) == __cmpxchg_u64((unsigned long *)ptep,
+                                                     pte_val(old_pte),
+                                                     pte_val(new_pte))) {
                        break;
+               }
        }
        return new_pte;
 }
@@ -335,7 +332,7 @@ static inline bool hpte_read_permission(unsigned long pp, unsigned long key)
 {
        if (key)
                return PP_RWRX <= pp && pp <= PP_RXRX;
-       return 1;
+       return true;
 }
 
 static inline bool hpte_write_permission(unsigned long pp, unsigned long key)
@@ -373,7 +370,7 @@ static inline bool slot_is_aligned(struct kvm_memory_slot *memslot,
        unsigned long mask = (pagesize >> PAGE_SHIFT) - 1;
 
        if (pagesize <= PAGE_SIZE)
-               return 1;
+               return true;
        return !(memslot->base_gfn & mask) && !(memslot->npages & mask);
 }