ANDROID: 16K: Fixup padding vm_flags bits on VMA splits

In some cases VMAs are split without the mmap write lock held;
later the lock is taken to fixup vm_flags of the original VMA.
Since some uppper bits of vm_flags are used to encode the ELF
padding ranges, they need to be modified on splits. This is
usually handled correctly by __split_vma(). However in the above
case, the flags get over witten later under the write lock.

Preserve vm_flag bits on reset to correctly represent padding.

Bug: 370026937
Bug: 357901498
Change-Id: I1cb75419e614791a47cbdb0341373f619daf0bf2
Signed-off-by: Kalesh Singh <kaleshsingh@google.com>
diff --git a/include/linux/mm.h b/include/linux/mm.h
index b855631..50e060f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -27,6 +27,7 @@
 #include <linux/sizes.h>
 #include <linux/sched.h>
 #include <linux/pgtable.h>
+#include <linux/pgsize_migration_inline.h>
 #include <linux/kasan.h>
 #include <linux/page_pinner.h>
 #include <linux/memremap.h>
@@ -844,6 +845,8 @@ static inline void vm_flags_reset(struct vm_area_struct *vma,
 				  vm_flags_t flags)
 {
 	vma_assert_write_locked(vma);
+	/* Preserve padding flags */
+	flags = vma_pad_fixup_flags(vma, flags);
 	vm_flags_init(vma, flags);
 }
 
@@ -851,6 +854,8 @@ static inline void vm_flags_reset_once(struct vm_area_struct *vma,
 				       vm_flags_t flags)
 {
 	vma_assert_write_locked(vma);
+	/* Preserve padding flags */
+	flags = vma_pad_fixup_flags(vma, flags);
 	WRITE_ONCE(ACCESS_PRIVATE(vma, __vm_flags), flags);
 }
 
diff --git a/mm/mlock.c b/mm/mlock.c
index 73e5c93..51234dc 100644
--- a/mm/mlock.c
+++ b/mm/mlock.c
@@ -533,7 +533,7 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,
 	if ((newflags & VM_LOCKED) && (oldflags & VM_LOCKED)) {
 		/* No work to do, and mlocking twice would be wrong */
 		vma_start_write(vma);
-		vm_flags_reset(vma, vma_pad_fixup_flags(vma, newflags));
+		vm_flags_reset(vma, newflags);
 	} else {
 		mlock_vma_pages_range(vma, start, end, newflags);
 	}
diff --git a/mm/mprotect.c b/mm/mprotect.c
index ab3eb62..3c57f1d 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -661,7 +661,7 @@ mprotect_fixup(struct vma_iterator *vmi, struct mmu_gather *tlb,
 	 * held in write mode.
 	 */
 	vma_start_write(vma);
-	vm_flags_reset(vma, vma_pad_fixup_flags(vma, newflags));
+	vm_flags_reset(vma, newflags);
 	if (vma_wants_manual_pte_write_upgrade(vma))
 		mm_cp_flags |= MM_CP_TRY_CHANGE_WRITABLE;
 	vma_set_page_prot(vma);