KVM: arm64: Add userspace flag to enable pointer authentication
authorAmit Daniel Kachhap <amit.kachhap@arm.com>
Tue, 23 Apr 2019 04:42:36 +0000 (10:12 +0530)
committerMarc Zyngier <marc.zyngier@arm.com>
Wed, 24 Apr 2019 14:30:40 +0000 (15:30 +0100)
Now that the building blocks of pointer authentication are present, lets
add userspace flags KVM_ARM_VCPU_PTRAUTH_ADDRESS and
KVM_ARM_VCPU_PTRAUTH_GENERIC. These flags will enable pointer
authentication for the KVM guest on a per-vcpu basis through the ioctl
KVM_ARM_VCPU_INIT.

This features will allow the KVM guest to allow the handling of
pointer authentication instructions or to treat them as undefined
if not set.

Necessary documentations are added to reflect the changes done.

Reviewed-by: Dave Martin <Dave.Martin@arm.com>
Signed-off-by: Amit Daniel Kachhap <amit.kachhap@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Marc Zyngier <marc.zyngier@arm.com>
Cc: Christoffer Dall <christoffer.dall@arm.com>
Cc: kvmarm@lists.cs.columbia.edu
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Documentation/arm64/pointer-authentication.txt
Documentation/virtual/kvm/api.txt
arch/arm64/include/asm/kvm_host.h
arch/arm64/include/uapi/asm/kvm.h
arch/arm64/kvm/reset.c

index 5baca42ba146dd56c6c3e1ca433173290fe9ef5c..fc71b33de87ed1fc58cfd26d4a9a7f0f40c2adff 100644 (file)
@@ -87,7 +87,21 @@ used to get and set the keys for a thread.
 Virtualization
 --------------
 
-Pointer authentication is not currently supported in KVM guests. KVM
-will mask the feature bits from ID_AA64ISAR1_EL1, and attempted use of
-the feature will result in an UNDEFINED exception being injected into
-the guest.
+Pointer authentication is enabled in KVM guest when each virtual cpu is
+initialised by passing flags KVM_ARM_VCPU_PTRAUTH_[ADDRESS/GENERIC] and
+requesting these two separate cpu features to be enabled. The current KVM
+guest implementation works by enabling both features together, so both
+these userspace flags are checked before enabling pointer authentication.
+The separate userspace flag will allow to have no userspace ABI changes
+if support is added in the future to allow these two features to be
+enabled independently of one another.
+
+As Arm Architecture specifies that Pointer Authentication feature is
+implemented along with the VHE feature so KVM arm64 ptrauth code relies
+on VHE mode to be present.
+
+Additionally, when these vcpu feature flags are not set then KVM will
+filter out the Pointer Authentication system key registers from
+KVM_GET/SET_REG_* ioctls and mask those features from cpufeature ID
+register. Any attempt to use the Pointer Authentication instructions will
+result in an UNDEFINED exception being injected into the guest.
index e410a9f0f0d48b7ed72d062c80cb7ef18c79221a..32afe7f5c35af57b86b24705f629586fed4836b4 100644 (file)
@@ -2761,6 +2761,16 @@ Possible features:
        - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU.
          Depends on KVM_CAP_ARM_PMU_V3.
 
+       - KVM_ARM_VCPU_PTRAUTH_ADDRESS: Enables Address Pointer authentication
+         for arm64 only.
+         Both KVM_ARM_VCPU_PTRAUTH_ADDRESS and KVM_ARM_VCPU_PTRAUTH_GENERIC
+         must be requested or neither must be requested.
+
+       - KVM_ARM_VCPU_PTRAUTH_GENERIC: Enables Generic Pointer authentication
+         for arm64 only.
+         Both KVM_ARM_VCPU_PTRAUTH_ADDRESS and KVM_ARM_VCPU_PTRAUTH_GENERIC
+         must be requested or neither must be requested.
+
        - KVM_ARM_VCPU_SVE: Enables SVE for the CPU (arm64 only).
          Depends on KVM_CAP_ARM_SVE.
          Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE):
index 7eebea7059c672917d6a9e8c3eff294fa37855b0..f772ac2fb3e9ab7da023da6bcb07e88d4bf3f00e 100644 (file)
@@ -49,7 +49,7 @@
 
 #define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
 
-#define KVM_VCPU_MAX_FEATURES 5
+#define KVM_VCPU_MAX_FEATURES 7
 
 #define KVM_REQ_SLEEP \
        KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
index edd2db8e516091475884a75b4e6fcc523cd06a20..7b7ac0f6cec9e87c93abbaa2ddffea565c3302b0 100644 (file)
@@ -104,6 +104,8 @@ struct kvm_regs {
 #define KVM_ARM_VCPU_PSCI_0_2          2 /* CPU uses PSCI v0.2 */
 #define KVM_ARM_VCPU_PMU_V3            3 /* Support guest PMUv3 */
 #define KVM_ARM_VCPU_SVE               4 /* enable SVE for this CPU */
+#define KVM_ARM_VCPU_PTRAUTH_ADDRESS   5 /* VCPU uses address authentication */
+#define KVM_ARM_VCPU_PTRAUTH_GENERIC   6 /* VCPU uses generic authentication */
 
 struct kvm_vcpu_init {
        __u32 target;
index 3402543fdcd3c000dbfb64fe00276de655040938..028d0c604652ef1b29298caeaba7a6058dcbdaa3 100644 (file)
@@ -221,6 +221,27 @@ static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu)
                memset(vcpu->arch.sve_state, 0, vcpu_sve_state_size(vcpu));
 }
 
+static int kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
+{
+       /* Support ptrauth only if the system supports these capabilities. */
+       if (!has_vhe())
+               return -EINVAL;
+
+       if (!system_supports_address_auth() ||
+           !system_supports_generic_auth())
+               return -EINVAL;
+       /*
+        * For now make sure that both address/generic pointer authentication
+        * features are requested by the userspace together.
+        */
+       if (!test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, vcpu->arch.features) ||
+           !test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, vcpu->arch.features))
+               return -EINVAL;
+
+       vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_PTRAUTH;
+       return 0;
+}
+
 /**
  * kvm_reset_vcpu - sets core registers and sys_regs to reset value
  * @vcpu: The VCPU pointer
@@ -261,6 +282,12 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
                kvm_vcpu_reset_sve(vcpu);
        }
 
+       if (test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, vcpu->arch.features) ||
+           test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, vcpu->arch.features)) {
+               if (kvm_vcpu_enable_ptrauth(vcpu))
+                       goto out;
+       }
+
        switch (vcpu->arch.target) {
        default:
                if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {