1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Copyright (C) 2020 ARM Ltd.
4 */
5#ifndef __ASM_MTE_H
6#define __ASM_MTE_H
7
8#define MTE_GRANULE_SIZE	UL(16)
9#define MTE_GRANULE_MASK	(~(MTE_GRANULE_SIZE - 1))
10#define MTE_TAG_SHIFT		56
11#define MTE_TAG_SIZE		4
12
13#ifndef __ASSEMBLY__
14
15#include <linux/page-flags.h>
16
17#include <asm/pgtable-types.h>
18
19void mte_clear_page_tags(void *addr);
20unsigned long mte_copy_tags_from_user(void *to, const void __user *from,
21				      unsigned long n);
22unsigned long mte_copy_tags_to_user(void __user *to, void *from,
23				    unsigned long n);
24int mte_save_tags(struct page *page);
25void mte_save_page_tags(const void *page_addr, void *tag_storage);
26bool mte_restore_tags(swp_entry_t entry, struct page *page);
27void mte_restore_page_tags(void *page_addr, const void *tag_storage);
28void mte_invalidate_tags(int type, pgoff_t offset);
29void mte_invalidate_tags_area(int type);
30void *mte_allocate_tag_storage(void);
31void mte_free_tag_storage(char *storage);
32
33#ifdef CONFIG_ARM64_MTE
34
35/* track which pages have valid allocation tags */
36#define PG_mte_tagged	PG_arch_2
37
38void mte_sync_tags(pte_t *ptep, pte_t pte);
39void mte_copy_page_tags(void *kto, const void *kfrom);
40void flush_mte_state(void);
41void mte_thread_switch(struct task_struct *next);
42void mte_suspend_exit(void);
43long set_mte_ctrl(struct task_struct *task, unsigned long arg);
44long get_mte_ctrl(struct task_struct *task);
45int mte_ptrace_copy_tags(struct task_struct *child, long request,
46			 unsigned long addr, unsigned long data);
47
48#else
49
50/* unused if !CONFIG_ARM64_MTE, silence the compiler */
51#define PG_mte_tagged	0
52
53static inline void mte_sync_tags(pte_t *ptep, pte_t pte)
54{
55}
56static inline void mte_copy_page_tags(void *kto, const void *kfrom)
57{
58}
59static inline void flush_mte_state(void)
60{
61}
62static inline void mte_thread_switch(struct task_struct *next)
63{
64}
65static inline void mte_suspend_exit(void)
66{
67}
68static inline long set_mte_ctrl(struct task_struct *task, unsigned long arg)
69{
70	return 0;
71}
72static inline long get_mte_ctrl(struct task_struct *task)
73{
74	return 0;
75}
76static inline int mte_ptrace_copy_tags(struct task_struct *child,
77				       long request, unsigned long addr,
78				       unsigned long data)
79{
80	return -EIO;
81}
82
83#endif
84
85#endif /* __ASSEMBLY__ */
86#endif /* __ASM_MTE_H  */
87