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)
#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
* 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);
}
# 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