[PATCH v2 19/20] KVM: s390: arm64: Promote PTRAUTH capability

From: Steffen Eiden

Date: Mon Aug 31 2026 - 13:16:40 EST


Promote the pointer authentication capability if supported by hardware.

Signed-off-by: Steffen Eiden <seiden@xxxxxxxxxxxxx>
---
arch/s390/include/asm/kvm_host_arm64.h | 8 ++------
arch/s390/kvm/arm64/arm.c | 9 +++++++++
arch/s390/kvm/arm64/feature.c | 18 ++++++++++++++++++
arch/s390/kvm/arm64/feature.h | 5 +++++
4 files changed, 34 insertions(+), 6 deletions(-)

diff --git a/arch/s390/include/asm/kvm_host_arm64.h b/arch/s390/include/asm/kvm_host_arm64.h
index 73eb09e98848..32facf045704 100644
--- a/arch/s390/include/asm/kvm_host_arm64.h
+++ b/arch/s390/include/asm/kvm_host_arm64.h
@@ -32,6 +32,8 @@ bool cpus_have_final_cap(unsigned int num);
#define KVM_HAVE_MMU_RWLOCK
#define KVM_MAX_VCPUS 1
#define KVM_S390_ARM64_IMPL_FEATURES ( \
+ BIT(KVM_ARM_VCPU_PTRAUTH_ADDRESS) | \
+ BIT(KVM_ARM_VCPU_PTRAUTH_GENERIC) | \
BIT(KVM_ARM_VCPU_SVE) \
)

@@ -133,7 +135,6 @@ struct kvm_vcpu_stat {
};

#define kvm_has_mte(_kvm) false
-#define vcpu_has_ptrauth(_vcpu) false

struct kvm_arch_memory_slot {
};
@@ -170,11 +171,6 @@ struct kvm_vm_stat {
struct kvm_vm_stat_generic generic;
};

-static inline bool system_has_full_ptr_auth(void)
-{
- return true;
-}
-
#define kvm_vm_is_protected(_kvm) false
#define vcpu_is_protected(_vcpu) false

diff --git a/arch/s390/kvm/arm64/arm.c b/arch/s390/kvm/arm64/arm.c
index a46c9c62a5f9..ebd8045c0900 100644
--- a/arch/s390/kvm/arm64/arm.c
+++ b/arch/s390/kvm/arm64/arm.c
@@ -57,6 +57,10 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
case KVM_CAP_ARM_SVE:
ret = system_supports_sve();
break;
+ case KVM_CAP_ARM_PTRAUTH_ADDRESS:
+ case KVM_CAP_ARM_PTRAUTH_GENERIC:
+ ret = kvm_has_full_ptr_auth();
+ break;
default:
ret = 0;
}
@@ -265,6 +269,11 @@ static unsigned long system_supported_vcpu_features(void)
if (!system_supports_sve())
clear_bit(KVM_ARM_VCPU_SVE, &features);

+ if (!kvm_has_full_ptr_auth()) {
+ clear_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, &features);
+ clear_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, &features);
+ }
+
return features;
}

diff --git a/arch/s390/kvm/arm64/feature.c b/arch/s390/kvm/arm64/feature.c
index 3847cdd2f92b..a2848e4b3e62 100644
--- a/arch/s390/kvm/arm64/feature.c
+++ b/arch/s390/kvm/arm64/feature.c
@@ -170,3 +170,21 @@ bool system_supports_sve(void)
read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1)) ==
ID_AA64PFR0_EL1_SVE_IMP;
}
+
+bool system_has_full_ptr_auth(void)
+{
+ u64 isar1 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR1_EL1);
+ u64 isar2 = read_sanitised_ftr_reg(SYS_ID_AA64ISAR2_EL1);
+ bool address_auth;
+ bool generic_auth;
+
+ address_auth = SYS_FIELD_GET(ID_AA64ISAR1_EL1, APA, isar1) >= ID_AA64ISAR1_EL1_APA_PAuth ||
+ SYS_FIELD_GET(ID_AA64ISAR1_EL1, API, isar1) >= ID_AA64ISAR1_EL1_API_PAuth ||
+ SYS_FIELD_GET(ID_AA64ISAR2_EL1, APA3, isar2) >= ID_AA64ISAR2_EL1_APA3_PAuth;
+
+ generic_auth = SYS_FIELD_GET(ID_AA64ISAR1_EL1, GPA, isar1) >= ID_AA64ISAR1_EL1_GPA_IMP ||
+ SYS_FIELD_GET(ID_AA64ISAR1_EL1, GPI, isar1) >= ID_AA64ISAR1_EL1_GPI_IMP ||
+ SYS_FIELD_GET(ID_AA64ISAR2_EL1, GPA3, isar2) >= ID_AA64ISAR2_EL1_GPA3_IMP;
+
+ return address_auth && generic_auth;
+}
diff --git a/arch/s390/kvm/arm64/feature.h b/arch/s390/kvm/arm64/feature.h
index 892cf8bcf3a1..c11ac0daa428 100644
--- a/arch/s390/kvm/arm64/feature.h
+++ b/arch/s390/kvm/arm64/feature.h
@@ -94,4 +94,9 @@ static inline u64 kvm_sae_irptc(void)

bool system_supports_sve(void);

+#define vcpu_has_ptrauth(vcpu) \
+ (vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_ADDRESS) || \
+ vcpu_has_feature(vcpu, KVM_ARM_VCPU_PTRAUTH_GENERIC))
+bool system_has_full_ptr_auth(void);
+
#endif /* ARCH_S390_KVM_FEATURE_H */
--
2.53.0