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

arm64: advertise ARMv8 extensions to 32-bit compat ELF binaries

This adds support for advertising the presence of ARMv8 Crypto
Extensions in the Aarch32 execution state to 32-bit ELF binaries
running in 32-bit compat mode under the arm64 kernel.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Ard Biesheuvel and committed by
Catalin Marinas
4cf761cd 28964d32

+38
+6
arch/arm64/include/asm/hwcap.h
··· 32 32 #define COMPAT_HWCAP_IDIV (COMPAT_HWCAP_IDIVA|COMPAT_HWCAP_IDIVT) 33 33 #define COMPAT_HWCAP_EVTSTRM (1 << 21) 34 34 35 + #define COMPAT_HWCAP2_AES (1 << 0) 36 + #define COMPAT_HWCAP2_PMULL (1 << 1) 37 + #define COMPAT_HWCAP2_SHA1 (1 << 2) 38 + #define COMPAT_HWCAP2_SHA2 (1 << 3) 39 + #define COMPAT_HWCAP2_CRC32 (1 << 4) 40 + 35 41 #ifndef __ASSEMBLY__ 36 42 /* 37 43 * This yields a mask that user programs can use to figure out what
+32
arch/arm64/kernel/setup.c
··· 243 243 block = (features >> 16) & 0xf; 244 244 if (block && !(block & 0x8)) 245 245 elf_hwcap |= HWCAP_CRC32; 246 + 247 + #ifdef CONFIG_COMPAT 248 + /* 249 + * ID_ISAR5_EL1 carries similar information as above, but pertaining to 250 + * the Aarch32 32-bit execution state. 251 + */ 252 + features = read_cpuid(ID_ISAR5_EL1); 253 + block = (features >> 4) & 0xf; 254 + if (!(block & 0x8)) { 255 + switch (block) { 256 + default: 257 + case 2: 258 + compat_elf_hwcap2 |= COMPAT_HWCAP2_PMULL; 259 + case 1: 260 + compat_elf_hwcap2 |= COMPAT_HWCAP2_AES; 261 + case 0: 262 + break; 263 + } 264 + } 265 + 266 + block = (features >> 8) & 0xf; 267 + if (block && !(block & 0x8)) 268 + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA1; 269 + 270 + block = (features >> 12) & 0xf; 271 + if (block && !(block & 0x8)) 272 + compat_elf_hwcap2 |= COMPAT_HWCAP2_SHA2; 273 + 274 + block = (features >> 16) & 0xf; 275 + if (block && !(block & 0x8)) 276 + compat_elf_hwcap2 |= COMPAT_HWCAP2_CRC32; 277 + #endif 246 278 } 247 279 248 280 static void __init setup_machine_fdt(phys_addr_t dt_phys)