diff --git a/mm/memory.c b/mm/memory.c
index 601159a46ab64e538dc1c2cbe710776e3ecb5208..160f5b503eaddeb5880cc0c4ac63c08821074e5c 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1577,7 +1577,14 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
 		entry = mk_pte(new_page, vma->vm_page_prot);
 		entry = maybe_mkwrite(pte_mkdirty(entry), vma);
 		lazy_mmu_prot_update(entry);
-		ptep_establish(vma, address, page_table, entry);
+		/*
+		 * Clear the pte entry and flush it first, before updating the
+		 * pte with the new entry. This will avoid a race condition
+		 * seen in the presence of one thread doing SMC and another
+		 * thread doing COW.
+		 */
+		ptep_clear_flush(vma, address, page_table);
+		set_pte_at(mm, address, page_table, entry);
 		update_mmu_cache(vma, address, entry);
 		lru_cache_add_active(new_page);
 		page_add_new_anon_rmap(new_page, vma, address);