diff options
author | Richard Henderson | 2021-02-12 19:49:00 +0100 |
---|---|---|
committer | Peter Maydell | 2021-02-16 14:17:16 +0100 |
commit | a11d3830d96ad8077440ce4e0aa60608f1f12dde (patch) | |
tree | 0ee3e706196b7abc381c0f140b2da997cabf11e0 /target/arm/mte_helper.c | |
parent | linux-user/aarch64: Signal SEGV_MTEAERR for async tag check error (diff) | |
download | qemu-a11d3830d96ad8077440ce4e0aa60608f1f12dde.tar.gz qemu-a11d3830d96ad8077440ce4e0aa60608f1f12dde.tar.xz qemu-a11d3830d96ad8077440ce4e0aa60608f1f12dde.zip |
target/arm: Add allocation tag storage for user mode
Use the now-saved PAGE_ANON and PAGE_MTE bits,
and the per-page saved data.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-id: 20210212184902.1251044-30-richard.henderson@linaro.org
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/mte_helper.c')
-rw-r--r-- | target/arm/mte_helper.c | 29 |
1 files changed, 27 insertions, 2 deletions
diff --git a/target/arm/mte_helper.c b/target/arm/mte_helper.c index d55f8d1e1e..1c569336ea 100644 --- a/target/arm/mte_helper.c +++ b/target/arm/mte_helper.c @@ -78,8 +78,33 @@ static uint8_t *allocation_tag_mem(CPUARMState *env, int ptr_mmu_idx, int tag_size, uintptr_t ra) { #ifdef CONFIG_USER_ONLY - /* Tag storage not implemented. */ - return NULL; + uint64_t clean_ptr = useronly_clean_ptr(ptr); + int flags = page_get_flags(clean_ptr); + uint8_t *tags; + uintptr_t index; + + if (!(flags & (ptr_access == MMU_DATA_STORE ? PAGE_WRITE : PAGE_READ))) { + /* SIGSEGV */ + arm_cpu_tlb_fill(env_cpu(env), ptr, ptr_size, ptr_access, + ptr_mmu_idx, false, ra); + g_assert_not_reached(); + } + + /* Require both MAP_ANON and PROT_MTE for the page. */ + if (!(flags & PAGE_ANON) || !(flags & PAGE_MTE)) { + return NULL; + } + + tags = page_get_target_data(clean_ptr); + if (tags == NULL) { + size_t alloc_size = TARGET_PAGE_SIZE >> (LOG2_TAG_GRANULE + 1); + tags = page_alloc_target_data(clean_ptr, alloc_size); + assert(tags != NULL); + } + + index = extract32(ptr, LOG2_TAG_GRANULE + 1, + TARGET_PAGE_BITS - LOG2_TAG_GRANULE - 1); + return tags + index; #else uintptr_t index; CPUIOTLBEntry *iotlbentry; |