summaryrefslogtreecommitdiffstats
path: root/arch/arm64/lib/mte.S
diff options
context:
space:
mode:
authorSteven Price <steven.price@arm.com>2020-05-13 16:37:50 +0100
committerCatalin Marinas <catalin.marinas@arm.com>2020-09-04 12:46:07 +0100
commit36943aba91860269abfba2e736e9534d48e90cae (patch)
tree4fb2f58ccd9e8811cad36b712738f2afc5e7ebb0 /arch/arm64/lib/mte.S
parent8a84802e2a2b1a682761a31c2685506b9f4e1840 (diff)
downloadlinux-stable-36943aba91860269abfba2e736e9534d48e90cae.tar.gz
linux-stable-36943aba91860269abfba2e736e9534d48e90cae.tar.bz2
linux-stable-36943aba91860269abfba2e736e9534d48e90cae.zip
arm64: mte: Enable swap of tagged pages
When swapping pages out to disk it is necessary to save any tags that have been set, and restore when swapping back in. Make use of the new page flag (PG_ARCH_2, locally named PG_mte_tagged) to identify pages with tags. When swapping out these pages the tags are stored in memory and later restored when the pages are brought back in. Because shmem can swap pages back in without restoring the userspace PTE it is also necessary to add a hook for shmem. Signed-off-by: Steven Price <steven.price@arm.com> [catalin.marinas@arm.com: move function prototypes to mte.h] [catalin.marinas@arm.com: drop '_tags' from arch_swap_restore_tags()] Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Will Deacon <will@kernel.org>
Diffstat (limited to 'arch/arm64/lib/mte.S')
-rw-r--r--arch/arm64/lib/mte.S45
1 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S
index 434f81d9a180..03ca6d8b8670 100644
--- a/arch/arm64/lib/mte.S
+++ b/arch/arm64/lib/mte.S
@@ -104,3 +104,48 @@ SYM_FUNC_START(mte_copy_tags_to_user)
2: sub x0, x0, x3 // update the number of tags copied
ret
SYM_FUNC_END(mte_copy_tags_to_user)
+
+/*
+ * Save the tags in a page
+ * x0 - page address
+ * x1 - tag storage
+ */
+SYM_FUNC_START(mte_save_page_tags)
+ multitag_transfer_size x7, x5
+1:
+ mov x2, #0
+2:
+ ldgm x5, [x0]
+ orr x2, x2, x5
+ add x0, x0, x7
+ tst x0, #0xFF // 16 tag values fit in a register,
+ b.ne 2b // which is 16*16=256 bytes
+
+ str x2, [x1], #8
+
+ tst x0, #(PAGE_SIZE - 1)
+ b.ne 1b
+
+ ret
+SYM_FUNC_END(mte_save_page_tags)
+
+/*
+ * Restore the tags in a page
+ * x0 - page address
+ * x1 - tag storage
+ */
+SYM_FUNC_START(mte_restore_page_tags)
+ multitag_transfer_size x7, x5
+1:
+ ldr x2, [x1], #8
+2:
+ stgm x2, [x0]
+ add x0, x0, x7
+ tst x0, #0xFF
+ b.ne 2b
+
+ tst x0, #(PAGE_SIZE - 1)
+ b.ne 1b
+
+ ret
+SYM_FUNC_END(mte_restore_page_tags)