diff options
author | Reiji Watanabe <reijiw@google.com> | 2021-12-06 01:47:36 +0100 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2021-12-06 18:02:10 +0100 |
commit | 685e2564daa1493053fcd7f1dbed38b35ee2f3cb (patch) | |
tree | f7409f8ee9f4ac811079d1f671cce80cf530d0e8 /arch/arm64/lib | |
parent | arm64: clear_page() shouldn't use DC ZVA when DCZID_EL0.DZP == 1 (diff) | |
download | linux-685e2564daa1493053fcd7f1dbed38b35ee2f3cb.tar.xz linux-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/lib')
-rw-r--r-- | arch/arm64/lib/mte.S | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S index e83643b3995f..f531dcb95174 100644 --- a/arch/arm64/lib/mte.S +++ b/arch/arm64/lib/mte.S @@ -43,17 +43,23 @@ SYM_FUNC_END(mte_clear_page_tags) * x0 - address to the beginning of the page */ SYM_FUNC_START(mte_zero_clear_page_tags) + and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag mrs x1, dczid_el0 + tbnz x1, #4, 2f // Branch if DC GZVA is prohibited and w1, w1, #0xf mov x2, #4 lsl x1, x2, x1 - and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag 1: dc gzva, x0 add x0, x0, x1 tst x0, #(PAGE_SIZE - 1) b.ne 1b ret + +2: stz2g x0, [x0], #(MTE_GRANULE_SIZE * 2) + tst x0, #(PAGE_SIZE - 1) + b.ne 2b + ret SYM_FUNC_END(mte_zero_clear_page_tags) /* |