ANDROID: mm: fix vma refcounting for SPF in vm_area_dup

vm_area_dup() should reset the vma refcount to avoid leaking the newly
created vma in case the original vma being copies has an elevated
refcount due to concurrent page fault.

Fixes: d9d7f843da68 ("ANDROID: mm: introduce vma refcounting to protect vma during SPF")
Bug: 253557903
Bug: 264933240
Change-Id: I11324ac5661823e9c97b71afe6a894a094439960
Signed-off-by: Suren Baghdasaryan <surenb@google.com>
(cherry picked from commit c24377e58ac888484c9a613074b2ea0c76ee7e95)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 6a5ba79..80b60b6 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -679,6 +679,15 @@
 	ANDROID_KABI_RESERVE(4);
 };
 
+static inline void INIT_VMA(struct vm_area_struct *vma)
+{
+#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
+	/* Start from 0 to use atomic_inc_unless_negative() in get_vma() */
+	atomic_set(&vma->file_ref_count, 0);
+#endif
+	INIT_LIST_HEAD(&vma->anon_vma_chain);
+}
+
 static inline void vma_init(struct vm_area_struct *vma, struct mm_struct *mm)
 {
 	static const struct vm_operations_struct dummy_vm_ops = {};
@@ -686,11 +695,7 @@
 	memset(vma, 0, sizeof(*vma));
 	vma->vm_mm = mm;
 	vma->vm_ops = &dummy_vm_ops;
-#ifdef CONFIG_SPECULATIVE_PAGE_FAULT
-        /* Start from 0 to use atomic_inc_unless_negative() in get_vma() */
-	atomic_set(&vma->file_ref_count, 0);
-#endif
-	INIT_LIST_HEAD(&vma->anon_vma_chain);
+	INIT_VMA(vma);
 }
 
 static inline void vma_set_anonymous(struct vm_area_struct *vma)
diff --git a/kernel/fork.c b/kernel/fork.c
index 2db857a..5b2a012 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -374,7 +374,7 @@
 		 * will be reinitialized.
 		 */
 		*new = data_race(*orig);
-		INIT_LIST_HEAD(&new->anon_vma_chain);
+		INIT_VMA(new);
 		new->vm_next = new->vm_prev = NULL;
 		dup_anon_vma_name(orig, new);
 	}