linux/arch/arm64/mm/copypage.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   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.
   7 */
   8
   9#include <linux/bitops.h>
  10#include <linux/mm.h>
  11
  12#include <asm/page.h>
  13#include <asm/cacheflush.h>
  14#include <asm/cpufeature.h>
  15#include <asm/mte.h>
  16
  17void copy_highpage(struct page *to, struct page *from)
  18{
  19        struct page *kto = page_address(to);
  20        struct page *kfrom = page_address(from);
  21
  22        copy_page(kto, kfrom);
  23
  24        if (system_supports_mte() && test_bit(PG_mte_tagged, &from->flags)) {
  25                set_bit(PG_mte_tagged, &to->flags);
  26                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();
  35                mte_copy_page_tags(kto, kfrom);
  36        }
  37}
  38EXPORT_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);
  47