Skip to content

Commit 7c7f550

Browse files
LeviYeoReumctmarinas
authored andcommitted
arm64: Report address tag when FEAT_MTE_TAGGED_FAR is supported
If FEAT_MTE_TAGGED_FAR (Armv8.9) is supported, bits 63:60 of the fault address are preserved in response to synchronous tag check faults (SEGV_MTESERR). This patch modifies below to support this feature: - Use the original FAR_EL1 value when an MTE tag check fault occurs, if ARM64_MTE_FAR is supported so that not only logical tag (bits 59:56) but also address tag (bits 63:60] being reported too. - Add HWCAP for mtefar to let user know bits 63:60 includes address tag information when when FEAT_MTE_TAGGED_FAR is supported. Applications that require this information should install a signal handler with the SA_EXPOSE_TAGBITS flag. While this introduces a minor ABI change, most applications do not set this flag and therefore will not be affected. Signed-off-by: Yeoreum Yun <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Catalin Marinas <[email protected]>
1 parent 6698453 commit 7c7f550

File tree

7 files changed

+18
-7
lines changed

7 files changed

+18
-7
lines changed

Documentation/arch/arm64/elf_hwcaps.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,9 @@ HWCAP2_SME_SF8DP4
435435
HWCAP2_POE
436436
Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
437437

438+
HWCAP3_MTE_FAR
439+
Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
440+
438441
4. Unused AT_HWCAP bits
439442
-----------------------
440443

Documentation/arch/arm64/tagged-pointers.rst

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,12 @@ that signal handlers in applications making use of tags cannot rely
6060
on the tag information for user virtual addresses being maintained
6161
in these fields unless the flag was set.
6262

63-
Due to architecture limitations, bits 63:60 of the fault address
64-
are not preserved in response to synchronous tag check faults
65-
(SEGV_MTESERR) even if SA_EXPOSE_TAGBITS was set. Applications should
66-
treat the values of these bits as undefined in order to accommodate
67-
future architecture revisions which may preserve the bits.
63+
If FEAT_MTE_TAGGED_FAR (Armv8.9) is supported, bits 63:60 of the fault address
64+
are preserved in response to synchronous tag check faults (SEGV_MTESERR)
65+
otherwise not preserved even if SA_EXPOSE_TAGBITS was set.
66+
Applications should interpret the values of these bits based on
67+
the support for the HWCAP3_MTE_FAR. If the support is not present,
68+
the values of these bits should be considered as undefined otherwise valid.
6869

6970
For signals raised in response to watchpoint debug exceptions, the
7071
tag information will be preserved regardless of the SA_EXPOSE_TAGBITS

arch/arm64/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
#define KERNEL_HWCAP_POE __khwcap2_feature(POE)
177177

178178
#define __khwcap3_feature(x) (const_ilog2(HWCAP3_ ## x) + 128)
179+
#define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR)
179180

180181
/*
181182
* This yields a mask that user programs can use to figure out what

arch/arm64/include/uapi/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,5 +143,6 @@
143143
/*
144144
* HWCAP3 flags - for AT_HWCAP3
145145
*/
146+
#define HWCAP3_MTE_FAR (1UL << 0)
146147

147148
#endif /* _UAPI__ASM_HWCAP_H */

arch/arm64/kernel/cpufeature.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3219,6 +3219,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
32193219
#ifdef CONFIG_ARM64_MTE
32203220
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE),
32213221
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3),
3222+
HWCAP_CAP(ID_AA64PFR2_EL1, MTEFAR, IMP, CAP_HWCAP, KERNEL_HWCAP_MTE_FAR),
32223223
#endif /* CONFIG_ARM64_MTE */
32233224
HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV),
32243225
HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP),

arch/arm64/kernel/cpuinfo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ static const char *const hwcap_str[] = {
160160
[KERNEL_HWCAP_SME_SFEXPA] = "smesfexpa",
161161
[KERNEL_HWCAP_SME_STMOP] = "smestmop",
162162
[KERNEL_HWCAP_SME_SMOP4] = "smesmop4",
163+
[KERNEL_HWCAP_MTE_FAR] = "mtefar",
163164
};
164165

165166
#ifdef CONFIG_COMPAT

arch/arm64/mm/fault.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -837,9 +837,12 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
837837
/*
838838
* The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
839839
* for tag check faults. Set them to corresponding bits in the untagged
840-
* address.
840+
* address if ARM64_MTE_FAR isn't supported.
841+
* Otherwise, bits 63:60 of FAR_EL1 are not UNKNOWN.
841842
*/
842-
far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
843+
if (!cpus_have_cap(ARM64_MTE_FAR))
844+
far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
845+
843846
do_bad_area(far, esr, regs);
844847
return 0;
845848
}

0 commit comments

Comments
 (0)