]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: vgic-its: Add error handling in vgic_its_cache_translation
authorKeisuke Nishimura <keisuke.nishimura@inria.fr>
Sat, 30 Nov 2024 14:49:53 +0000 (15:49 +0100)
committerOliver Upton <oliver.upton@linux.dev>
Wed, 4 Dec 2024 00:22:10 +0000 (16:22 -0800)
The return value of xa_store() needs to be checked. This fix adds an
error handling path that resolves the kref inconsistency on failure. As
suggested by Oliver Upton, this function does not return the error code
intentionally because the translation cache is best effort.

Fixes: 8201d1028caa ("KVM: arm64: vgic-its: Maintain a translation cache per ITS")
Signed-off-by: Keisuke Nishimura <keisuke.nishimura@inria.fr>
Suggested-by: Oliver Upton <oliver.upton@linux.dev>
Acked-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20241130144952.23729-1-keisuke.nishimura@inria.fr
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/vgic/vgic-its.c

index f4c4494645c34bf145baedf63267cbdee16cbe4c..fb96802799c6fedb5df3a5cbcf0b275fb86398a1 100644 (file)
@@ -608,12 +608,22 @@ static void vgic_its_cache_translation(struct kvm *kvm, struct vgic_its *its,
        lockdep_assert_held(&its->its_lock);
        vgic_get_irq_kref(irq);
 
+       old = xa_store(&its->translation_cache, cache_key, irq, GFP_KERNEL_ACCOUNT);
+
+       /*
+        * Put the reference taken on @irq if the store fails. Intentionally do
+        * not return the error as the translation cache is best effort.
+        */
+       if (xa_is_err(old)) {
+               vgic_put_irq(kvm, irq);
+               return;
+       }
+
        /*
         * We could have raced with another CPU caching the same
         * translation behind our back, ensure we don't leak a
         * reference if that is the case.
         */
-       old = xa_store(&its->translation_cache, cache_key, irq, GFP_KERNEL_ACCOUNT);
        if (old)
                vgic_put_irq(kvm, old);
 }