]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: s390: Fix a deadlock
authorClaudio Imbrenda <imbrenda@linux.ibm.com>
Tue, 3 Mar 2026 17:52:06 +0000 (18:52 +0100)
committerClaudio Imbrenda <imbrenda@linux.ibm.com>
Fri, 6 Mar 2026 11:41:28 +0000 (12:41 +0100)
In some scenarios, a deadlock can happen, involving _do_shadow_pte().

Convert all usages of pgste_get_lock() to pgste_get_trylock() in
_do_shadow_pte() and return -EAGAIN. All callers can already deal with
-EAGAIN being returned.

Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
Tested-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Reviewed-by: Janosch Frank <frankja@linux.ibm.com>
Reviewed-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
arch/s390/kvm/gaccess.c

index 4630b2a067ea61a299a3e41271cbf4bf33d90935..a9da9390867d3eff35c34c4b42543b341f336cde 100644 (file)
@@ -1434,7 +1434,8 @@ static int _do_shadow_pte(struct gmap *sg, gpa_t raddr, union pte *ptep_h, union
        if (rc)
                return rc;
 
-       pgste = pgste_get_lock(ptep_h);
+       if (!pgste_get_trylock(ptep_h, &pgste))
+               return -EAGAIN;
        newpte = _pte(f->pfn, f->writable, !p, 0);
        newpte.s.d |= ptep->s.d;
        newpte.s.sd |= ptep->s.sd;
@@ -1444,7 +1445,8 @@ static int _do_shadow_pte(struct gmap *sg, gpa_t raddr, union pte *ptep_h, union
        pgste_set_unlock(ptep_h, pgste);
 
        newpte = _pte(f->pfn, 0, !p, 0);
-       pgste = pgste_get_lock(ptep);
+       if (!pgste_get_trylock(ptep, &pgste))
+               return -EAGAIN;
        pgste = __dat_ptep_xchg(ptep, pgste, newpte, gpa_to_gfn(raddr), sg->asce, uses_skeys(sg));
        pgste_set_unlock(ptep, pgste);