vpaes: LoongArch: Use getauxval(AT_HWCAP) for LSX detection

Running LSX instructions requires both the hardware support and the
kernel support.  The `cpucfg` instruction only tests the hardware
support, causing a SIGILL if the hardware supports LSX but the kernel
does not.

Use `getauxval(AT_HWCAP)` as the ["Software Development and Build
Convention for LoongArch Architectures"][1] manual suggests.

The LOONGARCH_HWCAP_LSX and LOONGARCH_HWCAP_LASX bits are copied from
the manual too.  In Glibc 2.38 they'll be provided by <sys/auxv.h> as
well, but they are unavailable in earlier Glibc versions so we cannot
rely on it.

The getauxval syscall and Glibc wrapper are available since day one
(Linux-5.19 and Glibc-2.36) for LoongArch.

Fixes #21508.

[1]:https://github.com/loongson/la-softdev-convention/blob/master/la-softdev-convention.adoc#kernel-constraints

Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/21509)
This commit is contained in:
Xi Ruoyao 2023-07-21 02:07:04 +00:00 committed by Pauli
parent 7f14656e1c
commit c612289b77
3 changed files with 7 additions and 13 deletions

View File

@ -9,9 +9,8 @@
#ifndef OSSL_CRYPTO_LOONGARCH_ARCH_H
# define OSSL_CRYPTO_LOONGARCH_ARCH_H
extern unsigned int OPENSSL_loongarchcap_P;
# define LOONGARCH_CFG2 0x02
# define LOONGARCH_CFG2_LSX (1<<6)
# define LOONGARCH_CFG2_LASX (1<<7)
extern unsigned int OPENSSL_loongarch_hwcap_P;
# define LOONGARCH_HWCAP_LSX (1 << 4)
# define LOONGARCH_HWCAP_LASX (1 << 5)
#endif

View File

@ -6,17 +6,12 @@
* in the file LICENSE in the source distribution or at
* https://www.openssl.org/source/license.html
*/
#include <sys/auxv.h>
#include "loongarch_arch.h"
unsigned int OPENSSL_loongarchcap_P = 0;
unsigned int OPENSSL_loongarch_hwcap_P = 0;
void OPENSSL_cpuid_setup(void)
{
unsigned int reg;
__asm__ volatile(
"cpucfg %0, %1 \n\t"
: "+&r"(reg)
: "r"(LOONGARCH_CFG2)
);
OPENSSL_loongarchcap_P = reg;
OPENSSL_loongarch_hwcap_P = getauxval(AT_HWCAP);
}

View File

@ -165,7 +165,7 @@ void gcm_ghash_v8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len);
# if defined(__loongarch__) || defined(__loongarch64)
# include "loongarch_arch.h"
# if defined(VPAES_ASM)
# define VPAES_CAPABLE (OPENSSL_loongarchcap_P & LOONGARCH_CFG2_LSX)
# define VPAES_CAPABLE (OPENSSL_loongarch_hwcap_P & LOONGARCH_HWCAP_LSX)
# endif
# endif