Commit aaba098f authored by Andrew Murray's avatar Andrew Murray Committed by Will Deacon
Browse files

arm64: HWCAP: add support for AT_HWCAP2



As we will exhaust the first 32 bits of AT_HWCAP let's start
exposing AT_HWCAP2 to userspace to give us up to 64 caps.

Whilst it's possible to use the remaining 32 bits of AT_HWCAP, we
prefer to expand into AT_HWCAP2 in order to provide a consistent
view to userspace between ILP32 and LP64. However internal to the
kernel we prefer to continue to use the full space of elf_hwcap.

To reduce complexity and allow for future expansion, we now
represent hwcaps in the kernel as ordinals and use a
KERNEL_HWCAP_ prefix. This allows us to support automatic feature
based module loading for all our hwcaps.

We introduce cpu_set_feature to set hwcaps which complements the
existing cpu_have_feature helper. These helpers allow us to clean
up existing direct uses of elf_hwcap and reduce any future effort
required to move beyond 64 caps.

For convenience we also introduce cpu_{have,set}_named_feature which
makes use of the cpu_feature macro to allow providing a hwcap name
without a {KERNEL_}HWCAP_ prefix.

Signed-off-by: default avatarAndrew Murray <andrew.murray@arm.com>
[will: use const_ilog2() and tweak documentation]
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent a823c35f
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -13,9 +13,9 @@ architected discovery mechanism available to userspace code at EL0. The
kernel exposes the presence of these features to userspace through a set
of flags called hwcaps, exposed in the auxilliary vector.

Userspace software can test for features by acquiring the AT_HWCAP entry
of the auxilliary vector, and testing whether the relevant flags are
set, e.g.
Userspace software can test for features by acquiring the AT_HWCAP or
AT_HWCAP2 entry of the auxiliary vector, and testing whether the relevant
flags are set, e.g.

bool floating_point_is_present(void)
{
@@ -194,3 +194,10 @@ HWCAP_PACG
    Functionality implied by ID_AA64ISAR1_EL1.GPA == 0b0001 or
    ID_AA64ISAR1_EL1.GPI == 0b0001, as described by
    Documentation/arm64/pointer-authentication.txt.


4. Unused AT_HWCAP bits
-----------------------

For interoperation with userspace, the kernel guarantees that bits 62
and 63 of AT_HWCAP will always be returned as 0.
+1 −1
Original line number Diff line number Diff line
@@ -372,7 +372,7 @@ static struct aead_alg ccm_aes_alg = {

static int __init aes_mod_init(void)
{
	if (!(elf_hwcap & HWCAP_AES))
	if (!cpu_have_named_feature(AES))
		return -ENODEV;
	return crypto_register_aead(&ccm_aes_alg);
}
+1 −1
Original line number Diff line number Diff line
@@ -440,7 +440,7 @@ static int __init aes_init(void)
	int err;
	int i;

	if (!(elf_hwcap & HWCAP_ASIMD))
	if (!cpu_have_named_feature(ASIMD))
		return -ENODEV;

	err = crypto_register_skciphers(aes_algs, ARRAY_SIZE(aes_algs));
+1 −1
Original line number Diff line number Diff line
@@ -173,7 +173,7 @@ static struct skcipher_alg algs[] = {

static int __init chacha_simd_mod_init(void)
{
	if (!(elf_hwcap & HWCAP_ASIMD))
	if (!cpu_have_named_feature(ASIMD))
		return -ENODEV;

	return crypto_register_skciphers(algs, ARRAY_SIZE(algs));
+2 −2
Original line number Diff line number Diff line
@@ -101,7 +101,7 @@ static struct shash_alg crc_t10dif_alg[] = {{

static int __init crc_t10dif_mod_init(void)
{
	if (elf_hwcap & HWCAP_PMULL)
	if (cpu_have_named_feature(PMULL))
		return crypto_register_shashes(crc_t10dif_alg,
					       ARRAY_SIZE(crc_t10dif_alg));
	else
@@ -111,7 +111,7 @@ static int __init crc_t10dif_mod_init(void)

static void __exit crc_t10dif_mod_exit(void)
{
	if (elf_hwcap & HWCAP_PMULL)
	if (cpu_have_named_feature(PMULL))
		crypto_unregister_shashes(crc_t10dif_alg,
					  ARRAY_SIZE(crc_t10dif_alg));
	else
Loading