From nobody Thu Sep 4 16:28:48 2025 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4cHlKY21hHz66NBp; Thu, 04 Sep 2025 16:28:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R12" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4cHlKY1BBLz40PS; Thu, 04 Sep 2025 16:28:49 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1757003329; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lbuFmhgbI+o/qZtLa6qwy41CI3NFCA1Le2/X8tzvlsc=; b=AcefcQtvpSpRTJuJvbyd77iDSBcvN8fat68IeOCwX19NT4tgKlxbEl0Inzc66VFvq/0zTz JfEDPVOxqteGGE7LbBIe6s1NAS0L+OhSxtRZeZ7t19G0PeTJ96gWPlm0Jif10Oyfflfd1O vzvVt3KgyPwfCX5rFFN/FzsnbUZUAaXdtNJ38b8zvCKEvV1kmpn0cvvrtMJZ9Ciksu+MlD ZssqY7+p4KJCA/RRq9EF1Bv6yRLEWBUvm9BeOSA1hTAGXhOd0QCE7bW77UrLGla4gvHUhm WjsmektOQP3kjgIb3oVRAJQspcED+JSgVLA2N3xneqqV7rjv80v0dHOwzq90zg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1757003329; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=lbuFmhgbI+o/qZtLa6qwy41CI3NFCA1Le2/X8tzvlsc=; b=EZE9PeRSu2isGG8jDQXqLt65OR+D1lW6BBP5kxUJBEczkS3NdKB01PRkS8fKW/0UPVjw0z V/3iaxMSWl2s873rcCT/L52g+JtudCwg3yEANny4UmWDkbbv6nroH+QXR00OBS2s5O3kKx jVYBlyV9UGvvnMC+RYp2ACtai1zYiWQK1p/eXuY2BFaO/1KSEKdoXtTRwV3Dgy1VmisQ54 vHuFIVxoUKiCpdnPsPGY2j11D/F1AzE+wfbiwXNMh+jPiKfLf/EpjNeHVF54fwVVduRjY0 l8j1cgXyYlfscTzVVtr3IbuUiderT4pqKJvXrtsYWcbGB+C+fGVQkF3SF2Y/kQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1757003329; a=rsa-sha256; cv=none; b=Y87cVZJI1eXL6FhKKdM0CVUVT3djYyimOdBbQQIFFoYsIvtTQ78Q6DYcAWe00ZaZmYN900 z0gMt2A51jdDC4oVPejAebxrDjoz/KFuX5OK2NFr5M1WGQ6qVCFm7in9bFFbfGPe9pKNqz ySNB/1HKFiw5LzBEu4yDk5F2FOpAQ9YdLrbzRh/agQI3mek7r6NXfBecCkKp2sYB3PnvVc m7/3P7/MFnLQsx0TziBqLvG33n9S+l38zGwKCjM/nLXgS5obQTBY04sUWFfAvMg98x1TLu 8OEQu97vxzKZEwF8JaojghGtrifzP9PmhVEy4jnUM8K9qEmLQhZ8HEFR7OOsEQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4cHlKY0jKcz18xX; Thu, 04 Sep 2025 16:28:49 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 584GSnDr033106; Thu, 4 Sep 2025 16:28:49 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 584GSmPL033103; Thu, 4 Sep 2025 16:28:48 GMT (envelope-from git) Date: Thu, 4 Sep 2025 16:28:48 GMT Message-Id: <202509041628.584GSmPL033103@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: 4bc68fa98f68 - main - arm64: Support managing features from loader List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 4bc68fa98f68211ee7943d77cfc91f60ccb5880d Auto-Submitted: auto-generated The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=4bc68fa98f68211ee7943d77cfc91f60ccb5880d commit 4bc68fa98f68211ee7943d77cfc91f60ccb5880d Author: Andrew Turner AuthorDate: 2025-09-04 14:45:09 +0000 Commit: Andrew Turner CommitDate: 2025-09-04 14:45:09 +0000 arm64: Support managing features from loader Allow the user to enable/disable supported cpu features/errata from a known tunable. This will allow the user to disable features, e.g. to work around broken firmware. It can also be used to enable workarounds for rare errata. Reviewed by: imp Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D52358 --- sys/arm/arm/generic_timer.c | 9 ++++++--- sys/arm64/arm64/cpu_feat.c | 22 +++++++++++++++++++++- sys/arm64/arm64/identcpu.c | 10 +++++----- sys/arm64/arm64/machdep.c | 7 +++++-- sys/arm64/arm64/pmap.c | 9 ++++++--- sys/arm64/arm64/ptrauth.c | 8 ++++---- sys/arm64/include/cpu_feat.h | 27 ++++++++++++++++++++++++++- 7 files changed, 73 insertions(+), 19 deletions(-) diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c index 27c985c5fcbe..97976408c943 100644 --- a/sys/arm/arm/generic_timer.c +++ b/sys/arm/arm/generic_timer.c @@ -882,14 +882,17 @@ DELAY(int usec) TSEXIT(); } -static bool +static cpu_feat_en wfxt_check(const struct cpu_feat *feat __unused, u_int midr __unused) { uint64_t id_aa64isar2; if (!get_kernel_reg(ID_AA64ISAR2_EL1, &id_aa64isar2)) - return (false); - return (ID_AA64ISAR2_WFxT_VAL(id_aa64isar2) != ID_AA64ISAR2_WFxT_NONE); + return (FEAT_ALWAYS_DISABLE); + if (ID_AA64ISAR2_WFxT_VAL(id_aa64isar2) >= ID_AA64ISAR2_WFxT_NONE) + return (FEAT_DEFAULT_ENABLE); + + return (FEAT_ALWAYS_DISABLE); } static bool diff --git a/sys/arm64/arm64/cpu_feat.c b/sys/arm64/arm64/cpu_feat.c index fd1b8429295f..986d5079e980 100644 --- a/sys/arm64/arm64/cpu_feat.c +++ b/sys/arm64/arm64/cpu_feat.c @@ -40,10 +40,13 @@ static cpu_feat_errata_check_fn cpu_feat_check_cb = NULL; void enable_cpu_feat(uint32_t stage) { + char tunable[32]; struct cpu_feat **featp, *feat; uint32_t midr; u_int errata_count, *errata_list; cpu_feat_errata errata_status; + cpu_feat_en check_status; + bool val; MPASS((stage & ~CPU_FEAT_STAGE_MASK) == 0); @@ -60,9 +63,26 @@ enable_cpu_feat(uint32_t stage) PCPU_GET(cpuid) != 0) continue; - if (feat->feat_check != NULL && !feat->feat_check(feat, midr)) + if (feat->feat_check != NULL) continue; + check_status = feat->feat_check(feat, midr); + /* Ignore features that are not present */ + if (check_status == FEAT_ALWAYS_DISABLE) + continue; + + snprintf(tunable, sizeof(tunable), "hw.feat.%s", + feat->feat_name); + if (TUNABLE_BOOL_FETCH(tunable, &val)) { + /* Is the feature disabled by the tunable? */ + if (!val) + continue; + /* If enabled by the tunable then enable it */ + } else if (check_status == FEAT_DEFAULT_DISABLE) { + /* No tunable set and disabled by default */ + continue; + } + /* * Check if the feature has any errata that may need a * workaround applied (or it is to install the workaround for diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c index 6d70692fdf5d..f271891f423d 100644 --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -2293,16 +2293,16 @@ user_ctr_has_neoverse_n1_1542419(uint32_t midr, uint64_t ctr) return (false); } -static bool -user_ctr_check(const struct cpu_feat *feat __unused, u_int midr __unused) +static cpu_feat_en +user_ctr_check(const struct cpu_feat *feat __unused, u_int midr) { if (emulate_ctr) - return (true); + return (FEAT_DEFAULT_ENABLE); if (user_ctr_has_neoverse_n1_1542419(midr, READ_SPECIALREG(ctr_el0))) - return (true); + return (FEAT_DEFAULT_ENABLE); - return (false); + return (FEAT_ALWAYS_DISABLE); } static bool diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index c0aeae072570..627b02e82d34 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -173,13 +173,16 @@ SYSINIT(ssp_warn, SI_SUB_COPYRIGHT, SI_ORDER_ANY, print_ssp_warning, NULL); SYSINIT(ssp_warn2, SI_SUB_LAST, SI_ORDER_ANY, print_ssp_warning, NULL); #endif -static bool +static cpu_feat_en pan_check(const struct cpu_feat *feat __unused, u_int midr __unused) { uint64_t id_aa64mfr1; id_aa64mfr1 = READ_SPECIALREG(id_aa64mmfr1_el1); - return (ID_AA64MMFR1_PAN_VAL(id_aa64mfr1) != ID_AA64MMFR1_PAN_NONE); + if (ID_AA64MMFR1_PAN_VAL(id_aa64mfr1) == ID_AA64MMFR1_PAN_NONE) + return (FEAT_ALWAYS_DISABLE); + + return (FEAT_DEFAULT_ENABLE); } static bool diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 96bde42d2711..0ef23edbc0bf 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -1656,14 +1656,17 @@ pmap_init_pv_table(void) } } -static bool +static cpu_feat_en pmap_dbm_check(const struct cpu_feat *feat __unused, u_int midr __unused) { uint64_t id_aa64mmfr1; id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1); - return (ID_AA64MMFR1_HAFDBS_VAL(id_aa64mmfr1) >= - ID_AA64MMFR1_HAFDBS_AF_DBS); + if (ID_AA64MMFR1_HAFDBS_VAL(id_aa64mmfr1) >= + ID_AA64MMFR1_HAFDBS_AF_DBS) + return (FEAT_DEFAULT_ENABLE); + + return (FEAT_ALWAYS_DISABLE); } static bool diff --git a/sys/arm64/arm64/ptrauth.c b/sys/arm64/arm64/ptrauth.c index 7f453dfa278d..fdab5414e24c 100644 --- a/sys/arm64/arm64/ptrauth.c +++ b/sys/arm64/arm64/ptrauth.c @@ -82,7 +82,7 @@ ptrauth_disable(void) return (false); } -static bool +static cpu_feat_en ptrauth_check(const struct cpu_feat *feat __unused, u_int midr __unused) { uint64_t isar; @@ -116,14 +116,14 @@ ptrauth_check(const struct cpu_feat *feat __unused, u_int midr __unused) if (get_kernel_reg(ID_AA64ISAR1_EL1, &isar)) { if (ID_AA64ISAR1_APA_VAL(isar) > 0 || ID_AA64ISAR1_API_VAL(isar) > 0) { - return (true); + return (FEAT_DEFAULT_ENABLE); } } /* The QARMA3 algorithm is reported in ID_AA64ISAR2_EL1. */ if (get_kernel_reg(ID_AA64ISAR2_EL1, &isar)) { if (ID_AA64ISAR2_APA3_VAL(isar) > 0) { - return (true); + return (FEAT_DEFAULT_ENABLE); } } @@ -138,7 +138,7 @@ out: ID_AA64ISAR1_GPI_MASK, 0); update_special_reg(ID_AA64ISAR2_EL1, ID_AA64ISAR2_APA3_MASK, 0); - return (false); + return (FEAT_ALWAYS_DISABLE); } static bool diff --git a/sys/arm64/include/cpu_feat.h b/sys/arm64/include/cpu_feat.h index f62f3e334dc1..6a554b6baedf 100644 --- a/sys/arm64/include/cpu_feat.h +++ b/sys/arm64/include/cpu_feat.h @@ -40,6 +40,31 @@ typedef enum { /* kernel component. */ } cpu_feat_errata; +typedef enum { + /* + * Don't implement the feature or erratum wrokarount, + * e.g. the feature is not implemented or erratum is + * for another CPU. + */ + FEAT_ALWAYS_DISABLE, + + /* + * Disable by default, but allow the user to enable, + * e.g. For a rare erratum with a workaround, Arm + * Category B (rare) or similar. + */ + FEAT_DEFAULT_DISABLE, + + /* + * Enabled by default, bit allow the user to disable, + * e.g. For a common erratum with a workaround, Arm + * Category A or B or similar. + */ + FEAT_DEFAULT_ENABLE, + + /* We could add FEAT_ALWAYS_ENABLE if a need was found. */ +} cpu_feat_en; + #define CPU_FEAT_STAGE_MASK 0x00000001 #define CPU_FEAT_EARLY_BOOT 0x00000000 #define CPU_FEAT_AFTER_DEV 0x00000001 @@ -50,7 +75,7 @@ typedef enum { struct cpu_feat; -typedef bool (cpu_feat_check)(const struct cpu_feat *, u_int); +typedef cpu_feat_en (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 bool (cpu_feat_enable)(const struct cpu_feat *, cpu_feat_errata,