aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmit Daniel Kachhap <amit.kachhap@arm.com>2019-04-23 00:42:36 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2019-04-24 10:30:40 -0400
commita22fa321d13b0264976cbbc1d22f4c27c41d3642 (patch)
tree1f68397998eccf792fa7452d89a00ed6e6350488
parent384b40caa8afae44a54e8f69bd37097c0279fdce (diff)
KVM: arm64: Add userspace flag to enable pointer authentication
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>
-rw-r--r--Documentation/arm64/pointer-authentication.txt22
-rw-r--r--Documentation/virtual/kvm/api.txt10
-rw-r--r--arch/arm64/include/asm/kvm_host.h2
-rw-r--r--arch/arm64/include/uapi/asm/kvm.h2
-rw-r--r--arch/arm64/kvm/reset.c27
5 files changed, 58 insertions, 5 deletions
diff --git a/Documentation/arm64/pointer-authentication.txt b/Documentation/arm64/pointer-authentication.txt
index 5baca42ba146..fc71b33de87e 100644
--- a/Documentation/arm64/pointer-authentication.txt
+++ b/Documentation/arm64/pointer-authentication.txt
@@ -87,7 +87,21 @@ used to get and set the keys for a thread.
87Virtualization 87Virtualization
88-------------- 88--------------
89 89
90Pointer authentication is not currently supported in KVM guests. KVM 90Pointer authentication is enabled in KVM guest when each virtual cpu is
91will mask the feature bits from ID_AA64ISAR1_EL1, and attempted use of 91initialised by passing flags KVM_ARM_VCPU_PTRAUTH_[ADDRESS/GENERIC] and
92the feature will result in an UNDEFINED exception being injected into 92requesting these two separate cpu features to be enabled. The current KVM
93the guest. 93guest implementation works by enabling both features together, so both
94these userspace flags are checked before enabling pointer authentication.
95The separate userspace flag will allow to have no userspace ABI changes
96if support is added in the future to allow these two features to be
97enabled independently of one another.
98
99As Arm Architecture specifies that Pointer Authentication feature is
100implemented along with the VHE feature so KVM arm64 ptrauth code relies
101on VHE mode to be present.
102
103Additionally, when these vcpu feature flags are not set then KVM will
104filter out the Pointer Authentication system key registers from
105KVM_GET/SET_REG_* ioctls and mask those features from cpufeature ID
106register. Any attempt to use the Pointer Authentication instructions will
107result in an UNDEFINED exception being injected into the guest.
diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
index e410a9f0f0d4..32afe7f5c35a 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -2761,6 +2761,16 @@ Possible features:
2761 - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU. 2761 - KVM_ARM_VCPU_PMU_V3: Emulate PMUv3 for the CPU.
2762 Depends on KVM_CAP_ARM_PMU_V3. 2762 Depends on KVM_CAP_ARM_PMU_V3.
2763 2763
2764 - KVM_ARM_VCPU_PTRAUTH_ADDRESS: Enables Address Pointer authentication
2765 for arm64 only.
2766 Both KVM_ARM_VCPU_PTRAUTH_ADDRESS and KVM_ARM_VCPU_PTRAUTH_GENERIC
2767 must be requested or neither must be requested.
2768
2769 - KVM_ARM_VCPU_PTRAUTH_GENERIC: Enables Generic Pointer authentication
2770 for arm64 only.
2771 Both KVM_ARM_VCPU_PTRAUTH_ADDRESS and KVM_ARM_VCPU_PTRAUTH_GENERIC
2772 must be requested or neither must be requested.
2773
2764 - KVM_ARM_VCPU_SVE: Enables SVE for the CPU (arm64 only). 2774 - KVM_ARM_VCPU_SVE: Enables SVE for the CPU (arm64 only).
2765 Depends on KVM_CAP_ARM_SVE. 2775 Depends on KVM_CAP_ARM_SVE.
2766 Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE): 2776 Requires KVM_ARM_VCPU_FINALIZE(KVM_ARM_VCPU_SVE):
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 7eebea7059c6..f772ac2fb3e9 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -49,7 +49,7 @@
49 49
50#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS 50#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
51 51
52#define KVM_VCPU_MAX_FEATURES 5 52#define KVM_VCPU_MAX_FEATURES 7
53 53
54#define KVM_REQ_SLEEP \ 54#define KVM_REQ_SLEEP \
55 KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP) 55 KVM_ARCH_REQ_FLAGS(0, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h
index edd2db8e5160..7b7ac0f6cec9 100644
--- a/arch/arm64/include/uapi/asm/kvm.h
+++ b/arch/arm64/include/uapi/asm/kvm.h
@@ -104,6 +104,8 @@ struct kvm_regs {
104#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */ 104#define KVM_ARM_VCPU_PSCI_0_2 2 /* CPU uses PSCI v0.2 */
105#define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */ 105#define KVM_ARM_VCPU_PMU_V3 3 /* Support guest PMUv3 */
106#define KVM_ARM_VCPU_SVE 4 /* enable SVE for this CPU */ 106#define KVM_ARM_VCPU_SVE 4 /* enable SVE for this CPU */
107#define KVM_ARM_VCPU_PTRAUTH_ADDRESS 5 /* VCPU uses address authentication */
108#define KVM_ARM_VCPU_PTRAUTH_GENERIC 6 /* VCPU uses generic authentication */
107 109
108struct kvm_vcpu_init { 110struct kvm_vcpu_init {
109 __u32 target; 111 __u32 target;
diff --git a/arch/arm64/kvm/reset.c b/arch/arm64/kvm/reset.c
index 3402543fdcd3..028d0c604652 100644
--- a/arch/arm64/kvm/reset.c
+++ b/arch/arm64/kvm/reset.c
@@ -221,6 +221,27 @@ static void kvm_vcpu_reset_sve(struct kvm_vcpu *vcpu)
221 memset(vcpu->arch.sve_state, 0, vcpu_sve_state_size(vcpu)); 221 memset(vcpu->arch.sve_state, 0, vcpu_sve_state_size(vcpu));
222} 222}
223 223
224static int kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
225{
226 /* Support ptrauth only if the system supports these capabilities. */
227 if (!has_vhe())
228 return -EINVAL;
229
230 if (!system_supports_address_auth() ||
231 !system_supports_generic_auth())
232 return -EINVAL;
233 /*
234 * For now make sure that both address/generic pointer authentication
235 * features are requested by the userspace together.
236 */
237 if (!test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, vcpu->arch.features) ||
238 !test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, vcpu->arch.features))
239 return -EINVAL;
240
241 vcpu->arch.flags |= KVM_ARM64_GUEST_HAS_PTRAUTH;
242 return 0;
243}
244
224/** 245/**
225 * kvm_reset_vcpu - sets core registers and sys_regs to reset value 246 * kvm_reset_vcpu - sets core registers and sys_regs to reset value
226 * @vcpu: The VCPU pointer 247 * @vcpu: The VCPU pointer
@@ -261,6 +282,12 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
261 kvm_vcpu_reset_sve(vcpu); 282 kvm_vcpu_reset_sve(vcpu);
262 } 283 }
263 284
285 if (test_bit(KVM_ARM_VCPU_PTRAUTH_ADDRESS, vcpu->arch.features) ||
286 test_bit(KVM_ARM_VCPU_PTRAUTH_GENERIC, vcpu->arch.features)) {
287 if (kvm_vcpu_enable_ptrauth(vcpu))
288 goto out;
289 }
290
264 switch (vcpu->arch.target) { 291 switch (vcpu->arch.target) {
265 default: 292 default:
266 if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { 293 if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {