In order to be able to disable Pointer Authentication  at runtime,
whether it is for testing purposes, or to work around HW issues,
let's add support for overriding the ID_AA64ISAR1_EL1.{GPI,GPA,API,APA}
fields.

This is further mapped on the arm64.nopauth command-line alias.

Signed-off-by: Marc Zyngier <m...@kernel.org>
---
 Documentation/admin-guide/kernel-parameters.txt |  3 +++
 arch/arm64/include/asm/cpufeature.h             |  2 ++
 arch/arm64/kernel/cpufeature.c                  |  5 ++++-
 arch/arm64/kernel/idreg-override.c              | 17 +++++++++++++++++
 4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/Documentation/admin-guide/kernel-parameters.txt 
b/Documentation/admin-guide/kernel-parameters.txt
index 7599fd0f1ad7..f9cb28a39bd0 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -376,6 +376,9 @@
        arm64.nobti     [ARM64] Unconditionally disable Branch Target
                        Identification support
 
+       arm64.nopauth   [ARM64] Unconditionally disable Pointer Authentication
+                       support
+
        ataflop=        [HW,M68k]
 
        atarimouse=     [HW,MOUSE] Atari Mouse
diff --git a/arch/arm64/include/asm/cpufeature.h 
b/arch/arm64/include/asm/cpufeature.h
index d3e0f6dd43c4..9d8dcf380ad5 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -818,6 +818,8 @@ extern u64 id_aa64mmfr1_val;
 extern u64 id_aa64mmfr1_mask;
 extern u64 id_aa64pfr1_val;
 extern u64 id_aa64pfr1_mask;
+extern u64 id_aa64isar1_val;
+extern u64 id_aa64isar1_mask;
 
 u32 get_kvm_ipa_limit(void);
 void dump_cpu_features(void);
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index f223171a7c34..f5ba7fd615b5 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -559,6 +559,8 @@ u64 id_aa64mmfr1_val;
 u64 id_aa64mmfr1_mask;
 u64 id_aa64pfr1_val;
 u64 id_aa64pfr1_mask;
+u64 id_aa64isar1_val;
+u64 id_aa64isar1_mask;
 
 static const struct __ftr_reg_entry {
        u32                     sys_id;
@@ -604,7 +606,8 @@ static const struct __ftr_reg_entry {
 
        /* Op1 = 0, CRn = 0, CRm = 6 */
        ARM64_FTR_REG(SYS_ID_AA64ISAR0_EL1, ftr_id_aa64isar0),
-       ARM64_FTR_REG(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1),
+       ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ISAR1_EL1, ftr_id_aa64isar1,
+                              &id_aa64isar1_val, &id_aa64isar1_mask),
 
        /* Op1 = 0, CRn = 0, CRm = 7 */
        ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
diff --git a/arch/arm64/kernel/idreg-override.c 
b/arch/arm64/kernel/idreg-override.c
index a9e3ed193fd4..7037c9b214d0 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -43,6 +43,19 @@ static const struct reg_desc pfr1 __initdata = {
        },
 };
 
+static const struct reg_desc isar1 __initdata = {
+       .name           = "id_aa64isar1",
+       .val            = &id_aa64isar1_val,
+       .mask           = &id_aa64isar1_mask,
+       .fields         = {
+               { "gpi", ID_AA64ISAR1_GPI_SHIFT },
+               { "gpa", ID_AA64ISAR1_GPA_SHIFT },
+               { "api", ID_AA64ISAR1_API_SHIFT },
+               { "apa", ID_AA64ISAR1_APA_SHIFT },
+               {}
+       },
+};
+
 extern u64 kaslr_feature_val;
 extern u64 kaslr_feature_mask;
 
@@ -61,6 +74,7 @@ static const struct reg_desc kaslr __initdata = {
 static const struct reg_desc * const regs[] __initdata = {
        &mmfr1,
        &pfr1,
+       &isar1,
        &kaslr,
 };
 
@@ -71,6 +85,9 @@ static const struct {
        { "kvm-arm.mode=nvhe",          "id_aa64mmfr1.vh=0" },
        { "kvm-arm.mode=protected",     "id_aa64mmfr1.vh=0" },
        { "arm64.nobti",                "id_aa64pfr1.bt=0" },
+       { "arm64.nopauth",
+         "id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
+         "id_aa64isar1.api=0 id_aa64isar1.apa=0"          },
        { "nokaslr",                    "kaslr.disabled=1" },
 };
 
-- 
2.29.2

Reply via email to