~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm64/lib/mte.S

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  * Copyright (C) 2020 ARM Ltd.
  4  */
  5 #include <linux/linkage.h>
  6 
  7 #include <asm/asm-uaccess.h>
  8 #include <asm/assembler.h>
  9 #include <asm/mte.h>
 10 #include <asm/page.h>
 11 #include <asm/sysreg.h>
 12 
 13         .arch   armv8.5-a+memtag
 14 
 15 /*
 16  * multitag_transfer_size - set \reg to the block size that is accessed by the
 17  * LDGM/STGM instructions.
 18  */
 19         .macro  multitag_transfer_size, reg, tmp
 20         mrs_s   \reg, SYS_GMID_EL1
 21         ubfx    \reg, \reg, #GMID_EL1_BS_SHIFT, #GMID_EL1_BS_WIDTH
 22         mov     \tmp, #4
 23         lsl     \reg, \tmp, \reg
 24         .endm
 25 
 26 /*
 27  * Clear the tags in a page
 28  *   x0 - address of the page to be cleared
 29  */
 30 SYM_FUNC_START(mte_clear_page_tags)
 31         multitag_transfer_size x1, x2
 32 1:      stgm    xzr, [x0]
 33         add     x0, x0, x1
 34         tst     x0, #(PAGE_SIZE - 1)
 35         b.ne    1b
 36         ret
 37 SYM_FUNC_END(mte_clear_page_tags)
 38 
 39 /*
 40  * Zero the page and tags at the same time
 41  *
 42  * Parameters:
 43  *      x0 - address to the beginning of the page
 44  */
 45 SYM_FUNC_START(mte_zero_clear_page_tags)
 46         and     x0, x0, #(1 << MTE_TAG_SHIFT) - 1       // clear the tag
 47         mrs     x1, dczid_el0
 48         tbnz    x1, #4, 2f      // Branch if DC GZVA is prohibited
 49         and     w1, w1, #0xf
 50         mov     x2, #4
 51         lsl     x1, x2, x1
 52 
 53 1:      dc      gzva, x0
 54         add     x0, x0, x1
 55         tst     x0, #(PAGE_SIZE - 1)
 56         b.ne    1b
 57         ret
 58 
 59 2:      stz2g   x0, [x0], #(MTE_GRANULE_SIZE * 2)
 60         tst     x0, #(PAGE_SIZE - 1)
 61         b.ne    2b
 62         ret
 63 SYM_FUNC_END(mte_zero_clear_page_tags)
 64 
 65 /*
 66  * Copy the tags from the source page to the destination one
 67  *   x0 - address of the destination page
 68  *   x1 - address of the source page
 69  */
 70 SYM_FUNC_START(mte_copy_page_tags)
 71         mov     x2, x0
 72         mov     x3, x1
 73         multitag_transfer_size x5, x6
 74 1:      ldgm    x4, [x3]
 75         stgm    x4, [x2]
 76         add     x2, x2, x5
 77         add     x3, x3, x5
 78         tst     x2, #(PAGE_SIZE - 1)
 79         b.ne    1b
 80         ret
 81 SYM_FUNC_END(mte_copy_page_tags)
 82 
 83 /*
 84  * Read tags from a user buffer (one tag per byte) and set the corresponding
 85  * tags at the given kernel address. Used by PTRACE_POKEMTETAGS.
 86  *   x0 - kernel address (to)
 87  *   x1 - user buffer (from)
 88  *   x2 - number of tags/bytes (n)
 89  * Returns:
 90  *   x0 - number of tags read/set
 91  */
 92 SYM_FUNC_START(mte_copy_tags_from_user)
 93         mov     x3, x1
 94         cbz     x2, 2f
 95 1:
 96 USER(2f, ldtrb  w4, [x1])
 97         lsl     x4, x4, #MTE_TAG_SHIFT
 98         stg     x4, [x0], #MTE_GRANULE_SIZE
 99         add     x1, x1, #1
100         subs    x2, x2, #1
101         b.ne    1b
102 
103         // exception handling and function return
104 2:      sub     x0, x1, x3              // update the number of tags set
105         ret
106 SYM_FUNC_END(mte_copy_tags_from_user)
107 
108 /*
109  * Get the tags from a kernel address range and write the tag values to the
110  * given user buffer (one tag per byte). Used by PTRACE_PEEKMTETAGS.
111  *   x0 - user buffer (to)
112  *   x1 - kernel address (from)
113  *   x2 - number of tags/bytes (n)
114  * Returns:
115  *   x0 - number of tags read/set
116  */
117 SYM_FUNC_START(mte_copy_tags_to_user)
118         mov     x3, x0
119         cbz     x2, 2f
120 1:
121         ldg     x4, [x1]
122         ubfx    x4, x4, #MTE_TAG_SHIFT, #MTE_TAG_SIZE
123 USER(2f, sttrb  w4, [x0])
124         add     x0, x0, #1
125         add     x1, x1, #MTE_GRANULE_SIZE
126         subs    x2, x2, #1
127         b.ne    1b
128 
129         // exception handling and function return
130 2:      sub     x0, x0, x3              // update the number of tags copied
131         ret
132 SYM_FUNC_END(mte_copy_tags_to_user)
133 
134 /*
135  * Save the tags in a page
136  *   x0 - page address
137  *   x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
138  */
139 SYM_FUNC_START(mte_save_page_tags)
140         multitag_transfer_size x7, x5
141 1:
142         mov     x2, #0
143 2:
144         ldgm    x5, [x0]
145         orr     x2, x2, x5
146         add     x0, x0, x7
147         tst     x0, #0xFF               // 16 tag values fit in a register,
148         b.ne    2b                      // which is 16*16=256 bytes
149 
150         str     x2, [x1], #8
151 
152         tst     x0, #(PAGE_SIZE - 1)
153         b.ne    1b
154 
155         ret
156 SYM_FUNC_END(mte_save_page_tags)
157 
158 /*
159  * Restore the tags in a page
160  *   x0 - page address
161  *   x1 - tag storage, MTE_PAGE_TAG_STORAGE bytes
162  */
163 SYM_FUNC_START(mte_restore_page_tags)
164         multitag_transfer_size x7, x5
165 1:
166         ldr     x2, [x1], #8
167 2:
168         stgm    x2, [x0]
169         add     x0, x0, x7
170         tst     x0, #0xFF
171         b.ne    2b
172 
173         tst     x0, #(PAGE_SIZE - 1)
174         b.ne    1b
175 
176         ret
177 SYM_FUNC_END(mte_restore_page_tags)

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php