KVM: arm64: Propagate errors from __pkvm_prot_finalize hypercall
authorWill Deacon <will@kernel.org>
Fri, 8 Oct 2021 13:58:37 +0000 (14:58 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 18 Nov 2021 18:16:15 +0000 (19:16 +0100)
[ Upstream commit 2f2e1a5069679491d18cf9021da19b40c56a17f3 ]

If the __pkvm_prot_finalize hypercall returns an error, we WARN but fail
to propagate the failure code back to kvm_arch_init().

Pass a pointer to a zero-initialised return variable so that failure
to finalise the pKVM protections on a host CPU can be reported back to
KVM.

Cc: Marc Zyngier <maz@kernel.org>
Cc: Quentin Perret <qperret@google.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20211008135839.1193-5-will@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/arm64/kvm/arm.c

index fe102cd2e518354d8a84aebea8f6d372a839b0cf..9b328bb05596a1d7a1bc111c7b3752cd494a0c29 100644 (file)
@@ -1971,9 +1971,25 @@ out_err:
        return err;
 }
 
-static void _kvm_host_prot_finalize(void *discard)
+static void _kvm_host_prot_finalize(void *arg)
 {
-       WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize));
+       int *err = arg;
+
+       if (WARN_ON(kvm_call_hyp_nvhe(__pkvm_prot_finalize)))
+               WRITE_ONCE(*err, -EINVAL);
+}
+
+static int pkvm_drop_host_privileges(void)
+{
+       int ret = 0;
+
+       /*
+        * Flip the static key upfront as that may no longer be possible
+        * once the host stage 2 is installed.
+        */
+       static_branch_enable(&kvm_protected_mode_initialized);
+       on_each_cpu(_kvm_host_prot_finalize, &ret, 1);
+       return ret;
 }
 
 static int finalize_hyp_mode(void)
@@ -1987,15 +2003,7 @@ static int finalize_hyp_mode(void)
         * None of other sections should ever be introspected.
         */
        kmemleak_free_part(__hyp_bss_start, __hyp_bss_end - __hyp_bss_start);
-
-       /*
-        * Flip the static key upfront as that may no longer be possible
-        * once the host stage 2 is installed.
-        */
-       static_branch_enable(&kvm_protected_mode_initialized);
-       on_each_cpu(_kvm_host_prot_finalize, NULL, 1);
-
-       return 0;
+       return pkvm_drop_host_privileges();
 }
 
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)