xref: /openbmc/linux/arch/arm64/mm/copypage.c (revision 921d161f)
1caab277bSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
21d18c47cSCatalin Marinas /*
31d18c47cSCatalin Marinas  * Based on arch/arm/mm/copypage.c
41d18c47cSCatalin Marinas  *
51d18c47cSCatalin Marinas  * Copyright (C) 2002 Deep Blue Solutions Ltd, All Rights Reserved.
61d18c47cSCatalin Marinas  * Copyright (C) 2012 ARM Ltd.
71d18c47cSCatalin Marinas  */
81d18c47cSCatalin Marinas 
92563776bSVincenzo Frascino #include <linux/bitops.h>
101d18c47cSCatalin Marinas #include <linux/mm.h>
111d18c47cSCatalin Marinas 
121d18c47cSCatalin Marinas #include <asm/page.h>
131d18c47cSCatalin Marinas #include <asm/cacheflush.h>
142563776bSVincenzo Frascino #include <asm/cpufeature.h>
152563776bSVincenzo Frascino #include <asm/mte.h>
161d18c47cSCatalin Marinas 
172563776bSVincenzo Frascino void copy_highpage(struct page *to, struct page *from)
181d18c47cSCatalin Marinas {
19*921d161fSTong Tiangen 	void *kto = page_address(to);
20*921d161fSTong Tiangen 	void *kfrom = page_address(from);
212563776bSVincenzo Frascino 
221d18c47cSCatalin Marinas 	copy_page(kto, kfrom);
232563776bSVincenzo Frascino 
242563776bSVincenzo Frascino 	if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) {
252563776bSVincenzo Frascino 		set_bit(PG_mte_tagged, &to->flags);
26e5b8d921SVincenzo Frascino 		page_kasan_tag_reset(to);
27e5b8d921SVincenzo Frascino 		/*
28e5b8d921SVincenzo Frascino 		 * We need smp_wmb() in between setting the flags and clearing the
29e5b8d921SVincenzo Frascino 		 * tags because if another thread reads page->flags and builds a
30e5b8d921SVincenzo Frascino 		 * tagged address out of it, there is an actual dependency to the
31e5b8d921SVincenzo Frascino 		 * memory access, but on the current thread we do not guarantee that
32e5b8d921SVincenzo Frascino 		 * the new page->flags are visible before the tags were updated.
33e5b8d921SVincenzo Frascino 		 */
34e5b8d921SVincenzo Frascino 		smp_wmb();
352563776bSVincenzo Frascino 		mte_copy_page_tags(kto, kfrom);
361d18c47cSCatalin Marinas 	}
372563776bSVincenzo Frascino }
382563776bSVincenzo Frascino EXPORT_SYMBOL(copy_highpage);
392563776bSVincenzo Frascino 
402563776bSVincenzo Frascino void copy_user_highpage(struct page *to, struct page *from,
412563776bSVincenzo Frascino 			unsigned long vaddr, struct vm_area_struct *vma)
422563776bSVincenzo Frascino {
432563776bSVincenzo Frascino 	copy_highpage(to, from);
442563776bSVincenzo Frascino 	flush_dcache_page(to);
452563776bSVincenzo Frascino }
462563776bSVincenzo Frascino EXPORT_SYMBOL_GPL(copy_user_highpage);
47