aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/include/asm/mte-kasan.h
diff options
context:
space:
mode:
authorReiji Watanabe <reijiw@google.com>2021-12-05 16:47:36 -0800
committerCatalin Marinas <catalin.marinas@arm.com>2021-12-06 17:02:10 +0000
commit685e2564daa1493053fcd7f1dbed38b35ee2f3cb (patch)
treef7409f8ee9f4ac811079d1f671cce80cf530d0e8 /arch/arm64/include/asm/mte-kasan.h
parentarm64: clear_page() shouldn't use DC ZVA when DCZID_EL0.DZP == 1 (diff)
downloadlinux-dev-685e2564daa1493053fcd7f1dbed38b35ee2f3cb.tar.xz
linux-dev-685e2564daa1493053fcd7f1dbed38b35ee2f3cb.zip
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: 013bb59dbb7c ("arm64: mte: handle tags zeroing at page allocation time") Fixes: 3d0cca0b02ac ("kasan: speed up mte_set_mem_tag_range") Signed-off-by: Reiji Watanabe <reijiw@google.com> Link: https://lore.kernel.org/r/20211206004736.1520989-3-reijiw@google.com Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Diffstat (limited to 'arch/arm64/include/asm/mte-kasan.h')
-rw-r--r--arch/arm64/include/asm/mte-kasan.h8
1 files changed, 5 insertions, 3 deletions
diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h
index 478b9bcf69ad..e4704a403237 100644
--- a/arch/arm64/include/asm/mte-kasan.h
+++ b/arch/arm64/include/asm/mte-kasan.h
@@ -84,10 +84,12 @@ static inline void __dc_gzva(u64 p)
static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag,
bool init)
{
- u64 curr, mask, dczid_bs, end1, end2, end3;
+ u64 curr, mask, dczid, dczid_bs, dczid_dzp, end1, end2, end3;
/* Read DC G(Z)VA block size from the system register. */
- dczid_bs = 4ul << (read_cpuid(DCZID_EL0) & 0xf);
+ dczid = read_cpuid(DCZID_EL0);
+ dczid_bs = 4ul << (dczid & 0xf);
+ dczid_dzp = (dczid >> 4) & 1;
curr = (u64)__tag_set(addr, tag);
mask = dczid_bs - 1;
@@ -106,7 +108,7 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag,
*/
#define SET_MEMTAG_RANGE(stg_post, dc_gva) \
do { \
- if (size >= 2 * dczid_bs) { \
+ if (!dczid_dzp && size >= 2 * dczid_bs) {\
do { \
curr = stg_post(curr); \
} while (curr < end1); \