Skip to content

Commit 3ffe5eb

Browse files
author
Claudio Imbrenda
committed
KVM: s390: vsie: Fix races with partial gmap invalidations
Introduce a new boolean flag, used for shadow gmaps, to keep track of whether the gmap has been invalidated, either partially or totally. Use the new flag to check whether shadow gmap invalidations happened during shadowing. In such cases, abort whatever was going on, return -EAGAIN and let the caller try again. Fixes: 19d6c5b ("KVM: s390: vsie: Fix unshadowing while shadowing") Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com> Message-ID: <20260407161721.247044-1-imbrenda@linux.ibm.com>
1 parent bfe62a4 commit 3ffe5eb

3 files changed

Lines changed: 9 additions & 4 deletions

File tree

arch/s390/kvm/gaccess.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,7 +1449,7 @@ static int _do_shadow_pte(struct gmap *sg, gpa_t raddr, union pte *ptep_h, union
14491449
pgste_set_unlock(ptep_h, pgste);
14501450
if (rc)
14511451
return rc;
1452-
if (!sg->parent)
1452+
if (sg->invalidated)
14531453
return -EAGAIN;
14541454

14551455
newpte = _pte(f->pfn, 0, !p, 0);
@@ -1479,7 +1479,7 @@ static int _do_shadow_crste(struct gmap *sg, gpa_t raddr, union crste *host, uni
14791479

14801480
do {
14811481
/* _gmap_crstep_xchg_atomic() could have unshadowed this shadow gmap */
1482-
if (!sg->parent)
1482+
if (sg->invalidated)
14831483
return -EAGAIN;
14841484
oldcrste = READ_ONCE(*host);
14851485
newcrste = _crste_fc1(f->pfn, oldcrste.h.tt, f->writable, !p);
@@ -1492,7 +1492,7 @@ static int _do_shadow_crste(struct gmap *sg, gpa_t raddr, union crste *host, uni
14921492
if (!newcrste.h.p && !f->writable)
14931493
return -EOPNOTSUPP;
14941494
} while (!_gmap_crstep_xchg_atomic(sg->parent, host, oldcrste, newcrste, f->gfn, false));
1495-
if (!sg->parent)
1495+
if (sg->invalidated)
14961496
return -EAGAIN;
14971497

14981498
newcrste = _crste_fc1(f->pfn, oldcrste.h.tt, 0, !p);
@@ -1545,7 +1545,7 @@ static int _gaccess_do_shadow(struct kvm_s390_mmu_cache *mc, struct gmap *sg,
15451545
entries[i].pfn, i + 1, entries[i].writable);
15461546
if (rc)
15471547
return rc;
1548-
if (!sg->parent)
1548+
if (sg->invalidated)
15491549
return -EAGAIN;
15501550
}
15511551

@@ -1601,6 +1601,7 @@ static inline int _gaccess_shadow_fault(struct kvm_vcpu *vcpu, struct gmap *sg,
16011601
scoped_guard(spinlock, &parent->children_lock) {
16021602
if (READ_ONCE(sg->parent) != parent)
16031603
return -EAGAIN;
1604+
sg->invalidated = false;
16041605
rc = _gaccess_do_shadow(vcpu->arch.mc, sg, saddr, walk);
16051606
}
16061607
if (rc == -ENOMEM)

arch/s390/kvm/gmap.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ void gmap_remove_child(struct gmap *child)
181181

182182
list_del(&child->list);
183183
child->parent = NULL;
184+
child->invalidated = true;
184185
}
185186

186187
/**
@@ -1069,6 +1070,7 @@ static void gmap_unshadow_level(struct gmap *sg, gfn_t r_gfn, int level)
10691070
if (level > TABLE_TYPE_PAGE_TABLE)
10701071
align = 1UL << (11 * level + _SEGMENT_SHIFT);
10711072
kvm_s390_vsie_gmap_notifier(sg, ALIGN_DOWN(gaddr, align), ALIGN(gaddr + 1, align));
1073+
sg->invalidated = true;
10721074
if (dat_entry_walk(NULL, r_gfn, sg->asce, 0, level, &crstep, &ptep))
10731075
return;
10741076
if (ptep) {
@@ -1174,6 +1176,7 @@ static inline int __gmap_protect_asce_top_level(struct kvm_s390_mmu_cache *mc, s
11741176
scoped_guard(spinlock, &parent->children_lock) {
11751177
if (READ_ONCE(sg->parent) != parent)
11761178
return -EAGAIN;
1179+
sg->invalidated = false;
11771180
for (i = 0; i < CRST_TABLE_PAGES; i++) {
11781181
if (!context->f[i].valid)
11791182
continue;

arch/s390/kvm/gmap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ enum gmap_flags {
6060
struct gmap {
6161
unsigned long flags;
6262
unsigned char edat_level;
63+
bool invalidated;
6364
struct kvm *kvm;
6465
union asce asce;
6566
struct list_head list;

0 commit comments

Comments
 (0)