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

arm64: Add hwcaps for crypto and CRC32 extensions.

Advertise the optional cryptographic and CRC32 instructions to
user space where present. Several hwcap bits [3-7] are allocated.

Signed-off-by: Steve Capper <steve.capper@linaro.org>
[bit 2 is taken now so use bits 3-7 instead]
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Steve Capper and committed by
Catalin Marinas
4bff28cc 148eb0a1

+42 -1
+5 -1
arch/arm64/include/uapi/asm/hwcap.h
··· 22 22 #define HWCAP_FP (1 << 0) 23 23 #define HWCAP_ASIMD (1 << 1) 24 24 #define HWCAP_EVTSTRM (1 << 2) 25 - 25 + #define HWCAP_AES (1 << 3) 26 + #define HWCAP_PMULL (1 << 4) 27 + #define HWCAP_SHA1 (1 << 5) 28 + #define HWCAP_SHA2 (1 << 6) 29 + #define HWCAP_CRC32 (1 << 7) 26 30 27 31 #endif /* _UAPI__ASM_HWCAP_H */
+37
arch/arm64/kernel/setup.c
··· 126 126 static void __init setup_processor(void) 127 127 { 128 128 struct cpu_info *cpu_info; 129 + u64 features, block; 129 130 130 131 cpu_info = lookup_processor_type(read_cpuid_id()); 131 132 if (!cpu_info) { ··· 142 141 143 142 sprintf(init_utsname()->machine, ELF_PLATFORM); 144 143 elf_hwcap = 0; 144 + 145 + /* 146 + * ID_AA64ISAR0_EL1 contains 4-bit wide signed feature blocks. 147 + * The blocks we test below represent incremental functionality 148 + * for non-negative values. Negative values are reserved. 149 + */ 150 + features = read_cpuid(ID_AA64ISAR0_EL1); 151 + block = (features >> 4) & 0xf; 152 + if (!(block & 0x8)) { 153 + switch (block) { 154 + default: 155 + case 2: 156 + elf_hwcap |= HWCAP_PMULL; 157 + case 1: 158 + elf_hwcap |= HWCAP_AES; 159 + case 0: 160 + break; 161 + } 162 + } 163 + 164 + block = (features >> 8) & 0xf; 165 + if (block && !(block & 0x8)) 166 + elf_hwcap |= HWCAP_SHA1; 167 + 168 + block = (features >> 12) & 0xf; 169 + if (block && !(block & 0x8)) 170 + elf_hwcap |= HWCAP_SHA2; 171 + 172 + block = (features >> 16) & 0xf; 173 + if (block && !(block & 0x8)) 174 + elf_hwcap |= HWCAP_CRC32; 145 175 } 146 176 147 177 static void __init setup_machine_fdt(phys_addr_t dt_phys) ··· 312 280 "fp", 313 281 "asimd", 314 282 "evtstrm", 283 + "aes", 284 + "pmull", 285 + "sha1", 286 + "sha2", 287 + "crc32", 315 288 NULL 316 289 }; 317 290