#include <asm/book3s/64/hash-4k.h>
 #endif
 
+/* Bits to set in a PMD/PUD/PGD entry valid bit*/
+#define HASH_PMD_VAL_BITS              (0x8000000000000000UL)
+#define HASH_PUD_VAL_BITS              (0x8000000000000000UL)
+#define HASH_PGD_VAL_BITS              (0x8000000000000000UL)
+
 /*
  * Size of EA range mapped by our pagetables.
  */
 
 
 static inline int pmd_present(pmd_t pmd)
 {
+       /*
+        * A pmd is considerent present if _PAGE_PRESENT is set.
+        * We also need to consider the pmd present which is marked
+        * invalid during a split. Hence we look for _PAGE_INVALID
+        * if we find _PAGE_PRESENT cleared.
+        */
+       if (pmd_raw(pmd) & cpu_to_be64(_PAGE_PRESENT | _PAGE_INVALID))
+               return true;
 
-       return !pmd_none(pmd);
+       return false;
 }
 
 static inline int pmd_bad(pmd_t pmd)
 
 static inline int pud_present(pud_t pud)
 {
-       return !pud_none(pud);
+       return (pud_raw(pud) & cpu_to_be64(_PAGE_PRESENT));
 }
 
 extern struct page *pud_page(pud_t pud);
 
 static inline int pgd_present(pgd_t pgd)
 {
-       return !pgd_none(pgd);
+       return (pgd_raw(pgd) & cpu_to_be64(_PAGE_PRESENT));
 }
 
 static inline pte_t pgd_pte(pgd_t pgd)
 
         * 4k use hugepd format, so for hash set then to
         * zero
         */
-       __pmd_val_bits = 0;
-       __pud_val_bits = 0;
-       __pgd_val_bits = 0;
+       __pmd_val_bits = HASH_PMD_VAL_BITS;
+       __pud_val_bits = HASH_PUD_VAL_BITS;
+       __pgd_val_bits = HASH_PGD_VAL_BITS;
 
        __kernel_virt_start = H_KERN_VIRT_START;
        __kernel_virt_size = H_KERN_VIRT_SIZE;
 
                pmd_t *pmdp, pmd_t pmd)
 {
 #ifdef CONFIG_DEBUG_VM
-       WARN_ON(pte_present(pmd_pte(*pmdp)) && !pte_protnone(pmd_pte(*pmdp)));
+       /*
+        * Make sure hardware valid bit is not set. We don't do
+        * tlb flush for this update.
+        */
+       WARN_ON(pte_val(pmd_pte(*pmdp)) & _PAGE_PRESENT);
        assert_spin_locked(pmd_lockptr(mm, pmdp));
        WARN_ON(!(pmd_trans_huge(pmd) || pmd_devmap(pmd)));
 #endif
 {
        unsigned long old_pmd;
 
-       old_pmd = pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, 0);
+       old_pmd = pmd_hugepage_update(vma->vm_mm, address, pmdp, _PAGE_PRESENT, _PAGE_INVALID);
        flush_pmd_tlb_range(vma, address, address + HPAGE_PMD_SIZE);
        /*
         * This ensures that generic code that rely on IRQ disabling
 
                pte_t pte)
 {
        /*
-        * When handling numa faults, we already have the pte marked
-        * _PAGE_PRESENT, but we can be sure that it is not in hpte.
-        * Hence we can use set_pte_at for them.
+        * Make sure hardware valid bit is not set. We don't do
+        * tlb flush for this update.
         */
-       VM_WARN_ON(pte_present(*ptep) && !pte_protnone(*ptep));
+       VM_WARN_ON(pte_val(*ptep) & _PAGE_PRESENT);
 
        /* Add the pte bit when trying to set a pte */
        pte = __pte(pte_val(pte) | _PAGE_PTE);