mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 04:04:43 +01:00
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 <yeoreum.yun@arm.com>
Link: https://lore.kernel.org/r/20250618084513.1761345-3-yeoreum.yun@arm.com
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
parent
6698453689
commit
7c7f55039b
7 changed files with 18 additions and 7 deletions
|
|
@ -435,6 +435,9 @@ HWCAP2_SME_SF8DP4
|
|||
HWCAP2_POE
|
||||
Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001.
|
||||
|
||||
HWCAP3_MTE_FAR
|
||||
Functionality implied by ID_AA64PFR2_EL1.MTEFAR == 0b0001.
|
||||
|
||||
4. Unused AT_HWCAP bits
|
||||
-----------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -60,11 +60,12 @@ that signal handlers in applications making use of tags cannot rely
|
|||
on the tag information for user virtual addresses being maintained
|
||||
in these fields unless the flag was set.
|
||||
|
||||
Due to architecture limitations, bits 63:60 of the fault address
|
||||
are not preserved in response to synchronous tag check faults
|
||||
(SEGV_MTESERR) even if SA_EXPOSE_TAGBITS was set. Applications should
|
||||
treat the values of these bits as undefined in order to accommodate
|
||||
future architecture revisions which may preserve the bits.
|
||||
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)
|
||||
otherwise not preserved even if SA_EXPOSE_TAGBITS was set.
|
||||
Applications should interpret the values of these bits based on
|
||||
the support for the HWCAP3_MTE_FAR. If the support is not present,
|
||||
the values of these bits should be considered as undefined otherwise valid.
|
||||
|
||||
For signals raised in response to watchpoint debug exceptions, the
|
||||
tag information will be preserved regardless of the SA_EXPOSE_TAGBITS
|
||||
|
|
|
|||
|
|
@ -176,6 +176,7 @@
|
|||
#define KERNEL_HWCAP_POE __khwcap2_feature(POE)
|
||||
|
||||
#define __khwcap3_feature(x) (const_ilog2(HWCAP3_ ## x) + 128)
|
||||
#define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR)
|
||||
|
||||
/*
|
||||
* This yields a mask that user programs can use to figure out what
|
||||
|
|
|
|||
|
|
@ -143,5 +143,6 @@
|
|||
/*
|
||||
* HWCAP3 flags - for AT_HWCAP3
|
||||
*/
|
||||
#define HWCAP3_MTE_FAR (1UL << 0)
|
||||
|
||||
#endif /* _UAPI__ASM_HWCAP_H */
|
||||
|
|
|
|||
|
|
@ -3219,6 +3219,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
|
|||
#ifdef CONFIG_ARM64_MTE
|
||||
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE2, CAP_HWCAP, KERNEL_HWCAP_MTE),
|
||||
HWCAP_CAP(ID_AA64PFR1_EL1, MTE, MTE3, CAP_HWCAP, KERNEL_HWCAP_MTE3),
|
||||
HWCAP_CAP(ID_AA64PFR2_EL1, MTEFAR, IMP, CAP_HWCAP, KERNEL_HWCAP_MTE_FAR),
|
||||
#endif /* CONFIG_ARM64_MTE */
|
||||
HWCAP_CAP(ID_AA64MMFR0_EL1, ECV, IMP, CAP_HWCAP, KERNEL_HWCAP_ECV),
|
||||
HWCAP_CAP(ID_AA64MMFR1_EL1, AFP, IMP, CAP_HWCAP, KERNEL_HWCAP_AFP),
|
||||
|
|
|
|||
|
|
@ -160,6 +160,7 @@ static const char *const hwcap_str[] = {
|
|||
[KERNEL_HWCAP_SME_SFEXPA] = "smesfexpa",
|
||||
[KERNEL_HWCAP_SME_STMOP] = "smestmop",
|
||||
[KERNEL_HWCAP_SME_SMOP4] = "smesmop4",
|
||||
[KERNEL_HWCAP_MTE_FAR] = "mtefar",
|
||||
};
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
|
|
|||
|
|
@ -837,9 +837,12 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
|
|||
/*
|
||||
* The architecture specifies that bits 63:60 of FAR_EL1 are UNKNOWN
|
||||
* for tag check faults. Set them to corresponding bits in the untagged
|
||||
* address.
|
||||
* address if ARM64_MTE_FAR isn't supported.
|
||||
* Otherwise, bits 63:60 of FAR_EL1 are not UNKNOWN.
|
||||
*/
|
||||
far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
|
||||
if (!cpus_have_cap(ARM64_MTE_FAR))
|
||||
far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
|
||||
|
||||
do_bad_area(far, esr, regs);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue