Export the ID_AA64ISARn_EL1 registers to userspace through sysctl(2) such
authorkettenis <kettenis@openbsd.org>
Wed, 23 Mar 2022 23:36:35 +0000 (23:36 +0000)
committerkettenis <kettenis@openbsd.org>
Wed, 23 Mar 2022 23:36:35 +0000 (23:36 +0000)
that we can detect which instruction set extensions are supported without
relying in catching SIGILL.

ok deraadt@

sys/arch/arm64/arm64/cpu.c
sys/arch/arm64/arm64/machdep.c
sys/arch/arm64/include/cpu.h

index 654eac1..753f40b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cpu.c,v 1.61 2022/03/02 12:45:35 kettenis Exp $       */
+/*     $OpenBSD: cpu.c,v 1.62 2022/03/23 23:36:35 kettenis Exp $       */
 
 /*
  * Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
@@ -173,6 +173,9 @@ const struct implementers {
 char cpu_model[64];
 int cpu_node;
 
+uint64_t cpu_id_aa64isar0;
+uint64_t cpu_id_aa64isar1;
+
 #ifdef CRYPTO
 int arm64_has_aes;
 #endif
@@ -344,6 +347,15 @@ cpu_identify(struct cpu_info *ci)
         * Print CPU features encoded in the ID registers.
         */
 
+       if (READ_SPECIALREG(id_aa64isar0_el1) != cpu_id_aa64isar0) {
+               printf("\n%s: mismatched ID_AA64ISAR0_EL1",
+                   ci->ci_dev->dv_xname);
+       }
+       if (READ_SPECIALREG(id_aa64isar1_el1) != cpu_id_aa64isar1) {
+               printf("\n%s: mismatched ID_AA64ISAR1_EL1",
+                   ci->ci_dev->dv_xname);
+       }
+
        printf("\n%s: ", ci->ci_dev->dv_xname);
 
        /*
@@ -684,6 +696,9 @@ cpu_attach(struct device *parent, struct device *dev, void *aux)
                }
        } else {
 #endif
+               cpu_id_aa64isar0 = READ_SPECIALREG(id_aa64isar0_el1);
+               cpu_id_aa64isar1 = READ_SPECIALREG(id_aa64isar1_el1);
+
                cpu_identify(ci);
 
                if (OF_getproplen(ci->ci_node, "clocks") > 0) {
index 693c135..6453043 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.68 2022/02/25 13:51:02 visa Exp $ */
+/* $OpenBSD: machdep.c,v 1.69 2022/03/23 23:36:35 kettenis Exp $ */
 /*
  * Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
  * Copyright (c) 2021 Mark Kettenis <kettenis@openbsd.org>
@@ -313,6 +313,9 @@ cpu_switchto(struct proc *old, struct proc *new)
        cpu_switchto_asm(old, new);
 }
 
+extern uint64_t cpu_id_aa64isar0;
+extern uint64_t cpu_id_aa64isar1;
+
 /*
  * machine dependent system variables.
  */
@@ -340,6 +343,10 @@ cpu_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
                error = sysctl_rdstring(oldp, oldlenp, newp, compatible);
                free(compatible, M_TEMP, len);
                return error;
+       case CPU_ID_AA64ISAR0:
+               return sysctl_rdquad(oldp, oldlenp, newp, cpu_id_aa64isar0);
+       case CPU_ID_AA64ISAR1:
+               return sysctl_rdquad(oldp, oldlenp, newp, cpu_id_aa64isar1);
        default:
                return (EOPNOTSUPP);
        }
index c09ff80..a57b9c2 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: cpu.h,v 1.24 2022/01/01 18:52:37 kettenis Exp $ */
+/* $OpenBSD: cpu.h,v 1.25 2022/03/23 23:36:35 kettenis Exp $ */
 /*
  * Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
  *
  * CTL_MACHDEP definitions.
  */
 #define        CPU_COMPATIBLE          1       /* compatible property */
-#define        CPU_MAXID               2       /* number of valid machdep ids */
+#define        CPU_ID_AA64ISAR0        2
+#define        CPU_ID_AA64ISAR1        3
+#define        CPU_MAXID               4       /* number of valid machdep ids */
 
 #define        CTL_MACHDEP_NAMES { \
        { 0, 0 }, \
        { "compatible", CTLTYPE_STRING }, \
+       { "id_aa64isar0", CTLTYPE_QUAD }, \
+       { "id_aa64isar1", CTLTYPE_QUAD }, \
 }
 
 #ifdef _KERNEL