162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Based on arch/arm/mm/copypage.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2002 Deep Blue Solutions Ltd, All Rights Reserved.
662306a36Sopenharmony_ci * Copyright (C) 2012 ARM Ltd.
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/bitops.h>
1062306a36Sopenharmony_ci#include <linux/mm.h>
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci#include <asm/page.h>
1362306a36Sopenharmony_ci#include <asm/cacheflush.h>
1462306a36Sopenharmony_ci#include <asm/cpufeature.h>
1562306a36Sopenharmony_ci#include <asm/mte.h>
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_civoid copy_highpage(struct page *to, struct page *from)
1862306a36Sopenharmony_ci{
1962306a36Sopenharmony_ci	void *kto = page_address(to);
2062306a36Sopenharmony_ci	void *kfrom = page_address(from);
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci	copy_page(kto, kfrom);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	if (kasan_hw_tags_enabled())
2562306a36Sopenharmony_ci		page_kasan_tag_reset(to);
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	if (system_supports_mte() && page_mte_tagged(from)) {
2862306a36Sopenharmony_ci		/* It's a new page, shouldn't have been tagged yet */
2962306a36Sopenharmony_ci		WARN_ON_ONCE(!try_page_mte_tagging(to));
3062306a36Sopenharmony_ci		mte_copy_page_tags(kto, kfrom);
3162306a36Sopenharmony_ci		set_page_mte_tagged(to);
3262306a36Sopenharmony_ci	}
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ciEXPORT_SYMBOL(copy_highpage);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_civoid copy_user_highpage(struct page *to, struct page *from,
3762306a36Sopenharmony_ci			unsigned long vaddr, struct vm_area_struct *vma)
3862306a36Sopenharmony_ci{
3962306a36Sopenharmony_ci	copy_highpage(to, from);
4062306a36Sopenharmony_ci	flush_dcache_page(to);
4162306a36Sopenharmony_ci}
4262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(copy_user_highpage);
43