Skip to content

Commit 685e256

Browse files
reijiw-kvmctmarinas
authored andcommitted
arm64: mte: DC {GVA,GZVA} shouldn't be used when DCZID_EL0.DZP == 1
Currently, mte_set_mem_tag_range() and mte_zero_clear_page_tags() use DC {GVA,GZVA} unconditionally. But, they should make sure that DCZID_EL0.DZP, which indicates whether or not use of those instructions is prohibited, is zero when using those instructions. Use ST{G,ZG,Z2G} instead when DCZID_EL0.DZP == 1. Fixes: 013bb59 ("arm64: mte: handle tags zeroing at page allocation time") Fixes: 3d0cca0 ("kasan: speed up mte_set_mem_tag_range") Signed-off-by: Reiji Watanabe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent f0616ab commit 685e256

File tree

2 files changed

+12
-4
lines changed

2 files changed

+12
-4
lines changed

arch/arm64/include/asm/mte-kasan.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,12 @@ static inline void __dc_gzva(u64 p)
8484
static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag,
8585
bool init)
8686
{
87-
u64 curr, mask, dczid_bs, end1, end2, end3;
87+
u64 curr, mask, dczid, dczid_bs, dczid_dzp, end1, end2, end3;
8888

8989
/* Read DC G(Z)VA block size from the system register. */
90-
dczid_bs = 4ul << (read_cpuid(DCZID_EL0) & 0xf);
90+
dczid = read_cpuid(DCZID_EL0);
91+
dczid_bs = 4ul << (dczid & 0xf);
92+
dczid_dzp = (dczid >> 4) & 1;
9193

9294
curr = (u64)__tag_set(addr, tag);
9395
mask = dczid_bs - 1;
@@ -106,7 +108,7 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag,
106108
*/
107109
#define SET_MEMTAG_RANGE(stg_post, dc_gva) \
108110
do { \
109-
if (size >= 2 * dczid_bs) { \
111+
if (!dczid_dzp && size >= 2 * dczid_bs) {\
110112
do { \
111113
curr = stg_post(curr); \
112114
} while (curr < end1); \

arch/arm64/lib/mte.S

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,23 @@ SYM_FUNC_END(mte_clear_page_tags)
4343
* x0 - address to the beginning of the page
4444
*/
4545
SYM_FUNC_START(mte_zero_clear_page_tags)
46+
and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag
4647
mrs x1, dczid_el0
48+
tbnz x1, #4, 2f // Branch if DC GZVA is prohibited
4749
and w1, w1, #0xf
4850
mov x2, #4
4951
lsl x1, x2, x1
50-
and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag
5152

5253
1: dc gzva, x0
5354
add x0, x0, x1
5455
tst x0, #(PAGE_SIZE - 1)
5556
b.ne 1b
5657
ret
58+
59+
2: stz2g x0, [x0], #(MTE_GRANULE_SIZE * 2)
60+
tst x0, #(PAGE_SIZE - 1)
61+
b.ne 2b
62+
ret
5763
SYM_FUNC_END(mte_zero_clear_page_tags)
5864

5965
/*

0 commit comments

Comments
 (0)