Skip to content

Commit 58ce786

Browse files
Yicong Yangwilldeacon
authored andcommitted
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>
1 parent 151b92c commit 58ce786

7 files changed

Lines changed: 52 additions & 0 deletions

File tree

Documentation/arch/arm64/booting.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,18 @@ Before jumping into the kernel, the following conditions must be met:
556556

557557
- MDCR_EL3.TPM (bit 6) must be initialized to 0b0
558558

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+
559571
The requirements described above for CPU mode, caches, MMUs, architected
560572
timers, coherency and system registers apply to all CPUs. All CPUs must
561573
enter the kernel in the same exception level. Where the values documented

Documentation/arch/arm64/elf_hwcaps.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -444,6 +444,13 @@ HWCAP3_MTE_STORE_ONLY
444444
HWCAP3_LSFE
445445
Functionality implied by ID_AA64ISAR3_EL1.LSFE == 0b0001
446446

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+
447454

448455
4. Unused AT_HWCAP bits
449456
-----------------------

arch/arm64/include/asm/hwcap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@
179179
#define KERNEL_HWCAP_MTE_FAR __khwcap3_feature(MTE_FAR)
180180
#define KERNEL_HWCAP_MTE_STORE_ONLY __khwcap3_feature(MTE_STORE_ONLY)
181181
#define KERNEL_HWCAP_LSFE __khwcap3_feature(LSFE)
182+
#define KERNEL_HWCAP_LS64 __khwcap3_feature(LS64)
182183

183184
/*
184185
* 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
@@ -146,5 +146,6 @@
146146
#define HWCAP3_MTE_FAR (1UL << 0)
147147
#define HWCAP3_MTE_STORE_ONLY (1UL << 1)
148148
#define HWCAP3_LSFE (1UL << 2)
149+
#define HWCAP3_LS64 (1UL << 3)
149150

150151
#endif /* _UAPI__ASM_HWCAP_H */

arch/arm64/kernel/cpufeature.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ static const struct arm64_ftr_bits ftr_id_aa64isar0[] = {
240240
};
241241

242242
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),
243244
ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_XS_SHIFT, 4, 0),
244245
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_I8MM_SHIFT, 4, 0),
245246
ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64ISAR1_EL1_DGH_SHIFT, 4, 0),
@@ -2258,6 +2259,16 @@ static void cpu_enable_e0pd(struct arm64_cpu_capabilities const *cap)
22582259
}
22592260
#endif /* CONFIG_ARM64_E0PD */
22602261

2262+
static void cpu_enable_ls64(struct arm64_cpu_capabilities const *cap)
2263+
{
2264+
sysreg_clear_set(sctlr_el1, SCTLR_EL1_EnALS, SCTLR_EL1_EnALS);
2265+
}
2266+
2267+
static void cpu_enable_ls64_v(struct arm64_cpu_capabilities const *cap)
2268+
{
2269+
sysreg_clear_set(sctlr_el1, SCTLR_EL1_EnASR, 0);
2270+
}
2271+
22612272
#ifdef CONFIG_ARM64_PSEUDO_NMI
22622273
static bool can_use_gic_priorities(const struct arm64_cpu_capabilities *entry,
22632274
int scope)
@@ -3142,6 +3153,22 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
31423153
.matches = has_cpuid_feature,
31433154
ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, XNX, IMP)
31443155
},
3156+
{
3157+
.desc = "LS64",
3158+
.capability = ARM64_HAS_LS64,
3159+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
3160+
.matches = has_cpuid_feature,
3161+
.cpu_enable = cpu_enable_ls64,
3162+
ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LS64, LS64)
3163+
},
3164+
{
3165+
.desc = "LS64_V",
3166+
.capability = ARM64_HAS_LS64_V,
3167+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
3168+
.matches = has_cpuid_feature,
3169+
.cpu_enable = cpu_enable_ls64_v,
3170+
ARM64_CPUID_FIELDS(ID_AA64ISAR1_EL1, LS64, LS64_V)
3171+
},
31453172
{},
31463173
};
31473174

@@ -3261,6 +3288,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
32613288
HWCAP_CAP(ID_AA64ISAR1_EL1, BF16, EBF16, CAP_HWCAP, KERNEL_HWCAP_EBF16),
32623289
HWCAP_CAP(ID_AA64ISAR1_EL1, DGH, IMP, CAP_HWCAP, KERNEL_HWCAP_DGH),
32633290
HWCAP_CAP(ID_AA64ISAR1_EL1, I8MM, IMP, CAP_HWCAP, KERNEL_HWCAP_I8MM),
3291+
HWCAP_CAP(ID_AA64ISAR1_EL1, LS64, LS64, CAP_HWCAP, KERNEL_HWCAP_LS64),
32643292
HWCAP_CAP(ID_AA64ISAR2_EL1, LUT, IMP, CAP_HWCAP, KERNEL_HWCAP_LUT),
32653293
HWCAP_CAP(ID_AA64ISAR3_EL1, FAMINMAX, IMP, CAP_HWCAP, KERNEL_HWCAP_FAMINMAX),
32663294
HWCAP_CAP(ID_AA64ISAR3_EL1, LSFE, IMP, CAP_HWCAP, KERNEL_HWCAP_LSFE),

arch/arm64/kernel/cpuinfo.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static const char *const hwcap_str[] = {
8181
[KERNEL_HWCAP_PACA] = "paca",
8282
[KERNEL_HWCAP_PACG] = "pacg",
8383
[KERNEL_HWCAP_GCS] = "gcs",
84+
[KERNEL_HWCAP_LS64] = "ls64",
8485
[KERNEL_HWCAP_DCPODP] = "dcpodp",
8586
[KERNEL_HWCAP_SVE2] = "sve2",
8687
[KERNEL_HWCAP_SVEAES] = "sveaes",

arch/arm64/tools/cpucaps

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ HAS_HCX
4646
HAS_LDAPR
4747
HAS_LPA2
4848
HAS_LSE_ATOMICS
49+
HAS_LS64
50+
HAS_LS64_V
4951
HAS_MOPS
5052
HAS_NESTED_VIRT
5153
HAS_BBML2_NOABORT

0 commit comments

Comments
 (0)