From: Claudio Imbrenda <imbrenda@linux.ibm.com>
To: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org, linux-s390@vger.kernel.org,
borntraeger@de.ibm.com, frankja@linux.ibm.com, david@kernel.org,
seiden@linux.ibm.com, nrb@linux.ibm.com,
schlameuss@linux.ibm.com, gra@linux.ibm.com, hca@linux.ibm.com,
gerald.schaefer@linux.ibm.com, gor@linux.ibm.com,
agordeev@linux.ibm.com, svens@linux.ibm.com
Subject: [PATCH v5 7/9] KVM: s390: Fix cmma dirty tracking
Date: Mon, 22 Jun 2026 18:07:37 +0200 [thread overview]
Message-ID: <20260622160739.202044-8-imbrenda@linux.ibm.com> (raw)
In-Reply-To: <20260622160739.202044-1-imbrenda@linux.ibm.com>
It is possible that some guest memory areas have not been touched yet
when starting migration mode, and thus have no ptes allocated. Only
existing and allocated ptes should count toward the total of dirty cmma
entries.
When starting migration mode, count how many pages actually have a pte
(and PGSTE), instead of blindly counting the number of pages in all
memslots.
Also fix dat_get_cmma() to properly wrap around if the first attempt
reached the end of guest memory without finding cmma-dirty pages.
Fixes: e38c884df921 ("KVM: s390: Switch to new gmap")
Signed-off-by: Claudio Imbrenda <imbrenda@linux.ibm.com>
---
arch/s390/kvm/dat.c | 3 +++
arch/s390/kvm/gmap.c | 11 +++++++++--
arch/s390/kvm/kvm-s390.c | 8 +++-----
arch/s390/kvm/priv.c | 2 +-
4 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/s390/kvm/dat.c b/arch/s390/kvm/dat.c
index cffac7782c4b..0ad4ebc80eba 100644
--- a/arch/s390/kvm/dat.c
+++ b/arch/s390/kvm/dat.c
@@ -1253,6 +1253,9 @@ int dat_get_cmma(union asce asce, gfn_t *start, unsigned int *count, u8 *values,
};
_dat_walk_gfn_range(*start, asce_end(asce), asce, &ops, DAT_WALK_IGN_HOLES, &state);
+ /* If no dirty pages were found, wrap around and continue searching */
+ if (*start && state.start == -1)
+ _dat_walk_gfn_range(0, *start, asce, &ops, DAT_WALK_IGN_HOLES, &state);
if (state.start == -1) {
*count = 0;
diff --git a/arch/s390/kvm/gmap.c b/arch/s390/kvm/gmap.c
index e6e786811db8..a9a37fdeb809 100644
--- a/arch/s390/kvm/gmap.c
+++ b/arch/s390/kvm/gmap.c
@@ -1075,7 +1075,13 @@ int gmap_protect_rmap(struct kvm_s390_mmu_cache *mc, struct gmap *sg, gfn_t p_gf
static long __set_cmma_dirty_pte(union pte *ptep, gfn_t gfn, gfn_t next, struct dat_walk *walk)
{
- __atomic64_or(PGSTE_CMMA_D_BIT, &pgste_of(ptep)->val);
+ union pgste pgste;
+
+ pgste = pgste_get_lock(ptep);
+ pgste.cmma_d = 1;
+ pgste_set_unlock(ptep, pgste);
+ atomic64_inc(walk->priv);
+
if (need_resched())
return next;
return 0;
@@ -1089,7 +1095,8 @@ void gmap_set_cmma_all_dirty(struct gmap *gmap)
do {
scoped_guard(read_lock, &gmap->kvm->mmu_lock)
gfn = _dat_walk_gfn_range(gfn, asce_end(gmap->asce), gmap->asce, &ops,
- DAT_WALK_IGN_HOLES, NULL);
+ DAT_WALK_IGN_HOLES,
+ &gmap->kvm->arch.cmma_dirty_pages);
cond_resched();
} while (gfn);
}
diff --git a/arch/s390/kvm/kvm-s390.c b/arch/s390/kvm/kvm-s390.c
index 93141a68e0dd..cdd8b41d24ed 100644
--- a/arch/s390/kvm/kvm-s390.c
+++ b/arch/s390/kvm/kvm-s390.c
@@ -1190,7 +1190,6 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm)
{
struct kvm_memory_slot *ms;
struct kvm_memslots *slots;
- unsigned long ram_pages = 0;
int bkt;
/* migration mode already enabled */
@@ -1207,12 +1206,11 @@ static int kvm_s390_vm_start_migration(struct kvm *kvm)
kvm_for_each_memslot(ms, bkt, slots) {
if (!ms->dirty_bitmap)
return -EINVAL;
- ram_pages += ms->npages;
}
/* mark all the pages as dirty */
+ atomic64_set(&kvm->arch.cmma_dirty_pages, 0);
gmap_set_cmma_all_dirty(kvm->arch.gmap);
- atomic64_set(&kvm->arch.cmma_dirty_pages, ram_pages);
- kvm->arch.migration_mode = 1;
+ WRITE_ONCE(kvm->arch.migration_mode, 1);
kvm_s390_sync_request_broadcast(kvm, KVM_REQ_START_MIGRATION);
return 0;
}
@@ -1226,7 +1224,7 @@ static int kvm_s390_vm_stop_migration(struct kvm *kvm)
/* migration mode already disabled */
if (!kvm->arch.migration_mode)
return 0;
- kvm->arch.migration_mode = 0;
+ WRITE_ONCE(kvm->arch.migration_mode, 0);
if (kvm->arch.use_cmma)
kvm_s390_sync_request_broadcast(kvm, KVM_REQ_STOP_MIGRATION);
return 0;
diff --git a/arch/s390/kvm/priv.c b/arch/s390/kvm/priv.c
index 9bc6fd02ff77..ad0ddc433a73 100644
--- a/arch/s390/kvm/priv.c
+++ b/arch/s390/kvm/priv.c
@@ -1236,7 +1236,7 @@ static int handle_essa(struct kvm_vcpu *vcpu)
: ESSA_SET_STABLE_IF_RESIDENT))
return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION);
- if (!vcpu->kvm->arch.migration_mode) {
+ if (!READ_ONCE(vcpu->kvm->arch.migration_mode)) {
/*
* CMMA is enabled in the KVM settings, but is disabled in
* the SIE block and in the mm_context, and we are not doing
--
2.54.0
next prev parent reply other threads:[~2026-06-22 16:07 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-22 16:07 [PATCH v5 0/9] KVM: s390: A bunch of gmap-related fixes Claudio Imbrenda
2026-06-22 16:07 ` [PATCH v5 1/9] s390/mm: Fix handling of _PAGE_UNUSED pte bit Claudio Imbrenda
2026-06-22 16:07 ` [PATCH v5 2/9] KVM: s390: Fix dat_peek_cmma() overflow Claudio Imbrenda
2026-06-22 16:18 ` Christian Borntraeger
2026-06-22 16:07 ` [PATCH v5 3/9] KVM: s390: Do not set special large pages dirty Claudio Imbrenda
2026-06-22 16:07 ` [PATCH v5 4/9] KVM: s390: Fix code typo in gmap_protect_asce_top_level() Claudio Imbrenda
2026-06-22 16:07 ` [PATCH v5 5/9] KVM: s390: Fix handle_{sske,pfmf} under memory pressure Claudio Imbrenda
2026-06-22 16:07 ` [PATCH v5 6/9] KVM: s390: Fix locking in kvm_s390_set_mem_control() Claudio Imbrenda
2026-06-22 16:07 ` Claudio Imbrenda [this message]
2026-06-22 16:07 ` [PATCH v5 8/9] KVM: s390: selftests: Fix cmma selftest Claudio Imbrenda
2026-06-22 16:07 ` [PATCH v5 9/9] KVM: s390: Return failure in case of failure in kvm_s390_set_cmma_bits() Claudio Imbrenda
2026-06-23 9:30 ` Christian Borntraeger
2026-06-23 10:33 ` Claudio Imbrenda
2026-06-23 10:35 ` Christian Borntraeger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260622160739.202044-8-imbrenda@linux.ibm.com \
--to=imbrenda@linux.ibm.com \
--cc=agordeev@linux.ibm.com \
--cc=borntraeger@de.ibm.com \
--cc=david@kernel.org \
--cc=frankja@linux.ibm.com \
--cc=gerald.schaefer@linux.ibm.com \
--cc=gor@linux.ibm.com \
--cc=gra@linux.ibm.com \
--cc=hca@linux.ibm.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-s390@vger.kernel.org \
--cc=nrb@linux.ibm.com \
--cc=schlameuss@linux.ibm.com \
--cc=seiden@linux.ibm.com \
--cc=svens@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®