git: 9204a315a71c - main - arm64: Add a sysctl to see if features are enabled
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 04 Sep 2025 16:28:47 UTC
The branch main has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=9204a315a71c5aa9a9b8c11f2dcefb155dd5fc34
commit 9204a315a71c5aa9a9b8c11f2dcefb155dd5fc34
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-09-04 14:44:31 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2025-09-04 14:44:39 +0000
arm64: Add a sysctl to see if features are enabled
This will also be used as a tunable to control features in a later
change.
Reviewed by: imp
Sponsored by: Arm Ltd
Differential Revision: https://reviews.freebsd.org/D52357
---
sys/arm/arm/generic_timer.c | 5 +++--
sys/arm64/arm64/cpu_feat.c | 7 +++++--
sys/arm64/arm64/identcpu.c | 6 ++++--
sys/arm64/arm64/machdep.c | 6 ++++--
sys/arm64/arm64/pmap.c | 8 +++++---
sys/arm64/arm64/ptrauth.c | 6 ++++--
sys/arm64/include/cpu_feat.h | 13 ++++++++++---
7 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 841e5f9e96aa..27c985c5fcbe 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -892,16 +892,17 @@ wfxt_check(const struct cpu_feat *feat __unused, u_int midr __unused)
return (ID_AA64ISAR2_WFxT_VAL(id_aa64isar2) != ID_AA64ISAR2_WFxT_NONE);
}
-static void
+static bool
wfxt_enable(const struct cpu_feat *feat __unused,
cpu_feat_errata errata_status __unused, u_int *errata_list __unused,
u_int errata_count __unused)
{
/* will be called if wfxt_check returns true */
enable_wfxt = true;
+ return (true);
}
-CPU_FEAT(feat_wfxt,
+CPU_FEAT(feat_wfxt, "WFE and WFI instructions with timeout",
wfxt_check, NULL, wfxt_enable,
CPU_FEAT_AFTER_DEV | CPU_FEAT_SYSTEM);
#endif
diff --git a/sys/arm64/arm64/cpu_feat.c b/sys/arm64/arm64/cpu_feat.c
index cc262394913d..fd1b8429295f 100644
--- a/sys/arm64/arm64/cpu_feat.c
+++ b/sys/arm64/arm64/cpu_feat.c
@@ -32,6 +32,8 @@
#include <machine/cpu.h>
#include <machine/cpu_feat.h>
+SYSCTL_NODE(_hw, OID_AUTO, feat, CTLFLAG_RD, 0, "CPU features/errata");
+
/* TODO: Make this a list if we ever grow a callback other than smccc_errata */
static cpu_feat_errata_check_fn cpu_feat_check_cb = NULL;
@@ -97,8 +99,9 @@ enable_cpu_feat(uint32_t stage)
/* Shouldn't be possible */
MPASS(errata_status != ERRATA_UNKNOWN);
- feat->feat_enable(feat, errata_status, errata_list,
- errata_count);
+ if (feat->feat_enable(feat, errata_status, errata_list,
+ errata_count))
+ feat->feat_enabled = true;
}
}
diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index f823cbce37ed..6d70692fdf5d 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -2320,7 +2320,7 @@ user_ctr_has_errata(const struct cpu_feat *feat __unused, u_int midr,
return (false);
}
-static void
+static bool
user_ctr_enable(const struct cpu_feat *feat __unused,
cpu_feat_errata errata_status, u_int *errata_list, u_int errata_count)
{
@@ -2356,9 +2356,11 @@ user_ctr_enable(const struct cpu_feat *feat __unused,
WRITE_SPECIALREG(sctlr_el1,
READ_SPECIALREG(sctlr_el1) & ~SCTLR_UCT);
isb();
+
+ return (true);
}
-CPU_FEAT(trap_ctr,
+CPU_FEAT(trap_ctr, "Trap CTR_EL0",
user_ctr_check, user_ctr_has_errata, user_ctr_enable,
CPU_FEAT_AFTER_DEV | CPU_FEAT_PER_CPU);
diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c
index 8a83185df9b1..c0aeae072570 100644
--- a/sys/arm64/arm64/machdep.c
+++ b/sys/arm64/arm64/machdep.c
@@ -182,7 +182,7 @@ pan_check(const struct cpu_feat *feat __unused, u_int midr __unused)
return (ID_AA64MMFR1_PAN_VAL(id_aa64mfr1) != ID_AA64MMFR1_PAN_NONE);
}
-static void
+static bool
pan_enable(const struct cpu_feat *feat __unused,
cpu_feat_errata errata_status __unused, u_int *errata_list __unused,
u_int errata_count __unused)
@@ -200,9 +200,11 @@ pan_enable(const struct cpu_feat *feat __unused,
".arch_extension pan \n"
"msr pan, #1 \n"
".arch_extension nopan \n");
+
+ return (true);
}
-CPU_FEAT(feat_pan,
+CPU_FEAT(feat_pan, "Privileged access never",
pan_check, NULL, pan_enable,
CPU_FEAT_EARLY_BOOT | CPU_FEAT_PER_CPU);
diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c
index 77169e122106..96bde42d2711 100644
--- a/sys/arm64/arm64/pmap.c
+++ b/sys/arm64/arm64/pmap.c
@@ -1695,7 +1695,7 @@ pmap_dbm_has_errata(const struct cpu_feat *feat __unused, u_int midr,
return (false);
}
-static void
+static bool
pmap_dbm_enable(const struct cpu_feat *feat __unused,
cpu_feat_errata errata_status, u_int *errata_list __unused,
u_int errata_count)
@@ -1704,7 +1704,7 @@ pmap_dbm_enable(const struct cpu_feat *feat __unused,
/* Skip if there is an erratum affecting DBM */
if (errata_status != ERRATA_NONE)
- return;
+ return (false);
tcr = READ_SPECIALREG(tcr_el1) | TCR_HD;
WRITE_SPECIALREG(tcr_el1, tcr);
@@ -1714,9 +1714,11 @@ pmap_dbm_enable(const struct cpu_feat *feat __unused,
__asm __volatile("tlbi vmalle1");
dsb(nsh);
isb();
+
+ return (true);
}
-CPU_FEAT(feat_hafdbs,
+CPU_FEAT(feat_hafdbs, "Hardware management of the Access flag and dirty state",
pmap_dbm_check, pmap_dbm_has_errata, pmap_dbm_enable,
CPU_FEAT_AFTER_DEV | CPU_FEAT_PER_CPU);
diff --git a/sys/arm64/arm64/ptrauth.c b/sys/arm64/arm64/ptrauth.c
index 7f7a1dd41d8d..7f453dfa278d 100644
--- a/sys/arm64/arm64/ptrauth.c
+++ b/sys/arm64/arm64/ptrauth.c
@@ -141,7 +141,7 @@ out:
return (false);
}
-static void
+static bool
ptrauth_enable(const struct cpu_feat *feat __unused,
cpu_feat_errata errata_status __unused, u_int *errata_list __unused,
u_int errata_count __unused)
@@ -153,9 +153,11 @@ ptrauth_enable(const struct cpu_feat *feat __unused,
elf64_addr_mask_14.code |= PAC_ADDR_MASK_14;
elf64_addr_mask_14.data |= PAC_ADDR_MASK_14;
#endif
+
+ return (true);
}
-CPU_FEAT(feat_pauth,
+CPU_FEAT(feat_pauth, "Pointer Authentication",
ptrauth_check, NULL, ptrauth_enable,
CPU_FEAT_EARLY_BOOT | CPU_FEAT_SYSTEM);
diff --git a/sys/arm64/include/cpu_feat.h b/sys/arm64/include/cpu_feat.h
index 6a0b2d78f526..f62f3e334dc1 100644
--- a/sys/arm64/include/cpu_feat.h
+++ b/sys/arm64/include/cpu_feat.h
@@ -29,6 +29,7 @@
#define _MACHINE_CPU_FEAT_H_
#include <sys/linker_set.h>
+#include <sys/sysctl.h>
typedef enum {
ERRATA_UNKNOWN, /* Unknown erratum */
@@ -52,7 +53,7 @@ struct cpu_feat;
typedef bool (cpu_feat_check)(const struct cpu_feat *, u_int);
typedef bool (cpu_feat_has_errata)(const struct cpu_feat *, u_int,
u_int **, u_int *);
-typedef void (cpu_feat_enable)(const struct cpu_feat *, cpu_feat_errata,
+typedef bool (cpu_feat_enable)(const struct cpu_feat *, cpu_feat_errata,
u_int *, u_int);
struct cpu_feat {
@@ -61,18 +62,24 @@ struct cpu_feat {
cpu_feat_has_errata *feat_has_errata;
cpu_feat_enable *feat_enable;
uint32_t feat_flags;
+ bool feat_enabled;
};
SET_DECLARE(cpu_feat_set, struct cpu_feat);
-#define CPU_FEAT(name, check, has_errata, enable, flags) \
+SYSCTL_DECL(_hw_feat);
+
+#define CPU_FEAT(name, descr, check, has_errata, enable, flags) \
static struct cpu_feat name = { \
.feat_name = #name, \
.feat_check = check, \
.feat_has_errata = has_errata, \
.feat_enable = enable, \
.feat_flags = flags, \
+ .feat_enabled = false, \
}; \
-DATA_SET(cpu_feat_set, name)
+DATA_SET(cpu_feat_set, name); \
+SYSCTL_BOOL(_hw_feat, OID_AUTO, name, CTLFLAG_RD, &name.feat_enabled, \
+ 0, descr)
/*
* Allow drivers to mark an erratum as worked around, e.g. the Errata