Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

arm64: Add support for FEAT_{LS64, LS64_V}

Armv8.7 introduces single-copy atomic 64-byte loads and stores
instructions and its variants named under FEAT_{LS64, LS64_V}.
These features are identified by ID_AA64ISAR1_EL1.LS64 and the
use of such instructions in userspace (EL0) can be trapped.

As st64bv (FEAT_LS64_V) and st64bv0 (FEAT_LS64_ACCDATA) can not be tell
apart, FEAT_LS64 and FEAT_LS64_ACCDATA which will be supported in later
patch will be exported to userspace, FEAT_LS64_V will be enabled only
in kernel.

In order to support the use of corresponding instructions in userspace:
- Make ID_AA64ISAR1_EL1.LS64 visbile to userspace
- Add identifying and enabling in the cpufeature list
- Expose these support of these features to userspace through HWCAP3
and cpuinfo

ld64b/st64b (FEAT_LS64) and st64bv (FEAT_LS64_V) is intended for
special memory (device memory) so requires support by the CPU, system
and target memory location (device that support these instructions).
The HWCAP3_LS64, implies the support of CPU and system (since no
identification method from system, so SoC vendors should advertise
support in the CPU if system also support them).

Otherwise for ld64b/st64b the atomicity may not be guaranteed or a
DABT will be generated, so users (probably userspace driver developer)
should make sure the target memory (device) also have the support.
For st64bv 0xffffffffffffffff will be returned as status result for
unsupported memory so user should check it.

Document the restrictions along with HWCAP3_LS64.

Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Oliver Upton <oupton@kernel.org>
Signed-off-by: Yicong Yang <yangyicong@hisilicon.com>
Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Yicong Yang and committed by
Will Deacon
58ce7866 151b92c9

+52
+12
Documentation/arch/arm64/booting.rst
··· 556 556 557 557 - MDCR_EL3.TPM (bit 6) must be initialized to 0b0 558 558 559 + For CPUs with support for 64-byte loads and stores without status (FEAT_LS64): 560 + 561 + - If the kernel is entered at EL1 and EL2 is present: 562 + 563 + - HCRX_EL2.EnALS (bit 1) must be initialised to 0b1. 564 + 565 + For CPUs with support for 64-byte stores with status (FEAT_LS64_V): 566 + 567 + - If the kernel is entered at EL1 and EL2 is present: 568 + 569 + - HCRX_EL2.EnASR (bit 2) must be initialised to 0b1. 570 + 559 571 The requirements described above for CPU mode, caches, MMUs, architected 560 572 timers, coherency and system registers apply to all CPUs. All CPUs must 561 573 enter the kernel in the same exception level. Where the values documented
+7
Documentation/arch/arm64/elf_hwcaps.rst
··· 444 444 HWCAP3_LSFE 445 445 Functionality implied by ID_AA64ISAR3_EL1.LSFE == 0b0001 446 446 447 + HWCAP3_LS64 448 + Functionality implied by ID_AA64ISAR1_EL1.LS64 == 0b0001. Note that 449 + the function of instruction ld64b/st64b requires support by CPU, system 450 + and target (device) memory location and HWCAP3_LS64 implies the support 451 + of CPU. User should only use ld64b/st64b on supported target (device) 452 + memory location, otherwise fallback to the non-atomic alternatives. 453 + 447 454 448 455 4. Unused AT_HWCAP bits 449 456 -----------------------
+1
arch/arm64/include/asm/hwcap.h
··· 179 179 #define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR) 180 180 #define KERNEL_HWCAP_MTE_STORE_ONLY __khwcap3_feature(MTE_STORE_ONLY) 181 181 #define KERNEL_HWCAP_LSFE __khwcap3_feature(LSFE) 182 + #define KERNEL_HWCAP_LS64 __khwcap3_feature(LS64) 182 183 183 184 /* 184 185 * This yields a mask that user programs can use to figure out what
+1
arch/arm64/include/uapi/asm/hwcap.h
··· 146 146 #define HWCAP3_MTE_FAR (1UL << 0) 147 147 #define HWCAP3_MTE_STORE_ONLY (1UL << 1) 148 148 #define HWCAP3_LSFE (1UL << 2) 149 + #define HWCAP3_LS64 (1UL << 3) 149 150 150 151 #endif /* _UAPI__ASM_HWCAP_H */
+28
arch/arm64/kernel/cpufeature.c
··· 240 240 }; 241 241 242 242 static const struct arm64_ftr_bits ftr_id_aa64isar1[] = { 243 + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_LS64_SHIFT, 4, 0), 243 244 ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_XS_SHIFT, 4, 0), 244 245 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, 0), 245 246 ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, 0), ··· 2259 2258 } 2260 2259 #endif /* CONFIG_ARM64_E0PD */ 2261 2260 2261 + static void cpu_enable_ls64(struct arm64_cpu_capabilities const *cap) 2262 + { 2263 + sysreg_clear_set(sctlr_el1, SCTLR_EL1_EnALS, SCTLR_EL1_EnALS); 2264 + } 2265 + 2266 + static void cpu_enable_ls64_v(struct arm64_cpu_capabilities const *cap) 2267 + { 2268 + sysreg_clear_set(sctlr_el1, SCTLR_EL1_EnASR, 0); 2269 + } 2270 + 2262 2271 #ifdef CONFIG_ARM64_PSEUDO_NMI 2263 2272 static bool can_use_gic_priorities(const struct arm64_cpu_capabilities *entry, 2264 2273 int scope) ··· 3153 3142 .matches = has_cpuid_feature, 3154 3143 ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, XNX, IMP) 3155 3144 }, 3145 + { 3146 + .desc = "LS64", 3147 + .capability = ARM64_HAS_LS64, 3148 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 3149 + .matches = has_cpuid_feature, 3150 + .cpu_enable = cpu_enable_ls64, 3151 + ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LS64, LS64) 3152 + }, 3153 + { 3154 + .desc = "LS64_V", 3155 + .capability = ARM64_HAS_LS64_V, 3156 + .type = ARM64_CPUCAP_SYSTEM_FEATURE, 3157 + .matches = has_cpuid_feature, 3158 + .cpu_enable = cpu_enable_ls64_v, 3159 + ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LS64, LS64_V) 3160 + }, 3156 3161 {}, 3157 3162 }; 3158 3163 ··· 3288 3261 HWCAP_CAP(ID_AA64ISAR1_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_EBF16), 3289 3262 HWCAP_CAP(ID_AA64ISAR1_EL1, DGH, IMP, CAP_HWCAP, KERNEL_HWCAP_DGH), 3290 3263 HWCAP_CAP(ID_AA64ISAR1_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_I8MM), 3264 + HWCAP_CAP(ID_AA64ISAR1_EL1, LS64, LS64, CAP_HWCAP, KERNEL_HWCAP_LS64), 3291 3265 HWCAP_CAP(ID_AA64ISAR2_EL1, LUT, IMP, CAP_HWCAP, KERNEL_HWCAP_LUT), 3292 3266 HWCAP_CAP(ID_AA64ISAR3_EL1, FAMINMAX, IMP, CAP_HWCAP, KERNEL_HWCAP_FAMINMAX), 3293 3267 HWCAP_CAP(ID_AA64ISAR3_EL1, LSFE, IMP, CAP_HWCAP, KERNEL_HWCAP_LSFE),
+1
arch/arm64/kernel/cpuinfo.c
··· 81 81 [KERNEL_HWCAP_PACA] = "paca", 82 82 [KERNEL_HWCAP_PACG] = "pacg", 83 83 [KERNEL_HWCAP_GCS] = "gcs", 84 + [KERNEL_HWCAP_LS64] = "ls64", 84 85 [KERNEL_HWCAP_DCPODP] = "dcpodp", 85 86 [KERNEL_HWCAP_SVE2] = "sve2", 86 87 [KERNEL_HWCAP_SVEAES] = "sveaes",
+2
arch/arm64/tools/cpucaps
··· 46 46 HAS_LDAPR 47 47 HAS_LPA2 48 48 HAS_LSE_ATOMICS 49 + HAS_LS64 50 + HAS_LS64_V 49 51 HAS_MOPS 50 52 HAS_NESTED_VIRT 51 53 HAS_BBML2_NOABORT