blob: b5447e53cd73ee48ae65ecb90be18b3529bc4d34 [file] [log] [blame]
Thomas Gleixnercaab2772019-06-03 07:44:50 +02001// SPDX-License-Identifier: GPL-2.0-only
Catalin Marinas1d18c472012-03-05 11:49:27 +00002/*
3 * Based on arch/arm/mm/copypage.c
4 *
5 * Copyright (C) 2002 Deep Blue Solutions Ltd, All Rights Reserved.
6 * Copyright (C) 2012 ARM Ltd.
Catalin Marinas1d18c472012-03-05 11:49:27 +00007 */
8
Vincenzo Frascino25637762019-08-06 11:37:53 +01009#include <linux/bitops.h>
Catalin Marinas1d18c472012-03-05 11:49:27 +000010#include <linux/mm.h>
11
12#include <asm/page.h>
13#include <asm/cacheflush.h>
Vincenzo Frascino25637762019-08-06 11:37:53 +010014#include <asm/cpufeature.h>
15#include <asm/mte.h>
Catalin Marinas1d18c472012-03-05 11:49:27 +000016
Vincenzo Frascino25637762019-08-06 11:37:53 +010017void copy_highpage(struct page *to, struct page *from)
Catalin Marinas1d18c472012-03-05 11:49:27 +000018{
Vincenzo Frascino25637762019-08-06 11:37:53 +010019 struct page *kto = page_address(to);
20 struct page *kfrom = page_address(from);
21
Catalin Marinas1d18c472012-03-05 11:49:27 +000022 copy_page(kto, kfrom);
Vincenzo Frascino25637762019-08-06 11:37:53 +010023
24 if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) {
25 set_bit(PG_mte_tagged, &to->flags);
Vincenzo Frascinod7095e22020-12-22 12:01:31 -080026 page_kasan_tag_reset(to);
27 /*
28 * We need smp_wmb() in between setting the flags and clearing the
29 * tags because if another thread reads page->flags and builds a
30 * tagged address out of it, there is an actual dependency to the
31 * memory access, but on the current thread we do not guarantee that
32 * the new page->flags are visible before the tags were updated.
33 */
34 smp_wmb();
Vincenzo Frascino25637762019-08-06 11:37:53 +010035 mte_copy_page_tags(kto, kfrom);
36 }
Catalin Marinas1d18c472012-03-05 11:49:27 +000037}
Vincenzo Frascino25637762019-08-06 11:37:53 +010038EXPORT_SYMBOL(copy_highpage);
39
40void copy_user_highpage(struct page *to, struct page *from,
41 unsigned long vaddr, struct vm_area_struct *vma)
42{
43 copy_highpage(to, from);
44 flush_dcache_page(to);
45}
46EXPORT_SYMBOL_GPL(copy_user_highpage);