KVM: arm64: Save the host's PtrAuth keys in non-preemptible context
[platform/kernel/linux-rpi.git] / virt / kvm / arm / arm.c
index 86c6aa1..986fbc3 100644 (file)
@@ -354,6 +354,16 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu)
        return kvm_vgic_vcpu_init(vcpu);
 }
 
+#ifdef CONFIG_ARM64
+#define __ptrauth_save_key(regs, key)                                          \
+({                                                                             \
+       regs[key ## KEYLO_EL1] = read_sysreg_s(SYS_ ## key ## KEYLO_EL1);       \
+       regs[key ## KEYHI_EL1] = read_sysreg_s(SYS_ ## key ## KEYHI_EL1);       \
+})
+#else
+#define  __ptrauth_save_key(regs, key) do { } while (0)
+#endif
+
 void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
 {
        int *last_ran;
@@ -386,7 +396,17 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
        else
                vcpu_set_wfe_traps(vcpu);
 
-       vcpu_ptrauth_setup_lazy(vcpu);
+       if (vcpu_has_ptrauth(vcpu)) {
+               struct kvm_cpu_context __maybe_unused *ctxt = vcpu->arch.host_cpu_context;
+
+               __ptrauth_save_key(ctxt->sys_regs, APIA);
+               __ptrauth_save_key(ctxt->sys_regs, APIB);
+               __ptrauth_save_key(ctxt->sys_regs, APDA);
+               __ptrauth_save_key(ctxt->sys_regs, APDB);
+               __ptrauth_save_key(ctxt->sys_regs, APGA);
+
+               vcpu_ptrauth_disable(vcpu);
+       }
 }
 
 void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)